[mutter] compositor: Move event spoofing code to MetaBackendX11



commit e9eb3c32a9ccc3af9f733739409dae51392dd57e
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Wed Apr 23 13:59:58 2014 -0400

    compositor: Move event spoofing code to MetaBackendX11
    
    This is now where we handle device events.

 src/backends/x11/meta-backend-x11.c |   69 +++++++++++++++++++++++++++++
 src/compositor/compositor.c         |   81 -----------------------------------
 2 files changed, 69 insertions(+), 81 deletions(-)
---
diff --git a/src/backends/x11/meta-backend-x11.c b/src/backends/x11/meta-backend-x11.c
index 5fbdcdf..be11870 100644
--- a/src/backends/x11/meta-backend-x11.c
+++ b/src/backends/x11/meta-backend-x11.c
@@ -46,6 +46,10 @@ struct _MetaBackendX11Private
 
   int xsync_event_base;
   int xsync_error_base;
+
+  int xinput_opcode;
+  int xinput_event_base;
+  int xinput_error_base;
 };
 typedef struct _MetaBackendX11Private MetaBackendX11Private;
 
@@ -62,6 +66,47 @@ handle_alarm_notify (MetaBackend *backend,
       meta_idle_monitor_xsync_handle_xevent (backend->device_monitors[i], (XSyncAlarmNotifyEvent*)xevent);
 }
 
+/* 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 running as an X window manager, we need to respond to
+ * events from lots of windows. Trick Clutter into translating
+ * these events by pretending we got an event on the stage window.
+ */
+static void
+maybe_spoof_event_as_stage_event (MetaBackendX11 *x11,
+                                  XEvent         *event)
+{
+  MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
+
+  if (event->type == GenericEvent &&
+      event->xcookie.extension == priv->xinput_opcode)
+    {
+      XGetEventData (priv->xdisplay, &event->xcookie);
+
+      XIEvent *input_event = (XIEvent *) event->xcookie.data;
+      XIDeviceEvent *device_event = ((XIDeviceEvent *) input_event);
+
+      switch (input_event->evtype)
+        {
+        case XI_Motion:
+        case XI_ButtonPress:
+        case XI_ButtonRelease:
+        case XI_KeyPress:
+        case XI_KeyRelease:
+          {
+            ClutterStage *stage = CLUTTER_STAGE (clutter_stage_get_default ());
+            device_event->event = clutter_x11_get_stage_window (stage);
+            break;
+          }
+        default:
+          break;
+        }
+    }
+}
+
 static void
 handle_host_xevent (MetaBackend *backend,
                     XEvent      *xevent)
@@ -83,6 +128,8 @@ handle_host_xevent (MetaBackend *backend,
       }
   }
 
+  maybe_spoof_event_as_stage_event (x11, xevent);
+
  out:
   if (!bypass_clutter)
     clutter_x11_handle_event (xevent);
@@ -181,6 +228,28 @@ meta_backend_x11_post_init (MetaBackend *backend)
       !XSyncInitialize (priv->xdisplay, &major, &minor))
     meta_fatal ("Could not initialize XSync");
 
+  {
+    int major = 2, minor = 3;
+    gboolean has_xi = FALSE;
+
+    if (XQueryExtension (priv->xdisplay,
+                         "XInputExtension",
+                         &priv->xinput_opcode,
+                         &priv->xinput_error_base,
+                         &priv->xinput_event_base))
+      {
+        if (XIQueryVersion (priv->xdisplay, &major, &minor) == Success)
+          {
+            int version = (major * 10) + minor;
+            if (version >= 22)
+              has_xi = TRUE;
+          }
+      }
+
+    if (!has_xi)
+      meta_fatal ("X server doesn't have the XInput extension, version 2.2 or newer\n");
+  }
+
   META_BACKEND_CLASS (meta_backend_x11_parent_class)->post_init (backend);
 }
 
diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c
index 1475deb..a1ee527 100644
--- a/src/compositor/compositor.c
+++ b/src/compositor/compositor.c
@@ -752,82 +752,6 @@ meta_compositor_window_surface_changed (MetaCompositor *compositor,
   meta_window_actor_update_surface (window_actor);
 }
 
-static gboolean
-event_is_passive_button_grab (MetaDisplay   *display,
-                              XIDeviceEvent *device_event)
-{
-  /* see display.c for which events are passive button
-     grabs (meta_display_grab_window_buttons() and
-     meta_display_handle_events())
-     we need to filter them here because normally they
-     would be sent to gtk+ (they are on gtk+ frame xwindow),
-     but we want to redirect them to clutter
-  */
-
-  if (device_event->evtype != XI_ButtonPress)
-    return FALSE;
-
-  if (display->window_grab_modifiers == 0)
-    return FALSE;
-
-  if ((device_event->mods.effective & display->window_grab_modifiers) !=
-      display->window_grab_modifiers)
-    return FALSE;
-
-  return device_event->detail < 4;
-}
-
-/* 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 running as an X window manager, we need to respond to
- * events from lots of windows. Trick Clutter into translating
- * these events by pretending we got an event on the stage window.
- */
-static void
-maybe_spoof_event_as_stage_event (MetaCompositor *compositor,
-                                  MetaWindow     *window,
-                                  XEvent         *event)
-{
-  MetaDisplay *display = compositor->display;
-
-  if (event->type == GenericEvent &&
-      event->xcookie.extension == display->xinput_opcode)
-    {
-      XIEvent *input_event = (XIEvent *) event->xcookie.data;
-      XIDeviceEvent *device_event = ((XIDeviceEvent *) input_event);
-
-      switch (input_event->evtype)
-        {
-        case XI_Motion:
-        case XI_ButtonPress:
-        case XI_ButtonRelease:
-          /* If this is a window frame, and we think GTK+ needs to handle the event,
-             let GTK+ handle it without mangling */
-          if (window && window->frame && device_event->event == window->frame->xwindow &&
-              (meta_grab_op_is_clicking (display->grab_op) ||
-               (display->grab_op == META_GRAB_OP_NONE && !event_is_passive_button_grab (display, 
device_event))))
-            break;
-
-        case XI_KeyPress:
-        case XI_KeyRelease:
-            /* If this is a GTK+ widget, like a window menu, let GTK+ handle
-             * it as-is without mangling. */
-            if (meta_ui_window_is_widget (display->screen->ui, device_event->event))
-              break;
-
-            device_event->event = clutter_x11_get_stage_window (CLUTTER_STAGE (compositor->stage));
-            device_event->event_x = device_event->root_x;
-            device_event->event_y = device_event->root_y;
-          break;
-        default:
-          break;
-        }
-    }
-}
-
 /**
  * meta_compositor_process_event: (skip)
  * @compositor: 
@@ -840,11 +764,6 @@ meta_compositor_process_event (MetaCompositor *compositor,
                                XEvent         *event,
                                MetaWindow     *window)
 {
-  MetaDisplay *display = compositor->display;
-
-  if (!meta_is_wayland_compositor ())
-    maybe_spoof_event_as_stage_event (compositor, window, event);
-
   if (meta_plugin_manager_xevent_filter (compositor->plugin_mgr, event))
     return TRUE;
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]