macOS: fix focus loss when toggling non-native fullscreen mode

This commit is contained in:
Bryan Lee
2025-04-27 03:07:36 +08:00
parent 38445dca2a
commit a9a95e809b
2 changed files with 25 additions and 11 deletions

View File

@ -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

View File

@ -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