From 566d566f267f35bd3f259ff1fae9268b328bf924 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Wed, 7 Sep 2011 04:38:38 +0200 Subject: [PATCH] alt-tab: Do not hardcode ALT modifier While we allow for arbitrary modifiers in keybindings, both the alt-tab and ctrl-alt-tab popups close when ALT is not present in the modifier mask, resulting in ALT being de-facto hardcoded. Instead, pass the actual modifier mask when invoking the popups. https://bugzilla.gnome.org/show_bug.cgi?id=645200 --- js/ui/altTab.js | 20 +++++++++++++++++--- js/ui/ctrlAltTab.js | 12 +++++++----- js/ui/main.js | 3 ++- js/ui/windowManager.js | 10 +++++----- src/shell-marshal.list | 2 +- src/shell-wm.c | 8 +++++--- 6 files changed, 37 insertions(+), 18 deletions(-) diff --git a/js/ui/altTab.js b/js/ui/altTab.js index b6409e744..b8c002bf1 100644 --- a/js/ui/altTab.js +++ b/js/ui/altTab.js @@ -31,6 +31,18 @@ function mod(a, b) { return (a + b) % b; } +function primaryModifier(mask) { + if (mask == 0) + return 0; + + let primary = 1; + while (mask > 1) { + mask >>= 1; + primary <<= 1; + } + return primary; +} + function AltTabPopup() { this._init(); } @@ -48,6 +60,7 @@ AltTabPopup.prototype = { this.actor.connect('destroy', Lang.bind(this, this._onDestroy)); this._haveModal = false; + this._modifierMask = 0; this._currentApp = 0; this._currentWindow = -1; @@ -121,7 +134,7 @@ AltTabPopup.prototype = { } }, - show : function(backward, binding) { + show : function(backward, binding, mask) { let appSys = Shell.AppSystem.get_default(); let apps = appSys.get_running (); @@ -131,6 +144,7 @@ AltTabPopup.prototype = { if (!Main.pushModal(this.actor)) return false; this._haveModal = true; + this._modifierMask = primaryModifier(mask); this.actor.connect('key-press-event', Lang.bind(this, this._keyPressEvent)); this.actor.connect('key-release-event', Lang.bind(this, this._keyReleaseEvent)); @@ -179,7 +193,7 @@ AltTabPopup.prototype = { // details.) So we check now. (Have to do this after updating // selection.) let [x, y, mods] = global.get_pointer(); - if (!(mods & Gdk.ModifierType.MOD1_MASK)) { + if (!(mods & this._modifierMask)) { this._finish(); return false; } @@ -256,7 +270,7 @@ AltTabPopup.prototype = { _keyReleaseEvent : function(actor, event) { let [x, y, mods] = global.get_pointer(); - let state = mods & Clutter.ModifierType.MOD1_MASK; + let state = mods & this._modifierMask; if (state == 0) this._finish(); diff --git a/js/ui/ctrlAltTab.js b/js/ui/ctrlAltTab.js index 59d1a5e54..8662ff8cd 100644 --- a/js/ui/ctrlAltTab.js +++ b/js/ui/ctrlAltTab.js @@ -94,7 +94,7 @@ CtrlAltTabManager.prototype = { return a.x - b.x; }, - popup: function(backwards) { + popup: function(backwards, mask) { // Start with the set of focus groups that are currently mapped let items = this._items.filter(function (item) { return item.proxy.mapped; }); @@ -126,7 +126,7 @@ CtrlAltTabManager.prototype = { if (!this._popup) { this._popup = new CtrlAltTabPopup(); - this._popup.show(items, backwards); + this._popup.show(items, backwards, mask); this._popup.actor.connect('destroy', Lang.bind(this, function() { @@ -156,6 +156,7 @@ CtrlAltTabPopup.prototype = { this.actor.connect('destroy', Lang.bind(this, this._onDestroy)); this._haveModal = false; + this._modifierMask = 0; this._selection = 0; Main.uiGroup.add_actor(this.actor); @@ -192,10 +193,11 @@ CtrlAltTabPopup.prototype = { this._switcher.actor.allocate(childBox, flags); }, - show : function(items, startBackwards) { + show : function(items, startBackwards, mask) { if (!Main.pushModal(this.actor)) return false; this._haveModal = true; + this._modifierMask = AltTab.primaryModifier(mask); this._keyPressEventId = this.actor.connect('key-press-event', Lang.bind(this, this._keyPressEvent)); this._keyReleaseEventId = this.actor.connect('key-release-event', Lang.bind(this, this._keyReleaseEvent)); @@ -209,7 +211,7 @@ CtrlAltTabPopup.prototype = { this._select(this._selection); let [x, y, mods] = global.get_pointer(); - if (!(mods & Gdk.ModifierType.MOD1_MASK)) { + if (!(mods & this._modifierMask)) { this._finish(); return false; } @@ -255,7 +257,7 @@ CtrlAltTabPopup.prototype = { _keyReleaseEvent : function(actor, event) { let [x, y, mods] = global.get_pointer(); - let state = mods & Clutter.ModifierType.MOD1_MASK; + let state = mods & this._modifierMask; if (state == 0) this._finish(); diff --git a/js/ui/main.js b/js/ui/main.js index d926d0a30..b159c93c1 100644 --- a/js/ui/main.js +++ b/js/ui/main.js @@ -607,7 +607,8 @@ function _globalKeyPressHandler(actor, event) { } if (action == Meta.KeyBindingAction.SWITCH_PANELS) { - ctrlAltTabManager.popup(modifierState & Clutter.ModifierType.SHIFT_MASK); + ctrlAltTabManager.popup(modifierState & Clutter.ModifierType.SHIFT_MASK, + modifierState); return true; } diff --git a/js/ui/windowManager.js b/js/ui/windowManager.js index 95cf4ac77..728b13327 100644 --- a/js/ui/windowManager.js +++ b/js/ui/windowManager.js @@ -526,22 +526,22 @@ WindowManager.prototype = { shellwm.completed_switch_workspace(); }, - _startAppSwitcher : function(shellwm, binding, window, backwards) { + _startAppSwitcher : function(shellwm, binding, mask, window, backwards) { /* prevent a corner case where both popups show up at once */ if (this._workspaceSwitcherPopup != null) this._workspaceSwitcherPopup.actor.hide(); let tabPopup = new AltTab.AltTabPopup(); - if (!tabPopup.show(backwards, binding)) + if (!tabPopup.show(backwards, binding, mask)) tabPopup.destroy(); }, - _startA11ySwitcher : function(shellwm, binding, window, backwards) { - Main.ctrlAltTabManager.popup(backwards); + _startA11ySwitcher : function(shellwm, binding, mask, window, backwards) { + Main.ctrlAltTabManager.popup(backwards, mask); }, - _showWorkspaceSwitcher : function(shellwm, binding, window, backwards) { + _showWorkspaceSwitcher : function(shellwm, binding, mask, window, backwards) { if (global.screen.n_workspaces == 1) return; diff --git a/src/shell-marshal.list b/src/shell-marshal.list index 64b8235d4..a90160008 100644 --- a/src/shell-marshal.list +++ b/src/shell-marshal.list @@ -3,7 +3,7 @@ VOID:OBJECT,INT,INT,INT,INT VOID:BOXED VOID:BOXED,OBJECT VOID:OBJECT,OBJECT -VOID:STRING,OBJECT,BOOLEAN +VOID:STRING,UINT,OBJECT,BOOLEAN VOID:INT,INT VOID:STRING,STRING,STRING,STRING,BOXED VOID:STRING,OBJECT,STRING,BOXED diff --git a/src/shell-wm.c b/src/shell-wm.c index a47376355..dbc47aba3 100644 --- a/src/shell-wm.c +++ b/src/shell-wm.c @@ -131,6 +131,7 @@ shell_wm_class_init (ShellWMClass *klass) * ShellWM::keybinding: * @shellwm: the #ShellWM * @binding: the keybinding name + * @mask: the modifier mask used * @window: for window keybindings, the #MetaWindow * @backwards: for "reversible" keybindings, whether or not * the backwards (Shifted) variant was invoked @@ -147,9 +148,10 @@ shell_wm_class_init (ShellWMClass *klass) G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, 0, NULL, NULL, - _shell_marshal_VOID__STRING_OBJECT_BOOLEAN, - G_TYPE_NONE, 3, + _shell_marshal_VOID__STRING_UINT_OBJECT_BOOLEAN, + G_TYPE_NONE, 4, G_TYPE_STRING, + G_TYPE_UINT, META_TYPE_WINDOW, G_TYPE_BOOLEAN); } @@ -336,7 +338,7 @@ shell_wm_key_handler (MetaDisplay *display, g_signal_emit (wm, shell_wm_signals[KEYBINDING], g_quark_from_string (binding->name), - binding->name, window, backwards); + binding->name, binding->mask, window, backwards); } /**