From fd786219d14851d733f6b9608b51349d86761c0e Mon Sep 17 00:00:00 2001 From: Cameron Dart <8763518+SkamDart@users.noreply.github.com> Date: Mon, 10 Jun 2024 13:11:53 -0700 Subject: [PATCH 1/7] feat: focus-follows-mouse --- src/config/Config.zig | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/config/Config.zig b/src/config/Config.zig index 42e6cd584..0f6e73117 100644 --- a/src/config/Config.zig +++ b/src/config/Config.zig @@ -421,6 +421,12 @@ command: ?[]const u8 = null, /// This is primarily useful for scripts or debugging. @"wait-after-command": bool = false, +// If true, when there are multiple split panes, the mouse selects the pane +// that is focused. +// +// Default is false. +@"focus-follows-mouse": bool = false, + /// The number of milliseconds of runtime below which we consider a process exit /// to be abnormal. This is used to show an error message when the process exits /// too quickly. From 97bb59550559a780d79ceda73e17ac93cf860562 Mon Sep 17 00:00:00 2001 From: Cameron Dart <8763518+SkamDart@users.noreply.github.com> Date: Mon, 10 Jun 2024 15:30:42 -0700 Subject: [PATCH 2/7] macos: add to config --- macos/Sources/Ghostty/Ghostty.Config.swift | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/macos/Sources/Ghostty/Ghostty.Config.swift b/macos/Sources/Ghostty/Ghostty.Config.swift index dcee797c8..ab583e956 100644 --- a/macos/Sources/Ghostty/Ghostty.Config.swift +++ b/macos/Sources/Ghostty/Ghostty.Config.swift @@ -245,7 +245,15 @@ extension Ghostty { _ = ghostty_config_get(config, &v, key, UInt(key.count)) return v } - + + var focusFollowsMouse : Bool { + guard let config = self.config else { return false } + var v = false; + let key = "focus-follows-mouse" + _ = ghostty_config_get(config, &v, key, UInt(key.count)) + return v + } + var backgroundColor: Color { var rgb: UInt32 = 0 let bg_key = "background" From 29fb70197c668638dba5060b0bcac50778919229 Mon Sep 17 00:00:00 2001 From: Cameron Dart <8763518+SkamDart@users.noreply.github.com> Date: Mon, 10 Jun 2024 16:07:33 -0700 Subject: [PATCH 3/7] macos: surface focus follow mouse --- macos/Sources/Features/Terminal/TerminalController.swift | 5 +++-- macos/Sources/Features/Terminal/TerminalWindow.swift | 2 ++ macos/Sources/Ghostty/SurfaceView_AppKit.swift | 4 ++++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/macos/Sources/Features/Terminal/TerminalController.swift b/macos/Sources/Features/Terminal/TerminalController.swift index 86fb02442..98e90e565 100644 --- a/macos/Sources/Features/Terminal/TerminalController.swift +++ b/macos/Sources/Features/Terminal/TerminalController.swift @@ -197,9 +197,10 @@ class TerminalController: NSWindowController, NSWindowDelegate, window.isOpaque = true window.backgroundColor = .windowBackgroundColor } - + window.hasShadow = ghostty.config.macosWindowShadow - + window.focusFollowsMouse = ghostty.config.focusFollowsMouse + guard window.hasStyledTabs else { return } // The titlebar is always updated. We don't need to worry about opacity diff --git a/macos/Sources/Features/Terminal/TerminalWindow.swift b/macos/Sources/Features/Terminal/TerminalWindow.swift index 9e4d3600e..2d54db321 100644 --- a/macos/Sources/Features/Terminal/TerminalWindow.swift +++ b/macos/Sources/Features/Terminal/TerminalWindow.swift @@ -369,6 +369,8 @@ class TerminalWindow: NSWindow { } } + var focusFollowsMouse: Bool = false + // Find the NSTextField responsible for displaying the titlebar's title. private var titlebarTextField: NSTextField? { guard let titlebarContainer = contentView?.superview?.subviews diff --git a/macos/Sources/Ghostty/SurfaceView_AppKit.swift b/macos/Sources/Ghostty/SurfaceView_AppKit.swift index a5347e1ad..3c5cd71ef 100644 --- a/macos/Sources/Ghostty/SurfaceView_AppKit.swift +++ b/macos/Sources/Ghostty/SurfaceView_AppKit.swift @@ -480,6 +480,10 @@ extension Ghostty { let pos = self.convert(event.locationInWindow, from: nil) ghostty_surface_mouse_pos(surface, pos.x, frame.height - pos.y) + guard let window = self.window as? TerminalWindow else { return } + if !self.focused && window.focusFollowsMouse { + Ghostty.moveFocus(to: self) + } } override func mouseDragged(with event: NSEvent) { From fc52acd47a324bd3e08f9ae5464772848fb59f17 Mon Sep 17 00:00:00 2001 From: Cameron Dart <8763518+SkamDart@users.noreply.github.com> Date: Mon, 10 Jun 2024 18:22:28 -0700 Subject: [PATCH 4/7] update config in TerminalController.windowDidLoad and TerminalController.configDidReload --- macos/Sources/Features/Terminal/TerminalController.swift | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/macos/Sources/Features/Terminal/TerminalController.swift b/macos/Sources/Features/Terminal/TerminalController.swift index 98e90e565..81b86a215 100644 --- a/macos/Sources/Features/Terminal/TerminalController.swift +++ b/macos/Sources/Features/Terminal/TerminalController.swift @@ -111,6 +111,8 @@ class TerminalController: NSWindowController, NSWindowDelegate, //MARK: - Methods func configDidReload() { + guard let window = window as? TerminalWindow else { return } + window.focusFollowsMouse = ghostty.config.focusFollowsMouse syncAppearance() } @@ -199,7 +201,6 @@ class TerminalController: NSWindowController, NSWindowDelegate, } window.hasShadow = ghostty.config.macosWindowShadow - window.focusFollowsMouse = ghostty.config.focusFollowsMouse guard window.hasStyledTabs else { return } @@ -343,6 +344,8 @@ class TerminalController: NSWindowController, NSWindowDelegate, } } + window.focusFollowsMouse = ghostty.config.focusFollowsMouse + // Apply any additional appearance-related properties to the new window. syncAppearance() } From 92e16ccbf7e4c2a9fd12a1e8fea0f10ddbf9109e Mon Sep 17 00:00:00 2001 From: Cameron Dart <8763518+SkamDart@users.noreply.github.com> Date: Mon, 10 Jun 2024 18:23:06 -0700 Subject: [PATCH 5/7] no early return --- macos/Sources/Ghostty/SurfaceView_AppKit.swift | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/macos/Sources/Ghostty/SurfaceView_AppKit.swift b/macos/Sources/Ghostty/SurfaceView_AppKit.swift index 3c5cd71ef..9b78b868c 100644 --- a/macos/Sources/Ghostty/SurfaceView_AppKit.swift +++ b/macos/Sources/Ghostty/SurfaceView_AppKit.swift @@ -480,9 +480,10 @@ extension Ghostty { let pos = self.convert(event.locationInWindow, from: nil) ghostty_surface_mouse_pos(surface, pos.x, frame.height - pos.y) - guard let window = self.window as? TerminalWindow else { return } - if !self.focused && window.focusFollowsMouse { - Ghostty.moveFocus(to: self) + if let window = self.window as? TerminalWindow { + if !self.focused && window.focusFollowsMouse { + Ghostty.moveFocus(to: self) + } } } From 406d494e1d80a229cf6025c8ed6fc9ed208260eb Mon Sep 17 00:00:00 2001 From: Cameron Dart <8763518+SkamDart@users.noreply.github.com> Date: Thu, 13 Jun 2024 00:59:38 +0000 Subject: [PATCH 6/7] feat(gtk): focus follows mouse --- src/apprt/gtk/Surface.zig | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/apprt/gtk/Surface.zig b/src/apprt/gtk/Surface.zig index d696d8b38..57bbf0d38 100644 --- a/src/apprt/gtk/Surface.zig +++ b/src/apprt/gtk/Surface.zig @@ -1204,6 +1204,12 @@ fn gtkMouseMotion( .y = @floatCast(scaled.y), }; + // If we don't have focus, and we want it, grab it. + const gl_widget = @as(*c.GtkWidget, @ptrCast(self.gl_area)); + if (c.gtk_widget_has_focus(gl_widget) == 0 and self.app.config.@"focus-follows-mouse") { + self.grabFocus(); + } + self.core_surface.cursorPosCallback(self.cursor_pos) catch |err| { log.err("error in cursor pos callback err={}", .{err}); return; From 50019bc766686323eb87a514abe27dcd6a7f004b Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Tue, 18 Jun 2024 17:09:29 -0400 Subject: [PATCH 7/7] minor comment changes --- macos/Sources/Ghostty/SurfaceView_AppKit.swift | 11 +++++++---- src/config/Config.zig | 14 ++++++++------ 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/macos/Sources/Ghostty/SurfaceView_AppKit.swift b/macos/Sources/Ghostty/SurfaceView_AppKit.swift index 9b78b868c..b3c002d64 100644 --- a/macos/Sources/Ghostty/SurfaceView_AppKit.swift +++ b/macos/Sources/Ghostty/SurfaceView_AppKit.swift @@ -480,10 +480,13 @@ extension Ghostty { let pos = self.convert(event.locationInWindow, from: nil) ghostty_surface_mouse_pos(surface, pos.x, frame.height - pos.y) - if let window = self.window as? TerminalWindow { - if !self.focused && window.focusFollowsMouse { - Ghostty.moveFocus(to: self) - } + // 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 + { + Ghostty.moveFocus(to: self) } } diff --git a/src/config/Config.zig b/src/config/Config.zig index 0f6e73117..6e10e63fb 100644 --- a/src/config/Config.zig +++ b/src/config/Config.zig @@ -421,12 +421,6 @@ command: ?[]const u8 = null, /// This is primarily useful for scripts or debugging. @"wait-after-command": bool = false, -// If true, when there are multiple split panes, the mouse selects the pane -// that is focused. -// -// Default is false. -@"focus-follows-mouse": bool = false, - /// The number of milliseconds of runtime below which we consider a process exit /// to be abnormal. This is used to show an error message when the process exits /// too quickly. @@ -753,6 +747,14 @@ keybind: Keybinds = .{}, /// This configuration currently only works with GTK. @"window-new-tab-position": WindowNewTabPosition = .current, +// If true, when there are multiple split panes, the mouse selects the pane +// that is focused. This only applies to the currently focused window; i.e. +// mousing over a split in an unfocused window will now focus that split +// and bring the window to front. +// +// Default is false. +@"focus-follows-mouse": bool = false, + /// When enabled, the full GTK titlebar is displayed instead of your window /// manager's simple titlebar. The behavior of this option will vary with your /// window manager.