mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-15 16:26:08 +03:00
macos: set NSAppearance on windowDidLoad (#3077)
Fixes #3072 Previously, when `window-theme = auto`, the appearance was delayed enough on the DispatchQueue that the window was already visible. This would result in the window appearing with the wrong appearance before switching to the correct one. For annoying reasons, we can't set the NSApplication.shared.appearance in `applicationDidFinishLaunching` because it results in a deadlock with AppKit. This commit moves to set the `NSWindow.appearance` in `windowDidLoad` (and any config sync) to ensure that the appearance is set before the window is visible. This is probably the right solution anyways because this allows windows with different background colors to each have their own distinct appearance.
This commit is contained in:
@ -546,24 +546,7 @@ class AppDelegate: NSObject,
|
|||||||
|
|
||||||
/// Sync the appearance of our app with the theme specified in the config.
|
/// Sync the appearance of our app with the theme specified in the config.
|
||||||
private func syncAppearance(config: Ghostty.Config) {
|
private func syncAppearance(config: Ghostty.Config) {
|
||||||
guard let theme = config.windowTheme else { return }
|
NSApplication.shared.appearance = .init(ghosttyConfig: config)
|
||||||
switch (theme) {
|
|
||||||
case "dark":
|
|
||||||
let appearance = NSAppearance(named: .darkAqua)
|
|
||||||
NSApplication.shared.appearance = appearance
|
|
||||||
|
|
||||||
case "light":
|
|
||||||
let appearance = NSAppearance(named: .aqua)
|
|
||||||
NSApplication.shared.appearance = appearance
|
|
||||||
|
|
||||||
case "auto":
|
|
||||||
let color = OSColor(config.backgroundColor)
|
|
||||||
let appearance = NSAppearance(named: color.isLightColor ? .aqua : .darkAqua)
|
|
||||||
NSApplication.shared.appearance = appearance
|
|
||||||
|
|
||||||
default:
|
|
||||||
NSApplication.shared.appearance = nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//MARK: - Restorable State
|
//MARK: - Restorable State
|
||||||
|
@ -201,6 +201,9 @@ class TerminalController: BaseTerminalController {
|
|||||||
private func syncAppearance(_ surfaceConfig: Ghostty.SurfaceView.DerivedConfig) {
|
private func syncAppearance(_ surfaceConfig: Ghostty.SurfaceView.DerivedConfig) {
|
||||||
guard let window = self.window as? TerminalWindow else { return }
|
guard let window = self.window as? TerminalWindow else { return }
|
||||||
|
|
||||||
|
// Set our explicit appearance if we need to based on the configuration.
|
||||||
|
window.appearance = surfaceConfig.windowAppearance
|
||||||
|
|
||||||
// If our window is not visible, then we do nothing. Some things such as blurring
|
// If our window is not visible, then we do nothing. Some things such as blurring
|
||||||
// have no effect if the window is not visible. Ultimately, we'll have this called
|
// have no effect if the window is not visible. Ultimately, we'll have this called
|
||||||
// at some point when a surface becomes focused.
|
// at some point when a surface becomes focused.
|
||||||
|
@ -1097,12 +1097,14 @@ extension Ghostty {
|
|||||||
let backgroundOpacity: Double
|
let backgroundOpacity: Double
|
||||||
let macosWindowShadow: Bool
|
let macosWindowShadow: Bool
|
||||||
let windowTitleFontFamily: String?
|
let windowTitleFontFamily: String?
|
||||||
|
let windowAppearance: NSAppearance?
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
self.backgroundColor = Color(NSColor.windowBackgroundColor)
|
self.backgroundColor = Color(NSColor.windowBackgroundColor)
|
||||||
self.backgroundOpacity = 1
|
self.backgroundOpacity = 1
|
||||||
self.macosWindowShadow = true
|
self.macosWindowShadow = true
|
||||||
self.windowTitleFontFamily = nil
|
self.windowTitleFontFamily = nil
|
||||||
|
self.windowAppearance = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
init(_ config: Ghostty.Config) {
|
init(_ config: Ghostty.Config) {
|
||||||
@ -1110,6 +1112,7 @@ extension Ghostty {
|
|||||||
self.backgroundOpacity = config.backgroundOpacity
|
self.backgroundOpacity = config.backgroundOpacity
|
||||||
self.macosWindowShadow = config.macosWindowShadow
|
self.macosWindowShadow = config.macosWindowShadow
|
||||||
self.windowTitleFontFamily = config.windowTitleFontFamily
|
self.windowTitleFontFamily = config.windowTitleFontFamily
|
||||||
|
self.windowAppearance = .init(ghosttyConfig: config)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,4 +5,27 @@ extension NSAppearance {
|
|||||||
var isDark: Bool {
|
var isDark: Bool {
|
||||||
return name.rawValue.lowercased().contains("dark")
|
return name.rawValue.lowercased().contains("dark")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Initialize a desired NSAppearance for the Ghostty configuration.
|
||||||
|
convenience init?(ghosttyConfig config: Ghostty.Config) {
|
||||||
|
guard let theme = config.windowTheme else { return nil }
|
||||||
|
switch (theme) {
|
||||||
|
case "dark":
|
||||||
|
self.init(named: .darkAqua)
|
||||||
|
|
||||||
|
case "light":
|
||||||
|
self.init(named: .aqua)
|
||||||
|
|
||||||
|
case "auto":
|
||||||
|
let color = OSColor(config.backgroundColor)
|
||||||
|
if color.isLightColor {
|
||||||
|
self.init(named: .aqua)
|
||||||
|
} else {
|
||||||
|
self.init(named: .darkAqua)
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user