From bfbd043b59363ba5677fe9d9aae0cd30250dd5fc Mon Sep 17 00:00:00 2001 From: Damien Mehala Date: Sun, 29 Dec 2024 18:12:08 +0100 Subject: [PATCH] fix: quick terminal `focus-follows-mouse` behaviour Quick Terminal now focuses on the surface under the mouse pointer when `focus-follows-mouse` is enabled. Fixes #3337 --- .../Features/Terminal/BaseTerminalController.swift | 9 ++++++++- .../Features/Terminal/TerminalController.swift | 5 ----- macos/Sources/Features/Terminal/TerminalWindow.swift | 2 -- macos/Sources/Ghostty/SurfaceView_AppKit.swift | 11 ++++++----- 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/macos/Sources/Features/Terminal/BaseTerminalController.swift b/macos/Sources/Features/Terminal/BaseTerminalController.swift index b77e38f7c..54d505db9 100644 --- a/macos/Sources/Features/Terminal/BaseTerminalController.swift +++ b/macos/Sources/Features/Terminal/BaseTerminalController.swift @@ -45,6 +45,11 @@ class BaseTerminalController: NSWindowController, didSet { surfaceTreeDidChange(from: oldValue, to: surfaceTree) } } + /// Whether the terminal surface should focus when the mouse is over it. + var focusFollowsMouse: Bool { + self.derivedConfig.focusFollowsMouse + } + /// Non-nil when an alert is active so we don't overlap multiple. private var alert: NSAlert? = nil @@ -262,7 +267,6 @@ class BaseTerminalController: NSWindowController, // Set the main window title window.title = to - } func pwdDidChange(to: URL?) { @@ -604,15 +608,18 @@ class BaseTerminalController: NSWindowController, private struct DerivedConfig { let macosTitlebarProxyIcon: Ghostty.MacOSTitlebarProxyIcon let windowStepResize: Bool + let focusFollowsMouse: Bool init() { self.macosTitlebarProxyIcon = .visible self.windowStepResize = false + self.focusFollowsMouse = false } init(_ config: Ghostty.Config) { self.macosTitlebarProxyIcon = config.macosTitlebarProxyIcon self.windowStepResize = config.windowStepResize + self.focusFollowsMouse = config.focusFollowsMouse } } } diff --git a/macos/Sources/Features/Terminal/TerminalController.swift b/macos/Sources/Features/Terminal/TerminalController.swift index e6f5befff..c3b332cd4 100644 --- a/macos/Sources/Features/Terminal/TerminalController.swift +++ b/macos/Sources/Features/Terminal/TerminalController.swift @@ -117,9 +117,6 @@ class TerminalController: BaseTerminalController { // Update our derived config self.derivedConfig = DerivedConfig(config) - guard let window = window as? TerminalWindow else { return } - window.focusFollowsMouse = config.focusFollowsMouse - // If we have no surfaces in our window (is that possible?) then we update // our window appearance based on the root config. If we have surfaces, we // don't call this because the TODO @@ -422,8 +419,6 @@ class TerminalController: BaseTerminalController { } } - window.focusFollowsMouse = config.focusFollowsMouse - // Apply any additional appearance-related properties to the new window. We // apply this based on the root config but change it later based on surface // config (see focused surface change callback). diff --git a/macos/Sources/Features/Terminal/TerminalWindow.swift b/macos/Sources/Features/Terminal/TerminalWindow.swift index 503e76791..35f629bfd 100644 --- a/macos/Sources/Features/Terminal/TerminalWindow.swift +++ b/macos/Sources/Features/Terminal/TerminalWindow.swift @@ -414,8 +414,6 @@ class TerminalWindow: NSWindow { } } - var focusFollowsMouse: Bool = false - // Find the NSTextField responsible for displaying the titlebar's title. private var titlebarTextField: NSTextField? { guard let titlebarView = titlebarContainer?.subviews diff --git a/macos/Sources/Ghostty/SurfaceView_AppKit.swift b/macos/Sources/Ghostty/SurfaceView_AppKit.swift index 60de024d3..2cac4a0dd 100644 --- a/macos/Sources/Ghostty/SurfaceView_AppKit.swift +++ b/macos/Sources/Ghostty/SurfaceView_AppKit.swift @@ -617,11 +617,12 @@ extension Ghostty { let mods = Ghostty.ghosttyMods(event.modifierFlags) ghostty_surface_mouse_pos(surface, pos.x, frame.height - pos.y, mods) - // If focus follows mouse is enabled then move focus to this surface. - if let window = self.window as? TerminalWindow, - window.isKeyWindow && - window.focusFollowsMouse && - !self.focused + // Handle focus-follows-mouse + if let window, + let controller = window.windowController as? BaseTerminalController, + (window.isKeyWindow && + !self.focused && + controller.focusFollowsMouse) { Ghostty.moveFocus(to: self) }