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
This commit is contained in:
Carlos Garnacho 2015-06-30 19:04:13 +02:00 committed by Matthias Clasen
parent ef93c714f8
commit 0f3995a446

View File

@ -499,10 +499,13 @@ gdk_x11_device_xi2_window_at_position (GdkDevice *device,
XIButtonState button_state = { 0 }; XIButtonState button_state = { 0 };
XIModifierState mod_state; XIModifierState mod_state;
XIGroupState group_state; XIGroupState group_state;
Bool retval;
display = gdk_device_get_display (device); display = gdk_device_get_display (device);
screen = gdk_display_get_default_screen (display); 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 /* This function really only works if the mouse pointer is held still
* during its operation. If it moves from one leaf window to another * 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 * than we'll end up with inaccurate values for win_x, win_y
@ -549,8 +552,7 @@ gdk_x11_device_xi2_window_at_position (GdkDevice *device,
/* Free previous button mask, if any */ /* Free previous button mask, if any */
g_free (button_state.mask); g_free (button_state.mask);
gdk_x11_display_error_trap_push (display); retval = XIQueryPointer (xdisplay,
XIQueryPointer (xdisplay,
device_xi2->device_id, device_xi2->device_id,
xwindow, xwindow,
&root, &child, &root, &child,
@ -559,8 +561,9 @@ gdk_x11_device_xi2_window_at_position (GdkDevice *device,
&button_state, &button_state,
&mod_state, &mod_state,
&group_state); &group_state);
if (gdk_x11_display_error_trap_pop (display)) if (!retval)
continue; continue;
if (child != None) if (child != None)
{ {
pointer_window = child; pointer_window = child;
@ -609,8 +612,7 @@ gdk_x11_device_xi2_window_at_position (GdkDevice *device,
last = xwindow; last = xwindow;
free (button_state.mask); free (button_state.mask);
gdk_x11_display_error_trap_push (display); retval = XIQueryPointer (xdisplay,
XIQueryPointer (xdisplay,
device_xi2->device_id, device_xi2->device_id,
xwindow, xwindow,
&root, &xwindow, &root, &xwindow,
@ -619,7 +621,7 @@ gdk_x11_device_xi2_window_at_position (GdkDevice *device,
&button_state, &button_state,
&mod_state, &mod_state,
&group_state); &group_state);
if (gdk_x11_display_error_trap_pop (display)) if (!retval)
break; break;
if (get_toplevel && last != root && if (get_toplevel && last != root &&
@ -633,21 +635,32 @@ gdk_x11_device_xi2_window_at_position (GdkDevice *device,
gdk_x11_display_ungrab (display); gdk_x11_display_ungrab (display);
if (gdk_x11_display_error_trap_pop (display) == 0)
{
window = gdk_x11_window_lookup_for_display (display, last); window = gdk_x11_window_lookup_for_display (display, last);
impl = NULL; impl = NULL;
if (window) if (window)
impl = GDK_WINDOW_IMPL_X11 (window->impl); 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) if (win_x)
*win_x = (window) ? (xwin_x / impl->window_scale) : -1; *win_x = (window) ? (xwin_x / impl->window_scale) : -1;
if (win_y) if (win_y)
*win_y = (window) ? (xwin_y / impl->window_scale) : -1; *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; return window;
} }