[gnome-shell] status/keyboard: Add support for IBus input sources



commit 14d3235f1a9e569fa1492690572072667f9dc1ed
Author: Rui Matos <tiagomatos gmail com>
Date:   Tue May 29 19:30:14 2012 +0200

    status/keyboard: Add support for IBus input sources
    
    We connect to the IBus daemon asyncronously and use it to query info
    about input sources of the type 'ibus'. In case the daemon is or
    becomes unreachable we just skip showing input sources of this type.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=641531

 js/ui/status/keyboard.js |  108 +++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 101 insertions(+), 7 deletions(-)
---
diff --git a/js/ui/status/keyboard.js b/js/ui/status/keyboard.js
index db02a36..e9edef4 100644
--- a/js/ui/status/keyboard.js
+++ b/js/ui/status/keyboard.js
@@ -6,9 +6,19 @@ const Gio = imports.gi.Gio;
 const GLib = imports.gi.GLib;
 const GnomeDesktop = imports.gi.GnomeDesktop;
 const Lang = imports.lang;
+const Mainloop = imports.mainloop;
 const Shell = imports.gi.Shell;
 const St = imports.gi.St;
 
+try {
+    var IBus = imports.gi.IBus;
+    if (!('new_async' in IBus.Bus))
+        throw "IBus version is too old";
+} catch (e) {
+    var IBus = null;
+    log(e);
+}
+
 const Main = imports.ui.main;
 const PopupMenu = imports.ui.popupMenu;
 const PanelMenu = imports.ui.panelMenu;
@@ -19,6 +29,70 @@ const KEY_CURRENT_INPUT_SOURCE = 'current';
 const KEY_INPUT_SOURCES = 'sources';
 
 const INPUT_SOURCE_TYPE_XKB = 'xkb';
+const INPUT_SOURCE_TYPE_IBUS = 'ibus';
+
+const IBusManager = new Lang.Class({
+    Name: 'IBusManager',
+
+    _init: function(readyCallback) {
+        if (!IBus)
+            return;
+
+        IBus.init();
+
+        this._readyCallback = readyCallback;
+
+        this._ibus = null;
+        this._engines = {};
+        this._ready = false;
+
+        this._nameWatcherId = Gio.DBus.session.watch_name(IBus.SERVICE_IBUS,
+                                                          Gio.BusNameWatcherFlags.NONE,
+                                                          Lang.bind(this, this._onNameAppeared),
+                                                          Lang.bind(this, this._clear));
+    },
+
+    _clear: function() {
+        if (this._ibus)
+            this._ibus.destroy();
+
+        this._ibus = null;
+        this._engines = {};
+        this._ready = false;
+    },
+
+    _onNameAppeared: function() {
+        this._ibus = IBus.Bus.new_async();
+        this._ibus.connect('connected', Lang.bind(this, this._onConnected));
+    },
+
+    _onConnected: function() {
+        this._ibus.list_engines_async(-1, null, Lang.bind(this, this._initEngines));
+        this._ibus.connect('disconnected', Lang.bind(this, this._clear));
+    },
+
+    _initEngines: function(ibus, result) {
+        let enginesList = this._ibus.list_engines_async_finish(result);
+        if (enginesList) {
+            for (let i = 0; i < enginesList.length; ++i) {
+                let name = enginesList[i].get_name();
+                this._engines[name] = enginesList[i];
+            }
+            this._ready = true;
+            if (this._readyCallback)
+                this._readyCallback();
+        } else {
+            this._clear();
+        }
+    },
+
+    getEngineDesc: function(id) {
+        if (!IBus || !this._ready)
+            return null;
+
+        return this._engines[id];
+    }
+});
 
 const LayoutMenuItem = new Lang.Class({
     Name: 'LayoutMenuItem',
@@ -58,6 +132,8 @@ const InputSourceIndicator = new Lang.Class({
         this._currentSourceIndex = this._settings.get_uint(KEY_CURRENT_INPUT_SOURCE);
         this._xkbInfo = new GnomeDesktop.XkbInfo();
 
+        this._ibusManager = new IBusManager(Lang.bind(this, this._inputSourcesChanged));
+
         this._inputSourcesChanged();
 
         // re-using "allowSettings" for the keyboard layout is a bit shady,
@@ -120,13 +196,20 @@ const InputSourceIndicator = new Lang.Class({
         let infosByShortName = {};
 
         for (let i = 0; i < nSources; i++) {
+            let info = { exists: false };
             let [type, id] = sources.get_child_value(i).deep_unpack();
-            if (type != INPUT_SOURCE_TYPE_XKB)
-                continue;
 
-            let info = {};
-            [info.exists, info.displayName, info.shortName, , ] =
-                this._xkbInfo.get_layout_info(id);
+            if (type == INPUT_SOURCE_TYPE_XKB) {
+                [info.exists, info.displayName, info.shortName, , ] =
+                    this._xkbInfo.get_layout_info(id);
+            } else if (type == INPUT_SOURCE_TYPE_IBUS) {
+                let engineDesc = this._ibusManager.getEngineDesc(id);
+                if (engineDesc) {
+                    info.exists = true;
+                    info.displayName = engineDesc.get_longname();
+                    info.shortName = engineDesc.get_symbol();
+                }
+            }
 
             if (!info.exists)
                 continue;
@@ -175,8 +258,19 @@ const InputSourceIndicator = new Lang.Class({
 
         let sources = this._settings.get_value(KEY_INPUT_SOURCES);
         let current = this._settings.get_uint(KEY_CURRENT_INPUT_SOURCE);
-        let id = sources.get_child_value(current).deep_unpack()[1];
-        let [, , , xkbLayout, xkbVariant] = this._xkbInfo.get_layout_info(id);
+        let [type, id] = sources.get_child_value(current).deep_unpack();
+        let xkbLayout = '';
+        let xkbVariant = '';
+
+        if (type == INPUT_SOURCE_TYPE_XKB) {
+            [, , , xkbLayout, xkbVariant] = this._xkbInfo.get_layout_info(id);
+        } else if (type == INPUT_SOURCE_TYPE_IBUS) {
+            let engineDesc = this._ibusManager.getEngineDesc(id);
+            if (engineDesc) {
+                xkbLayout = engineDesc.get_layout();
+                xkbVariant = '';
+            }
+        }
 
         if (!xkbLayout || xkbLayout.length == 0)
             return;



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