status/keyboard: Add an Alt+Tab like input source switcher
https://bugzilla.gnome.org/show_bug.cgi?id=682315
This commit is contained in:
parent
6eef830ba4
commit
f61548234a
@ -2431,3 +2431,8 @@ StScrollBar StButton#vhandle:active {
|
|||||||
padding-bottom: 0px;
|
padding-bottom: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.input-source-switcher-symbol {
|
||||||
|
font-size: 42pt;
|
||||||
|
width: 96px;
|
||||||
|
height: 96px;
|
||||||
|
}
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
|
const Clutter = imports.gi.Clutter;
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const GLib = imports.gi.GLib;
|
const GLib = imports.gi.GLib;
|
||||||
const GnomeDesktop = imports.gi.GnomeDesktop;
|
const GnomeDesktop = imports.gi.GnomeDesktop;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
|
const Meta = imports.gi.Meta;
|
||||||
const Shell = imports.gi.Shell;
|
const Shell = imports.gi.Shell;
|
||||||
const Signals = imports.signals;
|
const Signals = imports.signals;
|
||||||
const St = imports.gi.St;
|
const St = imports.gi.St;
|
||||||
@ -21,6 +23,7 @@ try {
|
|||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
const PopupMenu = imports.ui.popupMenu;
|
const PopupMenu = imports.ui.popupMenu;
|
||||||
const PanelMenu = imports.ui.panelMenu;
|
const PanelMenu = imports.ui.panelMenu;
|
||||||
|
const SwitcherPopup = imports.ui.switcherPopup;
|
||||||
const Util = imports.misc.util;
|
const Util = imports.misc.util;
|
||||||
|
|
||||||
const DESKTOP_INPUT_SOURCES_SCHEMA = 'org.gnome.desktop.input-sources';
|
const DESKTOP_INPUT_SOURCES_SCHEMA = 'org.gnome.desktop.input-sources';
|
||||||
@ -227,6 +230,77 @@ const InputSource = new Lang.Class({
|
|||||||
});
|
});
|
||||||
Signals.addSignalMethods(InputSource.prototype);
|
Signals.addSignalMethods(InputSource.prototype);
|
||||||
|
|
||||||
|
const InputSourcePopup = new Lang.Class({
|
||||||
|
Name: 'InputSourcePopup',
|
||||||
|
Extends: SwitcherPopup.SwitcherPopup,
|
||||||
|
|
||||||
|
_init: function(items, action, actionBackward) {
|
||||||
|
this.parent(items);
|
||||||
|
|
||||||
|
this._action = action;
|
||||||
|
this._actionBackward = actionBackward;
|
||||||
|
},
|
||||||
|
|
||||||
|
_createSwitcher: function() {
|
||||||
|
this._switcherList = new InputSourceSwitcher(this._items);
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
_initialSelection: function(backward, binding) {
|
||||||
|
if (binding == 'switch-input-source') {
|
||||||
|
if (backward)
|
||||||
|
this._selectedIndex = this._items.length - 1;
|
||||||
|
} else if (binding == 'switch-input-source-backward') {
|
||||||
|
if (!backward)
|
||||||
|
this._selectedIndex = this._items.length - 1;
|
||||||
|
}
|
||||||
|
this._select(this._selectedIndex);
|
||||||
|
},
|
||||||
|
|
||||||
|
_keyPressHandler: function(keysym, backwards, action) {
|
||||||
|
if (action == this._action)
|
||||||
|
this._select(backwards ? this._previous() : this._next());
|
||||||
|
else if (action == this._actionBackward)
|
||||||
|
this._select(backwards ? this._next() : this._previous());
|
||||||
|
else if (keysym == Clutter.Left)
|
||||||
|
this._select(this._previous());
|
||||||
|
else if (keysym == Clutter.Right)
|
||||||
|
this._select(this._next());
|
||||||
|
},
|
||||||
|
|
||||||
|
_finish : function() {
|
||||||
|
this.parent();
|
||||||
|
|
||||||
|
this._items[this._selectedIndex].activate();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const InputSourceSwitcher = new Lang.Class({
|
||||||
|
Name: 'InputSourceSwitcher',
|
||||||
|
Extends: SwitcherPopup.SwitcherList,
|
||||||
|
|
||||||
|
_init: function(items) {
|
||||||
|
this.parent(true);
|
||||||
|
|
||||||
|
for (let i = 0; i < items.length; i++)
|
||||||
|
this._addIcon(items[i]);
|
||||||
|
},
|
||||||
|
|
||||||
|
_addIcon: function(item) {
|
||||||
|
let box = new St.BoxLayout({ vertical: true });
|
||||||
|
|
||||||
|
let bin = new St.Bin({ style_class: 'input-source-switcher-symbol' });
|
||||||
|
let symbol = new St.Label({ text: item.shortName });
|
||||||
|
bin.set_child(symbol);
|
||||||
|
box.add(bin, { x_fill: false, y_fill: false } );
|
||||||
|
|
||||||
|
let text = new St.Label({ text: item.displayName });
|
||||||
|
box.add(text, { x_fill: false });
|
||||||
|
|
||||||
|
this.addItem(box, text);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const InputSourceIndicator = new Lang.Class({
|
const InputSourceIndicator = new Lang.Class({
|
||||||
Name: 'InputSourceIndicator',
|
Name: 'InputSourceIndicator',
|
||||||
Extends: PanelMenu.Button,
|
Extends: PanelMenu.Button,
|
||||||
@ -254,6 +328,19 @@ const InputSourceIndicator = new Lang.Class({
|
|||||||
// All valid input sources currently in the gsettings
|
// All valid input sources currently in the gsettings
|
||||||
// KEY_INPUT_SOURCES list ordered by most recently used
|
// KEY_INPUT_SOURCES list ordered by most recently used
|
||||||
this._mruSources = [];
|
this._mruSources = [];
|
||||||
|
this._keybindingAction =
|
||||||
|
Main.wm.addKeybinding('switch-input-source',
|
||||||
|
new Gio.Settings({ schema: "org.gnome.shell.keybindings" }),
|
||||||
|
Meta.KeyBindingFlags.REVERSES,
|
||||||
|
Main.KeybindingMode.ALL,
|
||||||
|
Lang.bind(this, this._switchInputSource));
|
||||||
|
this._keybindingActionBackward =
|
||||||
|
Main.wm.addKeybinding('switch-input-source-backward',
|
||||||
|
new Gio.Settings({ schema: "org.gnome.shell.keybindings" }),
|
||||||
|
Meta.KeyBindingFlags.REVERSES |
|
||||||
|
Meta.KeyBindingFlags.REVERSED,
|
||||||
|
Main.KeybindingMode.ALL,
|
||||||
|
Lang.bind(this, this._switchInputSource));
|
||||||
this._settings = new Gio.Settings({ schema: DESKTOP_INPUT_SOURCES_SCHEMA });
|
this._settings = new Gio.Settings({ schema: DESKTOP_INPUT_SOURCES_SCHEMA });
|
||||||
this._settings.connect('changed::' + KEY_CURRENT_INPUT_SOURCE, Lang.bind(this, this._currentInputSourceChanged));
|
this._settings.connect('changed::' + KEY_CURRENT_INPUT_SOURCE, Lang.bind(this, this._currentInputSourceChanged));
|
||||||
this._settings.connect('changed::' + KEY_INPUT_SOURCES, Lang.bind(this, this._inputSourcesChanged));
|
this._settings.connect('changed::' + KEY_INPUT_SOURCES, Lang.bind(this, this._inputSourcesChanged));
|
||||||
@ -298,6 +385,14 @@ const InputSourceIndicator = new Lang.Class({
|
|||||||
this._inputSourcesChanged();
|
this._inputSourcesChanged();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_switchInputSource: function(display, screen, window, binding) {
|
||||||
|
let popup = new InputSourcePopup(this._mruSources, this._keybindingAction, this._keybindingActionBackward);
|
||||||
|
let modifiers = binding.get_modifiers();
|
||||||
|
let backwards = modifiers & Meta.VirtualModifier.SHIFT_MASK;
|
||||||
|
if (!popup.show(backwards, binding.get_name(), binding.get_mask()))
|
||||||
|
popup.destroy();
|
||||||
|
},
|
||||||
|
|
||||||
_currentInputSourceChanged: function() {
|
_currentInputSourceChanged: function() {
|
||||||
let nVisibleSources = Object.keys(this._inputSources).length;
|
let nVisibleSources = Object.keys(this._inputSources).length;
|
||||||
let newSourceIndex = this._settings.get_uint(KEY_CURRENT_INPUT_SOURCE);
|
let newSourceIndex = this._settings.get_uint(KEY_CURRENT_INPUT_SOURCE);
|
||||||
|
Loading…
Reference in New Issue
Block a user