aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilliam Hua <william.hua@canonical.com>2013-10-03 14:44:27 +0000
committerTarmac <Unknown>2013-10-03 14:44:27 +0000
commitdbc0fe12592b88ccfd89631a4e46baf5eaa2f656 (patch)
tree259094119fca0994369ed0e2145810aa32a262e3
parent3aa725b99fd01fbff48dd6b82dfdd43530ef27af (diff)
parent62e536eb83d30df39da4afe5e17e94a7625762ea (diff)
downloadayatana-indicator-keyboard-dbc0fe12592b88ccfd89631a4e46baf5eaa2f656.tar.gz
ayatana-indicator-keyboard-dbc0fe12592b88ccfd89631a4e46baf5eaa2f656.tar.bz2
ayatana-indicator-keyboard-dbc0fe12592b88ccfd89631a4e46baf5eaa2f656.zip
Set the selected user's first keyboard layout whenever it changes under unity-greeter. (LP #1233945). Fixes: https://bugs.launchpad.net/bugs/1233945.
Approved by PS Jenkins bot, Ted Gould, Michael Terry.
-rw-r--r--lib/Makefile.am7
-rw-r--r--lib/greeter.vala26
-rw-r--r--lib/main.vala152
3 files changed, 175 insertions, 10 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 0e6c70d1..fd8a945e 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -6,9 +6,10 @@ AM_VALAFLAGS = --enable-experimental-non-null \
--metadatadir $(top_srcdir)/deps \
--vapidir $(top_srcdir)/deps
-indicator_keyboard_service_SOURCES = main.vala \
- source.vala \
- common.vala
+indicator_keyboard_service_SOURCES = main.vala \
+ source.vala \
+ common.vala \
+ greeter.vala
indicator_keyboard_service_VALAFLAGS = $(AM_VALAFLAGS) \
--pkg gee-1.0 \
--pkg posix \
diff --git a/lib/greeter.vala b/lib/greeter.vala
new file mode 100644
index 00000000..c378bbd5
--- /dev/null
+++ b/lib/greeter.vala
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2013 Canonical Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: William Hua <william.hua@canonical.com>
+ */
+
+[DBus (name="com.canonical.UnityGreeter.List")]
+public interface Greeter : Object {
+
+ public abstract string get_active_entry () throws IOError;
+ public abstract void set_active_entry (string entry_name) throws IOError;
+
+ public signal void entry_selected (string entry_name);
+}
diff --git a/lib/main.vala b/lib/main.vala
index a0315590..190276f8 100644
--- a/lib/main.vala
+++ b/lib/main.vala
@@ -41,6 +41,8 @@ public class Indicator.Keyboard.Service : Object {
private MenuModel? menu_model;
private Menu? sources_menu;
+ private Greeter? greeter;
+ private string? greeter_user;
private uint lightdm_current;
[DBus (visible = false)]
@@ -55,6 +57,18 @@ public class Indicator.Keyboard.Service : Object {
Gdk.init (ref args);
}
+ if (is_login_user ()) {
+ var name = Environment.get_variable ("UNITY_GREETER_DBUS_NAME");
+
+ if (name != null) {
+ Bus.watch_name (BusType.SESSION,
+ (!) name,
+ BusNameWatcherFlags.NONE,
+ handle_name_appeared,
+ handle_name_vanished);
+ }
+ }
+
indicator_settings = new Settings ("com.canonical.indicator.keyboard");
indicator_settings.changed["visible"].connect (handle_changed_visible);
@@ -112,6 +126,108 @@ public class Indicator.Keyboard.Service : Object {
}
[DBus (visible = false)]
+ private void update_greeter_user () {
+ if (greeter_user == null && greeter != null) {
+ try {
+ greeter_user = ((!) greeter).get_active_entry ();
+ } catch (IOError error) {
+ warning ("error: %s", error.message);
+ }
+ }
+
+ string? source = null;
+
+ if (greeter_user != null) {
+ var manager = Act.UserManager.get_default ();
+
+ if (manager.is_loaded) {
+ Act.User? user = manager.get_user ((!) greeter_user);
+
+ if (user != null && ((!) user).is_loaded) {
+ VariantIter outer;
+ VariantIter inner;
+
+ var sources = ((!) user).input_sources;
+ sources.get ("aa{ss}", out outer);
+
+ while (outer.next ("a{ss}", out inner)) {
+ unowned string key;
+ unowned string value;
+
+ while (inner.next ("{&s&s}", out key, out value)) {
+ if (key == "xkb") {
+ source = value;
+ break;
+ }
+ }
+
+ if (source != null) {
+ break;
+ }
+ }
+
+ if (source == null) {
+ var layouts = ((!) user).xkeyboard_layouts;
+
+ if (layouts.length <= 0) {
+ var user_list = LightDM.UserList.get_instance ();
+ LightDM.User? light_user = user_list.get_user_by_name ((!) greeter_user);
+
+ if (light_user != null) {
+ layouts = ((!) light_user).get_layouts ();
+ }
+ }
+
+ if (layouts.length > 0) {
+ source = layouts[0];
+ source = ((!) source).replace (" ", "+");
+ source = ((!) source).replace ("\t", "+");
+ }
+ }
+ }
+ }
+ }
+
+ if (source == null) {
+ LightDM.Layout? layout = LightDM.get_layout ();
+
+ if (layout != null) {
+ source = ((!) layout).name;
+
+ if (source != null) {
+ source = ((!) source).replace (" ", "+");
+ source = ((!) source).replace ("\t", "+");
+ }
+ }
+ }
+
+ if (source != null) {
+ var array = source_settings.get_value ("sources");
+
+ for (int i = 0; i < array.n_children (); i++) {
+ unowned string type;
+ unowned string name;
+
+ array.get_child (i, "(&s&s)", out type, out name);
+
+ if (type == "xkb" && name == (!) source) {
+ source_settings.set_uint ("current", i);
+ break;
+ }
+ }
+ }
+ }
+
+ [DBus (visible = false)]
+ private void handle_entry_selected (string entry_name) {
+ if (greeter_user == null || entry_name != (!) greeter_user) {
+ greeter_user = entry_name;
+
+ update_greeter_user ();
+ }
+ }
+
+ [DBus (visible = false)]
private void migrate_keyboard_layouts () {
if (is_login_user ()) {
lightdm_current = source_settings.get_uint ("current");
@@ -285,15 +401,20 @@ public class Indicator.Keyboard.Service : Object {
}
}
- var layout = LightDM.get_layout ();
+ LightDM.Layout? layout = LightDM.get_layout ();
+
+ if (layout != null) {
+ string? source = ((!) layout).name;
- var source = layout.name;
- source = source.replace (" ", "+");
- source = source.replace ("\t", "+");
+ if (source != null) {
+ source = ((!) source).replace (" ", "+");
+ source = ((!) source).replace ("\t", "+");
- if (!added.contains (source)) {
- list.add (source);
- added.add (source);
+ if (!added.contains ((!) source)) {
+ list.add ((!) source);
+ added.add ((!) source);
+ }
+ }
}
var builder = new VariantBuilder (new VariantType ("a(ss)"));
@@ -309,6 +430,8 @@ public class Indicator.Keyboard.Service : Object {
}
source_settings.set_value ("sources", builder.end ());
+
+ update_greeter_user ();
}
[DBus (visible = false)]
@@ -617,6 +740,21 @@ public class Indicator.Keyboard.Service : Object {
}
[DBus (visible = false)]
+ private void handle_name_appeared (DBusConnection connection, string name, string name_owner) {
+ try {
+ greeter = Bus.get_proxy_sync (BusType.SESSION, name, "/list");
+ ((!) greeter).entry_selected.connect (handle_entry_selected);
+ } catch (IOError error) {
+ warning ("error: %s", error.message);
+ }
+ }
+
+ [DBus (visible = false)]
+ private void handle_name_vanished (DBusConnection connection, string name) {
+ greeter = null;
+ }
+
+ [DBus (visible = false)]
private void handle_bus_acquired (DBusConnection connection, string name) {
try {
connection.export_action_group ("/com/canonical/indicator/keyboard", get_action_group ());