aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.bzrignore2
-rw-r--r--.pc/applied-patches1
-rw-r--r--.pc/default-icon-colour.patch/lib/main.vala236
-rw-r--r--.pc/disable-experimental-non-null.patch/tests/Makefile.am18
-rw-r--r--.pc/relax-test-missing-ibus.patch/tests/main.vala675
-rw-r--r--data/Makefile.am6
-rw-r--r--debian/patches/default-icon-colour.patch14
-rw-r--r--debian/patches/disable-experimental-non-null.patch2
-rw-r--r--debian/patches/relax-test-missing-ibus.patch11
-rw-r--r--debian/patches/series1
-rw-r--r--lib/main.vala238
-rw-r--r--po/indicator-keyboard.pot8
-rw-r--r--tests/Makefile.am18
-rw-r--r--tests/indicator-keyboard-service.in2
-rwxr-xr-xtests/indicator-keyboard-test12
-rw-r--r--tests/main.vala2
16 files changed, 1003 insertions, 243 deletions
diff --git a/.bzrignore b/.bzrignore
index 66db2b25..85aabfae 100644
--- a/.bzrignore
+++ b/.bzrignore
@@ -30,6 +30,6 @@ po/POTFILES
po/stamp-it
tests/config.vala
tests/indicator-keyboard-service
-tests/indicator-keyboard-test
tests/indicator-keyboard-test.trs
+tests/indicator-keyboard-tests
tests/services/indicator-keyboard.service
diff --git a/.pc/applied-patches b/.pc/applied-patches
index 83bb2430..2a60b05c 100644
--- a/.pc/applied-patches
+++ b/.pc/applied-patches
@@ -1,2 +1,3 @@
default-icon-colour.patch
disable-experimental-non-null.patch
+relax-test-missing-ibus.patch
diff --git a/.pc/default-icon-colour.patch/lib/main.vala b/.pc/default-icon-colour.patch/lib/main.vala
index 5461814b..9ce6ca3b 100644
--- a/.pc/default-icon-colour.patch/lib/main.vala
+++ b/.pc/default-icon-colour.patch/lib/main.vala
@@ -1,6 +1,8 @@
[DBus (name = "com.canonical.indicator.keyboard")]
public class Indicator.Keyboard.Service : Object {
+ private bool use_gtk;
+ private bool use_bamf;
private MainLoop? loop;
private Settings indicator_settings;
private Settings source_settings;
@@ -21,14 +23,23 @@ public class Indicator.Keyboard.Service : Object {
private uint[]? icon_string_subscripts;
[DBus (visible = false)]
- public Service (bool force) {
+ public Service (ref unowned string[] args) {
Bus.own_name (BusType.SESSION,
"com.canonical.indicator.keyboard",
- BusNameOwnerFlags.ALLOW_REPLACEMENT | (force ? BusNameOwnerFlags.REPLACE : 0),
+ BusNameOwnerFlags.ALLOW_REPLACEMENT | ("--force" in args ? BusNameOwnerFlags.REPLACE : 0),
this.handle_bus_acquired,
null,
this.handle_name_lost);
+ this.use_gtk = "--use-gtk" in args;
+ this.use_bamf = "--use-bamf" in args;
+
+ if (this.use_gtk) {
+ this.use_gtk = Gtk.init_check (ref args);
+ } else {
+ Gdk.init (ref args);
+ }
+
this.indicator_settings = new Settings ("com.canonical.indicator.keyboard");
this.indicator_settings.changed["visible"].connect (this.handle_changed_visible);
@@ -118,17 +129,19 @@ public class Indicator.Keyboard.Service : Object {
[DBus (visible = false)]
private void update_window_sources () {
- var group_per_window = this.per_window_settings.get_boolean ("group-per-window");
-
- if (group_per_window != (this.window_sources != null)) {
- if (group_per_window) {
- this.window_sources = new Gee.HashMap<string, uint> ();
- this.matcher = Bamf.Matcher.get_default ();
- ((!) this.matcher).active_window_changed.connect (this.handle_active_window_changed);
- } else {
- ((!) this.matcher).active_window_changed.disconnect (this.handle_active_window_changed);
- this.matcher = null;
- this.window_sources = null;
+ if (this.use_bamf) {
+ var group_per_window = this.per_window_settings.get_boolean ("group-per-window");
+
+ if (group_per_window != (this.window_sources != null)) {
+ if (group_per_window) {
+ this.window_sources = new Gee.HashMap<string, uint> ();
+ this.matcher = Bamf.Matcher.get_default ();
+ ((!) this.matcher).active_window_changed.connect (this.handle_active_window_changed);
+ } else {
+ ((!) this.matcher).active_window_changed.disconnect (this.handle_active_window_changed);
+ this.matcher = null;
+ this.window_sources = null;
+ }
}
}
}
@@ -158,99 +171,113 @@ public class Indicator.Keyboard.Service : Object {
}
[DBus (visible = false)]
- private Gtk.StyleContext get_style_context () {
- var context = new Gtk.StyleContext ();
+ private Gtk.StyleContext? get_style_context () {
+ Gtk.StyleContext? context = null;
+
+ if (this.use_gtk) {
+ Gdk.Screen? screen = Gdk.Screen.get_default ();
- context.set_screen (Gdk.Screen.get_default ());
+ if (screen != null) {
+ context = new Gtk.StyleContext ();
+ ((!) context).set_screen ((!) screen);
- var path = new Gtk.WidgetPath ();
- path.append_type (typeof (Gtk.MenuItem));
- context.set_path (path);
+ var path = new Gtk.WidgetPath ();
+ path.append_type (typeof (Gtk.MenuItem));
+ ((!) context).set_path (path);
+ }
+ }
return context;
}
[DBus (visible = false)]
- protected virtual Icon create_icon (string? text, uint subscript) {
- const int W = 22;
- const int H = 22;
- const int w = 20;
- const int h = 20;
- const double R = 2.0;
- const double TEXT_SIZE = 12.0;
- const double SUBSCRIPT_SIZE = 8.0;
-
- Pango.FontDescription description;
+ protected virtual Icon? create_icon (string? text, uint subscript) {
+ Icon? icon = null;
+
var style = get_style_context ();
- var colour = style.get_color (Gtk.StateFlags.NORMAL);
- style.get (Gtk.StateFlags.NORMAL, Gtk.STYLE_PROPERTY_FONT, out description);
-
- var surface = new Cairo.ImageSurface (Cairo.Format.ARGB32, W, H);
- var context = new Cairo.Context (surface);
-
- context.translate (0.5 * (W - w), 0.5 * (H - h));
-
- context.new_sub_path ();
- context.arc (R, R, R, Math.PI, -0.5 * Math.PI);
- context.arc (w - R, R, R, -0.5 * Math.PI, 0);
- context.arc (w - R, h - R, R, 0, 0.5 * Math.PI);
- context.arc (R, h - R, R, 0.5 * Math.PI, Math.PI);
- context.close_path ();
-
- context.set_source_rgba (colour.red, colour.green, colour.blue, colour.alpha);
- context.fill ();
- context.set_operator (Cairo.Operator.CLEAR);
-
- if (text != null) {
- var text_layout = Pango.cairo_create_layout (context);
- text_layout.set_alignment (Pango.Alignment.CENTER);
- description.set_absolute_size (Pango.units_from_double (TEXT_SIZE));
- text_layout.set_font_description (description);
- text_layout.set_text ((!) text, -1);
- Pango.cairo_update_layout (context, text_layout);
- int text_width;
- int text_height;
- text_layout.get_pixel_size (out text_width, out text_height);
-
- if (subscript > 0) {
- var subscript_layout = Pango.cairo_create_layout (context);
- subscript_layout.set_alignment (Pango.Alignment.CENTER);
- description.set_absolute_size (Pango.units_from_double (SUBSCRIPT_SIZE));
- subscript_layout.set_font_description (description);
- subscript_layout.set_text (@"$subscript", -1);
- Pango.cairo_update_layout (context, subscript_layout);
- int subscript_width;
- int subscript_height;
- subscript_layout.get_pixel_size (out subscript_width, out subscript_height);
-
- context.save ();
- context.translate ((w - (text_width + subscript_width)) / 2, (h - text_height) / 2);
- Pango.cairo_layout_path (context, text_layout);
- context.fill ();
- context.restore ();
-
- context.save ();
- context.translate ((w + (text_width - subscript_width)) / 2, (h + text_height) / 2 - subscript_height);
- Pango.cairo_layout_path (context, subscript_layout);
- context.fill ();
- context.restore ();
- } else {
- context.save ();
- context.translate ((w - text_width) / 2, (h - text_height) / 2);
- Pango.cairo_layout_path (context, text_layout);
- context.fill ();
- context.restore ();
+
+ if (style != null) {
+ const int W = 22;
+ const int H = 22;
+ const int w = 20;
+ const int h = 20;
+ const double R = 2.0;
+ const double TEXT_SIZE = 12.0;
+ const double SUBSCRIPT_SIZE = 8.0;
+
+ Pango.FontDescription description;
+ var colour = ((!) style).get_color (Gtk.StateFlags.NORMAL);
+ ((!) style).get (Gtk.StateFlags.NORMAL, Gtk.STYLE_PROPERTY_FONT, out description);
+
+ var surface = new Cairo.ImageSurface (Cairo.Format.ARGB32, W, H);
+ var context = new Cairo.Context (surface);
+
+ context.translate (0.5 * (W - w), 0.5 * (H - h));
+
+ context.new_sub_path ();
+ context.arc (R, R, R, Math.PI, -0.5 * Math.PI);
+ context.arc (w - R, R, R, -0.5 * Math.PI, 0);
+ context.arc (w - R, h - R, R, 0, 0.5 * Math.PI);
+ context.arc (R, h - R, R, 0.5 * Math.PI, Math.PI);
+ context.close_path ();
+
+ context.set_source_rgba (colour.red, colour.green, colour.blue, colour.alpha);
+ context.fill ();
+ context.set_operator (Cairo.Operator.CLEAR);
+
+ if (text != null) {
+ var text_layout = Pango.cairo_create_layout (context);
+ text_layout.set_alignment (Pango.Alignment.CENTER);
+ description.set_absolute_size (Pango.units_from_double (TEXT_SIZE));
+ text_layout.set_font_description (description);
+ text_layout.set_text ((!) text, -1);
+ Pango.cairo_update_layout (context, text_layout);
+ int text_width;
+ int text_height;
+ text_layout.get_pixel_size (out text_width, out text_height);
+
+ if (subscript > 0) {
+ var subscript_layout = Pango.cairo_create_layout (context);
+ subscript_layout.set_alignment (Pango.Alignment.CENTER);
+ description.set_absolute_size (Pango.units_from_double (SUBSCRIPT_SIZE));
+ subscript_layout.set_font_description (description);
+ subscript_layout.set_text (@"$subscript", -1);
+ Pango.cairo_update_layout (context, subscript_layout);
+ int subscript_width;
+ int subscript_height;
+ subscript_layout.get_pixel_size (out subscript_width, out subscript_height);
+
+ context.save ();
+ context.translate ((w - (text_width + subscript_width)) / 2, (h - text_height) / 2);
+ Pango.cairo_layout_path (context, text_layout);
+ context.fill ();
+ context.restore ();
+
+ context.save ();
+ context.translate ((w + (text_width - subscript_width)) / 2, (h + text_height) / 2 - subscript_height);
+ Pango.cairo_layout_path (context, subscript_layout);
+ context.fill ();
+ context.restore ();
+ } else {
+ context.save ();
+ context.translate ((w - text_width) / 2, (h - text_height) / 2);
+ Pango.cairo_layout_path (context, text_layout);
+ context.fill ();
+ context.restore ();
+ }
}
- }
- var buffer = new ByteArray ();
+ var buffer = new ByteArray ();
+
+ surface.write_to_png_stream ((data) => {
+ buffer.append (data);
+ return Cairo.Status.SUCCESS;
+ });
- surface.write_to_png_stream ((data) => {
- buffer.append (data);
- return Cairo.Status.SUCCESS;
- });
+ icon = new BytesIcon (ByteArray.free_to_bytes ((owned) buffer));
+ }
- return new BytesIcon (ByteArray.free_to_bytes ((owned) buffer));
+ return icon;
}
[DBus (visible = false)]
@@ -387,15 +414,19 @@ public class Indicator.Keyboard.Service : Object {
icon_name = @"indicator-keyboard-$((!) icon_string)-$icon_subscript";
}
- var icon_theme = Gtk.IconTheme.get_default ();
- Gtk.IconInfo? icon_info = icon_theme.lookup_icon (icon_name, 22, 0);
+ if (this.use_gtk) {
+ var icon_theme = Gtk.IconTheme.get_default ();
+ Gtk.IconInfo? icon_info = icon_theme.lookup_icon (icon_name, 22, 0);
- if (icon_info != null) {
- try {
- this.icons[index] = Icon.new_for_string (((!) icon_info).get_filename ());
- } catch (Error error) {
- this.icons[index] = null;
+ if (icon_info != null) {
+ try {
+ this.icons[index] = Icon.new_for_string (((!) icon_info).get_filename ());
+ } catch (Error error) {
+ this.icons[index] = null;
+ }
}
+ } else {
+ this.icons[index] = new ThemedIcon (icon_name);
}
}
@@ -717,8 +748,7 @@ public class Indicator.Keyboard.Service : Object {
[DBus (visible = false)]
public static int main (string[] args) {
- Gtk.init (ref args);
- new Service ("--force" in args);
+ new Service (ref args);
return 0;
}
}
diff --git a/.pc/disable-experimental-non-null.patch/tests/Makefile.am b/.pc/disable-experimental-non-null.patch/tests/Makefile.am
index b4e80c02..e930b069 100644
--- a/.pc/disable-experimental-non-null.patch/tests/Makefile.am
+++ b/.pc/disable-experimental-non-null.patch/tests/Makefile.am
@@ -1,6 +1,6 @@
TESTS = indicator-keyboard-test
-check_PROGRAMS = indicator-keyboard-test
+check_PROGRAMS = indicator-keyboard-tests
AM_CFLAGS = -w
AM_LDFLAGS = -lm
@@ -8,11 +8,11 @@ AM_VALAFLAGS = --enable-experimental-non-null \
--metadatadir $(top_srcdir)/deps \
--vapidir $(top_srcdir)/deps
-indicator_keyboard_test_SOURCES = main.vala \
- config.vala
-indicator_keyboard_test_VALAFLAGS = $(AM_VALAFLAGS) \
- --pkg gio-2.0
-indicator_keyboard_test_CFLAGS = $(AM_CFLAGS) \
- $(GIO_CFLAGS)
-indicator_keyboard_test_LDFLAGS = $(AM_LDFLAGS) \
- $(GIO_LIBS)
+indicator_keyboard_tests_SOURCES = main.vala \
+ config.vala
+indicator_keyboard_tests_VALAFLAGS = $(AM_VALAFLAGS) \
+ --pkg gio-2.0
+indicator_keyboard_tests_CFLAGS = $(AM_CFLAGS) \
+ $(GIO_CFLAGS)
+indicator_keyboard_tests_LDFLAGS = $(AM_LDFLAGS) \
+ $(GIO_LIBS)
diff --git a/.pc/relax-test-missing-ibus.patch/tests/main.vala b/.pc/relax-test-missing-ibus.patch/tests/main.vala
new file mode 100644
index 00000000..4e121fcd
--- /dev/null
+++ b/.pc/relax-test-missing-ibus.patch/tests/main.vala
@@ -0,0 +1,675 @@
+const int TIMEOUT_S = 1;
+const int TIMEOUT_MS = 1000;
+
+[DBus (name = "com.canonical.indicator.keyboard.test")]
+public class Service : Object {
+
+ [DBus (visible = false)]
+ private string? _command;
+
+ [DBus (visible = false)]
+ public string? command {
+ get { return _command; }
+ }
+
+ public void execute (string command) {
+ this._command = command;
+
+ var pspec = this.get_class ().find_property ("command");
+
+ if (pspec != null) {
+ this.notify["command"] ((!) pspec);
+ }
+ }
+}
+
+struct Fixture {
+ TestDBus? bus;
+ uint service_name;
+ DBusConnection? connection;
+ Service? service;
+ uint object_name;
+}
+
+static void start_service (Fixture *fixture) {
+ if (fixture.connection != null) {
+ try {
+ fixture.service = new Service ();
+ fixture.object_name = ((!) fixture.connection).register_object ("/com/canonical/indicator/keyboard/test", fixture.service);
+ } catch (IOError error) {
+ fixture.connection = null;
+ fixture.service = null;
+ fixture.object_name = 0;
+
+ Test.message ("error: %s", error.message);
+ Test.fail ();
+ }
+ }
+}
+
+static void begin_test (void *data) {
+ var fixture = (Fixture *) data;
+
+ fixture.bus = new TestDBus (TestDBusFlags.NONE);
+ ((!) fixture.bus).add_service_dir (SERVICE_DIR);
+ ((!) fixture.bus).up ();
+
+ var loop = new MainLoop (null, false);
+
+ fixture.service_name = Bus.own_name (BusType.SESSION,
+ "com.canonical.indicator.keyboard.test",
+ BusNameOwnerFlags.ALLOW_REPLACEMENT | BusNameOwnerFlags.REPLACE,
+ (connection, name) => {
+ if (loop.is_running ()) {
+ fixture.connection = connection;
+
+ start_service (fixture);
+
+ loop.quit ();
+ }
+ },
+ null,
+ (connection, name) => {
+ if (loop.is_running ()) {
+ fixture.connection = null;
+ fixture.service = null;
+ fixture.object_name = 0;
+
+ loop.quit ();
+ }
+ });
+
+ loop.run ();
+
+ if (fixture.connection == null) {
+ Test.message ("error: Unable to connect to com.canonical.indicator.keyboard.test.");
+ Test.fail ();
+ }
+}
+
+static void end_test (void *data) {
+ var fixture = (Fixture *) data;
+
+ if (fixture.object_name != 0) {
+ ((!) fixture.connection).unregister_object (fixture.object_name);
+ fixture.object_name = 0;
+ }
+
+ if (fixture.service_name != 0) {
+ Bus.unown_name (fixture.service_name);
+ fixture.service_name = 0;
+ }
+
+ fixture.service = null;
+ fixture.connection = null;
+
+ if (fixture.bus != null) {
+ ((!) fixture.bus).down ();
+ fixture.bus = null;
+ }
+}
+
+static void test_activate_input_source (void *data) {
+ var fixture = (Fixture *) data;
+
+ if (fixture.object_name == 0) {
+ Test.message ("error: Test fixture not initialized.");
+ Test.fail ();
+ return;
+ }
+
+ try {
+ var current = 0;
+ var sources = "[('xkb', 'us'), ('xkb', 'ca+eng'), ('xkb', 'epo'), ('ibus', 'pinyin')]";
+ Process.spawn_command_line_sync (@"gsettings set org.gnome.desktop.input-sources current $current");
+ Process.spawn_command_line_sync (@"gsettings set org.gnome.desktop.input-sources sources \"$sources\"");
+ } catch (SpawnError error) {
+ Test.message ("error: %s", error.message);
+ Test.fail ();
+ return;
+ }
+
+ var action_group = DBusActionGroup.get ((!) fixture.connection,
+ "com.canonical.indicator.keyboard",
+ "/com/canonical/indicator/keyboard");
+ var loop = new MainLoop (null, false);
+ var signal_name = action_group.action_state_changed["current"].connect ((action, state) => {
+ loop.quit ();
+ });
+
+ action_group.list_actions ();
+ action_group.activate_action ("current", new Variant.uint32 (2));
+
+ var source = Timeout.add_seconds (TIMEOUT_S, () => { loop.quit (); return false; });
+ loop.run ();
+ Source.remove (source);
+ action_group.disconnect (signal_name);
+
+ var state = action_group.get_action_state ("current");
+ var current = state.get_uint32 ();
+ assert (current == 2);
+
+ try {
+ string output;
+ Process.spawn_command_line_sync ("gsettings get org.gnome.desktop.input-sources current", out output);
+ assert (strcmp (output, "uint32 2\n") == 0);
+ } catch (SpawnError error) {
+ Test.message ("error: %s", error.message);
+ Test.fail ();
+ return;
+ }
+}
+
+static void test_activate_character_map (void *data) {
+ var fixture = (Fixture *) data;
+
+ if (fixture.object_name == 0) {
+ Test.message ("error: Test fixture not initialized.");
+ Test.fail ();
+ return;
+ }
+
+ var action_group = DBusActionGroup.get ((!) fixture.connection,
+ "com.canonical.indicator.keyboard",
+ "/com/canonical/indicator/keyboard");
+ var loop = new MainLoop (null, false);
+ var signal_name = ((!) fixture.service).notify["command"].connect ((pspec) => {
+ loop.quit ();
+ });
+
+ action_group.activate_action ("map", null);
+
+ var source = Timeout.add_seconds (TIMEOUT_S, () => { loop.quit (); return false; });
+ loop.run ();
+ Source.remove (source);
+ ((!) fixture.service).disconnect (signal_name);
+
+ assert (strcmp ((!) ((!) fixture.service).command, "'gucharmap '") == 0);
+}
+
+static void test_activate_keyboard_layout_chart (void *data) {
+ var fixture = (Fixture *) data;
+
+ if (fixture.object_name == 0) {
+ Test.message ("error: Test fixture not initialized.");
+ Test.fail ();
+ return;
+ }
+
+ try {
+ var current = 1;
+ var sources = "[('xkb', 'us'), ('xkb', 'ca+eng'), ('xkb', 'epo'), ('ibus', 'pinyin')]";
+ Process.spawn_command_line_sync (@"gsettings set org.gnome.desktop.input-sources current $current");
+ Process.spawn_command_line_sync (@"gsettings set org.gnome.desktop.input-sources sources \"$sources\"");
+ } catch (SpawnError error) {
+ Test.message ("error: %s", error.message);
+ Test.fail ();
+ return;
+ }
+
+ var action_group = DBusActionGroup.get ((!) fixture.connection,
+ "com.canonical.indicator.keyboard",
+ "/com/canonical/indicator/keyboard");
+ var loop = new MainLoop (null, false);
+ var signal_name = ((!) fixture.service).notify["command"].connect ((pspec) => {
+ loop.quit ();
+ });
+
+ action_group.activate_action ("chart", null);
+
+ var source = Timeout.add_seconds (TIMEOUT_S, () => { loop.quit (); return false; });
+ loop.run ();
+ Source.remove (source);
+ ((!) fixture.service).disconnect (signal_name);
+
+ assert (strcmp ((!) ((!) fixture.service).command, "'gkbd-keyboard-display -l ca\teng'") == 0);
+}
+
+static void test_activate_text_entry_settings (void *data) {
+ var fixture = (Fixture *) data;
+
+ if (fixture.object_name == 0) {
+ Test.message ("error: Test fixture not initialized.");
+ Test.fail ();
+ return;
+ }
+
+ var action_group = DBusActionGroup.get ((!) fixture.connection,
+ "com.canonical.indicator.keyboard",
+ "/com/canonical/indicator/keyboard");
+ var loop = new MainLoop (null, false);
+ var signal_name = ((!) fixture.service).notify["command"].connect ((pspec) => {
+ loop.quit ();
+ });
+
+ action_group.activate_action ("settings", null);
+
+ var source = Timeout.add_seconds (TIMEOUT_S, () => { loop.quit (); return false; });
+ loop.run ();
+ Source.remove (source);
+ ((!) fixture.service).disconnect (signal_name);
+
+ assert (strcmp ((!) ((!) fixture.service).command, "'gnome-control-center region layouts'") == 0);
+}
+
+static void test_migration (void *data) {
+ var fixture = (Fixture *) data;
+
+ if (fixture.object_name == 0) {
+ Test.message ("error: Test fixture not initialized.");
+ Test.fail ();
+ return;
+ }
+
+ try {
+ var migrated = false;
+ var sources = "[('xkb', 'us')]";
+ var layouts = "['us', 'ca\teng', 'epo']";
+ Process.spawn_command_line_sync (@"gsettings set com.canonical.indicator.keyboard migrated $migrated");
+ Process.spawn_command_line_sync (@"gsettings set org.gnome.desktop.input-sources sources \"$sources\"");
+ Process.spawn_command_line_sync (@"gsettings set org.gnome.libgnomekbd.keyboard layouts \"$layouts\"");
+ } catch (SpawnError error) {
+ Test.message ("error: %s", error.message);
+ Test.fail ();
+ return;
+ }
+
+ try {
+ var cancellable = new Cancellable ();
+
+ var source = Timeout.add_seconds (TIMEOUT_S, () => { cancellable.cancel (); return false; });
+
+ var dbus_proxy = new DBusProxy.sync ((!) fixture.connection,
+ DBusProxyFlags.NONE,
+ null,
+ "org.freedesktop.DBus",
+ "/",
+ "org.freedesktop.DBus",
+ cancellable);
+
+ Source.remove (source);
+
+ if (cancellable.is_cancelled ()) {
+ Test.message ("error: Unable to connect to org.freedesktop.DBus.");
+ Test.fail ();
+ return;
+ }
+
+ dbus_proxy.call_sync ("StartServiceByName", new Variant ("(su)", "com.canonical.indicator.keyboard", 0), DBusCallFlags.NONE, TIMEOUT_MS);
+ } catch (Error error) {
+ Test.message ("error: %s", error.message);
+ Test.fail ();
+ return;
+ }
+
+ try {
+ string sources;
+ Process.spawn_command_line_sync ("gsettings get org.gnome.desktop.input-sources sources", out sources);
+ assert (strcmp (sources, "[('xkb', 'us'), ('xkb', 'ca+eng'), ('xkb', 'epo')]\n") == 0);
+ } catch (SpawnError error) {
+ Test.message ("error: %s", error.message);
+ Test.fail ();
+ return;
+ }
+}
+
+static void test_no_migration (void *data) {
+ var fixture = (Fixture *) data;
+
+ if (fixture.object_name == 0) {
+ Test.message ("error: Test fixture not initialized.");
+ Test.fail ();
+ return;
+ }
+
+ try {
+ var migrated = true;
+ var sources = "[('xkb', 'us')]";
+ var layouts = "['us', 'ca\teng', 'epo']";
+ Process.spawn_command_line_sync (@"gsettings set com.canonical.indicator.keyboard migrated $migrated");
+ Process.spawn_command_line_sync (@"gsettings set org.gnome.desktop.input-sources sources \"$sources\"");
+ Process.spawn_command_line_sync (@"gsettings set org.gnome.libgnomekbd.keyboard layouts \"$layouts\"");
+ } catch (SpawnError error) {
+ Test.message ("error: %s", error.message);
+ Test.fail ();
+ return;
+ }
+
+ try {
+ var cancellable = new Cancellable ();
+
+ var source = Timeout.add_seconds (TIMEOUT_S, () => { cancellable.cancel (); return false; });
+
+ var dbus_proxy = new DBusProxy.sync ((!) fixture.connection,
+ DBusProxyFlags.NONE,
+ null,
+ "org.freedesktop.DBus",
+ "/",
+ "org.freedesktop.DBus",
+ cancellable);
+
+ Source.remove (source);
+
+ if (cancellable.is_cancelled ()) {
+ Test.message ("error: Unable to connect to org.freedesktop.DBus.");
+ Test.fail ();
+ return;
+ }
+
+ dbus_proxy.call_sync ("StartServiceByName", new Variant ("(su)", "com.canonical.indicator.keyboard", 0), DBusCallFlags.NONE, TIMEOUT_MS);
+ } catch (Error error) {
+ Test.message ("error: %s", error.message);
+ Test.fail ();
+ return;
+ }
+
+ try {
+ string sources;
+ Process.spawn_command_line_sync ("gsettings get org.gnome.desktop.input-sources sources", out sources);
+ assert (strcmp (sources, "[('xkb', 'us')]\n") == 0);
+ } catch (SpawnError error) {
+ Test.message ("error: %s", error.message);
+ Test.fail ();
+ return;
+ }
+}
+
+static void test_update_visible (void *data) {
+ var fixture = (Fixture *) data;
+
+ if (fixture.object_name == 0) {
+ Test.message ("error: Test fixture not initialized.");
+ Test.fail ();
+ return;
+ }
+
+ bool visible;
+
+ try {
+ visible = true;
+ Process.spawn_command_line_sync (@"gsettings set com.canonical.indicator.keyboard visible $visible");
+ } catch (SpawnError error) {
+ Test.message ("error: %s", error.message);
+ Test.fail ();
+ return;
+ }
+
+ var action_group = DBusActionGroup.get ((!) fixture.connection,
+ "com.canonical.indicator.keyboard",
+ "/com/canonical/indicator/keyboard");
+ var loop = new MainLoop (null, false);
+ var signal_name = action_group.action_added["indicator"].connect ((action) => {
+ loop.quit ();
+ });
+
+ action_group.list_actions ();
+
+ var source = Timeout.add_seconds (TIMEOUT_S, () => { loop.quit (); return false; });
+ loop.run ();
+ Source.remove (source);
+ action_group.disconnect (signal_name);
+
+ var state = action_group.get_action_state ("indicator");
+ assert (state.lookup ("visible", "b", out visible));
+ assert (visible);
+
+ loop = new MainLoop (null, false);
+ signal_name = action_group.action_state_changed["indicator"].connect ((action, state) => {
+ loop.quit ();
+ });
+
+ try {
+ visible = false;
+ Process.spawn_command_line_sync (@"gsettings set com.canonical.indicator.keyboard visible $visible");
+ } catch (SpawnError error) {
+ Test.message ("error: %s", error.message);
+ Test.fail ();
+ return;
+ }
+
+ source = Timeout.add_seconds (TIMEOUT_S, () => { loop.quit (); return false; });
+ loop.run ();
+ Source.remove (source);
+ action_group.disconnect (signal_name);
+
+ state = action_group.get_action_state ("indicator");
+ assert (state.lookup ("visible", "b", out visible));
+ assert (!visible);
+
+ loop = new MainLoop (null, false);
+ signal_name = action_group.action_state_changed["indicator"].connect ((action, state) => {
+ loop.quit ();
+ });
+
+ try {
+ visible = true;
+ Process.spawn_command_line_sync (@"gsettings set com.canonical.indicator.keyboard visible $visible");
+ } catch (SpawnError error) {
+ Test.message ("error: %s", error.message);
+ Test.fail ();
+ return;
+ }
+
+ source = Timeout.add_seconds (TIMEOUT_S, () => { loop.quit (); return false; });
+ loop.run ();
+ Source.remove (source);
+ action_group.disconnect (signal_name);
+
+ state = action_group.get_action_state ("indicator");
+ assert (state.lookup ("visible", "b", out visible));
+ assert (visible);
+}
+
+static void test_update_input_source (void *data) {
+ var fixture = (Fixture *) data;
+
+ if (fixture.object_name == 0) {
+ Test.message ("error: Test fixture not initialized.");
+ Test.fail ();
+ return;
+ }
+
+ try {
+ var current = 0;
+ var sources = "[('xkb', 'us'), ('xkb', 'ca+eng'), ('xkb', 'epo'), ('ibus', 'pinyin')]";
+ Process.spawn_command_line_sync (@"gsettings set org.gnome.desktop.input-sources current $current");
+ Process.spawn_command_line_sync (@"gsettings set org.gnome.desktop.input-sources sources \"$sources\"");
+ } catch (SpawnError error) {
+ Test.message ("error: %s", error.message);
+ Test.fail ();
+ return;
+ }
+
+ var action_group = DBusActionGroup.get ((!) fixture.connection,
+ "com.canonical.indicator.keyboard",
+ "/com/canonical/indicator/keyboard");
+ var loop = new MainLoop (null, false);
+ var signal_name = action_group.action_state_changed["current"].connect ((action, state) => {
+ loop.quit ();
+ });
+
+ action_group.list_actions ();
+
+ try {
+ var current = 1;
+ Process.spawn_command_line_sync (@"gsettings set org.gnome.desktop.input-sources current $current");
+ } catch (SpawnError error) {
+ Test.message ("error: %s", error.message);
+ Test.fail ();
+ return;
+ }
+
+ var source = Timeout.add_seconds (TIMEOUT_S, () => { loop.quit (); return false; });
+ loop.run ();
+ Source.remove (source);
+ action_group.disconnect (signal_name);
+
+ var state = action_group.get_action_state ("current");
+ var current = state.get_uint32 ();
+ assert (current == 1);
+
+ try {
+ string output;
+ Process.spawn_command_line_sync ("gsettings get org.gnome.desktop.input-sources current", out output);
+ assert (strcmp (output, "uint32 1\n") == 0);
+ } catch (SpawnError error) {
+ Test.message ("error: %s", error.message);
+ Test.fail ();
+ return;
+ }
+
+ loop = new MainLoop (null, false);
+ signal_name = action_group.action_state_changed["current"].connect ((action, state) => {
+ loop.quit ();
+ });
+
+ try {
+ current = 0;
+ Process.spawn_command_line_sync (@"gsettings set org.gnome.desktop.input-sources current $current");
+ } catch (SpawnError error) {
+ Test.message ("error: %s", error.message);
+ Test.fail ();
+ return;
+ }
+
+ source = Timeout.add_seconds (TIMEOUT_S, () => { loop.quit (); return false; });
+ loop.run ();
+ Source.remove (source);
+ action_group.disconnect (signal_name);
+
+ state = action_group.get_action_state ("current");
+ current = state.get_uint32 ();
+ assert (current == 0);
+
+ try {
+ string output;
+ Process.spawn_command_line_sync ("gsettings get org.gnome.desktop.input-sources current", out output);
+ assert (strcmp (output, "uint32 0\n") == 0);
+ } catch (SpawnError error) {
+ Test.message ("error: %s", error.message);
+ Test.fail ();
+ return;
+ }
+}
+
+static void test_update_input_sources (void *data) {
+ var fixture = (Fixture *) data;
+
+ if (fixture.object_name == 0) {
+ Test.message ("error: Test fixture not initialized.");
+ Test.fail ();
+ return;
+ }
+
+ try {
+ var current = 0;
+ var sources = "[('xkb', 'us')]";
+ Process.spawn_command_line_sync (@"gsettings set org.gnome.desktop.input-sources current $current");
+ Process.spawn_command_line_sync (@"gsettings set org.gnome.desktop.input-sources sources \"$sources\"");
+ } catch (SpawnError error) {
+ Test.message ("error: %s", error.message);
+ Test.fail ();
+ return;
+ }
+
+ var menu_model = DBusMenuModel.get ((!) fixture.connection,
+ "com.canonical.indicator.keyboard",
+ "/com/canonical/indicator/keyboard/desktop");
+ var loop = new MainLoop (null, false);
+ var signal_name = menu_model.items_changed.connect ((position, removed, added) => {
+ loop.quit ();
+ });
+
+ menu_model.get_n_items ();
+
+ var source = Timeout.add_seconds (TIMEOUT_S, () => { loop.quit (); return false; });
+ loop.run ();
+ Source.remove (source);
+ menu_model.disconnect (signal_name);
+
+ var menu = menu_model.get_item_link (0, Menu.LINK_SUBMENU);
+ loop = new MainLoop (null, false);
+ signal_name = menu.items_changed.connect ((position, removed, added) => {
+ loop.quit ();
+ });
+
+ menu.get_n_items ();
+
+ source = Timeout.add_seconds (TIMEOUT_S, () => { loop.quit (); return false; });
+ loop.run ();
+ Source.remove (source);
+ menu.disconnect (signal_name);
+
+ var section = menu.get_item_link (0, Menu.LINK_SECTION);
+ loop = new MainLoop (null, false);
+ signal_name = section.items_changed.connect ((position, removed, added) => {
+ loop.quit ();
+ });
+
+ section.get_n_items ();
+
+ source = Timeout.add_seconds (TIMEOUT_S, () => { loop.quit (); return false; });
+ loop.run ();
+ Source.remove (source);
+ section.disconnect (signal_name);
+
+ string label;
+
+ assert (section.get_n_items () == 1);
+ section.get_item_attribute (0, Menu.ATTRIBUTE_LABEL, "s", out label);
+ assert (strcmp (label, "English (US)") == 0);
+
+ loop = new MainLoop (null, false);
+ signal_name = section.items_changed.connect ((position, removed, added) => {
+ if (section.get_n_items () == 4) {
+ loop.quit ();
+ }
+ });
+
+ try {
+ var sources = "[('xkb', 'us'), ('xkb', 'ca+eng'), ('xkb', 'epo'), ('ibus', 'pinyin')]";
+ Process.spawn_command_line_sync (@"gsettings set org.gnome.desktop.input-sources sources \"$sources\"");
+ } catch (SpawnError error) {
+ Test.message ("error: %s", error.message);
+ Test.fail ();
+ return;
+ }
+
+ source = Timeout.add_seconds (TIMEOUT_S, () => { loop.quit (); return false; });
+ loop.run ();
+ Source.remove (source);
+ section.disconnect (signal_name);
+
+ assert (section.get_n_items () == 4);
+ section.get_item_attribute (0, Menu.ATTRIBUTE_LABEL, "s", out label);
+ assert (strcmp (label, "English (US)") == 0);
+ section.get_item_attribute (1, Menu.ATTRIBUTE_LABEL, "s", out label);
+ assert (strcmp (label, "English (Canada)") == 0);
+ section.get_item_attribute (2, Menu.ATTRIBUTE_LABEL, "s", out label);
+ assert (strcmp (label, "Esperanto") == 0);
+ section.get_item_attribute (3, Menu.ATTRIBUTE_LABEL, "s", out label);
+ assert (strcmp (label, "Pinyin") == 0);
+}
+
+public int main (string[] args) {
+ Environment.set_variable ("DCONF_PROFILE", DCONF_PROFILE, true);
+ Environment.set_variable ("LC_ALL", "C", true);
+
+ Test.init (ref args, null);
+
+ var suite = new TestSuite ("indicator-keyboard");
+
+ suite.add (new TestCase ("activate-input-source", begin_test, test_activate_input_source, end_test, sizeof (Fixture)));
+ suite.add (new TestCase ("activate-character-map", begin_test, test_activate_character_map, end_test, sizeof (Fixture)));
+ suite.add (new TestCase ("activate-keyboard-layout-chart", begin_test, test_activate_keyboard_layout_chart, end_test, sizeof (Fixture)));
+ suite.add (new TestCase ("activate-text-entry-settings", begin_test, test_activate_text_entry_settings, end_test, sizeof (Fixture)));
+ suite.add (new TestCase ("migration", begin_test, test_migration, end_test, sizeof (Fixture)));
+ suite.add (new TestCase ("no-migration", begin_test, test_no_migration, end_test, sizeof (Fixture)));
+ suite.add (new TestCase ("update-visible", begin_test, test_update_visible, end_test, sizeof (Fixture)));
+ suite.add (new TestCase ("update-input-source", begin_test, test_update_input_source, end_test, sizeof (Fixture)));
+ suite.add (new TestCase ("update-input-sources", begin_test, test_update_input_sources, end_test, sizeof (Fixture)));
+
+ TestSuite.get_root ().add_suite (suite);
+
+ return Test.run ();
+}
diff --git a/data/Makefile.am b/data/Makefile.am
index 6157e491..885f5a60 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -34,9 +34,9 @@ servicedir = $(DBUS_SERVICE_DIR)
dist_service_DATA = indicator-keyboard.service
indicator-keyboard.service:
- $(AM_V_GEN) (echo '[D-BUS Service]'; \
- echo 'Name=com.canonical.indicator.keyboard'; \
- echo 'Exec=${libexecdir}/indicator-keyboard-service') > $@.tmp && \
+ $(AM_V_GEN) (echo '[D-BUS Service]'; \
+ echo 'Name=com.canonical.indicator.keyboard'; \
+ echo 'Exec=${libexecdir}/indicator-keyboard-service --use-gtk --use-bamf') > $@.tmp && \
mv $@.tmp $@
indicatordir = $(INDICATOR_DIR)
diff --git a/debian/patches/default-icon-colour.patch b/debian/patches/default-icon-colour.patch
index 0f1de6c0..e916f0a2 100644
--- a/debian/patches/default-icon-colour.patch
+++ b/debian/patches/default-icon-colour.patch
@@ -1,10 +1,10 @@
--- a/lib/main.vala
+++ b/lib/main.vala
-@@ -183,6 +183,7 @@
- Pango.FontDescription description;
- var style = get_style_context ();
- var colour = style.get_color (Gtk.StateFlags.NORMAL);
-+ colour = { 0.5, 0.5, 0.5, 1.0 };
- style.get (Gtk.StateFlags.NORMAL, Gtk.STYLE_PROPERTY_FONT, out description);
+@@ -207,6 +207,7 @@
- var surface = new Cairo.ImageSurface (Cairo.Format.ARGB32, W, H);
+ Pango.FontDescription description;
+ var colour = ((!) style).get_color (Gtk.StateFlags.NORMAL);
++ colour = { 0.5, 0.5, 0.5, 1.0 };
+ ((!) style).get (Gtk.StateFlags.NORMAL, Gtk.STYLE_PROPERTY_FONT, out description);
+
+ var surface = new Cairo.ImageSurface (Cairo.Format.ARGB32, W, H);
diff --git a/debian/patches/disable-experimental-non-null.patch b/debian/patches/disable-experimental-non-null.patch
index 69698d37..2d2329c3 100644
--- a/debian/patches/disable-experimental-non-null.patch
+++ b/debian/patches/disable-experimental-non-null.patch
@@ -9,7 +9,7 @@
+AM_VALAFLAGS = --metadatadir $(top_srcdir)/deps \
--vapidir $(top_srcdir)/deps
- indicator_keyboard_test_SOURCES = main.vala \
+ indicator_keyboard_tests_SOURCES = main.vala \
--- a/tests/main.vala
+++ b/tests/main.vala
@@ -146,7 +146,7 @@
diff --git a/debian/patches/relax-test-missing-ibus.patch b/debian/patches/relax-test-missing-ibus.patch
new file mode 100644
index 00000000..5b384579
--- /dev/null
+++ b/debian/patches/relax-test-missing-ibus.patch
@@ -0,0 +1,11 @@
+--- a/tests/main.vala
++++ b/tests/main.vala
+@@ -648,7 +648,7 @@
+ section.get_item_attribute (2, Menu.ATTRIBUTE_LABEL, "s", out label);
+ assert (strcmp (label, "Esperanto") == 0);
+ section.get_item_attribute (3, Menu.ATTRIBUTE_LABEL, "s", out label);
+- assert (strcmp (label, "Pinyin") == 0);
++ assert (label.ascii_casecmp ("Pinyin") == 0);
+ }
+
+ public int main (string[] args) {
diff --git a/debian/patches/series b/debian/patches/series
index 83bb2430..2a60b05c 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,2 +1,3 @@
default-icon-colour.patch
disable-experimental-non-null.patch
+relax-test-missing-ibus.patch
diff --git a/lib/main.vala b/lib/main.vala
index 7e2a6f32..bb908340 100644
--- a/lib/main.vala
+++ b/lib/main.vala
@@ -1,6 +1,8 @@
[DBus (name = "com.canonical.indicator.keyboard")]
public class Indicator.Keyboard.Service : Object {
+ private bool use_gtk;
+ private bool use_bamf;
private MainLoop? loop;
private Settings indicator_settings;
private Settings source_settings;
@@ -21,14 +23,23 @@ public class Indicator.Keyboard.Service : Object {
private uint[]? icon_string_subscripts;
[DBus (visible = false)]
- public Service (bool force) {
+ public Service (ref unowned string[] args) {
Bus.own_name (BusType.SESSION,
"com.canonical.indicator.keyboard",
- BusNameOwnerFlags.ALLOW_REPLACEMENT | (force ? BusNameOwnerFlags.REPLACE : 0),
+ BusNameOwnerFlags.ALLOW_REPLACEMENT | ("--force" in args ? BusNameOwnerFlags.REPLACE : 0),
this.handle_bus_acquired,
null,
this.handle_name_lost);
+ this.use_gtk = "--use-gtk" in args;
+ this.use_bamf = "--use-bamf" in args;
+
+ if (this.use_gtk) {
+ this.use_gtk = Gtk.init_check (ref args);
+ } else {
+ Gdk.init (ref args);
+ }
+
this.indicator_settings = new Settings ("com.canonical.indicator.keyboard");
this.indicator_settings.changed["visible"].connect (this.handle_changed_visible);
@@ -118,17 +129,19 @@ public class Indicator.Keyboard.Service : Object {
[DBus (visible = false)]
private void update_window_sources () {
- var group_per_window = this.per_window_settings.get_boolean ("group-per-window");
-
- if (group_per_window != (this.window_sources != null)) {
- if (group_per_window) {
- this.window_sources = new Gee.HashMap<string, uint> ();
- this.matcher = Bamf.Matcher.get_default ();
- ((!) this.matcher).active_window_changed.connect (this.handle_active_window_changed);
- } else {
- ((!) this.matcher).active_window_changed.disconnect (this.handle_active_window_changed);
- this.matcher = null;
- this.window_sources = null;
+ if (this.use_bamf) {
+ var group_per_window = this.per_window_settings.get_boolean ("group-per-window");
+
+ if (group_per_window != (this.window_sources != null)) {
+ if (group_per_window) {
+ this.window_sources = new Gee.HashMap<string, uint> ();
+ this.matcher = Bamf.Matcher.get_default ();
+ ((!) this.matcher).active_window_changed.connect (this.handle_active_window_changed);
+ } else {
+ ((!) this.matcher).active_window_changed.disconnect (this.handle_active_window_changed);
+ this.matcher = null;
+ this.window_sources = null;
+ }
}
}
}
@@ -158,100 +171,114 @@ public class Indicator.Keyboard.Service : Object {
}
[DBus (visible = false)]
- private Gtk.StyleContext get_style_context () {
- var context = new Gtk.StyleContext ();
+ private Gtk.StyleContext? get_style_context () {
+ Gtk.StyleContext? context = null;
+
+ if (this.use_gtk) {
+ Gdk.Screen? screen = Gdk.Screen.get_default ();
- context.set_screen (Gdk.Screen.get_default ());
+ if (screen != null) {
+ context = new Gtk.StyleContext ();
+ ((!) context).set_screen ((!) screen);
- var path = new Gtk.WidgetPath ();
- path.append_type (typeof (Gtk.MenuItem));
- context.set_path (path);
+ var path = new Gtk.WidgetPath ();
+ path.append_type (typeof (Gtk.MenuItem));
+ ((!) context).set_path (path);
+ }
+ }
return context;
}
[DBus (visible = false)]
- protected virtual Icon create_icon (string? text, uint subscript) {
- const int W = 22;
- const int H = 22;
- const int w = 20;
- const int h = 20;
- const double R = 2.0;
- const double TEXT_SIZE = 12.0;
- const double SUBSCRIPT_SIZE = 8.0;
-
- Pango.FontDescription description;
+ protected virtual Icon? create_icon (string? text, uint subscript) {
+ Icon? icon = null;
+
var style = get_style_context ();
- var colour = style.get_color (Gtk.StateFlags.NORMAL);
- colour = { 0.5, 0.5, 0.5, 1.0 };
- style.get (Gtk.StateFlags.NORMAL, Gtk.STYLE_PROPERTY_FONT, out description);
-
- var surface = new Cairo.ImageSurface (Cairo.Format.ARGB32, W, H);
- var context = new Cairo.Context (surface);
-
- context.translate (0.5 * (W - w), 0.5 * (H - h));
-
- context.new_sub_path ();
- context.arc (R, R, R, Math.PI, -0.5 * Math.PI);
- context.arc (w - R, R, R, -0.5 * Math.PI, 0);
- context.arc (w - R, h - R, R, 0, 0.5 * Math.PI);
- context.arc (R, h - R, R, 0.5 * Math.PI, Math.PI);
- context.close_path ();
-
- context.set_source_rgba (colour.red, colour.green, colour.blue, colour.alpha);
- context.fill ();
- context.set_operator (Cairo.Operator.CLEAR);
-
- if (text != null) {
- var text_layout = Pango.cairo_create_layout (context);
- text_layout.set_alignment (Pango.Alignment.CENTER);
- description.set_absolute_size (Pango.units_from_double (TEXT_SIZE));
- text_layout.set_font_description (description);
- text_layout.set_text ((!) text, -1);
- Pango.cairo_update_layout (context, text_layout);
- int text_width;
- int text_height;
- text_layout.get_pixel_size (out text_width, out text_height);
-
- if (subscript > 0) {
- var subscript_layout = Pango.cairo_create_layout (context);
- subscript_layout.set_alignment (Pango.Alignment.CENTER);
- description.set_absolute_size (Pango.units_from_double (SUBSCRIPT_SIZE));
- subscript_layout.set_font_description (description);
- subscript_layout.set_text (@"$subscript", -1);
- Pango.cairo_update_layout (context, subscript_layout);
- int subscript_width;
- int subscript_height;
- subscript_layout.get_pixel_size (out subscript_width, out subscript_height);
-
- context.save ();
- context.translate ((w - (text_width + subscript_width)) / 2, (h - text_height) / 2);
- Pango.cairo_layout_path (context, text_layout);
- context.fill ();
- context.restore ();
-
- context.save ();
- context.translate ((w + (text_width - subscript_width)) / 2, (h + text_height) / 2 - subscript_height);
- Pango.cairo_layout_path (context, subscript_layout);
- context.fill ();
- context.restore ();
- } else {
- context.save ();
- context.translate ((w - text_width) / 2, (h - text_height) / 2);
- Pango.cairo_layout_path (context, text_layout);
- context.fill ();
- context.restore ();
+
+ if (style != null) {
+ const int W = 22;
+ const int H = 22;
+ const int w = 20;
+ const int h = 20;
+ const double R = 2.0;
+ const double TEXT_SIZE = 12.0;
+ const double SUBSCRIPT_SIZE = 8.0;
+
+ Pango.FontDescription description;
+ var colour = ((!) style).get_color (Gtk.StateFlags.NORMAL);
+ colour = { 0.5, 0.5, 0.5, 1.0 };
+ ((!) style).get (Gtk.StateFlags.NORMAL, Gtk.STYLE_PROPERTY_FONT, out description);
+
+ var surface = new Cairo.ImageSurface (Cairo.Format.ARGB32, W, H);
+ var context = new Cairo.Context (surface);
+
+ context.translate (0.5 * (W - w), 0.5 * (H - h));
+
+ context.new_sub_path ();
+ context.arc (R, R, R, Math.PI, -0.5 * Math.PI);
+ context.arc (w - R, R, R, -0.5 * Math.PI, 0);
+ context.arc (w - R, h - R, R, 0, 0.5 * Math.PI);
+ context.arc (R, h - R, R, 0.5 * Math.PI, Math.PI);
+ context.close_path ();
+
+ context.set_source_rgba (colour.red, colour.green, colour.blue, colour.alpha);
+ context.fill ();
+ context.set_operator (Cairo.Operator.CLEAR);
+
+ if (text != null) {
+ var text_layout = Pango.cairo_create_layout (context);
+ text_layout.set_alignment (Pango.Alignment.CENTER);
+ description.set_absolute_size (Pango.units_from_double (TEXT_SIZE));
+ text_layout.set_font_description (description);
+ text_layout.set_text ((!) text, -1);
+ Pango.cairo_update_layout (context, text_layout);
+ int text_width;
+ int text_height;
+ text_layout.get_pixel_size (out text_width, out text_height);
+
+ if (subscript > 0) {
+ var subscript_layout = Pango.cairo_create_layout (context);
+ subscript_layout.set_alignment (Pango.Alignment.CENTER);
+ description.set_absolute_size (Pango.units_from_double (SUBSCRIPT_SIZE));
+ subscript_layout.set_font_description (description);
+ subscript_layout.set_text (@"$subscript", -1);
+ Pango.cairo_update_layout (context, subscript_layout);
+ int subscript_width;
+ int subscript_height;
+ subscript_layout.get_pixel_size (out subscript_width, out subscript_height);
+
+ context.save ();
+ context.translate ((w - (text_width + subscript_width)) / 2, (h - text_height) / 2);
+ Pango.cairo_layout_path (context, text_layout);
+ context.fill ();
+ context.restore ();
+
+ context.save ();
+ context.translate ((w + (text_width - subscript_width)) / 2, (h + text_height) / 2 - subscript_height);
+ Pango.cairo_layout_path (context, subscript_layout);
+ context.fill ();
+ context.restore ();
+ } else {
+ context.save ();
+ context.translate ((w - text_width) / 2, (h - text_height) / 2);
+ Pango.cairo_layout_path (context, text_layout);
+ context.fill ();
+ context.restore ();
+ }
}
- }
- var buffer = new ByteArray ();
+ var buffer = new ByteArray ();
+
+ surface.write_to_png_stream ((data) => {
+ buffer.append (data);
+ return Cairo.Status.SUCCESS;
+ });
- surface.write_to_png_stream ((data) => {
- buffer.append (data);
- return Cairo.Status.SUCCESS;
- });
+ icon = new BytesIcon (ByteArray.free_to_bytes ((owned) buffer));
+ }
- return new BytesIcon (ByteArray.free_to_bytes ((owned) buffer));
+ return icon;
}
[DBus (visible = false)]
@@ -388,15 +415,19 @@ public class Indicator.Keyboard.Service : Object {
icon_name = @"indicator-keyboard-$((!) icon_string)-$icon_subscript";
}
- var icon_theme = Gtk.IconTheme.get_default ();
- Gtk.IconInfo? icon_info = icon_theme.lookup_icon (icon_name, 22, 0);
+ if (this.use_gtk) {
+ var icon_theme = Gtk.IconTheme.get_default ();
+ Gtk.IconInfo? icon_info = icon_theme.lookup_icon (icon_name, 22, 0);
- if (icon_info != null) {
- try {
- this.icons[index] = Icon.new_for_string (((!) icon_info).get_filename ());
- } catch (Error error) {
- this.icons[index] = null;
+ if (icon_info != null) {
+ try {
+ this.icons[index] = Icon.new_for_string (((!) icon_info).get_filename ());
+ } catch (Error error) {
+ this.icons[index] = null;
+ }
}
+ } else {
+ this.icons[index] = new ThemedIcon (icon_name);
}
}
@@ -718,8 +749,7 @@ public class Indicator.Keyboard.Service : Object {
[DBus (visible = false)]
public static int main (string[] args) {
- Gtk.init (ref args);
- new Service ("--force" in args);
+ new Service (ref args);
return 0;
}
}
diff --git a/po/indicator-keyboard.pot b/po/indicator-keyboard.pot
index c76a057b..de95f228 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: 2013-07-04 00:11-0400\n"
+"POT-Creation-Date: 2013-07-17 16:04-0400\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,14 +17,14 @@ msgstr ""
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
-#: ../lib/main.c:2209 ../lib/main.vala:501
+#: ../lib/main.c:2297 ../lib/main.vala:532
msgid "Character Map"
msgstr ""
-#: ../lib/main.c:2211 ../lib/main.vala:502
+#: ../lib/main.c:2299 ../lib/main.vala:533
msgid "Keyboard Layout Chart"
msgstr ""
-#: ../lib/main.c:2213 ../lib/main.vala:503
+#: ../lib/main.c:2301 ../lib/main.vala:534
msgid "Text Entry Settings..."
msgstr ""
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 9161365e..2e0e0287 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -1,17 +1,17 @@
TESTS = indicator-keyboard-test
-check_PROGRAMS = indicator-keyboard-test
+check_PROGRAMS = indicator-keyboard-tests
AM_CFLAGS = -w
AM_LDFLAGS = -lm
AM_VALAFLAGS = --metadatadir $(top_srcdir)/deps \
--vapidir $(top_srcdir)/deps
-indicator_keyboard_test_SOURCES = main.vala \
- config.vala
-indicator_keyboard_test_VALAFLAGS = $(AM_VALAFLAGS) \
- --pkg gio-2.0
-indicator_keyboard_test_CFLAGS = $(AM_CFLAGS) \
- $(GIO_CFLAGS)
-indicator_keyboard_test_LDFLAGS = $(AM_LDFLAGS) \
- $(GIO_LIBS)
+indicator_keyboard_tests_SOURCES = main.vala \
+ config.vala
+indicator_keyboard_tests_VALAFLAGS = $(AM_VALAFLAGS) \
+ --pkg gio-2.0
+indicator_keyboard_tests_CFLAGS = $(AM_CFLAGS) \
+ $(GIO_CFLAGS)
+indicator_keyboard_tests_LDFLAGS = $(AM_LDFLAGS) \
+ $(GIO_LIBS)
diff --git a/tests/indicator-keyboard-service.in b/tests/indicator-keyboard-service.in
index a1f7d573..52a31988 100644
--- a/tests/indicator-keyboard-service.in
+++ b/tests/indicator-keyboard-service.in
@@ -2,4 +2,4 @@
PATH="@abs_top_builddir@/tests/execute:$PATH"
DCONF_PROFILE="@abs_top_builddir@/tests/profiles/indicator-keyboard-test"
-@abs_top_builddir@/lib/indicator-keyboard-service
+@abs_top_builddir@/lib/indicator-keyboard-service "$@"
diff --git a/tests/indicator-keyboard-test b/tests/indicator-keyboard-test
new file mode 100755
index 00000000..7f9e50ea
--- /dev/null
+++ b/tests/indicator-keyboard-test
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+if test "x$DISPLAY" = "x"
+then
+ Xvfb -ac -noreset -screen 0 800x600x16 -help 2>/dev/null 1>&2
+ XID=`for id in 101 102 103 104 105 106 107 197 199 211 223 227 293 307 308 309 310 311 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 4703 4721 4723 4729 4733 4751 9973 9974 9975 9976 9977 9978 9979 9980 9981 9982 9983 9984 9985 9986 9987 9988 9989 9990 9991 9992 9993 9994 9995 9996 9997 9998 9999 ; do test -e /tmp/.X$id-lock || { echo $id; exit 0; }; done; exit 1`
+ { Xvfb -ac -noreset -screen 0 800x600x16 :$XID -screen 0 800x600x16 -nolisten tcp -auth /dev/null >/dev/null 2>&1 & trap "kill -15 $! " 0 HUP INT QUIT TRAP USR1 PIPE TERM ; } || { echo "Gtk+Tests:ERROR: Failed to start Xvfb environment for X11 target tests."; exit 1; }
+ DISPLAY=:$XID
+ export DISPLAY
+fi
+
+./indicator-keyboard-tests
diff --git a/tests/main.vala b/tests/main.vala
index 4e121fcd..f4577f83 100644
--- a/tests/main.vala
+++ b/tests/main.vala
@@ -648,7 +648,7 @@ static void test_update_input_sources (void *data) {
section.get_item_attribute (2, Menu.ATTRIBUTE_LABEL, "s", out label);
assert (strcmp (label, "Esperanto") == 0);
section.get_item_attribute (3, Menu.ATTRIBUTE_LABEL, "s", out label);
- assert (strcmp (label, "Pinyin") == 0);
+ assert (label.ascii_casecmp ("Pinyin") == 0);
}
public int main (string[] args) {