[gtk+/gdk-backend: 43/91] Remove gdk_windowing_{get_device_state, window_at_device_position}
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/gdk-backend: 43/91] Remove gdk_windowing_{get_device_state, window_at_device_position}
- Date: Sat, 18 Dec 2010 01:09:26 +0000 (UTC)
commit a3280a45af2554ab95c254a980ecb24403d6c819
Author: Matthias Clasen <mclasen redhat com>
Date: Mon Dec 13 17:43:10 2010 -0500
Remove gdk_windowing_{get_device_state,window_at_device_position}
The !trusted workaround code is pushed down into the GdkDevice
subclasses, and we use the device vfuncs directly in gdkdisplay.c
gdk/gdkdevice.c | 35 ++++++++
gdk/gdkdeviceprivate.h | 22 ++++-
gdk/gdkdisplay.c | 44 ++++++++--
gdk/gdkinternals.h | 23 -----
gdk/x11/gdkdevice-core.c | 129 ++++++++++++++++++++++++----
gdk/x11/gdkdevice-xi.c | 1 +
gdk/x11/gdkdevice-xi2.c | 158 ++++++++++++++++++++++++++++------
gdk/x11/gdkwindow-x11.c | 214 ++--------------------------------------------
8 files changed, 343 insertions(+), 283 deletions(-)
---
diff --git a/gdk/gdkdevice.c b/gdk/gdkdevice.c
index 069fa77..704946e 100644
--- a/gdk/gdkdevice.c
+++ b/gdk/gdkdevice.c
@@ -1444,3 +1444,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 a9bb045..29332b2 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 0fbbe20..256922a 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
};
@@ -836,7 +842,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 */
@@ -950,15 +956,40 @@ multihead_window_at_device_position (GdkDisplay *display,
}
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,
gint *x,
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 *
@@ -1327,7 +1358,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) ||
@@ -1338,6 +1369,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 267a2d4..ef1aadc 100644
--- a/gdk/gdkinternals.h
+++ b/gdk/gdkinternals.h
@@ -323,40 +323,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 8e7b3c9..ff0d456 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 71b0ab5..e7dfb0c 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 09b2965..522eda9 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 (root == xwindow)
- xwindow = child;
+ 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;
+ 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 dd233bd..287a5bc 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))
- {
- 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);
+ if (GDK_WINDOW_DESTROYED (window))
+ return FALSE;
- return window;
+ GDK_DEVICE_GET_CLASS (device)->query_state (device, window,
+ NULL, &child,
+ NULL, NULL,
+ x, y, mask);
+ return child != NULL;
}
static GdkEventMask
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]