aboutsummaryrefslogtreecommitdiff
path: root/lib/main.vala
diff options
context:
space:
mode:
Diffstat (limited to 'lib/main.vala')
-rw-r--r--lib/main.vala257
1 files changed, 170 insertions, 87 deletions
diff --git a/lib/main.vala b/lib/main.vala
index a54cf904..8279b561 100644
--- a/lib/main.vala
+++ b/lib/main.vala
@@ -45,10 +45,13 @@ public class Indicator.Keyboard.Service : Object {
private SimpleActionGroup? action_group;
private SimpleAction? indicator_action;
- private MenuModel? menu_model;
- private Menu? sources_menu;
- private IBusMenu? ibus_menu;
+ private SimpleAction? active_action;
+ private IndicatorMenu? desktop_menu;
+ private IndicatorMenu? desktop_greeter_menu;
+ private IndicatorMenu? desktop_lockscreen_menu;
+ private KeyboardPlugin? keyboard_plugin;
+ private UnitySession? unity_session;
private UnityGreeter? unity_greeter;
private string? greeter_user;
private uint lightdm_current;
@@ -71,8 +74,16 @@ public class Indicator.Keyboard.Service : Object {
}
}
- if (sources_menu != null) {
- update_sources_menu ();
+ if (desktop_menu != null) {
+ get_desktop_menu ().set_sources (get_sources ());
+ }
+
+ if (desktop_greeter_menu != null) {
+ get_desktop_greeter_menu ().set_sources (get_sources ());
+ }
+
+ if (desktop_lockscreen_menu != null) {
+ get_desktop_lockscreen_menu ().set_sources (get_sources ());
}
if (indicator_action != null) {
@@ -96,6 +107,18 @@ public class Indicator.Keyboard.Service : Object {
}
} else {
Bus.watch_name (BusType.SESSION,
+ "org.gnome.SettingsDaemon.Keyboard",
+ BusNameWatcherFlags.NONE,
+ handle_keyboard_name_appeared,
+ handle_keyboard_name_vanished);
+
+ Bus.watch_name (BusType.SESSION,
+ "com.canonical.Unity",
+ BusNameWatcherFlags.NONE,
+ handle_unity_name_appeared,
+ handle_unity_name_vanished);
+
+ Bus.watch_name (BusType.SESSION,
"com.canonical.Unity.WindowStack",
BusNameWatcherFlags.NONE,
handle_window_stack_name_appeared,
@@ -128,8 +151,16 @@ public class Indicator.Keyboard.Service : Object {
IBus.init ();
ibus = new IBus.Bus ();
((!) ibus).connected.connect (() => {
- if (sources_menu != null) {
- update_sources_menu ();
+ if (desktop_menu != null) {
+ get_desktop_menu ().set_sources (get_sources ());
+ }
+
+ if (desktop_greeter_menu != null) {
+ get_desktop_greeter_menu ().set_sources (get_sources ());
+ }
+
+ if (desktop_lockscreen_menu != null) {
+ get_desktop_lockscreen_menu ().set_sources (get_sources ());
}
if (indicator_action != null) {
@@ -645,7 +676,7 @@ public class Indicator.Keyboard.Service : Object {
}
panel_timeout = Timeout.add (PROPERTIES_DELAY, () => {
- update_ibus_menu (list);
+ get_desktop_menu ().set_properties (list);
panel_timeout = 0;
return false;
});
@@ -653,25 +684,24 @@ public class Indicator.Keyboard.Service : Object {
[DBus (visible = false)]
private void handle_property_updated (IBus.Property property) {
- get_ibus_menu ().update_property (property);
+ get_desktop_menu ().update_property (property);
}
[DBus (visible = false)]
private void update_indicator_action () {
- var visible = indicator_settings.get_boolean ("visible");
- var current = source_settings.get_uint ("current");
- var sources = get_sources ();
-
Icon? icon = null;
string? name = null;
- if (current < sources.length) {
- icon = sources[current].icon;
- name = sources[current].name;
+ var sources = get_sources ();
+ var active = get_active_action ().get_state ().get_uint32 ();
+
+ if (active < sources.length) {
+ icon = sources[active].icon;
+ name = sources[active].name;
}
var builder = new VariantBuilder (new VariantType ("a{sv}"));
- builder.add ("{sv}", "visible", new Variant.boolean (visible));
+ builder.add ("{sv}", "visible", indicator_settings.get_value ("visible"));
if (name != null) {
var description = _ ("%s input source").printf ((!) name);
builder.add ("{sv}", "accessible-desc", new Variant.string (description));
@@ -695,6 +725,42 @@ public class Indicator.Keyboard.Service : Object {
}
[DBus (visible = false)]
+ private void handle_changed_active (Variant? value) {
+ if (value != null) {
+ ((!) active_action).set_state ((!) value);
+ update_indicator_action ();
+
+ if (keyboard_plugin != null) {
+ try {
+ ((!) keyboard_plugin).activate_input_source (((!) value).get_uint32 ());
+ } catch (IOError error) {
+ warning ("error: %s", error.message);
+ }
+ }
+ }
+ }
+
+ [DBus (visible = false)]
+ private void update_active_action () {
+ if (active_action != null) {
+ ((!) active_action).set_state (source_settings.get_value ("current"));
+ update_indicator_action ();
+ }
+ }
+
+ [DBus (visible = false)]
+ private Action get_active_action () {
+ if (active_action == null) {
+ var current = source_settings.get_value ("current");
+ active_action = new SimpleAction.stateful ("active", VariantType.UINT32, current);
+ ((!) active_action).activate.connect ((parameter) => { ((!) active_action).change_state (parameter); });
+ ((!) active_action).change_state.connect (handle_changed_active);
+ }
+
+ return (!) active_action;
+ }
+
+ [DBus (visible = false)]
private void handle_middle_click (Variant? parameter) {
handle_scroll_wheel (new Variant.int32 (-1));
}
@@ -717,7 +783,17 @@ public class Indicator.Keyboard.Service : Object {
protected virtual SimpleActionGroup create_action_group (Action root_action) {
var group = new SimpleActionGroup ();
+ /*
+ * The 'current' action reflects the current setting in
+ * GSettings and the 'active' action only exists to set the
+ * active input source without persisting it.
+ *
+ * The lock screen menu uses the 'active' action while the
+ * other menus instead persist the current input source.
+ */
+
group.add_action (root_action);
+ group.add_action (get_active_action ());
group.add_action (source_settings.create_action ("current"));
var action = new SimpleAction ("next", null);
@@ -753,48 +829,15 @@ public class Indicator.Keyboard.Service : Object {
}
[DBus (visible = false)]
- private void update_sources_menu () {
- if (sources_menu != null) {
- var menu = get_sources_menu ();
- menu.remove_all ();
-
- var sources = get_sources ();
- for (var i = 0; i < sources.length; i++) {
- var item = new MenuItem (sources[i].name, "indicator.current");
- item.set_attribute (Menu.ATTRIBUTE_TARGET, "u", i);
-
- var icon = sources[i].icon;
- if (icon != null) {
- item.set_icon ((!) icon);
- }
-
- menu.append_item (item);
- }
- } else {
- get_sources_menu ();
- }
- }
-
- [DBus (visible = false)]
- private Menu get_sources_menu () {
- if (sources_menu == null) {
- sources_menu = new Menu ();
- update_sources_menu ();
- }
-
- return (!) sources_menu;
- }
-
- [DBus (visible = false)]
- private void update_ibus_menu (IBus.PropList list) {
- get_ibus_menu ().set_properties (list);
- }
-
- [DBus (visible = false)]
- private IBusMenu get_ibus_menu () {
- if (ibus_menu == null) {
- ibus_menu = new IBusMenu (get_action_group ());
- ((!) ibus_menu).activate.connect ((property, state) => {
+ public IndicatorMenu get_desktop_menu () {
+ if (desktop_menu == null) {
+ var options = IndicatorMenu.Options.DCONF
+ | IndicatorMenu.Options.IBUS
+ | IndicatorMenu.Options.SETTINGS;
+
+ desktop_menu = new IndicatorMenu (get_action_group (), options);
+ ((!) desktop_menu).set_sources (get_sources ());
+ ((!) desktop_menu).activate.connect ((property, state) => {
var panel = get_ibus_panel ();
if (panel != null) {
@@ -807,43 +850,31 @@ public class Indicator.Keyboard.Service : Object {
});
}
- return (!) ibus_menu;
+ return (!) desktop_menu;
}
[DBus (visible = false)]
- protected virtual MenuModel create_menu_model (MenuModel sources_menu, MenuModel ibus_menu) {
- var menu = new Menu ();
+ public IndicatorMenu get_desktop_greeter_menu () {
+ if (desktop_greeter_menu == null) {
+ var options = IndicatorMenu.Options.DCONF;
- var submenu = new Menu ();
-
- submenu.append_section (null, sources_menu);
- submenu.append_section (null, ibus_menu);
-
- if (!is_login_user ()) {
- var section = new Menu ();
- section.append (_ ("Character Map"), "indicator.map");
- section.append (_ ("Keyboard Layout Chart"), "indicator.chart");
- section.append (_ ("Text Entry Settings..."), "indicator.settings");
- submenu.append_section (null, section);
+ desktop_greeter_menu = new IndicatorMenu (get_action_group (), options);
+ ((!) desktop_greeter_menu).set_sources (get_sources ());
}
- var indicator = new MenuItem.submenu ("x", submenu);
- indicator.set_attribute ("x-canonical-type", "s", "com.canonical.indicator.root");
- indicator.set_attribute ("x-canonical-secondary-action", "s", "indicator.next");
- indicator.set_attribute ("x-canonical-scroll-action", "s", "indicator.scroll");
- indicator.set_detailed_action ("indicator.indicator");
- menu.append_item (indicator);
-
- return menu;
+ return (!) desktop_greeter_menu;
}
[DBus (visible = false)]
- public MenuModel get_menu_model () {
- if (menu_model == null) {
- menu_model = create_menu_model (get_sources_menu (), get_ibus_menu ());
+ public IndicatorMenu get_desktop_lockscreen_menu () {
+ if (desktop_lockscreen_menu == null) {
+ var options = IndicatorMenu.Options.NONE;
+
+ desktop_lockscreen_menu = new IndicatorMenu (get_action_group (), options);
+ ((!) desktop_lockscreen_menu).set_sources (get_sources ());
}
- return (!) menu_model;
+ return (!) desktop_lockscreen_menu;
}
[DBus (visible = false)]
@@ -854,6 +885,7 @@ public class Indicator.Keyboard.Service : Object {
[DBus (visible = false)]
private void handle_changed_current (string key) {
update_indicator_action ();
+ update_active_action ();
update_login_layout ();
}
@@ -861,7 +893,9 @@ public class Indicator.Keyboard.Service : Object {
private void handle_changed_sources (string key) {
sources = null;
- update_sources_menu ();
+ get_desktop_menu ().set_sources (get_sources ());
+ get_desktop_greeter_menu ().set_sources (get_sources ());
+ get_desktop_lockscreen_menu ().set_sources (get_sources ());
update_indicator_action ();
update_login_layout ();
}
@@ -933,6 +967,53 @@ public class Indicator.Keyboard.Service : Object {
}
[DBus (visible = false)]
+ private void handle_keyboard_name_appeared (DBusConnection connection, string name, string name_owner) {
+ try {
+ keyboard_plugin = Bus.get_proxy_sync (BusType.SESSION, name, "/org/gnome/SettingsDaemon/Keyboard");
+ } catch (IOError error) {
+ warning ("error: %s", error.message);
+ }
+ }
+
+ [DBus (visible = false)]
+ private void handle_keyboard_name_vanished (DBusConnection connection, string name) {
+ keyboard_plugin = null;
+ }
+
+ [DBus (visible = false)]
+ private void handle_unity_name_appeared (DBusConnection connection, string name, string name_owner) {
+ try {
+ unity_session = Bus.get_proxy_sync (BusType.SESSION, name, "/com/canonical/Unity/Session");
+ ((!) unity_session).locked.connect (() => {
+ var sources = get_sources ();
+
+ if (sources.length > 0) {
+ var current = source_settings.get_uint ("current");
+
+ if (current < sources.length && sources[current].is_ibus) {
+ for (var i = 0; i < sources.length; i++) {
+ if (!sources[i].is_ibus) {
+ get_active_action ().change_state (new Variant.uint32 (i));
+ break;
+ }
+ }
+ }
+ }
+ });
+ ((!) unity_session).unlocked.connect (() => {
+ get_active_action ().change_state (source_settings.get_value ("current"));
+ });
+ } catch (IOError error) {
+ warning ("error: %s", error.message);
+ }
+ }
+
+ [DBus (visible = false)]
+ private void handle_unity_name_vanished (DBusConnection connection, string name) {
+ unity_session = null;
+ }
+
+ [DBus (visible = false)]
private void handle_window_stack_name_appeared (DBusConnection connection, string name, string name_owner) {
try {
window_stack = Bus.get_proxy_sync (BusType.SESSION, name, "/com/canonical/Unity/WindowStack");
@@ -951,7 +1032,9 @@ public class Indicator.Keyboard.Service : Object {
private void handle_bus_acquired (DBusConnection connection, string name) {
try {
connection.export_action_group ("/com/canonical/indicator/keyboard", get_action_group ());
- connection.export_menu_model ("/com/canonical/indicator/keyboard/desktop", get_menu_model ());
+ connection.export_menu_model ("/com/canonical/indicator/keyboard/desktop", get_desktop_menu ());
+ connection.export_menu_model ("/com/canonical/indicator/keyboard/desktop_greeter", get_desktop_greeter_menu ());
+ connection.export_menu_model ("/com/canonical/indicator/keyboard/desktop_lockscreen", get_desktop_lockscreen_menu ());
} catch (Error error) {
warning ("error: %s", error.message);
}