Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 25 additions & 19 deletions src/apprt/gtk/Surface.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down