aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/Makefile.am2
-rw-r--r--lib/Makefile.am16
-rw-r--r--lib/indicator-menu.vala30
-rw-r--r--lib/keyboard-plugin.vala23
-rw-r--r--lib/main.vala207
-rw-r--r--lib/unity-session.vala24
-rw-r--r--po/indicator-keyboard.pot10
7 files changed, 282 insertions, 30 deletions
diff --git a/data/Makefile.am b/data/Makefile.am
index 104d2073..03c377c7 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -57,7 +57,7 @@ com.canonical.indicator.keyboard:
echo 'ObjectPath=/com/canonical/indicator/keyboard/desktop_greeter'; \
echo ''; \
echo '[desktop_lockscreen]'; \
- echo 'ObjectPath=/com/canonical/indicator/keyboard/desktop_greeter'; \
+ echo 'ObjectPath=/com/canonical/indicator/keyboard/desktop_lockscreen'; \
echo ''; \
echo '[ubiquity]'; \
echo 'ObjectPath=/com/canonical/indicator/keyboard/desktop') > $@.tmp && \
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 9abf5ada..a19016d9 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -6,13 +6,15 @@ AM_VALAFLAGS = --enable-experimental-non-null \
--metadatadir $(top_srcdir)/deps \
--vapidir $(top_srcdir)/deps
-indicator_keyboard_service_SOURCES = main.vala \
- source.vala \
- common.vala \
- ibus-menu.vala \
- ibus-panel.vala \
- indicator-menu.vala \
- window-stack.vala \
+indicator_keyboard_service_SOURCES = main.vala \
+ source.vala \
+ common.vala \
+ ibus-menu.vala \
+ ibus-panel.vala \
+ indicator-menu.vala \
+ keyboard-plugin.vala \
+ window-stack.vala \
+ unity-session.vala \
unity-greeter.vala
indicator_keyboard_service_VALAFLAGS = $(AM_VALAFLAGS) \
--pkg gee-1.0 \
diff --git a/lib/indicator-menu.vala b/lib/indicator-menu.vala
index 1d92a6f6..8e5661e2 100644
--- a/lib/indicator-menu.vala
+++ b/lib/indicator-menu.vala
@@ -20,8 +20,9 @@ public class Indicator.Keyboard.IndicatorMenu : MenuModel {
public enum Options {
NONE = 0x0,
- IBUS = 0x1,
- SETTINGS = 0x2
+ DCONF = 0x1,
+ IBUS = 0x2,
+ SETTINGS = 0x4
}
private Options options;
@@ -30,7 +31,7 @@ public class Indicator.Keyboard.IndicatorMenu : MenuModel {
private Menu sources_section;
private IBusMenu properties_section;
- public IndicatorMenu (ActionMap? action_map = null, Options options = Options.IBUS | Options.SETTINGS) {
+ public IndicatorMenu (ActionMap? action_map = null, Options options = Options.NONE) {
var submenu = new Menu ();
sources_section = new Menu ();
@@ -51,10 +52,17 @@ public class Indicator.Keyboard.IndicatorMenu : MenuModel {
}
var indicator = new MenuItem.submenu (null, 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");
+ indicator.set_attribute ("x-canonical-type", "s", "com.canonical.indicator.root");
+
+ /* We need special mouse actions on the lock screen. */
+ if ((options & Options.DCONF) != Options.NONE) {
+ indicator.set_attribute ("x-canonical-secondary-action", "s", "indicator.next");
+ indicator.set_attribute ("x-canonical-scroll-action", "s", "indicator.scroll");
+ } else {
+ indicator.set_attribute ("x-canonical-secondary-action", "s", "indicator.locked_next");
+ indicator.set_attribute ("x-canonical-scroll-action", "s", "indicator.locked_scroll");
+ }
indicator_menu = new Menu ();
indicator_menu.append_item (indicator);
@@ -69,7 +77,15 @@ public class Indicator.Keyboard.IndicatorMenu : MenuModel {
for (var i = 0; i < sources.length; i++) {
if (!sources[i].is_ibus || (options & Options.IBUS) != Options.NONE) {
- var item = new MenuItem (sources[i].name, "indicator.current");
+ string action;
+
+ if ((options & Options.DCONF) != Options.NONE) {
+ action = "indicator.current";
+ } else {
+ action = "indicator.active";
+ }
+
+ var item = new MenuItem (sources[i].name, action);
item.set_attribute (Menu.ATTRIBUTE_TARGET, "u", i);
diff --git a/lib/keyboard-plugin.vala b/lib/keyboard-plugin.vala
new file mode 100644
index 00000000..5ee8ea24
--- /dev/null
+++ b/lib/keyboard-plugin.vala
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2014 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.SettingsDaemon.Keyboard.Private")]
+public interface KeyboardPlugin : Object {
+
+ public abstract void activate_input_source (uint index) throws IOError;
+}
diff --git a/lib/main.vala b/lib/main.vala
index 8543dd3e..8d39d757 100644
--- a/lib/main.vala
+++ b/lib/main.vala
@@ -45,9 +45,13 @@ public class Indicator.Keyboard.Service : Object {
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;
@@ -78,6 +82,10 @@ public class Indicator.Keyboard.Service : Object {
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 ();
}
@@ -99,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,
@@ -139,6 +159,10 @@ public class Indicator.Keyboard.Service : Object {
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 ();
}
@@ -665,20 +689,19 @@ public class Indicator.Keyboard.Service : Object {
[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));
@@ -702,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));
}
@@ -721,10 +780,62 @@ public class Indicator.Keyboard.Service : Object {
}
[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 non_ibus_length = 0;
+
+ /* Figure out how many non-IBus sources we have. */
+ foreach (var source in sources) {
+ if (!source.is_ibus) {
+ non_ibus_length++;
+ }
+ }
+
+ if (non_ibus_length > 1) {
+ var active_action = get_active_action ();
+ var active = active_action.state.get_uint32 ();
+ var offset = -((!) parameter).get_int32 () % non_ibus_length;
+
+ /* Make offset positive modulo non_ibus_length. */
+ if (offset < 0) {
+ offset += non_ibus_length;
+ }
+
+ /* We need to cycle through non-IBus sources only. */
+ while (offset > 0) {
+ do {
+ active = (active + 1) % sources.length;
+ } while (sources[active].is_ibus);
+
+ 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);
@@ -735,6 +846,14 @@ public class Indicator.Keyboard.Service : Object {
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);
@@ -762,7 +881,11 @@ public class Indicator.Keyboard.Service : Object {
[DBus (visible = false)]
public IndicatorMenu get_desktop_menu () {
if (desktop_menu == null) {
- desktop_menu = new IndicatorMenu (get_action_group ());
+ 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 ();
@@ -783,7 +906,9 @@ public class Indicator.Keyboard.Service : Object {
[DBus (visible = false)]
public IndicatorMenu get_desktop_greeter_menu () {
if (desktop_greeter_menu == null) {
- desktop_greeter_menu = new IndicatorMenu (get_action_group (), IndicatorMenu.Options.NONE);
+ var options = IndicatorMenu.Options.DCONF;
+
+ desktop_greeter_menu = new IndicatorMenu (get_action_group (), options);
((!) desktop_greeter_menu).set_sources (get_sources ());
}
@@ -791,6 +916,18 @@ public class Indicator.Keyboard.Service : Object {
}
[DBus (visible = false)]
+ 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 (!) desktop_lockscreen_menu;
+ }
+
+ [DBus (visible = false)]
private void handle_changed_visible (string key) {
update_indicator_action ();
}
@@ -798,6 +935,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 ();
}
@@ -807,6 +945,7 @@ public class Indicator.Keyboard.Service : Object {
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 ();
}
@@ -878,6 +1017,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");
@@ -898,6 +1084,7 @@ public class Indicator.Keyboard.Service : Object {
connection.export_action_group ("/com/canonical/indicator/keyboard", get_action_group ());
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);
}
diff --git a/lib/unity-session.vala b/lib/unity-session.vala
new file mode 100644
index 00000000..04bf3349
--- /dev/null
+++ b/lib/unity-session.vala
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2014 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.Unity.Session")]
+public interface UnitySession : Object {
+
+ public signal void locked ();
+ public signal void unlocked ();
+}
diff --git a/po/indicator-keyboard.pot b/po/indicator-keyboard.pot
index 38d5e005..52ce3b32 100644
--- a/po/indicator-keyboard.pot
+++ b/po/indicator-keyboard.pot
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2014-03-27 23:39+1300\n"
+"POT-Creation-Date: 2014-04-05 11:53+1300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -17,19 +17,19 @@ msgstr ""
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
-#: ../lib/main.vala:670
+#: ../lib/main.vala:706
#, c-format
msgid "%s input source"
msgstr ""
-#: ../lib/indicator-menu.vala:47
+#: ../lib/indicator-menu.vala:48
msgid "Character Map"
msgstr ""
-#: ../lib/indicator-menu.vala:48
+#: ../lib/indicator-menu.vala:49
msgid "Keyboard Layout Chart"
msgstr ""
-#: ../lib/indicator-menu.vala:49
+#: ../lib/indicator-menu.vala:50
msgid "Text Entry Settings..."
msgstr ""