[gtk+/xi2: 1049/1239] Make keyboard and pointer grabs use the same infrastructure.
- From: Carlos Garnacho <carlosg src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gtk+/xi2: 1049/1239] Make keyboard and pointer grabs use the same infrastructure.
- Date: Tue, 29 Sep 2009 10:55:28 +0000 (UTC)
commit d24c20d639d71dacff83cd68af2708bfa25b0e07
Author: Carlos Garnacho <carlos gnome org>
Date: Sat Sep 5 15:15:26 2009 +0200
Make keyboard and pointer grabs use the same infrastructure.
Now keyboard grabs also use the GdkDeviceGrabInfo machinery. Actual
keyboard grabbing is now handled by the GdkDevice code.
gdk/gdk.symbols | 9 +++-
gdk/gdkdisplay.c | 101 ++++++++++++++++++++++----------------
gdk/gdkdisplay.h | 1 -
gdk/gdkinternals.h | 8 ---
gdk/gdkwindow.c | 97 +++++++++++++++++++++++++++++++-----
gdk/x11/gdkdevicemanager-core.c | 32 +++++++-----
gdk/x11/gdkdevicemanager-xi2.c | 31 +++++++-----
gdk/x11/gdkdisplay-x11.c | 30 -----------
gdk/x11/gdkevents-x11.c | 2 +
gdk/x11/gdkmain-x11.c | 104 +++++---------------------------------
10 files changed, 202 insertions(+), 213 deletions(-)
---
diff --git a/gdk/gdk.symbols b/gdk/gdk.symbols
index bcfe0c3..40c03d8 100644
--- a/gdk/gdk.symbols
+++ b/gdk/gdk.symbols
@@ -68,7 +68,6 @@ gdk_get_display
gdk_get_use_xshm
gdk_set_use_xshm
#endif
-gdk_keyboard_grab
#endif
#endif
@@ -174,6 +173,12 @@ gdk_screen_height_mm G_GNUC_CONST
#endif
#endif
+#if IN_HEADER(__GDK_H__)
+#if IN_FILE(__GDK_WINDOW_C__)
+gdk_keyboard_grab
+#endif
+#endif
+
#if IN_HEADER(__GDK_PROPERTY_H__)
#if IN_FILE(__GDK_SELECTION_C__)
gdk_string_to_compound_text
@@ -416,6 +421,7 @@ gdk_display_get_event
gdk_display_get_pointer
gdk_display_get_type G_GNUC_CONST
gdk_display_get_window_at_pointer
+gdk_display_keyboard_ungrab
gdk_display_peek_event
gdk_display_pointer_ungrab
gdk_display_put_event
@@ -455,7 +461,6 @@ gdk_display_get_name
gdk_display_get_n_screens
gdk_display_get_screen
gdk_display_device_ungrab
-gdk_display_keyboard_ungrab
gdk_display_open
gdk_display_request_selection_notification
gdk_display_store_clipboard
diff --git a/gdk/gdkdisplay.c b/gdk/gdkdisplay.c
index 09a2004..ede927e 100644
--- a/gdk/gdkdisplay.c
+++ b/gdk/gdkdisplay.c
@@ -427,6 +427,43 @@ gdk_pointer_is_grabbed (void)
}
/**
+ * gdk_display_keyboard_ungrab:
+ * @display: a #GdkDisplay.
+ * @time_: a timestap (e.g #GDK_CURRENT_TIME).
+ *
+ * Release any keyboard grab
+ *
+ * Since: 2.2
+ */
+void
+gdk_display_keyboard_ungrab (GdkDisplay *display,
+ guint32 time)
+{
+ GdkDeviceManager *device_manager;
+ GList *devices, *dev;
+ GdkDevice *device;
+
+ g_return_if_fail (GDK_IS_DISPLAY (display));
+
+ device_manager = gdk_device_manager_get_for_display (display);
+ devices = gdk_device_manager_get_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
+
+ /* FIXME: Should this be generic to all backends? */
+ /* FIXME: What happens with extended devices? */
+ for (dev = devices; dev; dev = dev->next)
+ {
+ device = dev->data;
+
+ if (device->source != GDK_SOURCE_KEYBOARD)
+ continue;
+
+ gdk_display_device_ungrab (display, device, time);
+ }
+
+ g_list_free (devices);
+}
+
+/**
* gdk_keyboard_ungrab:
* @time_: a timestamp from a #GdkEvent, or %GDK_CURRENT_TIME if no
* timestamp is available.
@@ -971,7 +1008,6 @@ gdk_set_pointer_hooks (const GdkPointerHooks *new_hooks)
static void
generate_grab_broken_event (GdkWindow *window,
GdkDevice *device,
- gboolean keyboard,
gboolean implicit,
GdkWindow *grab_window)
{
@@ -983,7 +1019,7 @@ generate_grab_broken_event (GdkWindow *window,
event.type = GDK_GRAB_BROKEN;
event.grab_broken.window = window;
event.grab_broken.send_event = 0;
- event.grab_broken.keyboard = keyboard;
+ event.grab_broken.keyboard = (device->source == GDK_SOURCE_KEYBOARD) ? TRUE : FALSE;
event.grab_broken.implicit = implicit;
event.grab_broken.grab_window = grab_window;
event.grab_broken.device = device;
@@ -1299,7 +1335,7 @@ switch_to_pointer_grab (GdkDisplay *display,
if (last_grab->implicit_ungrab)
generate_grab_broken_event (last_grab->window,
device,
- FALSE, TRUE,
+ TRUE,
NULL);
}
}
@@ -1334,7 +1370,10 @@ _gdk_display_device_grab_update (GdkDisplay *display,
its the currently active one or scheduled to be active */
if (!current_grab->activated)
- switch_to_pointer_grab (display, device, current_grab, NULL, time, current_serial);
+ {
+ if (device->source != GDK_SOURCE_KEYBOARD)
+ switch_to_pointer_grab (display, device, current_grab, NULL, time, current_serial);
+ }
break;
}
@@ -1353,16 +1392,17 @@ _gdk_display_device_grab_update (GdkDisplay *display,
current_grab->window != next_grab->window)
generate_grab_broken_event (GDK_WINDOW (current_grab->window),
device,
- FALSE, current_grab->implicit,
+ current_grab->implicit,
next_grab? next_grab->window : NULL);
/* Remove old grab */
grabs = g_list_delete_link (grabs, grabs);
g_hash_table_insert (display->device_grabs, device, grabs);
- switch_to_pointer_grab (display, device,
- next_grab, current_grab,
- time, current_serial);
+ if (device->source != GDK_SOURCE_KEYBOARD)
+ switch_to_pointer_grab (display, device,
+ next_grab, current_grab,
+ time, current_serial);
free_device_grab (current_grab);
}
@@ -1489,38 +1529,6 @@ _gdk_display_check_grab_ownership (GdkDisplay *display,
return TRUE;
}
-void
-_gdk_display_set_has_keyboard_grab (GdkDisplay *display,
- GdkWindow *window,
- GdkWindow *native_window,
- gboolean owner_events,
- unsigned long serial,
- guint32 time)
-{
- if (display->keyboard_grab.window != NULL &&
- display->keyboard_grab.window != window)
- generate_grab_broken_event (display->keyboard_grab.window,
- display->core_pointer, /* FIXME: which event? core pointer not, clearly */
- TRUE, FALSE, window);
-
- display->keyboard_grab.window = window;
- display->keyboard_grab.native_window = native_window;
- display->keyboard_grab.owner_events = owner_events;
- display->keyboard_grab.serial = serial;
- display->keyboard_grab.time = time;
-}
-
-void
-_gdk_display_unset_has_keyboard_grab (GdkDisplay *display,
- gboolean implicit)
-{
- if (implicit)
- generate_grab_broken_event (display->keyboard_grab.window,
- display->core_pointer, /* FIXME: which device? core pointer not, clearly */
- TRUE, FALSE, NULL);
- display->keyboard_grab.window = NULL;
-}
-
GdkPointerWindowInfo *
_gdk_display_get_pointer_info (GdkDisplay *display,
GdkDevice *device)
@@ -1578,14 +1586,21 @@ gdk_keyboard_grab_info_libgtk_only (GdkDisplay *display,
GdkWindow **grab_window,
gboolean *owner_events)
{
+ GdkDeviceGrabInfo *info;
+
+ /* FIXME: merge this and the pointer function */
g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
- if (display->keyboard_grab.window)
+ /* FIXME: which device? */
+ info = _gdk_display_get_last_device_grab (display,
+ gdk_device_get_relative (display->core_pointer));
+
+ if (info)
{
if (grab_window)
- *grab_window = display->keyboard_grab.window;
+ *grab_window = info->window;
if (owner_events)
- *owner_events = display->keyboard_grab.owner_events;
+ *owner_events = info->owner_events;
return TRUE;
}
diff --git a/gdk/gdkdisplay.h b/gdk/gdkdisplay.h
index c75f15f..d629d20 100644
--- a/gdk/gdkdisplay.h
+++ b/gdk/gdkdisplay.h
@@ -103,7 +103,6 @@ struct _GdkDisplay
guint double_click_distance; /* Maximum distance between clicks in pixels */
GHashTable *device_grabs;
- GdkKeyboardGrabInfo keyboard_grab;
gulong motion_hint_serial; /* 0 == didn't deliver hinted motion event */
diff --git a/gdk/gdkinternals.h b/gdk/gdkinternals.h
index 18601c8..2fb237d 100644
--- a/gdk/gdkinternals.h
+++ b/gdk/gdkinternals.h
@@ -618,14 +618,6 @@ gboolean _gdk_display_end_device_grab (GdkDisplay *display,
gboolean _gdk_display_check_grab_ownership (GdkDisplay *display,
GdkDevice *device,
gulong serial);
-void _gdk_display_set_has_keyboard_grab (GdkDisplay *display,
- GdkWindow *window,
- GdkWindow *native_window,
- gboolean owner_events,
- unsigned long serial,
- guint32 time);
-void _gdk_display_unset_has_keyboard_grab (GdkDisplay *display,
- gboolean implicit);
void _gdk_display_enable_motion_hints (GdkDisplay *display);
GdkPointerWindowInfo * _gdk_display_get_pointer_info (GdkDisplay *display,
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
index 5f13646..6ff17be 100644
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@ -6445,18 +6445,12 @@ gdk_window_hide (GdkWindow *window)
TRUE))
gdk_display_pointer_ungrab (display, GDK_CURRENT_TIME);
- if (display->keyboard_grab.window != NULL)
- {
- if (is_parent_of (window, display->keyboard_grab.window))
- {
- /* Call this ourselves, even though gdk_display_keyboard_ungrab
- does so too, since we want to pass implicit == TRUE so the
- broken grab event is generated */
- _gdk_display_unset_has_keyboard_grab (display,
- TRUE);
- gdk_display_keyboard_ungrab (display, GDK_CURRENT_TIME);
- }
- }
+ if (_gdk_display_end_device_grab (display,
+ gdk_device_get_relative (display->core_pointer),
+ _gdk_windowing_window_get_next_serial (display),
+ window,
+ TRUE))
+ gdk_display_keyboard_ungrab (display, GDK_CURRENT_TIME);
private->state = GDK_WINDOW_STATE_WITHDRAWN;
}
@@ -9353,6 +9347,85 @@ gdk_pointer_grab (GdkWindow * window,
return res;
}
+GdkGrabStatus
+gdk_keyboard_grab (GdkWindow *window,
+ gboolean owner_events,
+ guint32 time)
+{
+ GdkWindow *native;
+ GdkDisplay *display;
+ GdkDeviceManager *device_manager;
+ GdkDevice *device;
+ GdkGrabStatus res = 0;
+ gulong serial;
+ GList *devices, *dev;
+
+ g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
+
+ /* Non-viewable client side window => fail */
+ if (!_gdk_window_has_impl (window) &&
+ !gdk_window_is_viewable (window))
+ return GDK_GRAB_NOT_VIEWABLE;
+
+ if (_gdk_native_windows)
+ native = window;
+ else
+ native = gdk_window_get_toplevel (window);
+
+ while (gdk_window_is_offscreen ((GdkWindowObject *)native))
+ {
+ native = gdk_offscreen_window_get_embedder (native);
+
+ if (native == NULL ||
+ (!_gdk_window_has_impl (native) &&
+ !gdk_window_is_viewable (native)))
+ return GDK_GRAB_NOT_VIEWABLE;
+
+ native = gdk_window_get_toplevel (native);
+ }
+
+ display = gdk_drawable_get_display (window);
+
+ serial = _gdk_windowing_window_get_next_serial (display);
+ device_manager = gdk_device_manager_get_for_display (display);
+ devices = gdk_device_manager_get_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
+
+ /* FIXME: Should this be generic to all backends? */
+ /* FIXME: What happens with extended devices? */
+ for (dev = devices; dev; dev = dev->next)
+ {
+ device = dev->data;
+
+ if (device->source != GDK_SOURCE_KEYBOARD)
+ continue;
+
+ res = _gdk_windowing_device_grab (device,
+ window,
+ native,
+ owner_events, 0,
+ NULL,
+ NULL,
+ time);
+
+ if (res == GDK_GRAB_SUCCESS)
+ _gdk_display_add_device_grab (display,
+ device,
+ window,
+ native,
+ GDK_OWNERSHIP_NONE,
+ owner_events, 0,
+ serial,
+ time,
+ FALSE);
+ }
+
+ /* FIXME: handle errors when grabbing */
+
+ g_list_free (devices);
+
+ return res;
+}
+
/**
* gdk_window_geometry_changed:
* @window: a #GdkWindow
diff --git a/gdk/x11/gdkdevicemanager-core.c b/gdk/x11/gdkdevicemanager-core.c
index 1177e05..dda714b 100644
--- a/gdk/x11/gdkdevicemanager-core.c
+++ b/gdk/x11/gdkdevicemanager-core.c
@@ -344,27 +344,31 @@ static GdkWindow *
get_event_window (GdkEventTranslator *translator,
XEvent *xevent)
{
+ GdkDeviceManager *device_manager;
GdkDisplay *display;
GdkWindow *window;
- display = gdk_device_manager_get_display (GDK_DEVICE_MANAGER (translator));
+ device_manager = GDK_DEVICE_MANAGER (translator);
+ display = gdk_device_manager_get_display (device_manager);
window = gdk_window_lookup_for_display (display, xevent->xany.window);
/* Apply keyboard grabs to non-native windows */
- if (/* Is key event */
- (xevent->type == KeyPress || xevent->type == KeyRelease) &&
- /* And we have a grab */
- display->keyboard_grab.window != NULL &&
- (
- /* The window is not a descendant of the grabbed window */
- !is_parent_of ((GdkWindow *)display->keyboard_grab.window, window) ||
- /* Or owner event is false */
- !display->keyboard_grab.owner_events
- )
- )
+ if (xevent->type == KeyPress || xevent->type == KeyRelease)
{
- /* Report key event against grab window */
- return display->keyboard_grab.window;
+ GdkDeviceGrabInfo *info;
+ gulong serial;
+
+ serial = _gdk_windowing_window_get_next_serial (display);
+ info = _gdk_display_has_device_grab (display,
+ GDK_DEVICE_MANAGER_CORE (device_manager)->core_keyboard,
+ serial);
+ if (info &&
+ (!is_parent_of (info->window, window) ||
+ !info->owner_events))
+ {
+ /* Report key event against grab window */
+ window = info->window;
+ }
}
return window;
diff --git a/gdk/x11/gdkdevicemanager-xi2.c b/gdk/x11/gdkdevicemanager-xi2.c
index 4cb0bac..a8f8829 100644
--- a/gdk/x11/gdkdevicemanager-xi2.c
+++ b/gdk/x11/gdkdevicemanager-xi2.c
@@ -710,20 +710,25 @@ get_event_window (GdkEventTranslator *translator,
window = gdk_window_lookup_for_display (display, xev->event);
/* Apply keyboard grabs to non-native windows */
- if (/* Is key event */
- (ev->evtype == XI_KeyPress || ev->evtype == XI_KeyRelease) &&
- /* And we have a grab */
- display->keyboard_grab.window != NULL &&
- (
- /* The window is not a descendant of the grabbed window */
- !is_parent_of ((GdkWindow *)display->keyboard_grab.window, window) ||
- /* Or owner event is false */
- !display->keyboard_grab.owner_events
- )
- )
+ if (ev->evtype == XI_KeyPress || ev->evtype == XI_KeyRelease)
{
- /* Report key event against grab window */
- window = display->keyboard_grab.window;
+ GdkDeviceGrabInfo *info;
+ GdkDevice *device;
+ gulong serial;
+
+ device = g_hash_table_lookup (GDK_DEVICE_MANAGER_XI2 (translator)->id_table,
+ GUINT_TO_POINTER (((XIDeviceEvent *) ev)->deviceid));
+
+ serial = _gdk_windowing_window_get_next_serial (display);
+ info = _gdk_display_has_device_grab (display, device, serial);
+
+ if (info &&
+ (!is_parent_of (info->window, window) ||
+ !info->owner_events))
+ {
+ /* Report key event against grab window */
+ window = info->window;
+ }
}
}
break;
diff --git a/gdk/x11/gdkdisplay-x11.c b/gdk/x11/gdkdisplay-x11.c
index 2af4ac5..aa0d0f8 100644
--- a/gdk/x11/gdkdisplay-x11.c
+++ b/gdk/x11/gdkdisplay-x11.c
@@ -1644,36 +1644,6 @@ gdk_display_device_ungrab (GdkDisplay *display,
}
/**
- * gdk_display_keyboard_ungrab:
- * @display: a #GdkDisplay.
- * @time_: a timestap (e.g #GDK_CURRENT_TIME).
- *
- * Release any keyboard grab
- *
- * Since: 2.2
- */
-void
-gdk_display_keyboard_ungrab (GdkDisplay *display,
- guint32 time)
-{
- Display *xdisplay;
- GdkDisplayX11 *display_x11;
-
- g_return_if_fail (GDK_IS_DISPLAY (display));
-
- display_x11 = GDK_DISPLAY_X11 (display);
- xdisplay = GDK_DISPLAY_XDISPLAY (display);
-
- XUngrabKeyboard (xdisplay, time);
- XFlush (xdisplay);
-
- if (time == GDK_CURRENT_TIME ||
- display->keyboard_grab.time == GDK_CURRENT_TIME ||
- !XSERVER_TIME_IS_LATER (display->keyboard_grab.time, time))
- _gdk_display_unset_has_keyboard_grab (display, FALSE);
-}
-
-/**
* gdk_display_beep:
* @display: a #GdkDisplay
*
diff --git a/gdk/x11/gdkevents-x11.c b/gdk/x11/gdkevents-x11.c
index 15afac1..4b9602b 100644
--- a/gdk/x11/gdkevents-x11.c
+++ b/gdk/x11/gdkevents-x11.c
@@ -961,6 +961,7 @@ gdk_event_translate (GdkDisplay *display,
if (window != NULL)
{
+#if 0
/* Apply keyboard grabs to non-native windows */
if (/* Is key event */
(xevent->type == KeyPress || xevent->type == KeyRelease) &&
@@ -978,6 +979,7 @@ gdk_event_translate (GdkDisplay *display,
window = display->keyboard_grab.window;;
window_private = (GdkWindowObject *) window;
}
+#endif
window_impl = GDK_WINDOW_IMPL_X11 (window_private->impl);
diff --git a/gdk/x11/gdkmain-x11.c b/gdk/x11/gdkmain-x11.c
index dc37100..6b1aa16 100644
--- a/gdk/x11/gdkmain-x11.c
+++ b/gdk/x11/gdkmain-x11.c
@@ -187,80 +187,6 @@ _gdk_windowing_device_grab (GdkDevice *device,
return status;
}
-/*
- *--------------------------------------------------------------
- * gdk_keyboard_grab
- *
- * Grabs the keyboard to a specific window
- *
- * Arguments:
- * "window" is the window which will receive the grab
- * "owner_events" specifies whether events will be reported as is,
- * or relative to "window"
- * "time" specifies the time
- *
- * Results:
- *
- * Side effects:
- * requires a corresponding call to gdk_keyboard_ungrab
- *
- *--------------------------------------------------------------
- */
-
-GdkGrabStatus
-gdk_keyboard_grab (GdkWindow * window,
- gboolean owner_events,
- guint32 time)
-{
- gint return_val;
- unsigned long serial;
- GdkDisplay *display;
- GdkDisplayX11 *display_x11;
- GdkWindow *native;
-
- g_return_val_if_fail (window != NULL, 0);
- g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
-
- 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 = GDK_WINDOW_DISPLAY (native);
- display_x11 = GDK_DISPLAY_X11 (display);
-
- serial = NextRequest (GDK_WINDOW_XDISPLAY (native));
-
- if (!GDK_WINDOW_DESTROYED (native))
- {
-#ifdef G_ENABLE_DEBUG
- if (_gdk_debug_flags & GDK_DEBUG_NOGRABS)
- return_val = GrabSuccess;
- else
-#endif
- return_val = XGrabKeyboard (GDK_WINDOW_XDISPLAY (native),
- GDK_WINDOW_XID (native),
- owner_events,
- GrabModeAsync, GrabModeAsync,
- time);
- if (G_UNLIKELY (!display_x11->trusted_client &&
- return_val == AlreadyGrabbed))
- /* we can't grab the keyboard, but we can do a GTK-local grab */
- return_val = GrabSuccess;
- }
- else
- return_val = AlreadyGrabbed;
-
- if (return_val == GrabSuccess)
- _gdk_display_set_has_keyboard_grab (display,
- window, native,
- owner_events,
- serial, time);
-
- return gdk_x11_convert_grab_status (return_val);
-}
-
/**
* _gdk_xgrab_check_unmap:
* @window: a #GdkWindow
@@ -280,18 +206,10 @@ _gdk_xgrab_check_unmap (GdkWindow *window,
/* FIXME: which device? */
_gdk_display_end_device_grab (display, display->core_pointer, serial, window, TRUE);
- if (display->keyboard_grab.window &&
- serial >= display->keyboard_grab.serial)
- {
- GdkWindowObject *private = GDK_WINDOW_OBJECT (window);
- GdkWindowObject *tmp = GDK_WINDOW_OBJECT (display->keyboard_grab.window);
-
- while (tmp && tmp != private)
- tmp = tmp->parent;
-
- if (tmp)
- _gdk_display_unset_has_keyboard_grab (display, TRUE);
- }
+ /* FIXME: which keyb? */
+ _gdk_display_end_device_grab (display,
+ gdk_device_get_relative (display->core_pointer),
+ serial, window, TRUE);
}
/**
@@ -321,10 +239,16 @@ _gdk_xgrab_check_destroy (GdkWindow *window)
grab->serial_end = grab->serial_start;
grab->implicit_ungrab = TRUE;
}
-
- if (window == display->keyboard_grab.native_window &&
- display->keyboard_grab.window != NULL)
- _gdk_display_unset_has_keyboard_grab (display, TRUE);
+
+ /* FIXME: which keyboard? */
+ grab = _gdk_display_get_last_device_grab (display,
+ gdk_device_get_relative (display->core_pointer));
+
+ if (grab && grab->native_window == window)
+ {
+ grab->serial_end = grab->serial_start;
+ grab->implicit_ungrab = TRUE;
+ }
}
void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]