[gnome-shell] windowManager: Implement keybinding_filter hook



commit 034408971dbbdccc467325808dce730e3fc17498
Author: Florian MÃllner <fmuellner gnome org>
Date:   Mon Aug 20 10:38:13 2012 +0200

    windowManager: Implement keybinding_filter hook
    
    We are currently using a hack to allow a select set of keybindings
    in the overview. Implement the new MetaPlugin keybinding_filter
    hook, which provides a cleaner way to achieve the same.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=688202

 js/ui/main.js            |   82 ----------------------------------------------
 js/ui/windowManager.js   |   31 +++++++++++++++++
 src/gnome-shell-plugin.c |   15 +++++++-
 src/shell-wm-private.h   |    3 ++
 src/shell-wm.c           |   20 +++++++++++
 5 files changed, 67 insertions(+), 84 deletions(-)
---
diff --git a/js/ui/main.js b/js/ui/main.js
index 638a857..db7698b 100644
--- a/js/ui/main.js
+++ b/js/ui/main.js
@@ -167,8 +167,6 @@ function start() {
 
     _startDate = new Date();
 
-    global.stage.connect('captured-event', _globalKeyPressHandler);
-
     log('GNOME Shell started at ' + _startDate);
 
     let perfModuleName = GLib.getenv("SHELL_PERF_MODULE");
@@ -465,86 +463,6 @@ function getWindowActorsForWorkspace(workspaceIndex) {
     });
 }
 
