From ac4b0dcac0b5b864a212ddf2c08280b72c5a8016 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 13 Jun 2025 14:57:49 -0700 Subject: [PATCH] macos: fix transparent tabs on sequoia --- .../TitlebarTabsVenturaTerminalWindow.swift | 16 ------- .../TransparentTitlebarTerminalWindow.swift | 47 +++++++++++++++++-- 2 files changed, 42 insertions(+), 21 deletions(-) diff --git a/macos/Sources/Features/Terminal/Window Styles/TitlebarTabsVenturaTerminalWindow.swift b/macos/Sources/Features/Terminal/Window Styles/TitlebarTabsVenturaTerminalWindow.swift index a236df107..99111b55b 100644 --- a/macos/Sources/Features/Terminal/Window Styles/TitlebarTabsVenturaTerminalWindow.swift +++ b/macos/Sources/Features/Terminal/Window Styles/TitlebarTabsVenturaTerminalWindow.swift @@ -99,9 +99,6 @@ class TitlebarTabsVenturaTerminalWindow: TerminalWindow { } } - // The remainder of this function only applies to styled tabs. - guard hasStyledTabs else { return } - titlebarSeparatorStyle = tabbedWindows != nil && !titlebarTabs ? .line : .none if titlebarTabs { hideToolbarOverflowButton() @@ -170,19 +167,6 @@ class TitlebarTabsVenturaTerminalWindow: TerminalWindow { // MARK: Tab Bar Styling - // This is true if we should apply styles to the titlebar or tab bar. - var hasStyledTabs: Bool { - // If we have titlebar tabs then we always style. - guard !titlebarTabs else { return true } - - // We style the tabs if they're transparent - return transparentTabs - } - - // Set to true if the background color should bleed through the titlebar/tab bar. - // This only applies to non-titlebar tabs. - var transparentTabs: Bool = false - var hasVeryDarkBackground: Bool { backgroundColor.luminance < 0.05 } diff --git a/macos/Sources/Features/Terminal/Window Styles/TransparentTitlebarTerminalWindow.swift b/macos/Sources/Features/Terminal/Window Styles/TransparentTitlebarTerminalWindow.swift index f949b6094..94e938326 100644 --- a/macos/Sources/Features/Terminal/Window Styles/TransparentTitlebarTerminalWindow.swift +++ b/macos/Sources/Features/Terminal/Window Styles/TransparentTitlebarTerminalWindow.swift @@ -11,6 +11,13 @@ class TransparentTitlebarTerminalWindow: TerminalWindow { /// KVO observation for tab group window changes. private var tabGroupWindowsObservation: NSKeyValueObservation? private var tabBarVisibleObservation: NSKeyValueObservation? + + deinit { + tabGroupWindowsObservation?.invalidate() + tabBarVisibleObservation?.invalidate() + } + + // MARK: NSWindow override func awakeFromNib() { super.awakeFromNib() @@ -19,11 +26,6 @@ class TransparentTitlebarTerminalWindow: TerminalWindow { // to learn why we need KVO. setupKVO() } - - deinit { - tabGroupWindowsObservation?.invalidate() - tabBarVisibleObservation?.invalidate() - } override func becomeMain() { super.becomeMain() @@ -40,6 +42,16 @@ class TransparentTitlebarTerminalWindow: TerminalWindow { } } } + + override func update() { + super.update() + + // On macOS 13 to 15, we need to hide the NSVisualEffectView in order to allow our + // titlebar to be truly transparent. + if #unavailable(macOS 26.0) { + hideEffectView() + } + } // MARK: Appearance @@ -86,6 +98,7 @@ class TransparentTitlebarTerminalWindow: TerminalWindow { guard let titlebarContainer else { return } titlebarContainer.wantsLayer = true titlebarContainer.layer?.backgroundColor = preferredBackgroundColor?.cgColor + effectViewIsHidden = false } // MARK: View Finders @@ -149,4 +162,28 @@ class TransparentTitlebarTerminalWindow: TerminalWindow { self.syncAppearance(lastSurfaceConfig) } } + + // MARK: macOS 13 to 15 + + // 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` creates a confusing visual design. + private var effectViewIsHidden = false + + private func hideEffectView() { + guard !effectViewIsHidden else { return } + + // By hiding the visual effect view, we allow the window's (or titlebar's in this case) + // background color to show through. If we were to set `titlebarAppearsTransparent` to true + // the selected tab would look fine, but the unselected ones and new tab button backgrounds + // would be an opaque color. When the titlebar isn't transparent, however, the system applies + // a compositing effect to the unselected tab backgrounds, which makes them blend with the + // titlebar's/window's background. + if let effectView = titlebarContainer?.descendants(withClassName: "NSVisualEffectView").first { + effectView.isHidden = true + } + + effectViewIsHidden = true + } }