diff --git a/gdk/gdkdevice.c b/gdk/gdkdevice.c index e8e27d23aa..6b9c693e34 100644 --- a/gdk/gdkdevice.c +++ b/gdk/gdkdevice.c @@ -1455,3 +1455,38 @@ _gdk_device_translate_axis (GdkDevice *device, return TRUE; } +gboolean +_gdk_device_query_state (GdkDevice *device, + GdkWindow *window, + GdkWindow **root_window, + GdkWindow **child_window, + gint *root_x, + gint *root_y, + gint *win_x, + gint *win_y, + GdkModifierType *mask) +{ + return GDK_DEVICE_GET_CLASS (device)->query_state (device, + window, + root_window, + child_window, + root_x, + root_y, + win_x, + win_y, + mask); +} + +GdkWindow * +_gdk_device_window_at_position (GdkDevice *device, + gint *win_x, + gint *win_y, + GdkModifierType *mask, + gboolean get_toplevel) +{ + return GDK_DEVICE_GET_CLASS (device)->window_at_position (device, + win_x, + win_y, + mask, + get_toplevel); +} diff --git a/gdk/gdkdeviceprivate.h b/gdk/gdkdeviceprivate.h index a9bb0455f1..29332b2f5d 100644 --- a/gdk/gdkdeviceprivate.h +++ b/gdk/gdkdeviceprivate.h @@ -85,10 +85,10 @@ struct _GdkDeviceClass GdkScreen *screen, gint x, gint y); - gboolean (* query_state) (GdkDevice *device, - GdkWindow *window, - GdkWindow **root_window, - GdkWindow **child_window, + gboolean (* query_state) (GdkDevice *device, + GdkWindow *window, + GdkWindow **root_window, + GdkWindow **child_window, gint *root_x, gint *root_y, gint *win_x, @@ -157,6 +157,20 @@ void _gdk_device_add_slave (GdkDevice *device, GdkDevice *slave); void _gdk_device_remove_slave (GdkDevice *device, GdkDevice *slave); +gboolean _gdk_device_query_state (GdkDevice *device, + GdkWindow *window, + GdkWindow **root_window, + GdkWindow **child_window, + gint *root_x, + gint *root_y, + gint *win_x, + gint *win_y, + GdkModifierType *mask); +GdkWindow * _gdk_device_window_at_position (GdkDevice *device, + gint *win_x, + gint *win_y, + GdkModifierType *mask, + gboolean get_toplevel); G_END_DECLS diff --git a/gdk/gdkdisplay.c b/gdk/gdkdisplay.c index b14ad84a6e..d78e7c9387 100644 --- a/gdk/gdkdisplay.c +++ b/gdk/gdkdisplay.c @@ -133,12 +133,18 @@ static GdkWindow *gdk_display_real_get_window_at_device_position (GdkDisplay GdkDevice *device, gint *win_x, gint *win_y); +static void gdk_display_real_get_device_state (GdkDisplay *display, + GdkDevice *device, + GdkScreen **screen, + gint *x, + gint *y, + GdkModifierType *mask); static GdkAppLaunchContext *gdk_display_real_get_app_launch_context (GdkDisplay *display); static guint signals[LAST_SIGNAL] = { 0 }; static const GdkDisplayDeviceHooks default_device_hooks = { - _gdk_windowing_get_device_state, + gdk_display_real_get_device_state, gdk_window_real_window_get_device_position, gdk_display_real_get_window_at_device_position }; @@ -838,7 +844,7 @@ gdk_display_real_get_window_at_device_position (GdkDisplay *display, GdkWindow *window; gint x, y; - window = _gdk_windowing_window_at_device_position (display, device, &x, &y, NULL, FALSE); + window = _gdk_device_window_at_position (device, &x, &y, NULL, FALSE); /* This might need corrections, as the native window returned may contain client side children */ @@ -951,6 +957,32 @@ multihead_window_at_device_position (GdkDisplay *display, return multihead_current_pointer_hooks->window_at_pointer (display, win_x, win_y); } +static void +gdk_display_real_get_device_state (GdkDisplay *display, + GdkDevice *device, + GdkScreen **screen, + gint *x, + gint *y, + GdkModifierType *mask) +{ + GdkScreen *default_screen; + GdkWindow *root; + + if (gdk_display_is_closed (display)) + return; + + default_screen = gdk_display_get_default_screen (display); + + _gdk_device_query_state (device, + gdk_screen_get_root_window (default_screen), + &root, NULL, + x, y, + NULL, NULL, + mask); + + *screen = gdk_window_get_screen (root); +} + static void multihead_default_get_pointer (GdkDisplay *display, GdkScreen **screen, @@ -958,9 +990,8 @@ multihead_default_get_pointer (GdkDisplay *display, gint *y, GdkModifierType *mask) { - return _gdk_windowing_get_device_state (display, - display->core_pointer, - screen, x, y, mask); + gdk_display_real_get_device_state (display, display->core_pointer, + screen, x, y, mask); } static GdkWindow * @@ -1329,7 +1360,7 @@ get_current_toplevel (GdkDisplay *display, int x, y; GdkModifierType state; - pointer_window = _gdk_windowing_window_at_device_position (display, device, &x, &y, &state, TRUE); + pointer_window = _gdk_device_window_at_position (device, &x, &y, &state, TRUE); if (pointer_window != NULL && (GDK_WINDOW_DESTROYED (pointer_window) || @@ -1340,6 +1371,7 @@ get_current_toplevel (GdkDisplay *display, *x_out = x; *y_out = y; *state_out = state; + return pointer_window; } diff --git a/gdk/gdkinternals.h b/gdk/gdkinternals.h index 2259bc5116..d14a8ee150 100644 --- a/gdk/gdkinternals.h +++ b/gdk/gdkinternals.h @@ -326,40 +326,17 @@ extern const GOptionEntry _gdk_windowing_args[]; gchar *_gdk_windowing_substitute_screen_number (const gchar *display_name, gint screen_number); -gulong _gdk_windowing_window_get_next_serial (GdkDisplay *display); void _gdk_windowing_window_get_offsets (GdkWindow *window, gint *x_offset, gint *y_offset); - -void _gdk_windowing_get_device_state (GdkDisplay *display, - GdkDevice *device, - GdkScreen **screen, - gint *x, - gint *y, - GdkModifierType *mask); -GdkWindow* _gdk_windowing_window_at_device_position (GdkDisplay *display, - GdkDevice *device, - gint *win_x, - gint *win_y, - GdkModifierType *mask, - gboolean get_toplevel); void _gdk_windowing_got_event (GdkDisplay *display, GList *event_link, GdkEvent *event, gulong serial); -void _gdk_windowing_window_process_updates_recurse (GdkWindow *window, - cairo_region_t *expose_region); -void _gdk_windowing_before_process_all_updates (void); -void _gdk_windowing_after_process_all_updates (void); - - #define GDK_WINDOW_IS_MAPPED(window) (((window)->state & GDK_WINDOW_STATE_WITHDRAWN) == 0) -void _gdk_windowing_display_set_sm_client_id (GdkDisplay *display, - const gchar *sm_client_id); - #define GDK_TYPE_PAINTABLE (_gdk_paintable_get_type ()) #define GDK_PAINTABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_PAINTABLE, GdkPaintable)) #define GDK_IS_PAINTABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDK_TYPE_PAINTABLE)) diff --git a/gdk/x11/gdkdevice-core.c b/gdk/x11/gdkdevice-core.c index 8e7b3c93ab..ff0d456e4c 100644 --- a/gdk/x11/gdkdevice-core.c +++ b/gdk/x11/gdkdevice-core.c @@ -243,23 +243,49 @@ gdk_device_core_query_state (GdkDevice *device, GdkModifierType *mask) { GdkDisplay *display; + GdkScreen *default_screen; Window xroot_window, xchild_window; int xroot_x, xroot_y, xwin_x, xwin_y; unsigned int xmask; display = gdk_window_get_display (window); + default_screen = gdk_display_get_default_screen (display); - if (!XQueryPointer (GDK_WINDOW_XDISPLAY (window), - GDK_WINDOW_XID (window), - &xroot_window, - &xchild_window, - &xroot_x, - &xroot_y, - &xwin_x, - &xwin_y, - &xmask)) + if (G_LIKELY (GDK_DISPLAY_X11 (display)->trusted_client)) { - return FALSE; + if (!XQueryPointer (GDK_WINDOW_XDISPLAY (window), + GDK_WINDOW_XID (window), + &xroot_window, + &xchild_window, + &xroot_x, + &xroot_y, + &xwin_x, + &xwin_y, + &xmask)) + return FALSE; + } + else + { + XSetWindowAttributes attributes; + Display *xdisplay; + Window xwindow, w; + + /* FIXME: untrusted clients not multidevice-safe */ + xdisplay = GDK_SCREEN_XDISPLAY (default_screen); + xwindow = GDK_SCREEN_XROOTWIN (default_screen); + + w = XCreateWindow (xdisplay, xwindow, 0, 0, 1, 1, 0, + CopyFromParent, InputOnly, CopyFromParent, + 0, &attributes); + XQueryPointer (xdisplay, w, + &xroot_window, + &xchild_window, + &xroot_x, + &xroot_y, + &xwin_x, + &xwin_y, + &xmask); + XDestroyWindow (xdisplay, w); } if (root_window) @@ -415,25 +441,92 @@ gdk_device_core_window_at_position (GdkDevice *device, xdisplay = GDK_SCREEN_XDISPLAY (screen); xwindow = GDK_SCREEN_XROOTWIN (screen); - XQueryPointer (xdisplay, xwindow, - &root, &child, - &xroot_x, &xroot_y, - &xwin_x, &xwin_y, - &xmask); + if (G_LIKELY (GDK_DISPLAY_X11 (display)->trusted_client)) + { + XQueryPointer (xdisplay, xwindow, + &root, &child, + &xroot_x, &xroot_y, + &xwin_x, &xwin_y, + &xmask); - if (root == xwindow) - xwindow = child; + if (root == xwindow) + xwindow = child; + else + xwindow = root; + } else - xwindow = root; + { + gint i, screens, width, height; + GList *toplevels, *list; + Window pointer_window, root, child; + int rootx = -1, rooty = -1; + int winx, winy; + unsigned int xmask; + + /* FIXME: untrusted clients case not multidevice-safe */ + pointer_window = None; + screens = gdk_display_get_n_screens (display); + + for (i = 0; i < screens; ++i) + { + screen = gdk_display_get_screen (display, i); + toplevels = gdk_screen_get_toplevel_windows (screen); + for (list = toplevels; list != NULL; list = g_list_next (list)) + { + window = GDK_WINDOW (list->data); + xwindow = GDK_WINDOW_XID (window); + gdk_x11_display_error_trap_push (display); + XQueryPointer (xdisplay, xwindow, + &root, &child, &rootx, &rooty, &winx, &winy, &xmask); + if (gdk_x11_display_error_trap_pop (display)) + continue; + if (child != None) + { + pointer_window = child; + break; + } + gdk_window_get_geometry (window, NULL, NULL, &width, &height); + if (winx >= 0 && winy >= 0 && winx < width && winy < height) + { + /* A childless toplevel, or below another window? */ + XSetWindowAttributes attributes; + Window w; + + w = XCreateWindow (xdisplay, xwindow, winx, winy, 1, 1, 0, + CopyFromParent, InputOnly, CopyFromParent, + 0, &attributes); + XMapWindow (xdisplay, w); + XQueryPointer (xdisplay, xwindow, + &root, &child, + &rootx, &rooty, &winx, &winy, &xmask); + XDestroyWindow (xdisplay, w); + if (child == w) + { + pointer_window = xwindow; + break; + } + } + } + + g_list_free (toplevels); + if (pointer_window != None) + break; + } + + xwindow = pointer_window; + } while (xwindow) { last = xwindow; + gdk_x11_display_error_trap_push (display); XQueryPointer (xdisplay, xwindow, &root, &xwindow, &xroot_x, &xroot_y, &xwin_x, &xwin_y, &xmask); + if (gdk_x11_display_error_trap_pop (display)) + break; if (get_toplevel && last != root && (window = gdk_window_lookup_for_display (display, last)) != NULL && diff --git a/gdk/x11/gdkdevice-xi.c b/gdk/x11/gdkdevice-xi.c index 71b0ab5c9c..e7dfb0ca6a 100644 --- a/gdk/x11/gdkdevice-xi.c +++ b/gdk/x11/gdkdevice-xi.c @@ -491,6 +491,7 @@ gdk_device_xi_window_at_position (GdkDevice *device, { return NULL; } + static void gdk_device_xi_select_window_events (GdkDevice *device, GdkWindow *window, diff --git a/gdk/x11/gdkdevice-xi2.c b/gdk/x11/gdkdevice-xi2.c index 09b2965d7a..522eda90df 100644 --- a/gdk/x11/gdkdevice-xi2.c +++ b/gdk/x11/gdkdevice-xi2.c @@ -298,6 +298,7 @@ gdk_device_xi2_query_state (GdkDevice *device, GdkModifierType *mask) { GdkDisplay *display; + GdkScreen *default_screen; GdkDeviceXI2Private *priv; Window xroot_window, xchild_window; gdouble xroot_x, xroot_y, xwin_x, xwin_y; @@ -310,21 +311,49 @@ gdk_device_xi2_query_state (GdkDevice *device, priv = GDK_DEVICE_XI2 (device)->priv; display = gdk_window_get_display (window); + default_screen = gdk_display_get_default_screen (display); - if (!XIQueryPointer (GDK_WINDOW_XDISPLAY (window), - priv->device_id, - GDK_WINDOW_XID (window), - &xroot_window, - &xchild_window, - &xroot_x, - &xroot_y, - &xwin_x, - &xwin_y, - &button_state, - &mod_state, - &group_state)) + if (G_LIKELY (GDK_DISPLAY_X11 (display)->trusted_client)) { - return FALSE; + if (!XIQueryPointer (GDK_WINDOW_XDISPLAY (window), + priv->device_id, + GDK_WINDOW_XID (window), + &xroot_window, + &xchild_window, + &xroot_x, + &xroot_y, + &xwin_x, + &xwin_y, + &button_state, + &mod_state, + &group_state)) + return FALSE; + } + else + { + XSetWindowAttributes attributes; + Display *xdisplay; + Window xwindow, w; + + /* FIXME: untrusted clients not multidevice-safe */ + xdisplay = GDK_SCREEN_XDISPLAY (default_screen); + xwindow = GDK_SCREEN_XROOTWIN (default_screen); + + w = XCreateWindow (xdisplay, xwindow, 0, 0, 1, 1, 0, + CopyFromParent, InputOnly, CopyFromParent, + 0, &attributes); + XIQueryPointer (xdisplay, priv->device_id, + w, + &xroot_window, + &xchild_window, + &xroot_x, + &xroot_y, + &xwin_x, + &xwin_y, + &button_state, + &mod_state, + &group_state); + XDestroyWindow (xdisplay, w); } if (root_window) @@ -455,24 +484,99 @@ gdk_device_xi2_window_at_position (GdkDevice *device, xdisplay = GDK_SCREEN_XDISPLAY (screen); xwindow = GDK_SCREEN_XROOTWIN (screen); - XIQueryPointer (xdisplay, - priv->device_id, - xwindow, - &root, &child, - &xroot_x, &xroot_y, - &xwin_x, &xwin_y, - &button_state, - &mod_state, - &group_state); + if (G_LIKELY (GDK_DISPLAY_X11 (display)->trusted_client)) + { + XIQueryPointer (xdisplay, + priv->device_id, + xwindow, + &root, &child, + &xroot_x, &xroot_y, + &xwin_x, &xwin_y, + &button_state, + &mod_state, + &group_state); - if (root == xwindow) - xwindow = child; + if (root == xwindow) + xwindow = child; + else + xwindow = root; + } else - xwindow = root; + { + gint i, screens, width, height; + GList *toplevels, *list; + Window pointer_window, root, child; + + /* FIXME: untrusted clients case not multidevice-safe */ + pointer_window = None; + screens = gdk_display_get_n_screens (display); + + for (i = 0; i < screens; ++i) + { + screen = gdk_display_get_screen (display, i); + toplevels = gdk_screen_get_toplevel_windows (screen); + for (list = toplevels; list != NULL; list = g_list_next (list)) + { + window = GDK_WINDOW (list->data); + xwindow = GDK_WINDOW_XID (window); + gdk_x11_display_error_trap_push (display); + XIQueryPointer (xdisplay, + priv->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)) + continue; + if (child != None) + { + pointer_window = child; + break; + } + gdk_window_get_geometry (window, NULL, NULL, &width, &height); + if (xwin_x >= 0 && xwin_y >= 0 && xwin_x < width && xwin_y < height) + { + /* A childless toplevel, or below another window? */ + XSetWindowAttributes attributes; + Window w; + + w = XCreateWindow (xdisplay, xwindow, (int)xwin_x, (int)xwin_y, 1, 1, 0, + CopyFromParent, InputOnly, CopyFromParent, + 0, &attributes); + XMapWindow (xdisplay, w); + XIQueryPointer (xdisplay, + priv->device_id, + xwindow, + &root, &child, + &xroot_x, &xroot_y, + &xwin_x, &xwin_y, + &button_state, + &mod_state, + &group_state); + XDestroyWindow (xdisplay, w); + if (child == w) + { + pointer_window = xwindow; + break; + } + } + } + + g_list_free (toplevels); + if (pointer_window != None) + break; + } + + xwindow = pointer_window; + } while (xwindow) { last = xwindow; + gdk_x11_display_error_trap_push (display); XIQueryPointer (xdisplay, priv->device_id, xwindow, @@ -482,6 +586,8 @@ gdk_device_xi2_window_at_position (GdkDevice *device, &button_state, &mod_state, &group_state); + if (gdk_x11_display_error_trap_pop (display)) + break; if (get_toplevel && last != root && (window = gdk_window_lookup_for_display (display, last)) != NULL && diff --git a/gdk/x11/gdkwindow-x11.c b/gdk/x11/gdkwindow-x11.c index dd233bd247..287a5bccfc 100644 --- a/gdk/x11/gdkwindow-x11.c +++ b/gdk/x11/gdkwindow-x11.c @@ -2781,66 +2781,6 @@ gdk_x11_window_get_frame_extents (GdkWindow *window, gdk_error_trap_pop_ignored (); } -void -_gdk_windowing_get_device_state (GdkDisplay *display, - GdkDevice *device, - GdkScreen **screen, - gint *x, - gint *y, - GdkModifierType *mask) -{ - GdkScreen *default_screen; - - if (gdk_display_is_closed (display)) - return; - - default_screen = gdk_display_get_default_screen (display); - - - if (G_LIKELY (GDK_DISPLAY_X11 (display)->trusted_client)) - { - GdkWindow *root; - - GDK_DEVICE_GET_CLASS (device)->query_state (device, - gdk_screen_get_root_window (default_screen), - &root, NULL, - x, y, - NULL, NULL, - mask); - *screen = gdk_window_get_screen (root); - } - else - { - XSetWindowAttributes attributes; - Display *xdisplay; - Window xwindow, w, root, child; - int rootx, rooty, winx, winy; - unsigned int xmask; - - /* FIXME: untrusted clients not multidevice-safe */ - - xdisplay = GDK_SCREEN_XDISPLAY (default_screen); - xwindow = GDK_SCREEN_XROOTWIN (default_screen); - - w = XCreateWindow (xdisplay, xwindow, 0, 0, 1, 1, 0, - CopyFromParent, InputOnly, CopyFromParent, - 0, &attributes); - XQueryPointer (xdisplay, w, - &root, &child, &rootx, &rooty, &winx, &winy, &xmask); - XDestroyWindow (xdisplay, w); - - if (root != None) - { - GdkWindow *gdk_root = gdk_window_lookup_for_display (display, root); - *screen = gdk_window_get_screen (gdk_root); - } - - *x = rootx; - *y = rooty; - *mask = xmask; - } -} - static gboolean gdk_window_x11_get_device_state (GdkWindow *window, GdkDevice *device, @@ -2848,156 +2788,18 @@ gdk_window_x11_get_device_state (GdkWindow *window, gint *y, GdkModifierType *mask) { - GdkDisplay *display = GDK_WINDOW_DISPLAY (window); - gboolean return_val; + GdkWindow *child; g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), FALSE); - return_val = TRUE; + if (GDK_WINDOW_DESTROYED (window)) + return FALSE; - if (!GDK_WINDOW_DESTROYED (window)) - { - if (G_LIKELY (GDK_DISPLAY_X11 (display)->trusted_client)) - { - GdkWindow *child; - - GDK_DEVICE_GET_CLASS (device)->query_state (device, window, - NULL, &child, - NULL, NULL, - x, y, mask); - return_val = (child != NULL); - } - else - { - GdkScreen *screen; - int originx, originy; - int rootx, rooty; - int winx = 0; - int winy = 0; - unsigned int xmask = 0; - - _gdk_windowing_get_device_state (gdk_window_get_display (window), device, - &screen, &rootx, &rooty, &xmask); - gdk_window_get_origin (window, &originx, &originy); - winx = rootx - originx; - winy = rooty - originy; - - *x = winx; - *y = winy; - *mask = xmask; - } - } - - return return_val; -} - -GdkWindow* -_gdk_windowing_window_at_device_position (GdkDisplay *display, - GdkDevice *device, - gint *win_x, - gint *win_y, - GdkModifierType *mask, - gboolean get_toplevel) -{ - GdkWindow *window; - GdkScreen *screen; - - screen = gdk_display_get_default_screen (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 - * and the result. - */ - gdk_x11_display_grab (display); - if (G_LIKELY (GDK_DISPLAY_X11 (display)->trusted_client)) - window = GDK_DEVICE_GET_CLASS (device)->window_at_position (device, win_x, win_y, mask, get_toplevel); - else - { - gint i, screens, width, height; - GList *toplevels, *list; - Window pointer_window, root, xwindow, child; - Window xwindow_last = 0; - Display *xdisplay; - int rootx = -1, rooty = -1; - int winx, winy; - unsigned int xmask; - - /* FIXME: untrusted clients case not multidevice-safe */ - - xwindow = GDK_SCREEN_XROOTWIN (screen); - xdisplay = GDK_SCREEN_XDISPLAY (screen); - - pointer_window = None; - screens = gdk_display_get_n_screens (display); - for (i = 0; i < screens; ++i) { - screen = gdk_display_get_screen (display, i); - toplevels = gdk_screen_get_toplevel_windows (screen); - for (list = toplevels; list != NULL; list = g_list_next (list)) { - window = GDK_WINDOW (list->data); - xwindow = GDK_WINDOW_XID (window); - gdk_error_trap_push (); - XQueryPointer (xdisplay, xwindow, - &root, &child, &rootx, &rooty, &winx, &winy, &xmask); - if (gdk_error_trap_pop ()) - continue; - if (child != None) - { - pointer_window = child; - break; - } - gdk_window_get_geometry (window, NULL, NULL, &width, &height); - if (winx >= 0 && winy >= 0 && winx < width && winy < height) - { - /* A childless toplevel, or below another window? */ - XSetWindowAttributes attributes; - Window w; - - w = XCreateWindow (xdisplay, xwindow, winx, winy, 1, 1, 0, - CopyFromParent, InputOnly, CopyFromParent, - 0, &attributes); - XMapWindow (xdisplay, w); - XQueryPointer (xdisplay, xwindow, - &root, &child, &rootx, &rooty, &winx, &winy, &xmask); - XDestroyWindow (xdisplay, w); - if (child == w) - { - pointer_window = xwindow; - break; - } - } - } - g_list_free (toplevels); - if (pointer_window != None) - break; - } - xwindow = pointer_window; - - while (xwindow) - { - xwindow_last = xwindow; - gdk_error_trap_push (); - XQueryPointer (xdisplay, xwindow, - &root, &xwindow, &rootx, &rooty, &winx, &winy, &xmask); - if (gdk_error_trap_pop ()) - break; - if (get_toplevel && xwindow_last != root && - (window = gdk_window_lookup_for_display (display, xwindow_last)) != NULL && - GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN) - break; - } - - window = gdk_window_lookup_for_display (display, xwindow_last); - - *win_x = window ? winx : -1; - *win_y = window ? winy : -1; - if (mask) - *mask = xmask; - } - - gdk_x11_display_ungrab (display); - - return window; + GDK_DEVICE_GET_CLASS (device)->query_state (device, window, + NULL, &child, + NULL, NULL, + x, y, mask); + return child != NULL; } static GdkEventMask