From 9dd2a467bae3c0927173cc4236bb7d62e4b9d1de Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Sat, 23 Jun 2012 10:56:07 +0200 Subject: [PATCH] Main: filter keybindings when the shell is modal Mutter now handles some keybindings even when the compositor is grabbed, so we need to filter the invocation at the handler level. This allows to finally get rid of a old hack. https://bugzilla.gnome.org/show_bug.cgi?id=613543 --- js/misc/util.js | 28 +++++++++++ js/ui/components/recorder.js | 2 + js/ui/main.js | 96 +++++------------------------------- js/ui/windowManager.js | 21 +++++--- 4 files changed, 54 insertions(+), 93 deletions(-) diff --git a/js/misc/util.js b/js/misc/util.js index fb936c941..846cf372d 100644 --- a/js/misc/util.js +++ b/js/misc/util.js @@ -288,3 +288,31 @@ function insertSorted(array, val, cmp) { return pos; } + +/** + * wrapKeybinding: + * + * Wrap a keybinding handler so that + * it ignores an invocation if the shell is modal, but + * not when the overview is active, or when global + * keybindings are allowed by session mode. + * This function is only useful for keybindings installed + * with Meta.KeybindingFlags.HANDLE_WHEN_GRABBED + */ +function wrapKeybinding(handler, onlyInOverview) { + return function() { + let handle; + + if (onlyInOverview) { + handle = Main.sessionMode.allowKeybindingsWhenModal || + Main.modalCount == (Main.overview.visible ? 1 : 0); + } else { + handle = true; + } + + if (handle) + return handler.apply(this, arguments); + else + return false; + } +} diff --git a/js/ui/components/recorder.js b/js/ui/components/recorder.js index 40baf44c8..a05740268 100644 --- a/js/ui/components/recorder.js +++ b/js/ui/components/recorder.js @@ -52,6 +52,8 @@ const Recorder = new Lang.Class({ Meta.disable_unredirect_for_screen(global.screen); recorder.record(); } + + return true; } }); diff --git a/js/ui/main.js b/js/ui/main.js index 638a85777..0a8b63f86 100644 --- a/js/ui/main.js +++ b/js/ui/main.js @@ -69,7 +69,7 @@ let _overridesSettings = null; let background = null; function _sessionUpdated() { - Meta.keybindings_set_custom_handler('panel-run-dialog', sessionMode.hasRunDialog ? openRunDialog : null); + Meta.keybindings_set_custom_handler('panel-run-dialog', sessionMode.hasRunDialog ? Util.wrapKeybinding(openRunDialog, true) : null); if (sessionMode.isGreeter) screenShield.showDialog(); } @@ -155,8 +155,14 @@ function start() { global.screen.override_workspace_layout(Meta.ScreenCorner.TOPLEFT, false, -1, 1); - Meta.keybindings_set_custom_handler('panel-main-menu', Lang.bind(overview, overview.toggle)); - global.display.connect('overlay-key', Lang.bind(overview, overview.toggle)); + Meta.keybindings_set_custom_handler('panel-main-menu', Util.wrapKeybinding(Lang.bind(overview, function() { + this.toggle(); + return true; + }), true)); + global.display.connect('overlay-key', Util.wrapKeybinding(Lang.bind(overview, function() { + this.toggle(); + return true; + }), true)); sessionMode.connect('update', _sessionUpdated); _sessionUpdated(); @@ -167,8 +173,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 +469,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) @@ -685,6 +609,8 @@ function openRunDialog() { runDialog = new RunDialog.RunDialog(); } runDialog.open(); + + return true; } /** diff --git a/js/ui/windowManager.js b/js/ui/windowManager.js index 6a52037d7..bc15e85e3 100644 --- a/js/ui/windowManager.js +++ b/js/ui/windowManager.js @@ -12,6 +12,7 @@ const AltTab = imports.ui.altTab; const WorkspaceSwitcherPopup = imports.ui.workspaceSwitcherPopup; const Main = imports.ui.main; const Tweener = imports.ui.tweener; +const Util = imports.misc.util; const SHELL_KEYBINDINGS_SCHEMA = 'org.gnome.shell.keybindings'; const WINDOW_ANIMATION_TIME = 0.25; @@ -102,13 +103,13 @@ const WindowManager = new Lang.Class({ this._workspaceSwitcherPopup = null; Meta.keybindings_set_custom_handler('switch-to-workspace-left', - Lang.bind(this, this._showWorkspaceSwitcher)); + Util.wrapKeybinding(Lang.bind(this, this._showWorkspaceSwitcher), true)); Meta.keybindings_set_custom_handler('switch-to-workspace-right', - Lang.bind(this, this._showWorkspaceSwitcher)); + Util.wrapKeybinding(Lang.bind(this, this._showWorkspaceSwitcher), true)); Meta.keybindings_set_custom_handler('switch-to-workspace-up', - Lang.bind(this, this._showWorkspaceSwitcher)); + Util.wrapKeybinding(Lang.bind(this, this._showWorkspaceSwitcher), true)); Meta.keybindings_set_custom_handler('switch-to-workspace-down', - Lang.bind(this, this._showWorkspaceSwitcher)); + Util.wrapKeybinding(Lang.bind(this, this._showWorkspaceSwitcher), true)); Meta.keybindings_set_custom_handler('move-to-workspace-left', Lang.bind(this, this._showWorkspaceSwitcher)); Meta.keybindings_set_custom_handler('move-to-workspace-right', @@ -126,7 +127,7 @@ const WindowManager = new Lang.Class({ Meta.keybindings_set_custom_handler('switch-group-backward', Lang.bind(this, this._startAppSwitcher)); Meta.keybindings_set_custom_handler('switch-panels', - Lang.bind(this, this._startA11ySwitcher)); + Util.wrapKeybinding(Lang.bind(this, this._startA11ySwitcher), true)); global.display.add_keybinding('open-application-menu', new Gio.Settings({ schema: SHELL_KEYBINDINGS_SCHEMA }), Meta.KeyBindingFlags.NONE, @@ -552,30 +553,32 @@ const WindowManager = new Lang.Class({ let backwards = modifiers & Meta.VirtualModifier.SHIFT_MASK; if (!tabPopup.show(backwards, binding.get_name(), binding.get_mask())) tabPopup.destroy(); + return true; }, _startA11ySwitcher : function(display, screen, window, binding) { let modifiers = binding.get_modifiers(); let backwards = modifiers & Meta.VirtualModifier.SHIFT_MASK; Main.ctrlAltTabManager.popup(backwards, binding.get_mask()); + return true; }, _openAppMenu : function(display, screen, window, event, binding) { Main.panel.openAppMenu(); + return true; }, _showWorkspaceSwitcher : function(display, screen, window, binding) { if (screen.n_workspaces == 1) - return; + return false; let [action,,,direction] = binding.get_name().split('-'); let direction = Meta.MotionDirection[direction.toUpperCase()]; let newWs; - if (direction != Meta.MotionDirection.UP && direction != Meta.MotionDirection.DOWN) - return; + return false; if (action == 'switch') newWs = this.actionMoveWorkspace(direction); @@ -591,6 +594,8 @@ const WindowManager = new Lang.Class({ } this._workspaceSwitcherPopup.display(direction, newWs.index()); } + + return true; }, actionMoveWorkspace: function(direction) {