diff --git a/js/gdm/loginDialog.js b/js/gdm/loginDialog.js index 911845281..3db832e29 100644 --- a/js/gdm/loginDialog.js +++ b/js/gdm/loginDialog.js @@ -660,6 +660,7 @@ const LoginDialog = new Lang.Class({ this.parent({ shellReactive: true, styleClass: 'login-dialog', parentActor: parentActor, + keybindingMode: Main.KeybindingMode.LOGIN_SCREEN, shouldFadeIn: false }); this.connect('destroy', Lang.bind(this, this._onDestroy)); diff --git a/js/ui/lookingGlass.js b/js/ui/lookingGlass.js index 3c3d094af..f5e47f47d 100644 --- a/js/ui/lookingGlass.js +++ b/js/ui/lookingGlass.js @@ -1129,7 +1129,7 @@ const LookingGlass = new Lang.Class({ if (this._open) return; - if (!Main.pushModal(this._entry)) + if (!Main.pushModal(this._entry, { keybindingMode: Main.KeybindingMode.LOOKING_GLASS })) return; this._notebook.selectIndex(0); diff --git a/js/ui/main.js b/js/ui/main.js index cc0587c79..75ab45b2e 100644 --- a/js/ui/main.js +++ b/js/ui/main.js @@ -40,6 +40,18 @@ const Util = imports.misc.util; const OVERRIDES_SCHEMA = 'org.gnome.shell.overrides'; const DEFAULT_BACKGROUND_COLOR = Clutter.Color.from_pixel(0x2e3436ff); +const KeybindingMode = { + NONE: 0, // block all keybindings + NORMAL: 1 << 0, // window mode + OVERVIEW: 1 << 1, + LOCK_SCREEN: 1 << 2, + UNLOCK_SCREEN: 1 << 3, + LOGIN_SCREEN: 1 << 4, + MESSAGE_TRAY: 1 << 5, + SYSTEM_MODAL: 1 << 6, + LOOKING_GLASS: 1 << 7 +}; + let componentManager = null; let panel = null; let overview = null; @@ -56,6 +68,7 @@ let shellDBusService = null; let shellMountOpDBusService = null; let screenSaverDBus = null; let modalCount = 0; +let keybindingMode = KeybindingMode.NORMAL; let modalActorFocusStack = []; let uiGroup = null; let magnifier = null; @@ -498,11 +511,16 @@ function isInModalStack(actor) { * - options: Meta.ModalOptions flags to indicate that the pointer is * already grabbed * + * - keybindingMode: used to set the current Main.KeybindingMode to filter + * global keybindings; the default of NONE will filter + * out all keybindings + * * Returns: true iff we successfully acquired a grab or already had one */ function pushModal(actor, params) { params = Params.parse(params, { timestamp: global.get_current_time(), - options: 0 }); + options: 0, + keybindingMode: KeybindingMode.NONE }); if (modalCount == 0) { if (!global.begin_modal(params.timestamp, params.options)) { @@ -532,8 +550,10 @@ function pushModal(actor, params) { modalActorFocusStack.push({ actor: actor, focus: curFocus, destroyId: actorDestroyId, - focusDestroyId: curFocusDestroyId }); + focusDestroyId: curFocusDestroyId, + keybindingMode: keybindingMode }); + keybindingMode = params.keybindingMode; global.stage.set_key_focus(actor); return true; } @@ -560,6 +580,7 @@ function popModal(actor, timestamp) { global.stage.set_key_focus(null); global.end_modal(timestamp); global.set_stage_input_mode(Shell.StageInputMode.NORMAL); + keybindingMode = KeybindingMode.NORMAL; throw new Error('incorrect pop'); } @@ -572,6 +593,7 @@ function popModal(actor, timestamp) { if (focusIndex == modalActorFocusStack.length - 1) { if (record.focus) record.focus.disconnect(record.focusDestroyId); + keybindingMode = record.keybindingMode; global.stage.set_key_focus(record.focus); } else { let t = modalActorFocusStack[modalActorFocusStack.length - 1]; @@ -581,6 +603,7 @@ function popModal(actor, timestamp) { for (let i = modalActorFocusStack.length - 1; i > focusIndex; i--) { modalActorFocusStack[i].focus = modalActorFocusStack[i - 1].focus; modalActorFocusStack[i].focusDestroyId = modalActorFocusStack[i - 1].focusDestroyId; + modalActorFocusStack[i].keybindingMode = modalActorFocusStack[i - 1].keybindingMode; } } modalActorFocusStack.splice(focusIndex, 1); @@ -591,6 +614,7 @@ function popModal(actor, timestamp) { global.end_modal(timestamp); global.set_stage_input_mode(Shell.StageInputMode.NORMAL); Meta.enable_unredirect_for_screen(global.screen); + keybindingMode = KeybindingMode.NORMAL; } function createLookingGlass() { diff --git a/js/ui/messageTray.js b/js/ui/messageTray.js index f1687d0f5..262ea1535 100644 --- a/js/ui/messageTray.js +++ b/js/ui/messageTray.js @@ -1453,7 +1453,8 @@ const MessageTray = new Lang.Class({ this.idleMonitor = new GnomeDesktop.IdleMonitor(); - this._grabHelper = new GrabHelper.GrabHelper(this.actor); + this._grabHelper = new GrabHelper.GrabHelper(this.actor, + { keybindingMode: Main.KeybindingMode.MESSAGE_TRAY }); this._grabHelper.addActor(this._summaryBoxPointer.actor); this._grabHelper.addActor(this.actor); if (Main.panel.statusArea.activities) diff --git a/js/ui/modalDialog.js b/js/ui/modalDialog.js index cb0a15f1b..04b007672 100644 --- a/js/ui/modalDialog.js +++ b/js/ui/modalDialog.js @@ -37,10 +37,12 @@ const ModalDialog = new Lang.Class({ params = Params.parse(params, { shellReactive: false, styleClass: null, parentActor: Main.uiGroup, + keybindingMode: Main.KeybindingMode.SYSTEM_MODAL, shouldFadeIn: true }); this.state = State.CLOSED; this._hasModal = false; + this._keybindingMode = params.keybindingMode; this._shellReactive = params.shellReactive; this._shouldFadeIn = params.shouldFadeIn; @@ -276,7 +278,8 @@ const ModalDialog = new Lang.Class({ pushModal: function (timestamp) { if (this._hasModal) return true; - if (!Main.pushModal(this._group, { timestamp: timestamp })) + if (!Main.pushModal(this._group, { timestamp: timestamp, + keybindingMode: this._keybindingMode })) return false; this._hasModal = true; diff --git a/js/ui/overview.js b/js/ui/overview.js index 658cb81a6..3f1663f33 100644 --- a/js/ui/overview.js +++ b/js/ui/overview.js @@ -591,7 +591,7 @@ const Overview = new Lang.Class({ if (this._shown) return; // Do this manually instead of using _syncInputMode, to handle failure - if (!Main.pushModal(this._group)) + if (!Main.pushModal(this._group, { keybindingMode: Main.KeybindingMode.OVERVIEW })) return; this._modal = true; this._animateVisible(); @@ -742,7 +742,8 @@ const Overview = new Lang.Class({ if (this._shown) { if (!this._modal) { - if (Main.pushModal(this._group)) + if (Main.pushModal(this._group, + { keybindingMode: Main.KeybindingMode.OVERVIEW })) this._modal = true; else this.hide(); diff --git a/js/ui/screenShield.js b/js/ui/screenShield.js index 8de5c6245..3338dcc0d 100644 --- a/js/ui/screenShield.js +++ b/js/ui/screenShield.js @@ -611,7 +611,7 @@ const ScreenShield = new Lang.Class({ } if (!this._isModal) { - Main.pushModal(this.actor); + Main.pushModal(this.actor, { keybindingMode: Main.KeybindingMode.LOCK_SCREEN }); this._isModal = true; } @@ -920,7 +920,7 @@ const ScreenShield = new Lang.Class({ lock: function(animate) { if (!this._isModal) { - Main.pushModal(this.actor); + Main.pushModal(this.actor, { keybindingMode: Main.KeybindingMode.LOCK_SCREEN }); this._isModal = true; } diff --git a/js/ui/unlockDialog.js b/js/ui/unlockDialog.js index 30699d9eb..2f46d648e 100644 --- a/js/ui/unlockDialog.js +++ b/js/ui/unlockDialog.js @@ -113,6 +113,7 @@ const UnlockDialog = new Lang.Class({ _init: function(parentActor) { this.parent({ shellReactive: true, styleClass: 'login-dialog', + keybindingMode: Main.KeybindingMode.UNLOCK_SCREEN, parentActor: parentActor });