[gnome-shell] status/keyboard: Add an Alt+Tab like input source switcher



commit f61548234ad217da0f199efd1931e775373c6603
Author: Rui Matos <tiagomatos gmail com>
Date:   Mon Dec 10 20:35:29 2012 +0100

    status/keyboard: Add an Alt+Tab like input source switcher
    
    https://bugzilla.gnome.org/show_bug.cgi?id=682315

 data/theme/gnome-shell.css |    5 ++
 js/ui/status/keyboard.js   |   95 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 100 insertions(+), 0 deletions(-)
---
diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css
index 388b48e..4084a84 100644
--- a/data/theme/gnome-shell.css
+++ b/data/theme/gnome-shell.css
@@ -2431,3 +2431,8 @@ StScrollBar StButton#vhandle:active {
     padding-bottom: 0px;
 }
 
+.input-source-switcher-symbol {
+   font-size: 42pt;
+   width: 96px;
+   height: 96px;
+}
diff --git a/js/ui/status/keyboard.js b/js/ui/status/keyboard.js
index a3f92a2..7959e64 100644
--- a/js/ui/status/keyboard.js
+++ b/js/ui/status/keyboard.js
@@ -1,9 +1,11 @@
 // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
 
+const Clutter = imports.gi.Clutter;
 const Gio = imports.gi.Gio;
 const GLib = imports.gi.GLib;
 const GnomeDesktop = imports.gi.GnomeDesktop;
 const Lang = imports.lang;
+const Meta = imports.gi.Meta;
 const Shell = imports.gi.Shell;
 const Signals = imports.signals;
 const St = imports.gi.St;
@@ -21,6 +23,7 @@ try {
 const Main = imports.ui.main;
 const PopupMenu = imports.ui.popupMenu;
 const PanelMenu = imports.ui.panelMenu;
+const SwitcherPopup = imports.ui.switcherPopup;
 const Util = imports.misc.util;
 
 const DESKTOP_INPUT_SOURCES_SCHEMA = 'org.gnome.desktop.input-sources';
@@ -227,6 +230,77 @@ const InputSource = new Lang.Class({
 });
 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({
     Name: 'InputSourceIndicator',
     Extends: PanelMenu.Button,
@@ -254,6 +328,19 @@ const InputSourceIndicator = new Lang.Class({
         // All valid input sources currently in the gsettings
         // KEY_INPUT_SOURCES list ordered by most recently used
         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.connect('changed::' + KEY_CURRENT_INPUT_SOURCE, Lang.bind(this, this._currentInputSourceChanged));
         this._settings.connect('changed::' + KEY_INPUT_SOURCES, Lang.bind(this, this._inputSourcesChanged));
@@ -298,6 +385,14 @@ const InputSourceIndicator = new Lang.Class({
         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() {
         let nVisibleSources = Object.keys(this._inputSources).length;
         let newSourceIndex = this._settings.get_uint(KEY_CURRENT_INPUT_SOURCE);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]