diff options
Diffstat (limited to 'lib/main.vala')
-rw-r--r-- | lib/main.vala | 257 |
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); } |