[gtk+/client-side-windows] Base pointer grab on get-offscreen-parent
- From: Alexander Larsson <alexl src gnome org>
- To: svn-commits-list gnome org
- Subject: [gtk+/client-side-windows] Base pointer grab on get-offscreen-parent
- Date: Mon, 8 Jun 2009 14:14:01 -0400 (EDT)
commit 904f0ccb7c9f5bb368ece32693b694318ac5c3fa
Author: Alexander Larsson <alexl redhat com>
Date: Fri Jun 5 14:50:58 2009 +0200
Base pointer grab on get-offscreen-parent
---
gdk/gdk.symbols | 2 +-
gdk/gdkinternals.h | 7 +++
gdk/gdkwindow.c | 106 +++++++++++++++++++++++++++++++++++++++++++++++++
gdk/x11/gdkmain-x11.c | 98 ++++++++-------------------------------------
4 files changed, 131 insertions(+), 82 deletions(-)
diff --git a/gdk/gdk.symbols b/gdk/gdk.symbols
index 44cee62..d7ec27c 100644
--- a/gdk/gdk.symbols
+++ b/gdk/gdk.symbols
@@ -69,7 +69,6 @@ gdk_get_use_xshm
gdk_set_use_xshm
#endif
gdk_keyboard_grab
-gdk_pointer_grab
#endif
#endif
@@ -715,6 +714,7 @@ gdk_window_set_user_data
gdk_window_thaw_toplevel_updates_libgtk_only
gdk_window_thaw_updates
gdk_window_set_composited
+gdk_pointer_grab
#endif
#endif
diff --git a/gdk/gdkinternals.h b/gdk/gdkinternals.h
index 288f518..b6da9bb 100644
--- a/gdk/gdkinternals.h
+++ b/gdk/gdkinternals.h
@@ -453,6 +453,13 @@ GdkWindow* _gdk_windowing_window_at_pointer (GdkDisplay *display,
gint *win_x,
gint *win_y,
GdkModifierType *mask);
+GdkGrabStatus _gdk_windowing_pointer_grab (GdkWindow *window,
+ GdkWindow *native,
+ gboolean owner_events,
+ GdkEventMask event_mask,
+ GdkWindow *confine_to,
+ GdkCursor *cursor,
+ guint32 time);
void _gdk_windowing_got_event (GdkDisplay *display,
GList *event_link,
GdkEvent *event,
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
index 178a4ec..76a9f82 100644
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@ -8434,6 +8434,112 @@ _gdk_display_set_window_under_pointer (GdkDisplay *display,
_gdk_display_enable_motion_hints (display);
}
+static GdkWindow *
+gdk_window_get_offscreen_parent (GdkWindow *window)
+{
+ GdkWindowObject *private = (GdkWindowObject *)window;
+ GdkWindow *res;
+
+ res = NULL;
+ g_signal_emit_by_name (private->impl_window,
+ "get-offscreen-parent",
+ &res);
+
+ return res;
+}
+
+/*
+ *--------------------------------------------------------------
+ * gdk_pointer_grab
+ *
+ * Grabs the pointer 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"
+ * "event_mask" masks only interesting events
+ * "confine_to" limits the cursor movement to the specified window
+ * "cursor" changes the cursor for the duration of the grab
+ * "time" specifies the time
+ *
+ * Results:
+ *
+ * Side effects:
+ * requires a corresponding call to gdk_pointer_ungrab
+ *
+ *--------------------------------------------------------------
+ */
+GdkGrabStatus
+gdk_pointer_grab (GdkWindow * window,
+ gboolean owner_events,
+ GdkEventMask event_mask,
+ GdkWindow * confine_to,
+ GdkCursor * cursor,
+ guint32 time)
+{
+ GdkWindow *native;
+ GdkDisplay *display;
+ GdkGrabStatus res;
+ gulong serial;
+
+ g_return_val_if_fail (window != NULL, 0);
+ g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
+ g_return_val_if_fail (confine_to == NULL || GDK_IS_WINDOW (confine_to), 0);
+
+ /* We need a native window for confine to to work, ensure we have one */
+ if (confine_to)
+ {
+ if (!gdk_window_ensure_native (confine_to))
+ {
+ g_warning ("Can't confine to grabbed window, not native");
+ confine_to = NULL;
+ }
+ }
+
+ /* Non-viewable client side window => fail */
+ if (!_gdk_window_has_impl (window) &&
+ !gdk_window_is_viewable (window))
+ return GDK_GRAB_NOT_VIEWABLE;
+
+ native = gdk_window_get_toplevel (window);
+ while (gdk_window_is_offscreen ((GdkWindowObject *)native))
+ {
+ native = gdk_window_get_offscreen_parent (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);
+
+ res = _gdk_windowing_pointer_grab (window,
+ native,
+ owner_events,
+ event_mask,
+ confine_to,
+ cursor,
+ time);
+
+ if (res == GDK_GRAB_SUCCESS)
+ _gdk_display_add_pointer_grab (display,
+ window,
+ native,
+ owner_events,
+ event_mask,
+ serial,
+ time,
+ FALSE);
+
+ return res;
+}
+
void
gdk_window_set_has_offscreen_children (GdkWindow *window,
gboolean has_offscreen_children)
diff --git a/gdk/x11/gdkmain-x11.c b/gdk/x11/gdkmain-x11.c
index 471a8f2..f12c709 100644
--- a/gdk/x11/gdkmain-x11.c
+++ b/gdk/x11/gdkmain-x11.c
@@ -138,16 +138,6 @@ gdk_x11_convert_grab_status (gint status)
return 0;
}
-struct XPointerGrabInfo {
- GdkDisplay *display;
- GdkWindow *window;
- GdkWindow *native_window;
- gboolean owner_events;
- gulong serial;
- guint event_mask;
- guint32 time;
-};
-
static void
has_pointer_grab_callback (GdkDisplay *display,
gpointer data,
@@ -156,81 +146,38 @@ has_pointer_grab_callback (GdkDisplay *display,
_gdk_display_pointer_grab_update (display, serial);
}
-/*
- *--------------------------------------------------------------
- * gdk_pointer_grab
- *
- * Grabs the pointer 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"
- * "event_mask" masks only interesting events
- * "confine_to" limits the cursor movement to the specified window
- * "cursor" changes the cursor for the duration of the grab
- * "time" specifies the time
- *
- * Results:
- *
- * Side effects:
- * requires a corresponding call to gdk_pointer_ungrab
- *
- *--------------------------------------------------------------
- */
-
GdkGrabStatus
-gdk_pointer_grab (GdkWindow * window,
- gboolean owner_events,
- GdkEventMask event_mask,
- GdkWindow * confine_to,
- GdkCursor * cursor,
- guint32 time)
+_gdk_windowing_pointer_grab (GdkWindow *window,
+ GdkWindow *native,
+ gboolean owner_events,
+ GdkEventMask event_mask,
+ GdkWindow *confine_to,
+ GdkCursor *cursor,
+ guint32 time)
{
gint return_val;
GdkCursorPrivate *cursor_private;
- GdkWindow *native;
GdkDisplayX11 *display_x11;
guint xevent_mask;
Window xwindow;
Window xconfine_to;
Cursor xcursor;
- unsigned long serial;
int i;
-
- g_return_val_if_fail (window != NULL, 0);
- g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
- g_return_val_if_fail (confine_to == NULL || GDK_IS_WINDOW (confine_to), 0);
-
- native = gdk_window_get_toplevel (window);
-
- /* We need a native window for confine to to work, ensure we have one */
- if (confine_to)
- gdk_window_ensure_native (confine_to);
-
- /* TODO: What do we do for offscreens and their children? We need to proxy the grab somehow */
- if (!GDK_IS_WINDOW_IMPL_X11 (GDK_WINDOW_OBJECT (native)->impl))
- return GDK_GRAB_SUCCESS;
- if (!_gdk_window_has_impl (window) &&
- !gdk_window_is_viewable (window))
- return GDK_GRAB_NOT_VIEWABLE;
-
if (confine_to)
confine_to = _gdk_window_get_impl_window (confine_to);
display_x11 = GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (native));
cursor_private = (GdkCursorPrivate*) cursor;
-
+
xwindow = GDK_WINDOW_XID (native);
- serial = NextRequest (GDK_WINDOW_XDISPLAY (native));
-
+
if (!confine_to || GDK_WINDOW_DESTROYED (confine_to))
xconfine_to = None;
else
xconfine_to = GDK_WINDOW_XID (confine_to);
-
+
if (!cursor)
xcursor = None;
else
@@ -238,7 +185,7 @@ gdk_pointer_grab (GdkWindow * window,
_gdk_x11_cursor_update_theme (cursor);
xcursor = cursor_private->xcursor;
}
-
+
xevent_mask = 0;
for (i = 0; i < _gdk_nenvent_masks; i++)
{
@@ -250,7 +197,7 @@ gdk_pointer_grab (GdkWindow * window,
* hints. If we set a native one we just wouldn't get any events.
*/
xevent_mask &= ~PointerMotionHintMask;
-
+
return_val = _gdk_input_grab_pointer (window,
native,
owner_events,
@@ -258,7 +205,7 @@ gdk_pointer_grab (GdkWindow * window,
confine_to,
time);
- if (return_val == GrabSuccess ||
+ if (return_val == GrabSuccess ||
G_UNLIKELY (!display_x11->trusted_client && return_val == AlreadyGrabbed))
{
if (!GDK_WINDOW_DESTROYED (native))
@@ -280,22 +227,11 @@ gdk_pointer_grab (GdkWindow * window,
else
return_val = AlreadyGrabbed;
}
-
+
if (return_val == GrabSuccess)
- {
- _gdk_display_add_pointer_grab (GDK_DISPLAY_OBJECT (display_x11),
- window,
- native,
- owner_events,
- event_mask,
- serial,
- time,
- FALSE);
-
- _gdk_x11_roundtrip_async (GDK_DISPLAY_OBJECT (display_x11),
- has_pointer_grab_callback,
- NULL);
- }
+ _gdk_x11_roundtrip_async (GDK_DISPLAY_OBJECT (display_x11),
+ has_pointer_grab_callback,
+ NULL);
return gdk_x11_convert_grab_status (return_val);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]