support various display types
* Add ability to set the language of a user from the greeter
* Set LANG variable based on the user language
+ * Add language selector into GTK greeter (disabled by default)
Overview of changes in lightdm 0.9.7
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk+" version="2.24"/>
+ <object class="GtkListStore" id="language_liststore">
+ <columns>
+ <!-- column-name label -->
+ <column type="gchararray"/>
+ <!-- column-name key -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
<object class="GtkWindow" id="login_window">
<property name="can_focus">False</property>
<property name="resizable">False</property>
<property name="position">0</property>
</packing>
</child>
+ <child>
+ <object class="GtkComboBox" id="language_combobox">
+ <property name="can_focus">False</property>
+ <property name="model">language_liststore</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
<child>
<object class="GtkButton" id="login_button">
<property name="label" translatable="yes">Login</property>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
- <property name="position">1</property>
+ <property name="position">2</property>
</packing>
</child>
<child>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
- <property name="position">2</property>
+ <property name="position">3</property>
</packing>
</child>
</object>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_action_appearance">False</property>
- <child>
- <object class="GtkHBox" id="power_menuitem_box">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="spacing">3</property>
- <child>
- <object class="GtkImage" id="power_menuitem_image">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="pixel_size">24</property>
- <property name="icon_name">system-shutdown</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
- </child>
- </object>
- </child>
<child type="submenu">
<object class="GtkMenu" id="power_menu">
<property name="visible">True</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_action_appearance">False</property>
- <child>
- <object class="GtkHBox" id="a11y_menuitem_box">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="spacing">3</property>
- <child>
- <object class="GtkImage" id="a11y_menuitem_image">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="pixel_size">24</property>
- <property name="icon_name">accessibility</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
- </child>
- </object>
- </child>
<child type="submenu">
<object class="GtkMenu" id="a11y_menu">
<property name="visible">True</property>
static GtkWidget *login_box, *prompt_box;
static GtkEntry *prompt_entry;
static GtkComboBox *session_combo;
+static GtkComboBox *language_combo;
static gchar *default_font_name, *default_theme_name;
static gboolean cancelling = FALSE, prompted = FALSE;
set_session (lightdm_greeter_get_default_session_hint (greeter));
}
+static gchar *
+get_language ()
+{
+ GtkTreeIter iter;
+ gchar *language;
+
+ if (!gtk_combo_box_get_active_iter (language_combo, &iter))
+ return NULL;
+
+ gtk_tree_model_get (gtk_combo_box_get_model (language_combo), &iter, 1, &language, -1);
+
+ return language;
+}
+
+static void
+set_language (const gchar *language)
+{
+ GtkTreeModel *model = gtk_combo_box_get_model (language_combo);
+ GtkTreeIter iter;
+ const gchar *default_language = NULL;
+
+ if (language && gtk_tree_model_get_iter_first (model, &iter))
+ {
+ do
+ {
+ gchar *s;
+ gboolean matched;
+ gtk_tree_model_get (model, &iter, 1, &s, -1);
+ matched = strcmp (s, language) == 0;
+ g_free (s);
+ if (matched)
+ {
+ gtk_combo_box_set_active_iter (language_combo, &iter);
+ return;
+ }
+ } while (gtk_tree_model_iter_next (model, &iter));
+ }
+
+ /* If failed to find this language, then try the default */
+ if (lightdm_get_language ())
+ default_language = lightdm_language_get_code (lightdm_get_language ());
+ if (default_language && g_strcmp0 (default_language, language) != 0)
+ set_language (default_language);
+}
+
static void
set_message_label (const gchar *text)
{
user = lightdm_user_list_get_user_by_name (lightdm_user_list_get_instance (), username);
if (user)
+ {
set_session (lightdm_user_get_session (user));
+ set_language (lightdm_user_get_language (user));
+ }
else
+ {
set_session (NULL);
+ set_language (NULL);
+ }
lightdm_greeter_authenticate (greeter, username);
}
static void
start_session (void)
{
+ gchar *language;
gchar *session;
+ language = get_language ();
+ if (language)
+ lightdm_greeter_set_language (greeter, language);
+ g_free (language);
+
session = get_session ();
if (!lightdm_greeter_start_session_sync (greeter, session, NULL))
{
}
int
-main(int argc, char **argv)
+main (int argc, char **argv)
{
GKeyFile *config;
GdkRectangle monitor_geometry;
prompt_entry = GTK_ENTRY (gtk_builder_get_object (builder, "prompt_entry"));
message_label = GTK_LABEL (gtk_builder_get_object (builder, "message_label"));
session_combo = GTK_COMBO_BOX (gtk_builder_get_object (builder, "session_combobox"));
+ language_combo = GTK_COMBO_BOX (gtk_builder_get_object (builder, "language_combobox"));
panel_window = GTK_WINDOW (gtk_builder_get_object (builder, "panel_window"));
gtk_label_set_text (GTK_LABEL (gtk_builder_get_object (builder, "hostname_label")), lightdm_get_hostname ());
}
set_session (NULL);
+ if (g_key_file_get_boolean (config, "greeter", "show-language-selector", NULL))
+ {
+ gtk_widget_show (GTK_WIDGET (language_combo));
+
+ renderer = gtk_cell_renderer_text_new();
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (language_combo), renderer, TRUE);
+ gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (language_combo), renderer, "text", 0);
+ model = gtk_combo_box_get_model (language_combo);
+ items = lightdm_get_languages ();
+ for (item = items; item; item = item->next)
+ {
+ LightDMLanguage *language = item->data;
+ gchar *label;
+
+ label = g_strdup_printf ("%s - %s", lightdm_language_get_name (language), lightdm_language_get_territory (language));
+
+ gtk_widget_show (GTK_WIDGET (language_combo));
+ gtk_list_store_append (GTK_LIST_STORE (model), &iter);
+ gtk_list_store_set (GTK_LIST_STORE (model), &iter,
+ 0, label,
+ 1, lightdm_language_get_code (language),
+ -1);
+ g_free (label);
+ }
+ set_language (NULL);
+ }
+
gtk_builder_connect_signals(builder, greeter);
gtk_widget_show (GTK_WIDGET (login_window));
#
[greeter]
#background=
+#show-language-selector=false
#theme-name=
#font-name=
#xft-antialias=
g_return_if_fail (priv->connected);
- write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_SET_LANGUAGE, 0, &offset);
+ write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_SET_LANGUAGE, string_length (language), &offset);
write_string (message, MAX_MESSAGE_LENGTH, language, &offset);
write_message (greeter, message, offset);
}
continue;
/* Ignore the non-interesting languages */
- if (strcmp (code, "C") == 0 || strcmp (code, "POSIX") == 0)
+ if (strcmp (code, "C") == 0 || g_str_has_prefix (code, "C.") || strcmp (code, "POSIX") == 0)
continue;
language = g_object_new (LIGHTDM_TYPE_LANGUAGE, "code", code, NULL);
*
* Return value: (transfer none): The current language or #NULL if no language.
**/
-const LightDMLanguage *
+LightDMLanguage *
lightdm_get_language (void)
{
const gchar *lang;
GList *link;
lang = g_getenv ("LANG");
+ if (!lang)
+ return NULL;
+
for (link = lightdm_get_languages (); link; link = link->next)
{
LightDMLanguage *language = link->data;
#ifdef _NL_IDENTIFICATION_LANGUAGE
priv->name = g_strdup (nl_langinfo (_NL_IDENTIFICATION_LANGUAGE));
#else
- priv->name = g_strdup ("Unknown");
+ priv->name = g_strdup (priv->code);
+ if (strchr (priv->name, '_'))
+ *strchr (priv->name, '_') = '\0';
#endif
setlocale(LC_ALL, current);
}
#ifdef _NL_IDENTIFICATION_TERRITORY
priv->territory = g_strdup (nl_langinfo (_NL_IDENTIFICATION_TERRITORY));
#else
- priv->territory = g_strdup ("Unknown");
+ if (strchr (priv->code, '_'))
+ {
+ priv->territory = g_strdup (strchr (priv->code, '_') + 1);
+ if (strchr (priv->territory, '.'))
+ *strchr (priv->territory, '.') = '\0';
+ }
+ else
+ priv->territory = g_strdup ("");
#endif
setlocale(LC_ALL, current);
}
GList *lightdm_get_languages (void);
-const LightDMLanguage *lightdm_get_language (void);
+LightDMLanguage *lightdm_get_language (void);
const gchar *lightdm_language_get_code (LightDMLanguage *language);
void Greeter::setLanguage (QString language)
{
- writeHeader(GREETER_MESSAGE_SET_LANGUAGE, 0);
+ writeHeader(GREETER_MESSAGE_SET_LANGUAGE, stringLength(language));
writeString (language);
flush();
}
return;
}
+ g_debug ("Greeter sets language %s", language);
user = pam_session_get_user (greeter->priv->authentication);
user_set_language (user, language);
}