[gtk+/xi2: 1000/1239] Implement grab ownership.
- From: Carlos Garnacho <carlosg src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gtk+/xi2: 1000/1239] Implement grab ownership.
- Date: Tue, 29 Sep 2009 10:54:43 +0000 (UTC)
commit 0c7953c09c3c528814643216235059c35e91be5f
Author: Carlos Garnacho <carlos gnome org>
Date: Fri Sep 4 00:48:02 2009 +0200
Implement grab ownership.
There are some things missing, such as sending crossing events when the
device events are blocked/unblocked by other device grab.
gdk/gdkdisplay.c | 95 +++++++++++++++++++++++++++++++++++++++++----------
gdk/gdkinternals.h | 23 ++++++++-----
gdk/gdktypes.h | 7 ++++
gdk/gdkwindow.c | 14 +++++++-
4 files changed, 110 insertions(+), 29 deletions(-)
---
diff --git a/gdk/gdkdisplay.c b/gdk/gdkdisplay.c
index 3aa5596..32da14a 100644
--- a/gdk/gdkdisplay.c
+++ b/gdk/gdkdisplay.c
@@ -1009,15 +1009,16 @@ _gdk_display_get_last_pointer_grab (GdkDisplay *display,
}
GdkPointerGrabInfo *
-_gdk_display_add_pointer_grab (GdkDisplay *display,
- GdkDevice *device,
- GdkWindow *window,
- GdkWindow *native_window,
- gboolean owner_events,
- GdkEventMask event_mask,
- unsigned long serial_start,
- guint32 time,
- gboolean implicit)
+_gdk_display_add_pointer_grab (GdkDisplay *display,
+ GdkDevice *device,
+ GdkWindow *window,
+ GdkWindow *native_window,
+ GdkGrabOwnership grab_ownership,
+ gboolean owner_events,
+ GdkEventMask event_mask,
+ unsigned long serial_start,
+ guint32 time,
+ gboolean implicit)
{
GdkPointerGrabInfo *info, *other_info;
GList *grabs, *l;
@@ -1032,6 +1033,7 @@ _gdk_display_add_pointer_grab (GdkDisplay *display,
info->event_mask = event_mask;
info->time = time;
info->implicit = implicit;
+ info->ownership = grab_ownership;
grabs = g_hash_table_lookup (display->device_grabs, device);
@@ -1367,28 +1369,35 @@ _gdk_display_pointer_grab_update (GdkDisplay *display,
}
static GList *
-find_pointer_grab (GdkDisplay *display,
- GdkDevice *device,
- gulong serial)
+grab_list_find (GList *grabs,
+ gulong serial)
{
GdkPointerGrabInfo *grab;
- GList *l;
-
- l = g_hash_table_lookup (display->device_grabs, device);
- while (l)
+ while (grabs)
{
- grab = l->data;
+ grab = grabs->data;
if (serial >= grab->serial_start && serial < grab->serial_end)
- return l;
+ return grabs;
- l = l->next;
+ grabs = grabs->next;
}
return NULL;
}
+static GList *
+find_pointer_grab (GdkDisplay *display,
+ GdkDevice *device,
+ gulong serial)
+{
+ GList *l;
+
+ l = g_hash_table_lookup (display->device_grabs, device);
+ return grab_list_find (l, serial);
+}
+
GdkPointerGrabInfo *
_gdk_display_has_pointer_grab (GdkDisplay *display,
GdkDevice *device,
@@ -1432,6 +1441,54 @@ _gdk_display_end_pointer_grab (GdkDisplay *display,
return FALSE;
}
+/* Returns TRUE if device events are not blocked by any grab */
+gboolean
+_gdk_display_check_grab_ownership (GdkDisplay *display,
+ GdkDevice *device,
+ gulong serial)
+{
+ GHashTableIter iter;
+ gpointer key, value;
+ GdkGrabOwnership higher_ownership, device_ownership;
+
+ g_hash_table_iter_init (&iter, display->device_grabs);
+ higher_ownership = device_ownership = GDK_OWNERSHIP_NONE;
+
+ while (g_hash_table_iter_next (&iter, &key, &value))
+ {
+ GdkPointerGrabInfo *grab;
+ GdkDevice *dev;
+ GList *grabs;
+
+ dev = key;
+ grabs = value;
+ grabs = grab_list_find (grabs, serial);
+
+ if (!grabs)
+ continue;
+
+ grab = grabs->data;
+
+ if (dev == device)
+ device_ownership = grab->ownership;
+ else
+ {
+ if (grab->ownership > higher_ownership)
+ higher_ownership = grab->ownership;
+ }
+ }
+
+ if (higher_ownership > device_ownership)
+ {
+ /* There's a higher priority ownership
+ * going on for other device(s)
+ */
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
void
_gdk_display_set_has_keyboard_grab (GdkDisplay *display,
GdkWindow *window,
diff --git a/gdk/gdkinternals.h b/gdk/gdkinternals.h
index 4bc4b9d..7065f74 100644
--- a/gdk/gdkinternals.h
+++ b/gdk/gdkinternals.h
@@ -182,6 +182,7 @@ typedef struct
guint event_mask;
gboolean implicit;
guint32 time;
+ GdkGrabOwnership ownership;
gboolean activated;
gboolean implicit_ungrab;
@@ -597,15 +598,16 @@ void _gdk_display_pointer_grab_update (GdkDisplay *display,
gulong current_serial);
GdkPointerGrabInfo *_gdk_display_get_last_pointer_grab (GdkDisplay *display,
GdkDevice *device);
-GdkPointerGrabInfo *_gdk_display_add_pointer_grab (GdkDisplay *display,
- GdkDevice *device,
- GdkWindow *window,
- GdkWindow *native_window,
- gboolean owner_events,
- GdkEventMask event_mask,
- unsigned long serial_start,
- guint32 time,
- gboolean implicit);
+GdkPointerGrabInfo *_gdk_display_add_pointer_grab (GdkDisplay *display,
+ GdkDevice *device,
+ GdkWindow *window,
+ GdkWindow *native_window,
+ GdkGrabOwnership grab_ownership,
+ gboolean owner_events,
+ GdkEventMask event_mask,
+ unsigned long serial_start,
+ guint32 time,
+ gboolean implicit);
GdkPointerGrabInfo * _gdk_display_has_pointer_grab (GdkDisplay *display,
GdkDevice *device,
gulong serial);
@@ -614,6 +616,9 @@ gboolean _gdk_display_end_pointer_grab (GdkDisplay *display,
gulong serial,
GdkWindow *if_child,
gboolean implicit);
+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,
diff --git a/gdk/gdktypes.h b/gdk/gdktypes.h
index ac8e443..54113ab 100644
--- a/gdk/gdktypes.h
+++ b/gdk/gdktypes.h
@@ -175,6 +175,13 @@ typedef enum
GDK_GRAB_FROZEN = 4
} GdkGrabStatus;
+typedef enum
+{
+ GDK_OWNERSHIP_NONE,
+ GDK_OWNERSHIP_WINDOW,
+ GDK_OWNERSHIP_APPLICATION
+} GdkGrabOwnership;
+
typedef void (*GdkInputFunction) (gpointer data,
gint source,
GdkInputCondition condition);
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
index 5656936..b0f46d1 100644
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@ -9324,6 +9324,7 @@ gdk_pointer_grab (GdkWindow * window,
device,
window,
native,
+ GDK_OWNERSHIP_NONE,
owner_events,
event_mask,
serial,
@@ -9748,6 +9749,7 @@ proxy_button_event (GdkEvent *source_event,
device,
pointer_window,
toplevel_window,
+ GDK_OWNERSHIP_NONE,
FALSE,
gdk_window_get_events (pointer_window),
serial,
@@ -9906,7 +9908,16 @@ _gdk_windowing_got_event (GdkDisplay *display,
device = gdk_event_get_device (event);
if (device)
- _gdk_display_pointer_grab_update (display, device, serial);
+ {
+ _gdk_display_pointer_grab_update (display, device, serial);
+
+ if (!_gdk_display_check_grab_ownership (display, device, serial))
+ {
+ /* Device events are blocked by another device grab */
+ unlink_event = TRUE;
+ goto out;
+ }
+ }
event_window = event->any.window;
if (!event_window)
@@ -9921,6 +9932,7 @@ _gdk_windowing_got_event (GdkDisplay *display,
device,
event_window,
event_window,
+ GDK_OWNERSHIP_NONE,
FALSE,
gdk_window_get_events (event_window),
serial,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]