From b85daf94830a3ca39d59237fdb07bc33ede1c450 Mon Sep 17 00:00:00 2001 From: Robert Tari Date: Sun, 24 Jan 2021 03:38:44 +0100 Subject: 100% re-write of the keyboard indicator in plain C. --- src/main.vala | 1265 --------------------------------------------------------- 1 file changed, 1265 deletions(-) delete mode 100644 src/main.vala (limited to 'src/main.vala') diff --git a/src/main.vala b/src/main.vala deleted file mode 100644 index 9bb3eb1f..00000000 --- a/src/main.vala +++ /dev/null @@ -1,1265 +0,0 @@ -/* - * 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 . - * - * Authors: William Hua - */ - -[DBus (name = "org.ayatana.indicator.keyboard")] -public class Indicator.Keyboard.Service : Object { - - private static const uint PROPERTIES_DELAY = 250; - - private static Service service; - - private bool force; - private bool use_gtk; - - private MainLoop? loop; - private Settings indicator_settings; - private Settings source_settings; - private Settings per_window_settings; - private SList users; - - private WindowStack? window_stack; - private Gee.HashMap? window_sources; - private uint focused_window_id; - - private IBus.Bus? ibus; - private IBusPanel? ibus_panel; - private ulong ibus_connected_id; - private uint panel_timeout; - - private Fcitx.InputMethod? fcitx; - private bool fcitx_initialized; - - private Source[]? sources; - - private SimpleActionGroup? action_group; - private SimpleAction? indicator_action; - 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; - - [DBus (visible = false)] - public Service (ref unowned string[] args) { - force = "--force" in args; - use_gtk = "--use-gtk" in args; - - if (use_gtk) { - use_gtk = Gtk.init_check (ref args); - - Gtk.IconTheme? icon_theme = Gtk.IconTheme.get_default (); - - if (icon_theme != null) { - ((!) icon_theme).changed.connect (() => { - if (sources != null) { - foreach (var source in (!) sources) { - source.icon = null; - } - } - - 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) { - update_indicator_action (); - } - }); - } - } else { - 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_unity_greeter_name_appeared, - handle_unity_greeter_name_vanished); - } - } 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, - "org.ayatana.Unity", - BusNameWatcherFlags.NONE, - handle_unity_name_appeared, - handle_unity_name_vanished); - - if (!is_fcitx_active ()) { - Bus.watch_name (BusType.SESSION, - "org.ayatana.Unity.WindowStack", - BusNameWatcherFlags.NONE, - handle_window_stack_name_appeared, - handle_window_stack_name_vanished); - } - } - - indicator_settings = new Settings ("org.ayatana.indicator.keyboard"); - indicator_settings.changed["visible"].connect (handle_changed_visible); - - source_settings = new Settings ("org.gnome.desktop.input-sources"); - source_settings.changed["current"].connect (handle_changed_current); - source_settings.changed["sources"].connect (handle_changed_sources); - - per_window_settings = new Settings ("org.gnome.libgnomekbd.desktop"); - per_window_settings.changed["group-per-window"].connect (handle_changed_group_per_window); - - migrate_keyboard_layouts (); - update_window_sources (); - acquire_bus_name (); - } - - [DBus (visible = false)] - private static bool is_login_user () { - return Environment.get_user_name () == "lightdm"; - } - - [DBus (visible = false)] - private static bool is_ibus_active () { - if (is_login_user ()) { - return false; - } - - var module = Environment.get_variable ("GTK_IM_MODULE"); - return module != null && (!) module == "ibus"; - } - - [DBus (visible = false)] - private static bool is_fcitx_active () { - if (is_login_user ()) { - return false; - } - - var module = Environment.get_variable ("GTK_IM_MODULE"); - return module != null && (!) module == "fcitx"; - } - - [DBus (visible = false)] - private IBus.Bus get_ibus () { - if (ibus == null) { - IBus.init (); - - var proxy = new IBus.Bus (); - - proxy.connected.connect (() => { - 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) { - update_indicator_action (); - } - }); - - ibus = proxy; - } - - return (!) ibus; - } - - [DBus (visible = false)] - private IBusPanel? get_ibus_panel () { - if (ibus_panel == null && get_ibus ().is_connected ()) { - var connection = get_ibus ().get_connection (); - var name = "org.freedesktop.IBus.Panel"; - var path = "/org/freedesktop/IBus/Panel"; - - try { - var proxy = connection.get_proxy_sync (name, path); - - proxy.properties_registered.connect ((variant) => { - var properties = new IBus.PropList (); - properties.deserialize (variant); - - if (properties is IBus.PropList) { - handle_properties_registered ((!) (properties as IBus.PropList)); - } - }); - proxy.property_updated.connect ((variant) => { - var type = IBus.PropType.NORMAL; - var state = IBus.PropState.INCONSISTENT; - var text = new IBus.Text.from_static_string (""); - var property = new IBus.Property ("", type, text, null, text, false, false, state, null); - property.deserialize (variant); - - if (property is IBus.Property) { - handle_property_updated ((!) (property as IBus.Property)); - } - }); - - ibus_panel = proxy; - } catch (IOError error) { - warning ("error: %s", error.message); - } - } - - return ibus_panel; - } - - [DBus (visible = false)] - private Fcitx.InputMethod? get_fcitx () { - if (!fcitx_initialized) { - fcitx_initialized = true; - - if (is_fcitx_active ()) { - try { - var proxy = new Fcitx.InputMethod (BusType.SESSION, DBusProxyFlags.NONE, 0); - proxy.notify["current-im"].connect ((pspec) => { handle_changed_current ("current"); }); - fcitx = proxy; - } catch (Error error) { - warning ("error: %s", error.message); - } - } - } - - return fcitx; - } - - [DBus (visible = false)] - public void up () { - if (loop == null) { - var main_loop = new MainLoop (); - loop = main_loop; - main_loop.run (); - } - } - - [DBus (visible = false)] - public void down () { - if (loop != null) { - ((!) loop).quit (); - loop = null; - } - } - - [DBus (visible = false)] - private void acquire_bus_name () { - Bus.own_name (BusType.SESSION, - "org.ayatana.indicator.keyboard", - BusNameOwnerFlags.ALLOW_REPLACEMENT | (force ? BusNameOwnerFlags.REPLACE : 0), - handle_bus_acquired, - null, - handle_name_lost); - } - - [DBus (visible = false)] - private void update_greeter_user () { - if (greeter_user == null && unity_greeter != null) { - try { - greeter_user = ((!) unity_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) { - foreach (var outer in ((!) user).input_sources) { - foreach (var inner in (!) outer) { - unowned string key; - unowned string value; - - ((!) inner).get ("{&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].replace (" ", "+").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 (var 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 = get_current (); - - var manager = Act.UserManager.get_default (); - - if (manager.is_loaded) { - users = manager.list_users (); - - foreach (var user in users) { - if (user.is_loaded) { - migrate_input_sources (); - } else { - user.notify["is-loaded"].connect ((pspec) => { - if (user.is_loaded) { - migrate_input_sources (); - } - }); - } - } - } else { - manager.notify["is-loaded"].connect ((pspec) => { - if (manager.is_loaded) { - users = manager.list_users (); - - foreach (var user in users) { - if (user.is_loaded) { - migrate_input_sources (); - } else { - user.notify["is-loaded"].connect ((pspec) => { - if (user.is_loaded) { - migrate_input_sources (); - } - }); - } - } - } - }); - } - - var user_list = LightDM.UserList.get_instance (); - - user_list.user_added.connect ((user) => { migrate_input_sources (); }); - user_list.user_changed.connect ((user) => { migrate_input_sources (); }); - user_list.user_removed.connect ((user) => { migrate_input_sources (); }); - - /* Force the loading of the user list. */ - user_list.get_user_by_name (""); - } else { - if (!indicator_settings.get_boolean ("migrated")) { - var builder = new VariantBuilder (new VariantType ("a(ss)")); - var length = 0; - - var layout_settings = new Settings ("org.gnome.libgnomekbd.keyboard"); - var layouts = layout_settings.get_strv ("layouts"); - - foreach (var layout in layouts) { - var source = layout; - source = source.replace (" ", "+"); - source = source.replace ("\t", "+"); - - builder.add ("(ss)", "xkb", source); - length++; - } - - var engines = get_ibus ().list_active_engines (); - - foreach (var engine in engines) { - if (length == 0 || engine.name.has_prefix ("xkb")) { - var source = "us"; - string? layout = engine.get_layout (); - string? variant = engine.get_layout_variant (); - - if (layout != null && ((!) layout).length == 0) { - layout = null; - } - - if (variant != null && ((!) variant).length == 0) { - variant = null; - } - - if (layout != null && variant != null) { - source = @"$((!) layout)+$((!) variant)"; - } else if (layout != null) { - source = (!) layout; - } - - builder.add ("(ss)", "xkb", source); - length++; - } - - if (!engine.name.has_prefix ("xkb")) { - builder.add ("(ss)", "ibus", engine.name); - length++; - } - } - - source_settings.set_value ("sources", builder.end ()); - indicator_settings.set_boolean ("migrated", true); - } - } - } - - [DBus (visible = false)] - private void migrate_input_sources () { - var list = new Gee.LinkedList (); - var added = new Gee.HashSet (); - - foreach (var user in users) { - if (user.is_loaded) { - var done = false; - - foreach (var outer in user.input_sources) { - foreach (var inner in (!) outer) { - unowned string key; - unowned string source; - - ((!) inner).get ("{&s&s}", out key, out source); - - if (key == "xkb") { - done = true; - - if (!added.contains (source)) { - list.add (source); - added.add (source); - } - } - } - } - - if (!done) { - var layouts = user.xkeyboard_layouts; - foreach (var layout in layouts) { - done = true; - - var source = layout; - source = source.replace (" ", "+"); - source = source.replace ("\t", "+"); - - if (!added.contains (source)) { - list.add (source); - added.add (source); - } - } - } - - if (!done) { - var user_list = LightDM.UserList.get_instance (); - LightDM.User? light_user = user_list.get_user_by_name (user.user_name); - - if (light_user != null) { - var layouts = ((!) light_user).get_layouts (); - foreach (var layout in layouts) { - done = true; - - var source = layout; - source = source.replace (" ", "+"); - source = source.replace ("\t", "+"); - - if (!added.contains (source)) { - list.add (source); - added.add (source); - } - } - } - } - } - } - - LightDM.Layout? layout = LightDM.get_layout (); - - if (layout != null) { - string? source = ((!) layout).name; - - if (source != null) { - source = ((!) source).replace (" ", "+"); - source = ((!) source).replace ("\t", "+"); - - if (!added.contains ((!) source)) { - list.add ((!) source); - added.add ((!) source); - } - } - } - - var builder = new VariantBuilder (new VariantType ("a(ss)")); - - foreach (var name in list) { - builder.add ("(ss)", "xkb", name); - } - - if (lightdm_current < list.size) { - source_settings.set_uint ("current", lightdm_current); - } else { - source_settings.set_uint ("current", list.size - 1); - } - - source_settings.set_value ("sources", builder.end ()); - - update_greeter_user (); - } - - [DBus (visible = false)] - private void update_login_layout () { - if (is_login_user ()) { - unowned List layouts = LightDM.get_layouts (); - var current = get_current (); - - if (current < get_sources ().length) { - var source = get_sources ()[current]; - string? name = null; - - if (source.layout != null && source.variant != null) { - name = @"$((!) source.layout)\t$((!) source.variant)"; - } else if (source.layout != null) { - name = source.layout; - } - - if (name != null) { - foreach (var layout in layouts) { - if (layout.name == (!) name) { - LightDM.set_layout (layout); - break; - } - } - } - } - } - } - - [DBus (visible = false)] - private void update_window_sources () { - if (window_stack != null) { - var group_per_window = per_window_settings.get_boolean ("group-per-window"); - - if (group_per_window != (window_sources != null)) { - if (group_per_window) { - focused_window_id = 0; - - try { - var windows = ((!) window_stack).get_window_stack (); - - foreach (var window in windows) { - if (window.focused) { - focused_window_id = window.window_id; - break; - } - } - } catch (IOError error) { - warning ("error: %s", error.message); - } - - window_sources = new Gee.HashMap (); - ((!) window_stack).window_destroyed.connect (handle_window_destroyed); - ((!) window_stack).focused_window_changed.connect (handle_focused_window_changed); - } else { - ((!) window_stack).focused_window_changed.disconnect (handle_focused_window_changed); - ((!) window_stack).window_destroyed.disconnect (handle_window_destroyed); - window_sources = null; - } - } - } - } - - [DBus (visible = false)] - private void handle_changed_group_per_window (string key) { - update_window_sources (); - } - - [DBus (visible = false)] - private void handle_window_destroyed (uint window_id, string app_id) { - ((!) window_sources).unset (window_id); - } - - [DBus (visible = false)] - private void handle_focused_window_changed (uint window_id, string app_id, uint stage) { - var sources = get_sources (); - var old_current = get_current (); - - if (old_current < sources.length) { - ((!) window_sources)[focused_window_id] = sources[old_current]; - } - - if (!(((!) window_sources).has_key (window_id))) { - var default_group = per_window_settings.get_int ("default-group"); - - if (default_group >= 0) { - for (var offset = 0; offset < sources.length; offset++) { - var current = (default_group + offset) % sources.length; - var source = sources[current]; - - if (source.is_xkb || - (source.is_ibus && is_ibus_active ()) || - (source.is_fcitx && is_fcitx_active ())) { - if (current != old_current) { - source_settings.set_uint ("current", current); - } - - break; - } - } - } - } else { - var source = ((!) window_sources)[window_id]; - - for (var current = 0; current < sources.length; current++) { - if (sources[current] == source) { - if (current != old_current) { - source_settings.set_uint ("current", current); - } - - break; - } - } - } - - focused_window_id = window_id; - } - - [DBus (visible = false)] - private uint get_current () { - if (is_fcitx_active () && get_fcitx () != null) { - string? engine = ((!) get_fcitx ()).current_im; - - if (engine != null) { - var is_xkb = ((!) engine).has_prefix ("fcitx-keyboard-"); - var type = is_xkb ? "xkb" : "fcitx"; - var name = (!) engine; - - if (is_xkb) { - name = name.substring ("fcitx-keyboard-".length); - var index = name.index_of ("-"); - if (index >= 0) { - name.data[index] = '+'; - } - } - - var i = 0; - - foreach (var pair in source_settings.get_value ("sources")) { - unowned string source_type; - unowned string source_name; - - ((!) pair).get ("(&s&s)", out source_type, out source_name); - - if (source_name == name && source_type == type) { - return i; - } - - i++; - } - } - } - - return source_settings.get_uint ("current"); - } - - [DBus (visible = false)] - private Source[] get_sources () { - if (sources == null) { - var array = source_settings.get_value ("sources"); - - sources = new Source[array.n_children ()]; - - for (var i = 0; i < ((!) sources).length; i++) { - sources[i] = new Source(array.get_child_value (i), use_gtk); - sources[i].show_subscript = false; - sources[i].subscript = 1; - - for (var j = (int) i - 1; j >= 0; j--) { - if ((!) sources[j].short_name == (!) sources[i].short_name) { - sources[i].subscript = sources[j].subscript + 1; - sources[i].show_subscript = true; - sources[j].show_subscript = true; - - break; - } - } - - if (ibus_connected_id == 0 && sources[i].is_ibus) { - ibus_connected_id = get_ibus ().connected.connect (() => { get_ibus_panel (); }); - get_ibus ().disconnected.connect (() => { ibus_panel = null; }); - - if (get_ibus ().is_connected ()) { - get_ibus_panel (); - } - } - } - } - - return (!) sources; - } - - [DBus (visible = false)] - private void handle_properties_registered (IBus.PropList list) { - if (panel_timeout > 0) { - GLib.Source.remove (panel_timeout); - panel_timeout = 0; - } - - panel_timeout = Timeout.add (PROPERTIES_DELAY, () => { - get_desktop_menu ().set_properties (list); - panel_timeout = 0; - return false; - }); - } - - [DBus (visible = false)] - private void handle_property_updated (IBus.Property property) { - get_desktop_menu ().update_property (property); - } - - [DBus (visible = false)] - private void update_indicator_action () { - Icon? icon = null; - string? name = null; - - 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", indicator_settings.get_value ("visible")); - if (name != null) { - var description = _ ("%s input source").printf ((!) name); - builder.add ("{sv}", "accessible-desc", new Variant.string (description)); - } - if (icon != null) { - builder.add ("{sv}", "icon", ((!) icon).serialize ()); - } - - get_indicator_action ().set_state (builder.end ()); - } - - [DBus (visible = false)] - private SimpleAction get_indicator_action () { - if (indicator_action == null) { - var state = new Variant.parsed ("{ 'visible' : }"); - indicator_action = new SimpleAction.stateful ("indicator", null, state); - update_indicator_action (); - } - - return (!) indicator_action; - } - - [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 (new Variant.uint32 (get_current ())); - update_indicator_action (); - } - } - - [DBus (visible = false)] - private Action get_active_action () { - if (active_action == null) { - var action = new SimpleAction.stateful ("active", VariantType.UINT32, new Variant.uint32 (get_current ())); - action.change_state.connect (handle_changed_active); - active_action = action; - } - - return (!) active_action; - } - - [DBus (visible = false)] - private void handle_middle_click (Variant? parameter) { - handle_scroll_wheel (new Variant.int32 (-1)); - } - - [DBus (visible = false)] - private void handle_scroll_wheel (Variant? parameter) { - if (parameter != null) { - var old_current = get_current (); - var sources = get_sources (); - var length = 0; - - foreach (var source in sources) { - if (source.is_xkb || - (source.is_ibus && is_ibus_active ()) || - (source.is_fcitx && is_fcitx_active ())) { - length++; - } - } - - if (length > 1) { - var current = old_current; - var offset = -((!) parameter).get_int32 () % length; - var jump = 1; - - if (offset < 0) { - offset = -offset; - jump = sources.length - jump; - } - - /* - * We need to cycle through offset valid input sources, skipping those that aren't - * valid for this session (i.e. skipping Fcitx ones if IBus is active and vice-versa. - * jump is the direction we need to cycle in, which is 1 if we want to cycle forward - * and -1 (mod sources.length) if we want to cycle backward. - */ - - for (; offset > 0; offset--) { - do { - current = (current + jump) % sources.length; - } while ((sources[current].is_ibus && !is_ibus_active ()) || - (sources[current].is_fcitx && !is_fcitx_active ())); - } - - if (current != old_current) { - source_settings.set_uint ("current", current); - } - } - } - } - - [DBus (visible = false)] - private void handle_middle_click_when_locked (Variant? parameter) { - handle_scroll_wheel_when_locked (new Variant.int32 (-1)); - } - - [DBus (visible = false)] - private void handle_scroll_wheel_when_locked (Variant? parameter) { - if (parameter != null) { - var sources = get_sources (); - var xkb_length = 0; - - /* Figure out how many Xkb sources we have. */ - foreach (var source in sources) { - if (source.is_xkb) { - xkb_length++; - } - } - - if (xkb_length > 1) { - var active_action = get_active_action (); - var active = active_action.get_state ().get_uint32 (); - var offset = -((!) parameter).get_int32 () % xkb_length; - - /* Make offset positive modulo xkb_length. */ - if (offset < 0) { - offset += xkb_length; - } - - /* We need to cycle through Xkb sources only. */ - while (offset > 0) { - do { - active = (active + 1) % sources.length; - } while (!sources[active].is_xkb); - - offset--; - } - - active_action.change_state (new Variant.uint32 (active)); - } - } - } - - [DBus (visible = false)] - 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); - action.activate.connect (handle_middle_click); - group.add_action (action); - - action = new SimpleAction ("scroll", VariantType.INT32); - action.activate.connect (handle_scroll_wheel); - group.add_action (action); - - action = new SimpleAction ("locked_next", null); - action.activate.connect (handle_middle_click_when_locked); - group.add_action (action); - - action = new SimpleAction ("locked_scroll", VariantType.INT32); - action.activate.connect (handle_scroll_wheel_when_locked); - group.add_action (action); - - action = new SimpleAction ("map", null); - action.activate.connect (handle_activate_map); - group.add_action (action); - - action = new SimpleAction ("chart", null); - action.activate.connect (handle_activate_chart); - group.add_action (action); - - action = new SimpleAction ("settings", null); - action.activate.connect (handle_activate_settings); - group.add_action (action); - - return group; - } - - [DBus (visible = false)] - public SimpleActionGroup get_action_group () { - if (action_group == null) { - action_group = create_action_group (get_indicator_action ()); - } - - return (!) action_group; - } - - [DBus (visible = false)] - public IndicatorMenu get_desktop_menu () { - if (desktop_menu == null) { - var options = IndicatorMenu.Options.DCONF; - - if (!is_fcitx_active ()) { - options |= IndicatorMenu.Options.XKB | IndicatorMenu.Options.SETTINGS; - - if (is_ibus_active ()) { - options |= IndicatorMenu.Options.IBUS; - } - } - - var menu = new IndicatorMenu (get_action_group (), options); - - menu.set_sources (get_sources ()); - menu.activate.connect ((property, state) => { - var panel = get_ibus_panel (); - - if (panel != null) { - try { - ((!) panel).activate_property (property.key, state); - } catch (IOError error) { - warning ("error: %s", error.message); - } - } - }); - - desktop_menu = menu; - } - - return (!) desktop_menu; - } - - [DBus (visible = false)] - public IndicatorMenu get_desktop_greeter_menu () { - if (desktop_greeter_menu == null) { - var options = IndicatorMenu.Options.DCONF | - IndicatorMenu.Options.XKB; - - var menu = new IndicatorMenu (get_action_group (), options); - menu.set_sources (get_sources ()); - desktop_greeter_menu = menu; - } - - return (!) desktop_greeter_menu; - } - - [DBus (visible = false)] - public IndicatorMenu get_desktop_lockscreen_menu () { - if (desktop_lockscreen_menu == null) { - var options = IndicatorMenu.Options.XKB; - - var menu = new IndicatorMenu (get_action_group (), options); - menu.set_sources (get_sources ()); - desktop_lockscreen_menu = menu; - } - - return (!) desktop_lockscreen_menu; - } - - [DBus (visible = false)] - private void handle_changed_visible (string key) { - update_indicator_action (); - } - - [DBus (visible = false)] - private void handle_changed_current (string key) { - update_indicator_action (); - update_active_action (); - update_login_layout (); - } - - [DBus (visible = false)] - private void handle_changed_sources (string key) { - sources = null; - - 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 (); - } - - [DBus (visible = false)] - private void handle_activate_map (Variant? parameter) { - try { - Process.spawn_command_line_async ("gucharmap"); - } catch (SpawnError error) { - warning ("error: %s", error.message); - } - } - - [DBus (visible = false)] - private void handle_activate_chart (Variant? parameter) { - string? layout = "us"; - string? variant = null; - - var sources = get_sources (); - var current = get_current (); - - if (current < sources.length) { - layout = sources[current].layout; - variant = sources[current].variant; - } - - var has_layout = layout != null && ((!) layout).get_char () != '\0'; - var has_variant = variant != null && ((!) variant).get_char () != '\0'; - - try { - string command; - - if (has_layout && has_variant) { - command = @"gkbd-keyboard-display -l \"$((!) layout)\t$((!) variant)\""; - } else if (has_layout) { - command = @"gkbd-keyboard-display -l $((!) layout)"; - } else { - command = @"gkbd-keyboard-display -l us"; - } - - Process.spawn_command_line_async (command); - } catch (SpawnError error) { - warning ("error: %s", error.message); - } - } - - [DBus (visible = false)] - private void handle_activate_settings (Variant? parameter) { - try { - Process.spawn_command_line_async ("unity-control-center region layouts"); - } catch (SpawnError error) { - warning ("error: %s", error.message); - } - } - - [DBus (visible = false)] - private void handle_unity_greeter_name_appeared (DBusConnection connection, string name, string name_owner) { - try { - var greeter = Bus.get_proxy_sync (BusType.SESSION, name, "/list"); - greeter.entry_selected.connect (handle_entry_selected); - unity_greeter = greeter; - } catch (IOError error) { - warning ("error: %s", error.message); - } - } - - [DBus (visible = false)] - private void handle_unity_greeter_name_vanished (DBusConnection connection, string name) { - unity_greeter = null; - } - - [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 { - var session = Bus.get_proxy_sync (BusType.SESSION, name, "/org/ayatana/Unity/Session"); - - session.locked.connect (() => { - var sources = get_sources (); - - if (sources.length > 0) { - var current = get_current (); - - if (current < sources.length && !sources[current].is_xkb) { - for (var i = 0; i < sources.length; i++) { - if (sources[i].is_xkb) { - get_active_action ().change_state (new Variant.uint32 (i)); - break; - } - } - } - } - }); - session.unlocked.connect (() => { - get_active_action ().change_state (new Variant.uint32 (get_current ())); - }); - - unity_session = session; - } 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, "/org/ayatana/Unity/WindowStack"); - update_window_sources (); - } catch (IOError error) { - warning ("error: %s", error.message); - } - } - - [DBus (visible = false)] - private void handle_window_stack_name_vanished (DBusConnection connection, string name) { - window_stack = null; - } - - [DBus (visible = false)] - private void handle_bus_acquired (DBusConnection connection, string name) { - try { - connection.export_action_group ("/org/ayatana/indicator/keyboard", get_action_group ()); - connection.export_menu_model ("/org/ayatana/indicator/keyboard/desktop", get_desktop_menu ()); - connection.export_menu_model ("/org/ayatana/indicator/keyboard/desktop_greeter", get_desktop_greeter_menu ()); - connection.export_menu_model ("/org/ayatana/indicator/keyboard/desktop_lockscreen", get_desktop_lockscreen_menu ()); - } catch (Error error) { - warning ("error: %s", error.message); - } - } - - [DBus (visible = false)] - private void handle_name_lost (DBusConnection? connection, string name) { - down (); - } - - [DBus (visible = false)] - public static int main (string[] args) { - Service.service = new Service (ref args); - - Posix.signal (Posix.SIGTERM, (code) => { - Service.service.down (); - }); - - Service.service.up (); - - return 0; - } -} -- cgit v1.2.3