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) {