aboutsummaryrefslogtreecommitdiff
path: root/src/main.vala
diff options
context:
space:
mode:
authorRobert Tari <robert@tari.in>2021-01-24 03:38:44 +0100
committerMike Gabriel <mike.gabriel@das-netzwerkteam.de>2021-01-27 17:10:40 +0100
commitb85daf94830a3ca39d59237fdb07bc33ede1c450 (patch)
tree8d704b1d8614759da71fbe42dca737c0e2261142 /src/main.vala
parent9b8fb0492c8c05630644d840aef520f3c6b17829 (diff)
downloadayatana-indicator-keyboard-b85daf94830a3ca39d59237fdb07bc33ede1c450.tar.gz
ayatana-indicator-keyboard-b85daf94830a3ca39d59237fdb07bc33ede1c450.tar.bz2
ayatana-indicator-keyboard-b85daf94830a3ca39d59237fdb07bc33ede1c450.zip
100% re-write of the keyboard indicator in plain C.
Diffstat (limited to 'src/main.vala')
-rw-r--r--src/main.vala1265
1 files changed, 0 insertions, 1265 deletions
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 <http://www.gnu.org/licenses/>.
- *
- * Authors: William Hua <william.hua@canonical.com>
- */
-
-[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<Act.User> users;
-
- private WindowStack? window_stack;
- private Gee.HashMap<uint, Source>? 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<IBusPanel> (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<string> ();
- var added = new Gee.HashSet<string> ();
-
- 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<LightDM.Layout> 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<uint, Source> ();
- ((!) 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' : <false> }");
- 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<UnityGreeter> (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<UnitySession> (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;
- }
-}