[gtk+] Extend _gdk_windowing_window_at_pointer to be able to get toplevels only
- From: Alexander Larsson <alexl src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gtk+] Extend _gdk_windowing_window_at_pointer to be able to get toplevels only
- Date: Mon, 28 Sep 2009 13:32:03 +0000 (UTC)
commit 5ebb32d1ffa23241d562fb4d5be02bc6f156b515
Author: Alexander Larsson <alexl redhat com>
Date: Mon Sep 28 15:21:54 2009 +0200
Extend _gdk_windowing_window_at_pointer to be able to get toplevels only
This has two advantages:
1) In many backends, this is faster as we can terminate the window
hierarchy traversal earlier
2) When used in gdkdisplay.c::get_current_toplevel() to get the
current toplevel that has the pointer we now correctly return
a toplevel with the pointer in it where the pointer is inside
some foreign subwindow of a toplevel window.
The second advantage fixes some bugs in client side event generation
when the pointer is inside such a foreign child window.
gdk/directfb/gdkwindow-directfb.c | 20 ++++++++++++++++++++
gdk/gdkdisplay.c | 20 +++-----------------
gdk/gdkinternals.h | 3 ++-
gdk/quartz/gdkwindow-quartz.c | 23 ++++++++++++++++++++++-
gdk/win32/gdkwindow-win32.c | 8 +++++++-
gdk/x11/gdkwindow-x11.c | 11 ++++++++++-
6 files changed, 64 insertions(+), 21 deletions(-)
---
diff --git a/gdk/directfb/gdkwindow-directfb.c b/gdk/directfb/gdkwindow-directfb.c
index 85859e7..c0ff8e1 100644
--- a/gdk/directfb/gdkwindow-directfb.c
+++ b/gdk/directfb/gdkwindow-directfb.c
@@ -2099,6 +2099,26 @@ _gdk_windowing_window_at_pointer (GdkDisplay *display,
if (win_y)
*win_y = wy;
+ if (get_toplevel)
+ {
+ GdkWindowObject *w = (GdkWindowObject *)retval;
+ /* Requested toplevel, find it. */
+ /* TODO: This can be implemented more efficient by never
+ recursing into children in the first place */
+ if (w)
+ {
+ /* Convert to toplevel */
+ while (w->parent != NULL &&
+ w->parent->window_type != GDK_WINDOW_ROOT)
+ {
+ *win_x += w->x;
+ *win_y += w->y;
+ w = w->parent;
+ }
+ retval = (GdkWindow *)w;
+ }
+ }
+
return retval;
}
diff --git a/gdk/gdkdisplay.c b/gdk/gdkdisplay.c
index d22ff00..d020b16 100644
--- a/gdk/gdkdisplay.c
+++ b/gdk/gdkdisplay.c
@@ -510,7 +510,7 @@ gdk_display_real_get_window_at_pointer (GdkDisplay *display,
GdkWindow *window;
gint x, y;
- window = _gdk_windowing_window_at_pointer (display, &x, &y, NULL);
+ window = _gdk_windowing_window_at_pointer (display, &x, &y, NULL, FALSE);
/* This might need corrections, as the native window returned
may contain client side children */
@@ -913,34 +913,20 @@ get_current_toplevel (GdkDisplay *display,
GdkModifierType *state_out)
{
GdkWindow *pointer_window;
- GdkWindowObject *w;
int x, y;
GdkModifierType state;
- pointer_window = _gdk_windowing_window_at_pointer (display, &x, &y, &state);
+ pointer_window = _gdk_windowing_window_at_pointer (display, &x, &y, &state, TRUE);
if (pointer_window != NULL &&
(GDK_WINDOW_DESTROYED (pointer_window) ||
GDK_WINDOW_TYPE (pointer_window) == GDK_WINDOW_ROOT ||
GDK_WINDOW_TYPE (pointer_window) == GDK_WINDOW_FOREIGN))
pointer_window = NULL;
- w = (GdkWindowObject *)pointer_window;
- if (w)
- {
- /* Convert to toplevel */
- while (w->parent != NULL &&
- w->parent->window_type != GDK_WINDOW_ROOT)
- {
- x += w->x;
- y += w->y;
- w = w->parent;
- }
- }
-
*x_out = x;
*y_out = y;
*state_out = state;
- return (GdkWindow *)w;
+ return pointer_window;
}
static void
diff --git a/gdk/gdkinternals.h b/gdk/gdkinternals.h
index de082bd..51db55f 100644
--- a/gdk/gdkinternals.h
+++ b/gdk/gdkinternals.h
@@ -461,7 +461,8 @@ void _gdk_windowing_get_pointer (GdkDisplay *display,
GdkWindow* _gdk_windowing_window_at_pointer (GdkDisplay *display,
gint *win_x,
gint *win_y,
- GdkModifierType *mask);
+ GdkModifierType *mask,
+ gboolean get_toplevel);
GdkGrabStatus _gdk_windowing_pointer_grab (GdkWindow *window,
GdkWindow *native,
gboolean owner_events,
diff --git a/gdk/quartz/gdkwindow-quartz.c b/gdk/quartz/gdkwindow-quartz.c
index ac22d5f..4764498 100644
--- a/gdk/quartz/gdkwindow-quartz.c
+++ b/gdk/quartz/gdkwindow-quartz.c
@@ -1938,7 +1938,8 @@ GdkWindow *
_gdk_windowing_window_at_pointer (GdkDisplay *display,
gint *win_x,
gint *win_y,
- GdkModifierType *mask)
+ GdkModifierType *mask,
+ gboolean get_toplevel)
{
GdkWindow *found_window;
gint x, y;
@@ -1976,6 +1977,26 @@ _gdk_windowing_window_at_pointer (GdkDisplay *display,
if (mask)
*mask = tmp_mask;
+ if (get_toplevel)
+ {
+ GdkWindowObject *w = (GdkWindowObject *)found_window;
+ /* Requested toplevel, find it. */
+ /* TODO: This can be implemented more efficient by never
+ recursing into children in the first place */
+ if (w)
+ {
+ /* Convert to toplevel */
+ while (w->parent != NULL &&
+ w->parent->window_type != GDK_WINDOW_ROOT)
+ {
+ *win_x += w->x;
+ *win_y += w->y;
+ w = w->parent;
+ }
+ found_window = (GdkWindow *)w;
+ }
+ }
+
return found_window;
}
diff --git a/gdk/win32/gdkwindow-win32.c b/gdk/win32/gdkwindow-win32.c
index c945631..e472b91 100644
--- a/gdk/win32/gdkwindow-win32.c
+++ b/gdk/win32/gdkwindow-win32.c
@@ -2261,7 +2261,8 @@ GdkWindow*
_gdk_windowing_window_at_pointer (GdkDisplay *display,
gint *win_x,
gint *win_y,
- GdkModifierType *mask)
+ GdkModifierType *mask,
+ gboolean get_toplevel)
{
GdkWindow *window;
POINT point, pointc;
@@ -2283,6 +2284,11 @@ _gdk_windowing_window_at_pointer (GdkDisplay *display,
ScreenToClient (hwnd, &point);
do {
+ if (get_toplevel &&
+ (window = gdk_win32_handle_table_lookup ((GdkNativeWindow) hwnd)) != NULL &&
+ GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
+ break;
+
hwndc = ChildWindowFromPoint (hwnd, point);
ClientToScreen (hwnd, &point);
ScreenToClient (hwndc, &point);
diff --git a/gdk/x11/gdkwindow-x11.c b/gdk/x11/gdkwindow-x11.c
index 257dba7..f98290b 100644
--- a/gdk/x11/gdkwindow-x11.c
+++ b/gdk/x11/gdkwindow-x11.c
@@ -3215,7 +3215,8 @@ GdkWindow*
_gdk_windowing_window_at_pointer (GdkDisplay *display,
gint *win_x,
gint *win_y,
- GdkModifierType *mask)
+ GdkModifierType *mask,
+ gboolean get_toplevel)
{
GdkWindow *window;
GdkScreen *screen;
@@ -3251,6 +3252,10 @@ _gdk_windowing_window_at_pointer (GdkDisplay *display,
while (xwindow)
{
xwindow_last = xwindow;
+ if (get_toplevel &&
+ (window = gdk_window_lookup_for_display (display, xwindow)) != NULL &&
+ GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
+ break;
XQueryPointer (xdisplay, xwindow,
&root, &xwindow, &rootx, &rooty, &winx, &winy, &xmask);
}
@@ -3310,6 +3315,10 @@ _gdk_windowing_window_at_pointer (GdkDisplay *display,
while (xwindow)
{
xwindow_last = xwindow;
+ if (get_toplevel &&
+ (window = gdk_window_lookup_for_display (display, xwindow)) != NULL &&
+ GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
+ break;
gdk_error_trap_push ();
XQueryPointer (xdisplay, xwindow,
&root, &xwindow, &rootx, &rooty, &winx, &winy, &xmask);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]