From f84bcfbb971b973465a7e50a95057a10f8c5f265 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Tue, 16 Nov 2021 10:52:35 +0100 Subject: [PATCH] gtkmain: Disable implicit grab active state on CROSSING_GRAB leave events This grab-induced crossing event may come from outer means while there are buttons pressed (e.g. WM window drags/resizes in X11), the implicit active state should be undone in that situation. Also, separate the handling of GDK_LEAVE_NOTIFY, as it's fundamentally different from GDK_TOUCH_END/CANCEL handling. Fixes: https://gitlab.gnome.org/GNOME/gtk/-/issues/4416 --- gtk/gtkmain.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/gtk/gtkmain.c b/gtk/gtkmain.c index 4c49be49d5..bb25aaca63 100644 --- a/gtk/gtkmain.c +++ b/gtk/gtkmain.c @@ -1345,14 +1345,26 @@ handle_pointing_event (GdkEvent *event) switch ((guint) type) { case GDK_LEAVE_NOTIFY: + if (gdk_crossing_event_get_mode (event) == GDK_CROSSING_GRAB) + { + GtkWidget *grab_widget; + + grab_widget = + gtk_window_lookup_pointer_focus_implicit_grab (toplevel, + device, + sequence); + if (grab_widget) + set_widget_active_state (grab_widget, FALSE); + } + + old_target = update_pointer_focus_state (toplevel, event, NULL); + gtk_synthesize_crossing_events (GTK_ROOT (toplevel), GTK_CROSSING_POINTER, old_target, NULL, + event, gdk_crossing_event_get_mode (event), NULL); + break; case GDK_TOUCH_END: case GDK_TOUCH_CANCEL: old_target = update_pointer_focus_state (toplevel, event, NULL); - if (type == GDK_TOUCH_END || type == GDK_TOUCH_CANCEL) - set_widget_active_state (old_target, FALSE); - else if (type == GDK_LEAVE_NOTIFY) - gtk_synthesize_crossing_events (GTK_ROOT (toplevel), GTK_CROSSING_POINTER, old_target, NULL, - event, gdk_crossing_event_get_mode (event), NULL); + set_widget_active_state (old_target, FALSE); break; case GDK_DRAG_LEAVE: {