diff options
author | Rui Matos <tiagomatos@gmail.com> | 2014-10-30 17:58:16 +0100 |
---|---|---|
committer | Rui Matos <tiagomatos@gmail.com> | 2014-10-30 17:58:16 +0100 |
commit | a6b0132193d1c4031035d4d412285a488dfaf2a6 (patch) | |
tree | f04782c654c8d28b4048fade886a10f8d3066b07 | |
parent | 5fb41bfd440b10ae1ee6ce5570e61ba71366d60f (diff) | |
download | gnome-initial-setup-a6b0132193d1c4031035d4d412285a488dfaf2a6.tar.gz |
keyboard: Preserve system keyboard layouts
If there are keyboard layouts already configured system wide we should
keep and import them as user input sources.
For simplicity we still only allow the user to choose one input source
and in that case we'll use it as the default, i.e. the first.
The first system layout, if it exists, is pre-selected in the chooser.
-rw-r--r-- | gnome-initial-setup/pages/keyboard/gis-keyboard-page.c | 118 |
1 files changed, 114 insertions, 4 deletions
diff --git a/gnome-initial-setup/pages/keyboard/gis-keyboard-page.c b/gnome-initial-setup/pages/keyboard/gis-keyboard-page.c index 3a856b5..8f3ad34 100644 --- a/gnome-initial-setup/pages/keyboard/gis-keyboard-page.c +++ b/gnome-initial-setup/pages/keyboard/gis-keyboard-page.c @@ -45,6 +45,8 @@ struct _GisKeyboardPagePrivate { GCancellable *cancellable; GPermission *permission; GSettings *input_settings; + + GSList *system_sources; }; typedef struct _GisKeyboardPagePrivate GisKeyboardPagePrivate; @@ -64,6 +66,8 @@ gis_keyboard_page_finalize (GObject *object) g_clear_object (&priv->localed); g_clear_object (&priv->input_settings); + g_slist_free_full (priv->system_sources, g_free); + G_OBJECT_CLASS (gis_keyboard_page_parent_class)->finalize (object); } @@ -71,12 +75,25 @@ static void set_input_settings (GisKeyboardPage *self) { GisKeyboardPagePrivate *priv = gis_keyboard_page_get_instance_private (self); + const gchar *type; + const gchar *id; GVariantBuilder builder; + GSList *l; + + type = cc_input_chooser_get_input_type (CC_INPUT_CHOOSER (priv->input_chooser)); + id = cc_input_chooser_get_input_id (CC_INPUT_CHOOSER (priv->input_chooser)); g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(ss)")); - g_variant_builder_add (&builder, "(ss)", - cc_input_chooser_get_input_type (CC_INPUT_CHOOSER (priv->input_chooser)), - cc_input_chooser_get_input_id (CC_INPUT_CHOOSER (priv->input_chooser))); + g_variant_builder_add (&builder, "(ss)", type, id); + + for (l = priv->system_sources; l; l = l->next) { + const gchar *sid = l->data; + + if (g_str_equal (id, sid) && g_str_equal (type, "xkb")) + continue; + + g_variant_builder_add (&builder, "(ss)", "xkb", sid); + } g_settings_set_value (priv->input_settings, KEY_INPUT_SOURCES, g_variant_builder_end (&builder)); g_settings_set_uint (priv->input_settings, KEY_CURRENT_INPUT_SOURCE, 0); @@ -89,17 +106,49 @@ set_localed_input (GisKeyboardPage *self) { GisKeyboardPagePrivate *priv = gis_keyboard_page_get_instance_private (self); const gchar *layout, *variant; + GString *layouts; + GString *variants; + GSList *l; if (!priv->localed) return; cc_input_chooser_get_layout (CC_INPUT_CHOOSER (priv->input_chooser), &layout, &variant); + if (layout == NULL) + layout = ""; + if (variant == NULL) + variant = ""; + + layouts = g_string_new (layout); + variants = g_string_new (variant); + +#define LAYOUT(a) (a[0]) +#define VARIANT(a) (a[1] ? a[1] : "") + for (l = priv->system_sources; l; l = l->next) { + const gchar *sid = l->data; + gchar **lv = g_strsplit (sid, "+", -1); + + if (!g_str_equal (LAYOUT (lv), layout) || + !g_str_equal (VARIANT (lv), variant)) { + if (layouts->str[0]) { + g_string_append_c (layouts, ','); + g_string_append_c (variants, ','); + } + g_string_append (layouts, LAYOUT (lv)); + g_string_append (variants, VARIANT (lv)); + } + g_strfreev (lv); + } +#undef LAYOUT +#undef VARIANT g_dbus_proxy_call (priv->localed, "SetX11Keyboard", - g_variant_new ("(ssssbb)", layout, "", variant, "", TRUE, TRUE), + g_variant_new ("(ssssbb)", layouts->str, "", variants->str, "", TRUE, TRUE), G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); + g_string_free (layouts, TRUE); + g_string_free (variants, TRUE); } static void @@ -152,6 +201,66 @@ gis_keyboard_page_apply (GisPage *page, } static void +load_localed_input (GisKeyboardPage *self) +{ + GisKeyboardPagePrivate *priv = gis_keyboard_page_get_instance_private (self); + GVariant *v; + const gchar *s; + gchar *id; + guint i, n; + gchar **layouts = NULL; + gchar **variants = NULL; + GSList *sources = NULL; + + if (!priv->localed) + return; + + v = g_dbus_proxy_get_cached_property (priv->localed, "X11Layout"); + if (v) { + s = g_variant_get_string (v, NULL); + layouts = g_strsplit (s, ",", -1); + g_variant_unref (v); + } + + v = g_dbus_proxy_get_cached_property (priv->localed, "X11Variant"); + if (v) { + s = g_variant_get_string (v, NULL); + if (s && *s) + variants = g_strsplit (s, ",", -1); + g_variant_unref (v); + } + + if (variants && variants[0]) + n = MIN (g_strv_length (layouts), g_strv_length (variants)); + else if (layouts && layouts[0]) + n = g_strv_length (layouts); + else + n = 0; + + for (i = 0; i < n && layouts[i][0]; i++) { + if (variants && variants[i] && variants[i][0]) + id = g_strdup_printf ("%s+%s", layouts[i], variants[i]); + else + id = g_strdup (layouts[i]); + sources = g_slist_prepend (sources, id); + } + + g_strfreev (variants); + g_strfreev (layouts); + + /* These will be added silently after the user selection when + * writing out the settings. */ + g_slist_free_full (priv->system_sources, g_free); + priv->system_sources = g_slist_reverse (sources); + + /* We only pre-select the first system layout. */ + if (priv->system_sources) + cc_input_chooser_set_input (CC_INPUT_CHOOSER (priv->input_chooser), + (const gchar *) priv->system_sources->data, + "xkb"); +} + +static void update_page_complete (GisKeyboardPage *self) { GisKeyboardPagePrivate *priv = gis_keyboard_page_get_instance_private (self); @@ -183,6 +292,7 @@ localed_proxy_ready (GObject *source, priv->localed = proxy; + load_localed_input (self); update_page_complete (self); } |