From: Carlos Garnacho Date: Tue, 30 Jun 2015 17:04:13 +0000 (+0200) Subject: x11: Avoid X error traps within server grabs X-Git-Tag: archive/raspbian/4.4.1+ds1-2+rpi1^2~18^2~24^2~9246 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=0f3995a446e77a7c0a752a23bf2bd6a4e93b2c6a;p=gtk4.git 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 --- diff --git a/gdk/x11/gdkdevice-xi2.c b/gdk/x11/gdkdevice-xi2.c index b02f4c3e5f..515840b83a 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; }