diff --git a/macos/Sources/Features/Terminal/BaseTerminalController.swift b/macos/Sources/Features/Terminal/BaseTerminalController.swift index b502e56e0..c33a6d303 100644 --- a/macos/Sources/Features/Terminal/BaseTerminalController.swift +++ b/macos/Sources/Features/Terminal/BaseTerminalController.swift @@ -279,11 +279,11 @@ class BaseTerminalController: NSWindowController, func titleDidChange(to: String) { guard let window else { return } - + // Set the main window title window.title = to } - + func pwdDidChange(to: URL?) { guard let window else { return } @@ -362,11 +362,17 @@ class BaseTerminalController: NSWindowController, } func fullscreenDidChange() { - // For some reason focus can get lost when we change fullscreen. Regardless of - // mode above we just move it back. - if let focusedSurface { - Ghostty.moveFocus(to: focusedSurface) - } + // If we are in on-native fullscreen, try to restore the surface + // that was focused *before* entering fullscreen + // See: https://github.com/ghostty-org/ghostty/pull/7201 + let preferredSurface = (fullscreenStyle as? NonNativeFullscreen) + .flatMap { $0.isFullscreen ? $0.getSavedFocusedSurface() : nil } + + guard let surface = preferredSurface ?? focusedSurface else { return } + + // For some reason focus can get lost when we change fullscreen. + // Regardless of mode above we just move it back. + Ghostty.moveFocus(to: surface) } // MARK: Clipboard Confirmation diff --git a/macos/Sources/Helpers/Fullscreen.swift b/macos/Sources/Helpers/Fullscreen.swift index b6fb08271..5804a810b 100644 --- a/macos/Sources/Helpers/Fullscreen.swift +++ b/macos/Sources/Helpers/Fullscreen.swift @@ -258,14 +258,16 @@ class NonNativeFullscreen: FullscreenBase, FullscreenStyle { } } - // Unset our saved state, we're restored! - self.savedState = nil - // Focus window window.makeKeyAndOrderFront(nil) - // Notify the delegate + // Notify the delegate BEFORE unsetting the saved state + // This way fullscreenDidChange() can still access savedState.focusedSurface + // See: https://github.com/ghostty-org/ghostty/pull/7201 self.delegate?.fullscreenDidChange() + + // Unset our saved state, we're restored! + self.savedState = nil } private func fullscreenFrame(_ screen: NSScreen) -> NSRect { @@ -315,6 +317,10 @@ class NonNativeFullscreen: FullscreenBase, FullscreenStyle { exit() } + func getSavedFocusedSurface() -> Ghostty.SurfaceView? { + return savedState?.focusedSurface + } + // MARK: Dock private func hideDock() { @@ -344,6 +350,7 @@ class NonNativeFullscreen: FullscreenBase, FullscreenStyle { let styleMask: NSWindow.StyleMask let dock: Bool let menu: Bool + let focusedSurface: Ghostty.SurfaceView? init?(_ window: NSWindow) { guard let contentView = window.contentView else { return nil } @@ -354,6 +361,7 @@ class NonNativeFullscreen: FullscreenBase, FullscreenStyle { self.contentFrame = window.convertToScreen(contentView.frame) self.styleMask = window.styleMask self.dock = window.screen?.hasDock ?? false + self.focusedSurface = (window as? TerminalWindow)?.windowController.flatMap { $0 as? BaseTerminalController }?.focusedSurface // We hide the menu only if this window is not on any fullscreen // spaces. We do this because fullscreen spaces already hide the