[gtk/wip/carlosg/scrollbar-fixes: 2/2] gdk/x11: Ignore regular crossing events while in implicit grabs



commit c0c5ce2f9b48fdba77db2d504ea53ab265167eb2
Author: Carlos Garnacho <carlosg gnome org>
Date:   Thu Jul 9 16:53:47 2020 +0200

    gdk/x11: Ignore regular crossing events while in implicit grabs
    
    If we create an implicit grab on a surface, leave the surface, and
    release the button, we would get 2 XI_Leave events, one with mode
    XINotifyNormal when the pointer leaves the surface, and another with
    mode XINotifyUngrab when the button is released.
    
    Meanwhile, the upper layers rely on crossing events being paired,
    and particularly in no crossing event being sent until the implicit
    grab is dismissed (either by releasing it, or via more pervasive
    grabs).
    
    Ignoring the set of XINotifyNormal events while an implicit grab
    is active adapts the X11 backend to this behavior. If the grab were
    released or taken away by another grab, a crossing event with one
    of the other XINotify*Grab/XINotify*Ungrab will be generated.
    
    Fixes: https://gitlab.gnome.org/GNOME/gtk/-/issues/2879

 gdk/x11/gdkdevicemanager-xi2.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)
---
diff --git a/gdk/x11/gdkdevicemanager-xi2.c b/gdk/x11/gdkdevicemanager-xi2.c
index 0db1865c17..de6feaad3d 100644
--- a/gdk/x11/gdkdevicemanager-xi2.c
+++ b/gdk/x11/gdkdevicemanager-xi2.c
@@ -1874,6 +1874,7 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
     case XI_Leave:
       {
         XIEnterEvent *xev = (XIEnterEvent *) ev;
+        GdkModifierType state;
 
         GDK_DISPLAY_NOTE (display, EVENTS,
                   g_message ("%s notify:\twindow %ld\n\tsubwindow:%ld\n"
@@ -1890,6 +1891,18 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
         source_device = g_hash_table_lookup (device_manager->id_table,
                                              GUINT_TO_POINTER (xev->sourceid));
 
+        state = _gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group);
+
+        /* Ignore normal crossing events while there is an implicit grab.
+         * We will receive a crossing event with one of the other details if
+         * the implicit grab were finished (eg. releasing the button outside
+         * the window triggers a XINotifyUngrab leave).
+         */
+        if (xev->mode == XINotifyNormal &&
+            (state & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK |
+                      GDK_BUTTON4_MASK | GDK_BUTTON5_MASK)))
+          break;
+
         if (ev->evtype == XI_Enter &&
             xev->detail != XINotifyInferior && xev->mode != XINotifyPassiveUngrab &&
             GDK_IS_TOPLEVEL (surface))
@@ -1916,12 +1929,11 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
                                         device,
                                         source_device,
                                         xev->time,
-                                        _gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, 
&xev->group),
+                                        state,
                                         (double) xev->event_x / scale,
                                         (double) xev->event_y / scale,
                                         translate_crossing_mode (xev->mode),
                                         translate_notify_type (xev->detail));
-           
       }
       break;
     case XI_FocusIn:


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