[gtk+/gtk-3-16] x11: Avoid X error traps within server grabs



commit a90c7f191fb8527cd5b79c57f6c47e3776af1f5f
Author: Carlos Garnacho <carlosg gnome org>
Date:   Tue Jun 30 19:04:13 2015 +0200

    x11: Avoid X error traps within server grabs
    
    gdk_x11_device_xi2_window_at_position() may attempt to push/pop
    a few error trap pairs while traversing the window tree. Move it
    outside the server grab, and around the multiple XIQueryPointer
    calls we may do here.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=751739

 gdk/x11/gdkdevice-xi2.c |   73 +++++++++++++++++++++++++++-------------------
 1 files changed, 43 insertions(+), 30 deletions(-)
---
diff --git a/gdk/x11/gdkdevice-xi2.c b/gdk/x11/gdkdevice-xi2.c
index 66c3a31..6d49b9a 100644
--- a/gdk/x11/gdkdevice-xi2.c
+++ b/gdk/x11/gdkdevice-xi2.c
@@ -499,10 +499,13 @@ gdk_x11_device_xi2_window_at_position (GdkDevice       *device,
   XIButtonState button_state = { 0 };
   XIModifierState mod_state;
   XIGroupState group_state;
+  Bool retval;
 
   display = gdk_device_get_display (device);
   screen = gdk_display_get_default_screen (display);
 
+  gdk_x11_display_error_trap_push (display);
+
   /* This function really only works if the mouse pointer is held still
    * during its operation. If it moves from one leaf window to another
    * than we'll end up with inaccurate values for win_x, win_y
@@ -549,18 +552,18 @@ gdk_x11_device_xi2_window_at_position (GdkDevice       *device,
           /* Free previous button mask, if any */
           g_free (button_state.mask);
 
-          gdk_x11_display_error_trap_push (display);
-          XIQueryPointer (xdisplay,
-                          device_xi2->device_id,
-                          xwindow,
-                          &root, &child,
-                          &xroot_x, &xroot_y,
-                          &xwin_x, &xwin_y,
-                          &button_state,
-                          &mod_state,
-                          &group_state);
-          if (gdk_x11_display_error_trap_pop (display))
+          retval = XIQueryPointer (xdisplay,
+                                   device_xi2->device_id,
+                                   xwindow,
+                                   &root, &child,
+                                   &xroot_x, &xroot_y,
+                                   &xwin_x, &xwin_y,
+                                   &button_state,
+                                   &mod_state,
+                                   &group_state);
+          if (!retval)
             continue;
+
           if (child != None)
             {
               pointer_window = child;
@@ -609,17 +612,16 @@ gdk_x11_device_xi2_window_at_position (GdkDevice       *device,
       last = xwindow;
       free (button_state.mask);
 
-      gdk_x11_display_error_trap_push (display);
-      XIQueryPointer (xdisplay,
-                      device_xi2->device_id,
-                      xwindow,
-                      &root, &xwindow,
-                      &xroot_x, &xroot_y,
-                      &xwin_x, &xwin_y,
-                      &button_state,
-                      &mod_state,
-                      &group_state);
-      if (gdk_x11_display_error_trap_pop (display))
+      retval = XIQueryPointer (xdisplay,
+                               device_xi2->device_id,
+                               xwindow,
+                               &root, &xwindow,
+                               &xroot_x, &xroot_y,
+                               &xwin_x, &xwin_y,
+                               &button_state,
+                               &mod_state,
+                               &group_state);
+      if (!retval)
         break;
 
       if (get_toplevel && last != root &&
@@ -633,10 +635,25 @@ gdk_x11_device_xi2_window_at_position (GdkDevice       *device,
 
   gdk_x11_display_ungrab (display);
 
-  window = gdk_x11_window_lookup_for_display (display, last);
-  impl = NULL;
-  if (window)
-    impl = GDK_WINDOW_IMPL_X11 (window->impl);
+  if (gdk_x11_display_error_trap_pop (display) == 0)
+    {
+      window = gdk_x11_window_lookup_for_display (display, last);
+      impl = NULL;
+      if (window)
+        impl = GDK_WINDOW_IMPL_X11 (window->impl);
+
+      if (mask)
+        *mask = _gdk_x11_device_xi2_translate_state (&mod_state, &button_state, &group_state);
+
+      free (button_state.mask);
+    }
+  else
+    {
+      window = NULL;
+
+      if (mask)
+        *mask = 0;
+    }
 
   if (win_x)
     *win_x = (window) ? (xwin_x / impl->window_scale) : -1;
@@ -644,10 +661,6 @@ gdk_x11_device_xi2_window_at_position (GdkDevice       *device,
   if (win_y)
     *win_y = (window) ? (xwin_y / impl->window_scale) : -1;
 
-  if (mask)
-    *mask = _gdk_x11_device_xi2_translate_state (&mod_state, &button_state, &group_state);
-
-  free (button_state.mask);
 
   return window;
 }


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