-// This function encapsulates hacks to make certain global keybindings
-// work even when we are in one of our modes where global keybindings
-// are disabled with a global grab. (When there is a global grab, then
-// all key events will be delivered to the stage, so ::captured-event
-// on the stage can be used for global keybindings.)
-function _globalKeyPressHandler(actor, event) {
-    if (modalCount == 0)
-        return false;
-    if (event.type() != Clutter.EventType.KEY_PRESS && event.type() != Clutter.EventType.KEY_RELEASE)
-        return false;
-
-    if (!sessionMode.allowKeybindingsWhenModal) {
-        if (modalCount > (overview.visible ? 1 : 0))
-            return false;
-    }
-
-    let symbol = event.get_key_symbol();
-    let keyCode = event.get_key_code();
-    let ignoredModifiers = global.display.get_ignored_modifier_mask();
-    let modifierState = event.get_state() & ~ignoredModifiers;
-
-    // This relies on the fact that Clutter.ModifierType is the same as Gdk.ModifierType
-    let action = global.display.get_keybinding_action(keyCode, modifierState);
-
-    if (event.type() == Clutter.EventType.KEY_PRESS) {
-        if (action == Meta.KeyBindingAction.SWITCH_PANELS) {
-            ctrlAltTabManager.popup(modifierState & Clutter.ModifierType.SHIFT_MASK,
-                                    modifierState);
-            return true;
-        }
-
-        switch (action) {
-            // left/right would effectively act as synonyms for up/down if we enabled them;
-            // but that could be considered confusing; we also disable them in the main view.
-            //
-            // case Meta.KeyBindingAction.WORKSPACE_LEFT:
-            //  if (!sessionMode.hasWorkspaces)
-            //      return false;
-            //
-            //     wm.actionMoveWorkspaceLeft();
-            //     return true;
-            // case Meta.KeyBindingAction.WORKSPACE_RIGHT:
-            //  if (!sessionMode.hasWorkspaces)
-            //      return false;
-            //
-            //     wm.actionMoveWorkspaceRight();
-            //     return true;
-            case Meta.KeyBindingAction.WORKSPACE_UP:
-                if (!sessionMode.hasWorkspaces)
-                    return false;
-
-                wm.actionMoveWorkspace(Meta.MotionDirection.UP);
-                return true;
-            case Meta.KeyBindingAction.WORKSPACE_DOWN:
-                if (!sessionMode.hasWorkspaces)
-                    return false;
-
-                wm.actionMoveWorkspace(Meta.MotionDirection.DOWN);
-                return true;
-            case Meta.KeyBindingAction.PANEL_RUN_DIALOG:
-            case Meta.KeyBindingAction.COMMAND_2:
-                if (!sessionMode.hasRunDialog)
-                    return false;
-
-                openRunDialog();
-                return true;
-            case Meta.KeyBindingAction.PANEL_MAIN_MENU:
-                overview.hide();
-                return true;
-        }
-    } else if (event.type() == Clutter.EventType.KEY_RELEASE) {
-        if (action == Meta.KeyBindingAction.OVERLAY_KEY) {
-            overview.hide();
-            return true;
-        }
-    }
-
-    return false;
-}
-
 function _findModal(actor) {
     for (let i = 0; i < modalActorFocusStack.length; i++) {
         if (modalActorFocusStack[i].actor == actor)
diff --git a/js/ui/windowManager.js b/js/ui/windowManager.js
index 6a52037..eb7570f 100644
--- a/js/ui/windowManager.js
+++ b/js/ui/windowManager.js
@@ -99,6 +99,7 @@ const WindowManager = new Lang.Class({
         this._shellwm.connect('unmaximize', Lang.bind(this, this._unmaximizeWindow));
         this._shellwm.connect('map', Lang.bind(this, this._mapWindow));
         this._shellwm.connect('destroy', Lang.bind(this, this._destroyWindow));
+        this._shellwm.connect('filter-keybinding', Lang.bind(this, this._filterKeybinding));
 
         this._workspaceSwitcherPopup = null;
         Meta.keybindings_set_custom_handler('switch-to-workspace-left',
@@ -424,6 +425,36 @@ const WindowManager = new Lang.Class({
         }
     },
 
+    _filterKeybinding: function(shellwm, binding) {
+        if (!Main.sessionMode.allowKeybindingsWhenModal) {
+            if (Main.modalCount > (Main.overview.visible ? 1 : 0))
+                return true;
+        }
+        let action = Meta.prefs_get_keybinding_action(binding.get_name());
+        switch (action) {
+            // left/right would effectively act as synonyms for up/down if we enabled them;
+            // but that could be considered confusing; we also disable them in the main view.
+            //
+            // case Meta.KeyBindingAction.WORKSPACE_LEFT:
+            // case Meta.KeyBindingAction.WORKSPACE_RIGHT:
+            case Meta.KeyBindingAction.WORKSPACE_UP:
+            case Meta.KeyBindingAction.WORKSPACE_DOWN:
+                return !Main.sessionMode.hasWorkspaces;
+
+            case Meta.KeyBindingAction.PANEL_RUN_DIALOG:
+            case Meta.KeyBindingAction.COMMAND_2:
+            case Meta.KeyBindingAction.PANEL_MAIN_MENU:
+            case Meta.KeyBindingAction.OVERLAY_KEY:
+            case Meta.KeyBindingAction.SWITCH_PANELS:
+                return false;
+        }
+
+        if (Main.modalCount == 0 && binding.is_builtin())
+            return false;
+
+        return true;
+    },
+
     _switchWorkspace : function(shellwm, from, to, direction) {
         if (!this._shouldAnimate()) {
             shellwm.completed_switch_workspace();
diff --git a/src/gnome-shell-plugin.c b/src/gnome-shell-plugin.c
index 737c190..03ae79a 100644
--- a/src/gnome-shell-plugin.c
+++ b/src/gnome-shell-plugin.c
@@ -72,6 +72,9 @@ static void gnome_shell_plugin_kill_switch_workspace (MetaPlugin      *plugin);
 
 static gboolean              gnome_shell_plugin_xevent_filter (MetaPlugin *plugin,
                                                                XEvent     *event);
+
+static gboolean              gnome_shell_plugin_keybinding_filter (MetaPlugin *plugin,
+                                                                   MetaKeyBinding *binding);
 static const MetaPluginInfo *gnome_shell_plugin_plugin_info   (MetaPlugin *plugin);
 
 
@@ -126,8 +129,9 @@ gnome_shell_plugin_class_init (GnomeShellPluginClass *klass)
   plugin_class->kill_window_effects   = gnome_shell_plugin_kill_window_effects;
   plugin_class->kill_switch_workspace = gnome_shell_plugin_kill_switch_workspace;
 
-  plugin_class->xevent_filter    = gnome_shell_plugin_xevent_filter;
-  plugin_class->plugin_info      = gnome_shell_plugin_plugin_info;
+  plugin_class->xevent_filter     = gnome_shell_plugin_xevent_filter;
+  plugin_class->keybinding_filter = gnome_shell_plugin_keybinding_filter;
+  plugin_class->plugin_info       = gnome_shell_plugin_plugin_info;
 }
 
 static void
@@ -337,6 +341,13 @@ gnome_shell_plugin_xevent_filter (MetaPlugin *plugin,
   return clutter_x11_handle_event (xev) != CLUTTER_X11_FILTER_CONTINUE;
 }
 
+static gboolean
+gnome_shell_plugin_keybinding_filter (MetaPlugin     *plugin,
+                                      MetaKeyBinding *binding)
+{
+  return _shell_wm_filter_keybinding (get_shell_wm (), binding);
+}
+
 static const
 MetaPluginInfo *gnome_shell_plugin_plugin_info (MetaPlugin *plugin)
 {
diff --git a/src/shell-wm-private.h b/src/shell-wm-private.h
index c0cd84d..6fc9348 100644
--- a/src/shell-wm-private.h
+++ b/src/shell-wm-private.h
@@ -35,6 +35,9 @@ void _shell_wm_kill_window_effects   (ShellWM             *wm,
                                       MetaWindowActor     *actor);
 void _shell_wm_kill_switch_workspace (ShellWM             *wm);
 
+gboolean _shell_wm_filter_keybinding (ShellWM             *wm,
+                                      MetaKeyBinding      *binding);
+
 G_END_DECLS
 
 #endif /* __SHELL_WM_PRIVATE_H__ */
diff --git a/src/shell-wm.c b/src/shell-wm.c
index 835c970..08aceb7 100644
--- a/src/shell-wm.c
+++ b/src/shell-wm.c
@@ -26,6 +26,7 @@ enum
   SWITCH_WORKSPACE,
   KILL_SWITCH_WORKSPACE,
   KILL_WINDOW_EFFECTS,
+  FILTER_KEYBINDING,
 
   LAST_SIGNAL
 };
@@ -115,6 +116,14 @@ shell_wm_class_init (ShellWMClass *klass)
           NULL, NULL, NULL,
 		  G_TYPE_NONE, 1,
 		  META_TYPE_WINDOW_ACTOR);
+  shell_wm_signals[FILTER_KEYBINDING] =
+    g_signal_new ("filter-keybinding",
+                  G_TYPE_FROM_CLASS (klass),
+                  G_SIGNAL_RUN_LAST,
+                  0,
+                  g_signal_accumulator_true_handled, NULL, NULL,
+                  G_TYPE_BOOLEAN, 1,
+                  META_TYPE_KEY_BINDING);
 }
 
 void
@@ -267,6 +276,17 @@ _shell_wm_destroy (ShellWM         *wm,
   g_signal_emit (wm, shell_wm_signals[DESTROY], 0, actor);
 }
 
+gboolean
+_shell_wm_filter_keybinding (ShellWM             *wm,
+                             MetaKeyBinding      *binding)
+{
+  gboolean rv;
+
+  g_signal_emit (wm, shell_wm_signals[FILTER_KEYBINDING], 0, binding, &rv);
+
+  return rv;
+}
+
 /**
  * shell_wm_new:
  * @plugin: the #MetaPlugin



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