[mutter] Add compositor hook to process keybindings selectively



commit 424fc5245a602a7c90618db1e014393d163b7574
Author: Florian MÃllner <fmuellner gnome org>
Date:   Fri Aug 10 02:27:18 2012 +0200

    Add compositor hook to process keybindings selectively
    
    Currently keybindings are blocked while the compositor holds a grab; if
    we want a keybinding to be available anyway, we use captured ClutterEvents
    to determine the KeyBindingAction the event would have triggered and
    run our own handlers (ugh).
    Instead, provide a hook to allow the compositor to filter out keybindings
    before processing them normally, regardless of whether the compositor
    holds a grab or not.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=688202

 src/compositor/compositor.c          |   13 +++++++++++++
 src/compositor/meta-plugin-manager.c |   13 +++++++++++++
 src/compositor/meta-plugin-manager.h |    3 +++
 src/core/display.c                   |    3 ---
 src/core/keybindings.c               |    4 +++-
 src/meta/compositor.h                |    4 ++++
 src/meta/meta-plugin.h               |    3 +++
 7 files changed, 39 insertions(+), 4 deletions(-)
---
diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c
index e0e9b71..c6a85aa 100644
--- a/src/compositor/compositor.c
+++ b/src/compositor/compositor.c
@@ -815,6 +815,19 @@ meta_compositor_process_event (MetaCompositor *compositor,
   return FALSE;
 }
 
+gboolean
+meta_compositor_filter_keybinding (MetaCompositor *compositor,
+                                   MetaScreen     *screen,
+                                   MetaKeyBinding *binding)
+{
+  MetaCompScreen *info = meta_screen_get_compositor_data (screen);
+
+  if (info->plugin_mgr)
+    return meta_plugin_manager_filter_keybinding (info->plugin_mgr, binding);
+
+  return FALSE;
+}
+
 void
 meta_compositor_show_window (MetaCompositor *compositor,
 			     MetaWindow	    *window,
diff --git a/src/compositor/meta-plugin-manager.c b/src/compositor/meta-plugin-manager.c
index ff391c2..87b50b3 100644
--- a/src/compositor/meta-plugin-manager.c
+++ b/src/compositor/meta-plugin-manager.c
@@ -281,6 +281,19 @@ meta_plugin_manager_switch_workspace (MetaPluginManager   *plugin_mgr,
   return retval;
 }
 
+gboolean
+meta_plugin_manager_filter_keybinding (MetaPluginManager *plugin_mgr,
+                                       MetaKeyBinding    *binding)
+{
+  MetaPlugin *plugin = plugin_mgr->plugin;
+  MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
+
+  if (klass->keybinding_filter)
+    return klass->keybinding_filter (plugin, binding);
+
+  return FALSE;
+}
+
 /*
  * The public method that the compositor hooks into for desktop switching.
  *
diff --git a/src/compositor/meta-plugin-manager.h b/src/compositor/meta-plugin-manager.h
index 3177fb5..9df24c1 100644
--- a/src/compositor/meta-plugin-manager.h
+++ b/src/compositor/meta-plugin-manager.h
@@ -67,6 +67,9 @@ gboolean meta_plugin_manager_switch_workspace (MetaPluginManager   *mgr,
                                                gint                 to,
                                                MetaMotionDirection  direction);
 
+gboolean meta_plugin_manager_filter_keybinding (MetaPluginManager  *mgr,
+                                                MetaKeyBinding     *binding);
+
 gboolean meta_plugin_manager_xevent_filter (MetaPluginManager *mgr,
                                             XEvent            *xev);
 
diff --git a/src/core/display.c b/src/core/display.c
index 42cf7b4..a515a18 100644
--- a/src/core/display.c
+++ b/src/core/display.c
@@ -1959,9 +1959,6 @@ event_callback (XEvent   *event,
     {
     case KeyPress:
     case KeyRelease:
-      if (display->grab_op == META_GRAB_OP_COMPOSITOR)
-        break;
-
       /* For key events, it's important to enforce single-handling, or
        * we can get into a confused state. So if a keybinding is
        * handled (because it's one of our hot-keys, or because we are
diff --git a/src/core/keybindings.c b/src/core/keybindings.c
index 4892942..97a04af 100644
--- a/src/core/keybindings.c
+++ b/src/core/keybindings.c
@@ -29,6 +29,7 @@
 #include <config.h>
 #include "keybindings-private.h"
 #include "workspace-private.h"
+#include <meta/compositor.h>
 #include <meta/errors.h>
 #include "edge-resistance.h"
 #include "ui.h"
@@ -1412,7 +1413,8 @@ process_event (MetaKeyBinding       *bindings,
           event->type != KeyPress ||
           bindings[i].keycode != event->xkey.keycode ||
           ((event->xkey.state & 0xff & ~(display->ignored_modifier_mask)) !=
-           bindings[i].mask))
+           bindings[i].mask) ||
+          meta_compositor_filter_keybinding (display->compositor, screen, &bindings[i]))
         continue;
 
       /*
diff --git a/src/meta/compositor.h b/src/meta/compositor.h
index c65267b..8ccd46d 100644
--- a/src/meta/compositor.h
+++ b/src/meta/compositor.h
@@ -71,6 +71,10 @@ gboolean meta_compositor_process_event (MetaCompositor *compositor,
                                         XEvent         *event,
                                         MetaWindow     *window);
 
+gboolean meta_compositor_filter_keybinding (MetaCompositor *compositor,
+                                            MetaScreen     *screen,
+                                            MetaKeyBinding *binding);
+
 /* At a high-level, a window is not-visible or visible. When a
  * window is added (with add_window()) it is not visible.
  * show_window() indicates a transition from not-visible to
diff --git a/src/meta/meta-plugin.h b/src/meta/meta-plugin.h
index 0f49d8c..9a3d0a3 100644
--- a/src/meta/meta-plugin.h
+++ b/src/meta/meta-plugin.h
@@ -105,6 +105,9 @@ struct _MetaPluginClass
   gboolean (*xevent_filter) (MetaPlugin       *plugin,
                              XEvent           *event);
 
+  gboolean (*keybinding_filter) (MetaPlugin     *plugin,
+                                 MetaKeyBinding *binding);
+
   const MetaPluginInfo * (*plugin_info) (MetaPlugin *plugin);
 };
 



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