keyboard: track XKB group configuration change

Since GNOME 3.6, switching XKB layouts changes the group
configuration.  This patch tries to track group configuration changes
and reconstruct UI as needed.  See also caribou bug#694011.

https://bugzilla.gnome.org/show_bug.cgi?id=681735
This commit is contained in:
Daiki Ueno 2013-02-18 12:01:04 +09:00
parent 764eed7599
commit 824fbe09c2
2 changed files with 37 additions and 16 deletions

View File

@ -108,6 +108,7 @@ PKG_CHECK_MODULES(BROWSER_PLUGIN, gio-2.0 >= $GIO_MIN_VERSION json-glib-1.0 >= 0
PKG_CHECK_MODULES(TRAY, gtk+-3.0) PKG_CHECK_MODULES(TRAY, gtk+-3.0)
PKG_CHECK_MODULES(GVC, libpulse >= $PULSE_MIN_VERS libpulse-mainloop-glib gobject-2.0) PKG_CHECK_MODULES(GVC, libpulse >= $PULSE_MIN_VERS libpulse-mainloop-glib gobject-2.0)
PKG_CHECK_MODULES(DESKTOP_SCHEMAS, gsettings-desktop-schemas >= 3.7.4) PKG_CHECK_MODULES(DESKTOP_SCHEMAS, gsettings-desktop-schemas >= 3.7.4)
PKG_CHECK_MODULES(CARIBOU, caribou-1.0 >= 0.4.8)
AC_MSG_CHECKING([for bluetooth support]) AC_MSG_CHECKING([for bluetooth support])
PKG_CHECK_EXISTS([gnome-bluetooth-1.0 >= 3.1.0], PKG_CHECK_EXISTS([gnome-bluetooth-1.0 >= 3.1.0],

View File

@ -185,6 +185,10 @@ const Keyboard = new Lang.Class({
_destroyKeyboard: function() { _destroyKeyboard: function() {
if (this._keyboardNotifyId) if (this._keyboardNotifyId)
this._keyboard.disconnect(this._keyboardNotifyId); this._keyboard.disconnect(this._keyboardNotifyId);
if (this._keyboardGroupAddedId)
this._keyboard.disconnect(this._keyboardGroupAddedId);
if (this._keyboardGroupRemovedId)
this._keyboard.disconnect(this._keyboardGroupRemovedId);
if (this._focusNotifyId) if (this._focusNotifyId)
global.stage.disconnect(this._focusNotifyId); global.stage.disconnect(this._focusNotifyId);
this._keyboard = null; this._keyboard = null;
@ -215,6 +219,8 @@ const Keyboard = new Lang.Class({
this.actor.text_direction = Clutter.TextDirection.LTR; this.actor.text_direction = Clutter.TextDirection.LTR;
this._keyboardNotifyId = this._keyboard.connect('notify::active-group', Lang.bind(this, this._onGroupChanged)); this._keyboardNotifyId = this._keyboard.connect('notify::active-group', Lang.bind(this, this._onGroupChanged));
this._keyboardGroupAddedId = this._keyboard.connect('group-added', Lang.bind(this, this._onGroupAdded));
this._keyboardGroupRemovedId = this._keyboard.connect('group-removed', Lang.bind(this, this._onGroupRemoved));
this._focusNotifyId = global.stage.connect('notify::key-focus', Lang.bind(this, this._onKeyFocusChanged)); this._focusNotifyId = global.stage.connect('notify::key-focus', Lang.bind(this, this._onKeyFocusChanged));
this._createSource(); this._createSource();
@ -247,26 +253,30 @@ const Keyboard = new Lang.Class({
Lang.bind(this, function() { this.Show(time); })); Lang.bind(this, function() { this.Show(time); }));
}, },
_createLayersForGroup: function (gname) {
let group = this._keyboard.get_group(gname);
group.connect('notify::active-level', Lang.bind(this, this._onLevelChanged));
let layers = {};
let levels = group.get_levels();
for (let j = 0; j < levels.length; ++j) {
let lname = levels[j];
let level = group.get_level(lname);
let layout = new St.BoxLayout({ style_class: 'keyboard-layout',
vertical: true });
this._loadRows(level, layout);
layers[lname] = layout;
this.actor.add(layout, { x_fill: false });
layout.hide();
}
return layers;
},
_addKeys: function () { _addKeys: function () {
let groups = this._keyboard.get_groups(); let groups = this._keyboard.get_groups();
for (let i = 0; i < groups.length; ++i) { for (let i = 0; i < groups.length; ++i) {
let gname = groups[i]; let gname = groups[i];
let group = this._keyboard.get_group(gname); this._groups[gname] = this._createLayersForGroup(gname);
group.connect('notify::active-level', Lang.bind(this, this._onLevelChanged));
let layers = {};
let levels = group.get_levels();
for (let j = 0; j < levels.length; ++j) {
let lname = levels[j];
let level = group.get_level(lname);
let layout = new St.BoxLayout({ style_class: 'keyboard-layout',
vertical: true });
this._loadRows(level, layout);
layers[lname] = layout;
this.actor.add(layout, { x_fill: false });
layout.hide();
}
this._groups[gname] = layers;
} }
this._setActiveLayer(); this._setActiveLayer();
@ -401,6 +411,16 @@ const Keyboard = new Lang.Class({
this._redraw(); this._redraw();
}, },
_onGroupAdded: function (keyboard, gname) {
if (!(gname in this._groups))
this._groups[gname] = this._createLayersForGroup(gname);
},
_onGroupRemoved: function (keyboard, gname) {
// Since _createLayersForGroup is costly, don't remove the
// actors from _groups, so they can be reused.
},
_setActiveLayer: function () { _setActiveLayer: function () {
let active_group_name = this._keyboard.active_group; let active_group_name = this._keyboard.active_group;
let active_group = this._keyboard.get_group(active_group_name); let active_group = this._keyboard.get_group(active_group_name);