diff --git a/macos/Sources/Features/Terminal/TerminalController.swift b/macos/Sources/Features/Terminal/TerminalController.swift index 84b8ad01c..419505aa8 100644 --- a/macos/Sources/Features/Terminal/TerminalController.swift +++ b/macos/Sources/Features/Terminal/TerminalController.swift @@ -166,10 +166,6 @@ class TerminalController: NSWindowController, NSWindowDelegate, private func syncAppearance() { guard let window = self.window as? TerminalWindow else { return } - let backgroundColor = OSColor(ghostty.config.backgroundColor) - let appearance = NSAppearance(named: backgroundColor.isLightColor ? .aqua : .darkAqua) - window.appearance = appearance - // Set the font for the window and tab titles. if let titleFontName = ghostty.config.windowTitleFontFamily { window.titlebarFont = NSFont(name: titleFontName, size: NSFont.systemFontSize) @@ -177,6 +173,7 @@ class TerminalController: NSWindowController, NSWindowDelegate, window.titlebarFont = nil } + let backgroundColor = OSColor(ghostty.config.backgroundColor) window.backgroundColor = backgroundColor window.titlebarColor = backgroundColor.withAlphaComponent(ghostty.config.backgroundOpacity) window.updateTabBar() @@ -257,6 +254,11 @@ class TerminalController: NSWindowController, NSWindowDelegate, // This makes sure our titlebar renders correctly when there is a transparent background window.titlebarColor = backgroundColor.withAlphaComponent(ghostty.config.backgroundOpacity) + + // Make sure our theme is set on the window so styling is correct. + if let windowTheme = ghostty.config.windowTheme { + window.windowTheme = .init(rawValue: windowTheme) + } // Handle titlebar tabs config option. Something about what we do while setting up the // titlebar tabs interferes with the window restore process unless window.tabbingMode diff --git a/macos/Sources/Features/Terminal/TerminalWindow.swift b/macos/Sources/Features/Terminal/TerminalWindow.swift index a5cd51264..070ad46dc 100644 --- a/macos/Sources/Features/Terminal/TerminalWindow.swift +++ b/macos/Sources/Features/Terminal/TerminalWindow.swift @@ -75,11 +75,15 @@ class TerminalWindow: NSWindow { tab.attributedTitle = attributedTitle } } + + // The window theme configuration from Ghostty. This is used to control some + // behaviors that don't look quite right in certain situations. + var windowTheme: TerminalWindowTheme? // We only need to set this once, but need to do it after the window has been created in order // to determine if the theme is using a very dark background, in which case we don't want to // remove the effect view if the default tab bar is being used since the effect created in - // `updateTabsForVeryDarkBackgrounds`. + // `updateTabsForVeryDarkBackgrounds` creates a confusing visual design. private var effectViewIsHidden = false override func becomeKey() { @@ -119,6 +123,24 @@ class TerminalWindow: NSWindow { override func update() { super.update() + if titlebarTabs { + updateTabsForVeryDarkBackgrounds() + // This is called when we open, close, switch, and reorder tabs, at which point we determine if the + // first tab in the tab bar is selected. If it is, we make the `windowButtonsBackdrop` color the same + // as that of the active tab (i.e. the titlebar's background color), otherwise we make it the same + // color as the background of unselected tabs. + if let index = windowController?.window?.tabbedWindows?.firstIndex(of: self) { + windowButtonsBackdrop?.isHighlighted = index == 0 + } + } + + updateResetZoomTitlebarButtonVisibility() + + // The remainder of the styles we only apply if we're on "auto" theming + // because they conflict with the appearance being forced a certain + // direction. See issue #1709. + guard let windowTheme, windowTheme == .auto else { return } + titlebarSeparatorStyle = tabbedWindows != nil && !titlebarTabs ? .line : .none if !effectViewIsHidden { @@ -137,20 +159,8 @@ class TerminalWindow: NSWindow { effectViewIsHidden = true } - if titlebarTabs { - updateTabsForVeryDarkBackgrounds() - // This is called when we open, close, switch, and reorder tabs, at which point we determine if the - // first tab in the tab bar is selected. If it is, we make the `windowButtonsBackdrop` color the same - // as that of the active tab (i.e. the titlebar's background color), otherwise we make it the same - // color as the background of unselected tabs. - if let index = windowController?.window?.tabbedWindows?.firstIndex(of: self) { - windowButtonsBackdrop?.isHighlighted = index == 0 - } - } - updateNewTabButtonOpacity() - updateNewTabButtonImage() - updateResetZoomTitlebarButtonVisibility() + updateNewTabButtonImage() } override func updateConstraintsIfNeeded() { @@ -626,3 +636,9 @@ fileprivate class WindowButtonsBackdropView: NSView { layer?.addSublayer(overlayLayer) } } + +enum TerminalWindowTheme: String { + case auto + case light + case dark +}