diff --git a/js/js-resources.gresource.xml b/js/js-resources.gresource.xml index c99189cfe..977809f58 100644 --- a/js/js-resources.gresource.xml +++ b/js/js-resources.gresource.xml @@ -16,6 +16,7 @@ misc/fileUtils.js misc/gnomeSession.js misc/history.js + misc/ibusManager.js misc/jsParse.js misc/loginManager.js misc/modemManager.js diff --git a/js/misc/ibusManager.js b/js/misc/ibusManager.js new file mode 100644 index 000000000..c571fb7ca --- /dev/null +++ b/js/misc/ibusManager.js @@ -0,0 +1,151 @@ +// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- + +const Lang = imports.lang; +const Signals = imports.signals; + +try { + var IBus = imports.gi.IBus; + if (!('new_async' in IBus.Bus)) + throw "IBus version is too old"; + const IBusCandidatePopup = imports.ui.ibusCandidatePopup; +} catch (e) { + var IBus = null; + log(e); +} + +let _ibusManager = null; + +function getIBusManager() { + if (_ibusManager == null) + _ibusManager = new IBusManager(); + return _ibusManager; +} + +const IBusManager = new Lang.Class({ + Name: 'IBusManager', + + _init: function() { + if (!IBus) + return; + + IBus.init(); + + this._candidatePopup = new IBusCandidatePopup.CandidatePopup(); + + this._panelService = null; + this._engines = {}; + this._ready = false; + this._registerPropertiesId = 0; + this._currentEngineName = null; + + this._ibus = IBus.Bus.new_async(); + this._ibus.connect('connected', Lang.bind(this, this._onConnected)); + this._ibus.connect('disconnected', Lang.bind(this, this._clear)); + // Need to set this to get 'global-engine-changed' emitions + this._ibus.set_watch_ibus_signal(true); + this._ibus.connect('global-engine-changed', Lang.bind(this, this._engineChanged)); + }, + + _clear: function() { + if (this._panelService) + this._panelService.destroy(); + + this._panelService = null; + this._candidatePopup.setPanelService(null); + this._engines = {}; + this._ready = false; + this._registerPropertiesId = 0; + this._currentEngineName = null; + + this.emit('ready', false); + }, + + _onConnected: function() { + this._ibus.list_engines_async(-1, null, Lang.bind(this, this._initEngines)); + this._ibus.request_name_async(IBus.SERVICE_PANEL, + IBus.BusNameFlag.REPLACE_EXISTING, + -1, null, + Lang.bind(this, this._initPanelService)); + }, + + _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._updateReadiness(); + } else { + this._clear(); + } + }, + + _initPanelService: function(ibus, result) { + let success = this._ibus.request_name_async_finish(result); + if (success) { + this._panelService = new IBus.PanelService({ connection: this._ibus.get_connection(), + object_path: IBus.PATH_PANEL }); + this._candidatePopup.setPanelService(this._panelService); + this._panelService.connect('update-property', Lang.bind(this, this._updateProperty)); + // If an engine is already active we need to get its properties + this._ibus.get_global_engine_async(-1, null, Lang.bind(this, function(i, result) { + let engine; + try { + engine = this._ibus.get_global_engine_async_finish(result); + if (!engine) + return; + } catch(e) { + return; + } + this._engineChanged(this._ibus, engine.get_name()); + })); + this._updateReadiness(); + } else { + this._clear(); + } + }, + + _updateReadiness: function() { + this._ready = (Object.keys(this._engines).length > 0 && + this._panelService != null); + this.emit('ready', this._ready); + }, + + _engineChanged: function(bus, engineName) { + if (!this._ready) + return; + + this._currentEngineName = engineName; + + if (this._registerPropertiesId != 0) + return; + + this._registerPropertiesId = + this._panelService.connect('register-properties', Lang.bind(this, function(p, props) { + if (!props.get(0)) + return; + + this._panelService.disconnect(this._registerPropertiesId); + this._registerPropertiesId = 0; + + this.emit('properties-registered', this._currentEngineName, props); + })); + }, + + _updateProperty: function(panel, prop) { + this.emit('property-updated', this._currentEngineName, prop); + }, + + activateProperty: function(key, state) { + this._panelService.property_activate(key, state); + }, + + getEngineDesc: function(id) { + if (!IBus || !this._ready) + return null; + + return this._engines[id]; + } +}); +Signals.addSignalMethods(IBusManager.prototype); diff --git a/js/ui/status/keyboard.js b/js/ui/status/keyboard.js index 0bca2177a..76e1241ab 100644 --- a/js/ui/status/keyboard.js +++ b/js/ui/status/keyboard.js @@ -11,22 +11,15 @@ const Signals = imports.signals; const St = imports.gi.St; const Gettext = imports.gettext; -try { - var IBus = imports.gi.IBus; - if (!('new_async' in IBus.Bus)) - throw "IBus version is too old"; - const IBusCandidatePopup = imports.ui.ibusCandidatePopup; -} catch (e) { - var IBus = null; - log(e); -} - 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 IBus = imports.misc.ibusManager.IBus; +const IBusManager = imports.misc.ibusManager; + const DESKTOP_INPUT_SOURCES_SCHEMA = 'org.gnome.desktop.input-sources'; const KEY_CURRENT_INPUT_SOURCE = 'current'; const KEY_INPUT_SOURCES = 'sources'; @@ -62,139 +55,6 @@ function holdKeyboard() { global.freeze_keyboard(global.get_current_time()); } -const IBusManager = new Lang.Class({ - Name: 'IBusManager', - - _init: function(readyCallback) { - if (!IBus) - return; - - IBus.init(); - - this._readyCallback = readyCallback; - this._candidatePopup = new IBusCandidatePopup.CandidatePopup(); - - this._panelService = null; - this._engines = {}; - this._ready = false; - this._registerPropertiesId = 0; - this._currentEngineName = null; - - this._ibus = IBus.Bus.new_async(); - this._ibus.connect('connected', Lang.bind(this, this._onConnected)); - this._ibus.connect('disconnected', Lang.bind(this, this._clear)); - // Need to set this to get 'global-engine-changed' emitions - this._ibus.set_watch_ibus_signal(true); - this._ibus.connect('global-engine-changed', Lang.bind(this, this._engineChanged)); - }, - - _clear: function() { - if (this._panelService) - this._panelService.destroy(); - - this._panelService = null; - this._candidatePopup.setPanelService(null); - this._engines = {}; - this._ready = false; - this._registerPropertiesId = 0; - this._currentEngineName = null; - - if (this._readyCallback) - this._readyCallback(false); - }, - - _onConnected: function() { - this._ibus.list_engines_async(-1, null, Lang.bind(this, this._initEngines)); - this._ibus.request_name_async(IBus.SERVICE_PANEL, - IBus.BusNameFlag.REPLACE_EXISTING, - -1, null, - Lang.bind(this, this._initPanelService)); - }, - - _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._updateReadiness(); - } else { - this._clear(); - } - }, - - _initPanelService: function(ibus, result) { - let success = this._ibus.request_name_async_finish(result); - if (success) { - this._panelService = new IBus.PanelService({ connection: this._ibus.get_connection(), - object_path: IBus.PATH_PANEL }); - this._candidatePopup.setPanelService(this._panelService); - this._panelService.connect('update-property', Lang.bind(this, this._updateProperty)); - // If an engine is already active we need to get its properties - this._ibus.get_global_engine_async(-1, null, Lang.bind(this, function(i, result) { - let engine; - try { - engine = this._ibus.get_global_engine_async_finish(result); - if (!engine) - return; - } catch(e) { - return; - } - this._engineChanged(this._ibus, engine.get_name()); - })); - this._updateReadiness(); - } else { - this._clear(); - } - }, - - _updateReadiness: function() { - this._ready = (Object.keys(this._engines).length > 0 && - this._panelService != null); - - if (this._readyCallback) - this._readyCallback(this._ready); - }, - - _engineChanged: function(bus, engineName) { - if (!this._ready) - return; - - this._currentEngineName = engineName; - - if (this._registerPropertiesId != 0) - return; - - this._registerPropertiesId = - this._panelService.connect('register-properties', Lang.bind(this, function(p, props) { - if (!props.get(0)) - return; - - this._panelService.disconnect(this._registerPropertiesId); - this._registerPropertiesId = 0; - - this.emit('properties-registered', this._currentEngineName, props); - })); - }, - - _updateProperty: function(panel, prop) { - this.emit('property-updated', this._currentEngineName, prop); - }, - - activateProperty: function(key, state) { - this._panelService.property_activate(key, state); - }, - - getEngineDesc: function(id) { - if (!IBus || !this._ready) - return null; - - return this._engines[id]; - } -}); -Signals.addSignalMethods(IBusManager.prototype); - const LayoutMenuItem = new Lang.Class({ Name: 'LayoutMenuItem', Extends: PopupMenu.PopupBaseMenuItem, @@ -374,7 +234,8 @@ const InputSourceIndicator = new Lang.Class({ this._propSection.actor.hide(); this._ibusReady = false; - this._ibusManager = new IBusManager(Lang.bind(this, this._ibusReadyCallback)); + this._ibusManager = IBusManager.getIBusManager(); + this._ibusManager.connect('ready', Lang.bind(this, this._ibusReadyCallback)); this._ibusManager.connect('properties-registered', Lang.bind(this, this._ibusPropertiesRegistered)); this._ibusManager.connect('property-updated', Lang.bind(this, this._ibusPropertyUpdated)); this._inputSourcesChanged(); @@ -410,7 +271,7 @@ const InputSourceIndicator = new Lang.Class({ this._showLayoutItem.actor.visible = Main.sessionMode.allowSettings; }, - _ibusReadyCallback: function(ready) { + _ibusReadyCallback: function(im, ready) { if (this._ibusReady == ready) return;