[mutter] compositor: Spoof events on the guard window
- From: Jasper St. Pierre <jstpierre src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter] compositor: Spoof events on the guard window
- Date: Sun, 17 Feb 2013 20:44:28 +0000 (UTC)
commit 5e9621ed8077a6b5f53574a9350ee4f8846f9753
Author: Jasper St. Pierre <jstpierre mecheye net>
Date: Fri Dec 21 07:32:41 2012 -0500
compositor: Spoof events on the guard window
This allows events generated for the guard window to be picked up
by Clutter as if they were events for the mutter stage.
https://bugzilla.gnome.org/show_bug.cgi?id=681540
src/compositor/compositor.c | 48 +++++++++++++++++++++++++++++++++++++++++++
1 files changed, 48 insertions(+), 0 deletions(-)
---
diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c
index bb9cc38..1103751 100644
--- a/src/compositor/compositor.c
+++ b/src/compositor/compositor.c
@@ -812,6 +812,52 @@ meta_compositor_window_shape_changed (MetaCompositor *compositor,
meta_window_actor_update_shape (window_actor);
}
+/* Clutter makes the assumption that there is only one X window
+ * per stage, which is a valid assumption to make for a generic
+ * application toolkit. As such, it will ignore any events sent
+ * to the a stage that isn't its X window.
+ *
+ * When a user clicks on what she thinks is the wallpaper, she
+ * is actually clicking on the guard window, which is an entirely
+ * separate top-level override-redirect window in the hierarchy.
+ * We want to recieve events on this guard window so that users
+ * can right-click on the background actor. We do this by telling
+ * Clutter a little white lie, by transforming clicks on the guard
+ * window to become clicks on the stage window, allowing Clutter
+ * to process the event normally.
+ */
+static void
+maybe_spoof_guard_window_event_as_stage_event (MetaCompScreen *info,
+ XEvent *event)
+{
+ MetaDisplay *display = meta_screen_get_display (info->screen);
+
+ if (event->type == GenericEvent &&
+ event->xcookie.extension == display->xinput_opcode)
+ {
+ XIEvent *input_event = (XIEvent *) event->xcookie.data;
+
+ /* Only care about pointer events for now. */
+ switch (input_event->evtype)
+ {
+ case XI_Motion:
+ case XI_ButtonPress:
+ case XI_ButtonRelease:
+ {
+ XIDeviceEvent *device_event = ((XIDeviceEvent *) input_event);
+ if (device_event->event == info->screen->guard_window)
+ {
+ Window xwin = clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage));
+ device_event->event = xwin;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+}
+
/**
* meta_compositor_process_event: (skip)
*
@@ -860,6 +906,8 @@ meta_compositor_process_event (MetaCompositor *compositor,
info = meta_screen_get_compositor_data (screen);
+ maybe_spoof_guard_window_event_as_stage_event (info, event);
+
if (meta_plugin_manager_xevent_filter (info->plugin_mgr, event))
{
DEBUG_TRACE ("meta_compositor_process_event (filtered,window==NULL)\n");
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]