[mutter/wip/focus: 3/5] display: Send input events to Clutter



commit 0778ec8952ce3fa2d658a4c173eccfcdf7ec6fb6
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Tue Feb 25 19:38:56 2014 -0500

    display: Send input events to Clutter
    
    This lets us have proper keybinding handling.

 src/compositor/compositor.c |   46 ---------------------------------
 src/core/display.c          |   59 ++++++++++++++++++++++++++++++++++++------
 2 files changed, 50 insertions(+), 55 deletions(-)
---
diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c
index 0fd6d67..e46ec28 100644
--- a/src/compositor/compositor.c
+++ b/src/compositor/compositor.c
@@ -952,50 +952,6 @@ meta_compositor_window_surface_changed (MetaCompositor *compositor,
   meta_window_actor_update_surface (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 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 (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;
-
-      switch (input_event->evtype)
-        {
-        case XI_Motion:
-        case XI_ButtonPress:
-        case XI_ButtonRelease:
-        case XI_KeyPress:
-        case XI_KeyRelease:
-          {
-            XIDeviceEvent *device_event = ((XIDeviceEvent *) input_event);
-
-            /* If this is a GTK+ widget, like a window menu, let GTK+ handle
-             * it as-is without mangling. */
-            if (meta_ui_window_is_widget (info->screen->ui, device_event->event))
-              break;
-
-            device_event->event = clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage));
-          }
-          break;
-        default:
-          break;
-        }
-    }
-}
-
 /**
  * meta_compositor_process_event: (skip)
  * @compositor: 
@@ -1044,8 +1000,6 @@ meta_compositor_process_event (MetaCompositor *compositor,
 
          info = meta_screen_get_compositor_data (screen);
 
-          maybe_spoof_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");
diff --git a/src/core/display.c b/src/core/display.c
index 869577b..a43a230 100644
--- a/src/core/display.c
+++ b/src/core/display.c
@@ -54,6 +54,8 @@
 #include "meta-idle-monitor-private.h"
 #include "meta-cursor-tracker-private.h"
 
+#include <clutter/x11/clutter-x11.h>
+
 #ifdef HAVE_RANDR
 #include <X11/extensions/Xrandr.h>
 #endif
@@ -2304,6 +2306,45 @@ meta_display_handle_event (MetaDisplay        *display,
   return bypass_clutter;
 }
 
+/* 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
+spoof_event_as_stage_event (MetaScreen *screen,
+                            XIEvent    *input_event)
+{
+  switch (input_event->evtype)
+    {
+    case XI_Motion:
+    case XI_ButtonPress:
+    case XI_ButtonRelease:
+    case XI_KeyPress:
+    case XI_KeyRelease:
+      {
+        XIDeviceEvent *device_event = ((XIDeviceEvent *) input_event);
+        ClutterActor *stage;
+
+        /* If this is a GTK+ widget, like a window menu, let GTK+ handle
+         * it as-is without mangling. */
+        if (meta_ui_window_is_widget (screen->ui, device_event->event))
+          break;
+
+        /* XXX -- find the stage window properly */
+        stage = clutter_stage_get_default ();
+        device_event->event = clutter_x11_get_stage_window (CLUTTER_STAGE (stage));
+      }
+      break;
+    default:
+      break;
+    }
+}
+
 static gboolean
 handle_input_xevent (MetaDisplay *display,
                      XIEvent     *input_event,
@@ -2311,6 +2352,7 @@ handle_input_xevent (MetaDisplay *display,
 {
   XIDeviceEvent *device_event = (XIDeviceEvent *) input_event;
   XIEnterEvent *enter_event = (XIEnterEvent *) input_event;
+  MetaScreen *screen = meta_display_screen_for_root (display, device_event->root);
   Window modified;
   MetaWindow *window;
   gboolean frame_was_receiver;
@@ -2573,15 +2615,10 @@ handle_input_xevent (MetaDisplay *display,
        * screen; this will make keybindings and workspace-launched items
        * actually appear on the right screen.
        */
-      {
-        MetaScreen *new_screen =
-          meta_display_screen_for_root (display, enter_event->root);
-
-        if (new_screen != NULL && display->active_screen != new_screen)
-          meta_workspace_focus_default_window (new_screen->active_workspace,
-                                               NULL,
-                                               enter_event->time);
-      }
+      if (screen != NULL && display->active_screen != screen)
+        meta_workspace_focus_default_window (screen->active_workspace,
+                                             NULL,
+                                             enter_event->time);
 
       /* Check if we've entered a window; do this even if window->has_focus to
        * avoid races.
@@ -2653,6 +2690,10 @@ handle_input_xevent (MetaDisplay *display,
       return TRUE;
     }
 
+  /* Send the event to the Clutter */
+  if (!meta_is_wayland_compositor ())
+    spoof_event_as_stage_event (screen, input_event);
+
   return FALSE;
 }
 


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