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
This commit is contained in:
parent
e757b06987
commit
9dd2a467ba
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -52,6 +52,8 @@ const Recorder = new Lang.Class({
|
||||
Meta.disable_unredirect_for_screen(global.screen);
|
||||
recorder.record();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user