From 88674a1957e82ecb548a00e5d8a7e575136f670a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoffer=20T=C3=B8nnessen?= Date: Fri, 27 Dec 2024 21:48:09 +0100 Subject: [PATCH] Restore hidden titlebar after fullscreen This fixes https://github.com/ghostty-org/ghostty/issues/3535 . There exists an issue in ghostty on mac where if you have hidden your titlebar, then enter fullscreen, the titlebar will reappear after exiting fullscreen. The reason for this is that after exiting fullscreen macos reapplies some styling on the new window created after exiting fullscreen. To combat this we will reapply the styling to hide the titlebar after exiting fullscreen. Required config: ``` macos-titlebar-style = hidden macos-non-native-fullscreen = true ``` Steps to reproduce: - Open Ghostty - Enter fullscreen (non-native) - Exit fullscreen On main you will see the titlebar reappearing after exiting fullscreen, while that does not happen with this patch. --- .../Terminal/TerminalController.swift | 76 +++++++++++-------- 1 file changed, 44 insertions(+), 32 deletions(-) diff --git a/macos/Sources/Features/Terminal/TerminalController.swift b/macos/Sources/Features/Terminal/TerminalController.swift index c3b332cd40..331f26c974 100644 --- a/macos/Sources/Features/Terminal/TerminalController.swift +++ b/macos/Sources/Features/Terminal/TerminalController.swift @@ -101,6 +101,12 @@ class TerminalController: BaseTerminalController { // When our fullscreen state changes, we resync our appearance because some // properties change when fullscreen or not. guard let focusedSurface else { return } + if (!(fullscreenStyle?.isFullscreen ?? false) && + ghostty.config.macosTitlebarStyle == "hidden") + { + applyHiddenTitlebarStyle() + } + syncAppearance(focusedSurface.derivedConfig) } @@ -274,6 +280,43 @@ class TerminalController: BaseTerminalController { shouldCascadeWindows = false } + fileprivate func applyHiddenTitlebarStyle() { + guard let window else { return } + + window.styleMask = [ + // We need `titled` in the mask to get the normal window frame + .titled, + + // Full size content view so we can extend + // content in to the hidden titlebar's area + .fullSizeContentView, + + .resizable, + .closable, + .miniaturizable, + ] + + // Hide the title + window.titleVisibility = .hidden + window.titlebarAppearsTransparent = true + + // Hide the traffic lights (window control buttons) + window.standardWindowButton(.closeButton)?.isHidden = true + window.standardWindowButton(.miniaturizeButton)?.isHidden = true + window.standardWindowButton(.zoomButton)?.isHidden = true + + // Disallow tabbing if the titlebar is hidden, since that will (should) also hide the tab bar. + window.tabbingMode = .disallowed + + // Nuke it from orbit -- hide the titlebar container entirely, just in case. There are + // some operations that appear to bring back the titlebar visibility so this ensures + // it is gone forever. + if let themeFrame = window.contentView?.superview, + let titleBarContainer = themeFrame.firstDescendant(withClassName: "NSTitlebarContainerView") { + titleBarContainer.isHidden = true + } + } + override func windowDidLoad() { super.windowDidLoad() guard let window = window as? TerminalWindow else { return } @@ -365,38 +408,7 @@ class TerminalController: BaseTerminalController { // If our titlebar style is "hidden" we adjust the style appropriately if (config.macosTitlebarStyle == "hidden") { - window.styleMask = [ - // We need `titled` in the mask to get the normal window frame - .titled, - - // Full size content view so we can extend - // content in to the hidden titlebar's area - .fullSizeContentView, - - .resizable, - .closable, - .miniaturizable, - ] - - // Hide the title - window.titleVisibility = .hidden - window.titlebarAppearsTransparent = true - - // Hide the traffic lights (window control buttons) - window.standardWindowButton(.closeButton)?.isHidden = true - window.standardWindowButton(.miniaturizeButton)?.isHidden = true - window.standardWindowButton(.zoomButton)?.isHidden = true - - // Disallow tabbing if the titlebar is hidden, since that will (should) also hide the tab bar. - window.tabbingMode = .disallowed - - // Nuke it from orbit -- hide the titlebar container entirely, just in case. There are - // some operations that appear to bring back the titlebar visibility so this ensures - // it is gone forever. - if let themeFrame = window.contentView?.superview, - let titleBarContainer = themeFrame.firstDescendant(withClassName: "NSTitlebarContainerView") { - titleBarContainer.isHidden = true - } + applyHiddenTitlebarStyle() } // In various situations, macOS automatically tabs new windows. Ghostty handles