[gtk/wip/carlosg/x11-wm-drags] gtkmain: Disable implicit grab active state on CROSSING_GRAB leave events




commit f84bcfbb971b973465a7e50a95057a10f8c5f265
Author: Carlos Garnacho <carlosg gnome org>
Date:   Tue Nov 16 10:52:35 2021 +0100

    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:
       {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]