From 2b9dc3338a399d41652cbcea2fc32fa697b4514d Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Thu, 4 Dec 2008 12:44:09 +0100 Subject: [PATCH] Fix up keyboard grab handling --- gdk/x11/gdkevents-x11.c | 34 +++++++++++++++++++++++++++++++--- gdk/x11/gdkmain-x11.c | 12 +++++++++--- 2 files changed, 40 insertions(+), 6 deletions(-) diff --git a/gdk/x11/gdkevents-x11.c b/gdk/x11/gdkevents-x11.c index b2a438c281..26e5de456b 100644 --- a/gdk/x11/gdkevents-x11.c +++ b/gdk/x11/gdkevents-x11.c @@ -867,6 +867,24 @@ set_user_time (GdkWindow *window, gdk_event_get_time (event)); } +static gboolean +is_parent_of (GdkWindow *parent, + GdkWindow *child) +{ + GdkWindow *w; + + w = child; + while (w != NULL) + { + if (w == parent) + return TRUE; + + w = gdk_window_get_parent (w); + } + + return FALSE; +} + static gboolean gdk_event_translate (GdkDisplay *display, GdkEvent *event, @@ -941,10 +959,20 @@ gdk_event_translate (GdkDisplay *display, if (window != NULL) { - /* Rewrite keyboard grabs to offscreen windows */ - if ((xevent->type == KeyPress || xevent->type == KeyRelease) && - window_private == display_x11->keyboard_xgrab_native_window) + /* Apply keyboard grabs to non-native windows */ + if (/* Is key event */ + (xevent->type == KeyPress || xevent->type == KeyRelease) && + /* And we have a grab */ + display_x11->keyboard_xgrab_window != NULL && + ( + /* The window is not a descendant of the grabbed window */ + !is_parent_of (display_x11->keyboard_xgrab_window, window) || + /* Or owner event is false */ + !display_x11->keyboard_xgrab_owner_events + ) + ) { + /* Report key event against grab window */ window_private = display_x11->keyboard_xgrab_window; window = (GdkWindow *) window_private; } diff --git a/gdk/x11/gdkmain-x11.c b/gdk/x11/gdkmain-x11.c index 2ab67c74a4..89a9c75f55 100644 --- a/gdk/x11/gdkmain-x11.c +++ b/gdk/x11/gdkmain-x11.c @@ -206,6 +206,10 @@ gdk_pointer_grab (GdkWindow * window, native = gdk_window_get_toplevel (window); + /* TODO: What do we do for offscreens and children? We need to proxy the grab somehow */ + if (!GDK_IS_WINDOW_IMPL_X11 (GDK_WINDOW_OBJECT (native)->impl)) + return GDK_GRAB_SUCCESS; + if (confine_to) confine_to = _gdk_window_get_impl_window (confine_to); @@ -310,13 +314,15 @@ gdk_keyboard_grab (GdkWindow * window, GdkDisplayX11 *display_x11; GdkWindow *native; - if (1) return 0; /* TODO: fix */ - g_return_val_if_fail (window != NULL, 0); g_return_val_if_fail (GDK_IS_WINDOW (window), 0); - native = _gdk_window_get_impl_window (window); + native = gdk_window_get_toplevel (window); + /* TODO: What do we do for offscreens and children? We need to proxy the grab somehow */ + if (!GDK_IS_WINDOW_IMPL_X11 (GDK_WINDOW_OBJECT (native)->impl)) + return GDK_GRAB_SUCCESS; + display_x11 = GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (native)); serial = NextRequest (GDK_WINDOW_XDISPLAY (native));