From faea09bbdea196d78684e79a58012a74ee98a3d9 Mon Sep 17 00:00:00 2001 From: james Date: Sat, 11 Jan 2025 23:53:19 -0500 Subject: [PATCH] for GTK runtime, don't call cursorPosCallback in mouse motion callback if the cursor hasn't actually moved --- src/apprt/gtk/Surface.zig | 44 ++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/src/apprt/gtk/Surface.zig b/src/apprt/gtk/Surface.zig index c16f696b19..c5a001f340 100644 --- a/src/apprt/gtk/Surface.zig +++ b/src/apprt/gtk/Surface.zig @@ -1496,31 +1496,37 @@ fn gtkMouseMotion( .y = @floatCast(scaled.y), }; - // When the GLArea is resized under the mouse, GTK issues a mouse motion - // event. This has the unfortunate side effect of causing focus to potentially - // change when `focus-follows-mouse` is enabled. To prevent this, we check - // if the cursor is still in the same place as the last event and only grab - // focus if it has moved. + // There seem to be at least two cases where GTK issues a mouse motion + // event without the cursor actually moving: + // 1. GLArea is resized under the mouse. This has the unfortunate + // side effect of causing focus to potentially change when + // `focus-follows-mouse` is enabled. + // 2. The window title is updated. This can cause the mouse to unhide + // incorrectly when hide-mouse-when-typing is enabled. + // To prevent incorrect behavior, we'll only grab focus and + // continue with callback logic if the cursor has actually moved. const is_cursor_still = @abs(self.cursor_pos.x - pos.x) < 1 and @abs(self.cursor_pos.y - pos.y) < 1; - // If we don't have focus, and we want it, grab it. - const gl_widget = @as(*c.GtkWidget, @ptrCast(self.gl_area)); - if (!is_cursor_still and c.gtk_widget_has_focus(gl_widget) == 0 and self.app.config.@"focus-follows-mouse") { - self.grabFocus(); - } + if (!is_cursor_still) { + // 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(); + } - // Our pos changed, update - self.cursor_pos = pos; + // Our pos changed, update + self.cursor_pos = pos; - // Get our modifiers - const gtk_mods = c.gdk_event_get_modifier_state(event); - const mods = gtk_key.translateMods(gtk_mods); + // Get our modifiers + const gtk_mods = c.gdk_event_get_modifier_state(event); + const mods = gtk_key.translateMods(gtk_mods); - self.core_surface.cursorPosCallback(self.cursor_pos, mods) catch |err| { - log.err("error in cursor pos callback err={}", .{err}); - return; - }; + self.core_surface.cursorPosCallback(self.cursor_pos, mods) catch |err| { + log.err("error in cursor pos callback err={}", .{err}); + return; + }; + } } fn gtkMouseLeave(