diff --git a/plugins/keyboard/gsd-keyboard-xkb.c b/plugins/keyboard/gsd-keyboard-xkb.c index 346fdba..19ae642 100644 --- a/plugins/keyboard/gsd-keyboard-xkb.c +++ b/plugins/keyboard/gsd-keyboard-xkb.c @@ -158,18 +158,42 @@ apply_xkb_settings (void) gdm_keyboard_layout = NULL; if (gdm_layout != NULL) { GSList *layouts; + GSList *found_node; + layouts = gconf_client_get_list (conf_client, GKBD_KEYBOARD_CONFIG_KEY_LAYOUTS, GCONF_VALUE_STRING, NULL); - if (layouts == NULL) { - layouts = - g_slist_append (layouts, - g_strdup (gdm_layout)); + + /* Add the layout if it doesn't already exist. XKB limits the + * total number of layouts to four. If we already have four + * layouts configured, we replace the last one. This prevents the + * list from becoming full if the user has a habit of selecting + * many different keyboard layouts in GDM. */ + + found_node = g_slist_find_custom (layouts, gdm_layout, g_strcmp0); + + if (found_node) { + if (g_slist_position (layouts, found_node) > 3) { + /* If the layout we found appears after the + * fourth entry, we move it up to fourth place. + * Otherwise, XKB will not activate it. */ + g_free (found_node->data); + layouts = g_slist_delete_link (layouts, found_node); + found_node = NULL; + } + } + + if (!found_node) { + /* Insert in fourth slot or at the end of list, + * whichever comes first */ + layouts = g_slist_insert (layouts, g_strdup (gdm_layout), 3); + gconf_client_set_list (conf_client, GKBD_KEYBOARD_CONFIG_KEY_LAYOUTS, GCONF_VALUE_STRING, layouts, NULL); } + g_slist_foreach (layouts, (GFunc) g_free, NULL); g_slist_free (layouts); }