summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Cameron <brian.cameron@sun.com>2006-10-30 19:14:55 +0000
committerBrian Cameron <bcameron@src.gnome.org>2006-10-30 19:14:55 +0000
commitdcab1dc1622020de83fba92af081c242e51e40bf (patch)
tree711cdf9fc6f455dd54125cd048d0143aec8ac9f0
parent83c01bd8a587be7de9615e519443ccb094382783 (diff)
downloadgdm-dcab1dc1622020de83fba92af081c242e51e40bf.tar.gz
Now support combo style lists in 2.16. Patch backported from 2.17 without
2006-10-30 Brian Cameron <brian.cameron@sun.com> * gui/gdmconfig.[ch], gdmsession.[ch], greeter/greeter.c, greeter_action_language.[ch], greeter_canvas_item.c, greeter/greeter_item.h, greeter/greeter_item_customlist.[ch], greeter/greeter_item_ulist.c, greeter/greeter_parser.c, greeter_session.[ch]: Now support combo style lists in 2.16. Patch backported from 2.17 without docs or theme changes. This way these features work in 2.16 but do not break translation. * gui/gdmlogin.c: Number of usability fixes for gdmlogin.c. Now do not bother showing browser userlist widget if there are no users to display. Now OK and Cancel buttons are set sensitive or insensitive based on context (OK only if something is in the entry field and Cancel if not on "Username" request). Fixed bug causing face browser to autoselect first user. I changed the behavior of how key events are listened to. Now respond on release instead of press for accepting Tab key as Enter, back_prog delay, timed_login reset, and flexiserver reaping. This made setting the buttons sensitive/insensitive easier.
-rw-r--r--ChangeLog21
-rw-r--r--gui/gdmconfig.c2
-rw-r--r--gui/gdmconfig.h2
-rw-r--r--gui/gdmlogin.c113
-rw-r--r--gui/gdmsession.c31
-rw-r--r--gui/gdmsession.h1
-rw-r--r--gui/greeter/greeter.c1
-rw-r--r--gui/greeter/greeter_action_language.c140
-rw-r--r--gui/greeter/greeter_action_language.h13
-rw-r--r--gui/greeter/greeter_canvas_item.c42
-rw-r--r--gui/greeter/greeter_item.h5
-rw-r--r--gui/greeter/greeter_item_customlist.c546
-rw-r--r--gui/greeter/greeter_item_customlist.h2
-rw-r--r--gui/greeter/greeter_item_ulist.c6
-rw-r--r--gui/greeter/greeter_parser.c35
-rw-r--r--gui/greeter/greeter_session.c34
-rw-r--r--gui/greeter/greeter_session.h1
17 files changed, 836 insertions, 159 deletions
diff --git a/ChangeLog b/ChangeLog
index 2402e623..fd006a4d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+2006-10-30 Brian Cameron <brian.cameron@sun.com>
+
+ * gui/gdmconfig.[ch], gdmsession.[ch], greeter/greeter.c,
+ greeter_action_language.[ch], greeter_canvas_item.c,
+ greeter/greeter_item.h, greeter/greeter_item_customlist.[ch],
+ greeter/greeter_item_ulist.c, greeter/greeter_parser.c,
+ greeter_session.[ch]: Now support combo style lists in 2.16.
+ Patch backported from 2.17 without docs or theme changes. This
+ way these features work in 2.16 but do not break translation.
+
+ * gui/gdmlogin.c: Number of usability fixes for gdmlogin.c. Now
+ do not bother showing browser userlist widget if there are no
+ users to display. Now OK and Cancel buttons are set sensitive or
+ insensitive based on context (OK only if something is in the entry
+ field and Cancel if not on "Username" request). Fixed bug causing
+ face browser to autoselect first user. I changed the behavior
+ of how key events are listened to. Now respond on release instead
+ of press for accepting Tab key as Enter, back_prog delay,
+ timed_login reset, and flexiserver reaping. This made setting the
+ buttons sensitive/insensitive easier.
+
2006-10-23 Brian Cameron <brian.cameron@sun.com>
* utils/Makefile.am: Remove X_EXTRA_LIBS and X_LIBS from
diff --git a/gui/gdmconfig.c b/gui/gdmconfig.c
index df3cb643..e8b1667f 100644
--- a/gui/gdmconfig.c
+++ b/gui/gdmconfig.c
@@ -658,7 +658,7 @@ gdm_config_reload_bool (gchar *key)
}
void
-gdm_set_servauth (gchar *file, gchar *key, gchar *id)
+gdm_save_customlist_data (gchar *file, gchar *key, gchar *id)
{
VeConfig *cfg;
cfg = ve_config_get (file);
diff --git a/gui/gdmconfig.h b/gui/gdmconfig.h
index e0e8d390..37f8466e 100644
--- a/gui/gdmconfig.h
+++ b/gui/gdmconfig.h
@@ -37,7 +37,7 @@ gboolean gdm_config_reload_int (gchar *key);
gboolean gdm_config_reload_bool (gchar *key);
GSList * gdm_config_get_xservers (gboolean flexible);
-void gdm_set_servauth (gchar *file,
+void gdm_save_customlist_data (gchar *file,
gchar *key,
gchar *id);
char * gdm_get_theme_greeter (gchar *file,
diff --git a/gui/gdmlogin.c b/gui/gdmlogin.c
index 031994ff..2573b3cc 100644
--- a/gui/gdmlogin.c
+++ b/gui/gdmlogin.c
@@ -101,7 +101,7 @@ static GtkWidget *title_box = NULL;
static GtkWidget *clock_label = NULL;
static GtkWidget *entry;
static GtkWidget *ok_button;
-static GtkWidget *cancel_button;
+static GtkWidget *start_again_button;
static GtkWidget *msg;
static GtkWidget *auto_timed_msg;
static GtkWidget *err_box;
@@ -249,7 +249,7 @@ back_prog_watch_events (void)
g_signal_add_emission_hook (sid, 0, back_prog_delay_timeout,
NULL, NULL);
- sid = g_signal_lookup ("key_press_event", GTK_TYPE_WIDGET);
+ sid = g_signal_lookup ("key_release_event", GTK_TYPE_WIDGET);
g_signal_add_emission_hook (sid, 0, back_prog_delay_timeout,
NULL, NULL);
@@ -875,7 +875,7 @@ gdm_login_enter (GtkWidget *entry)
gtk_widget_set_sensitive (entry, FALSE);
gtk_widget_set_sensitive (ok_button, FALSE);
- gtk_widget_set_sensitive (cancel_button, FALSE);
+ gtk_widget_set_sensitive (start_again_button, FALSE);
login_string = gtk_entry_get_text (GTK_ENTRY (entry));
@@ -902,8 +902,6 @@ gdm_login_enter (GtkWidget *entry)
/* obviously being 100% reliable is not an issue for
this test */
gtk_widget_set_sensitive (entry, TRUE);
- gtk_widget_set_sensitive (ok_button, TRUE);
- gtk_widget_set_sensitive (cancel_button, TRUE);
gtk_widget_grab_focus (entry);
gtk_window_set_focus (GTK_WINDOW (login), entry);
return;
@@ -928,19 +926,19 @@ gdm_login_ok_button_press (GtkButton *button, GtkWidget *entry)
}
static void
-gdm_login_cancel_button_press (GtkButton *button, GtkWidget *entry)
+gdm_login_start_again_button_press (GtkButton *button, GtkWidget *entry)
{
GtkTreeSelection *selection;
- if (selected_user != NULL)
- g_free (selected_user);
- selected_user = NULL;
-
if (browser != NULL) {
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (browser));
gtk_tree_selection_unselect_all (selection);
}
+ if (selected_user != NULL)
+ g_free (selected_user);
+ selected_user = NULL;
+
printf ("%c%c%c\n", STX, BEL,
GDM_INTERRUPT_CANCEL);
fflush (stdout);
@@ -1540,10 +1538,11 @@ process_operation (guchar op_code,
gdm_config_get_bool (GDM_KEY_SOUND_ON_LOGIN));
gtk_label_set_text_with_mnemonic (GTK_LABEL (label), _("_Username:"));
greeter_probably_login_prompt = TRUE;
+ gtk_widget_set_sensitive (start_again_button, FALSE);
} else {
+ gtk_widget_set_sensitive (start_again_button, TRUE);
if (tmp != NULL)
gtk_label_set_text (GTK_LABEL (label), tmp);
- greeter_probably_login_prompt = FALSE;
}
g_free (tmp);
@@ -1552,8 +1551,7 @@ process_operation (guchar op_code,
gtk_entry_set_max_length (GTK_ENTRY (entry), PW_ENTRY_SIZE);
gtk_entry_set_visibility (GTK_ENTRY (entry), TRUE);
gtk_widget_set_sensitive (entry, TRUE);
- gtk_widget_set_sensitive (ok_button, TRUE);
- gtk_widget_set_sensitive (cancel_button, TRUE);
+ gtk_widget_set_sensitive (ok_button, FALSE);
gtk_widget_grab_focus (entry);
gtk_window_set_focus (GTK_WINDOW (login), entry);
gtk_widget_show (entry);
@@ -1573,8 +1571,10 @@ process_operation (guchar op_code,
case GDM_NOECHO:
tmp = ve_locale_to_utf8 (args);
if (tmp != NULL && strcmp (tmp, _("Password:")) == 0) {
+ gtk_widget_set_sensitive (start_again_button, TRUE);
gtk_label_set_text_with_mnemonic (GTK_LABEL (label), _("_Password:"));
} else {
+ gtk_widget_set_sensitive (start_again_button, FALSE);
if (tmp != NULL)
gtk_label_set_text (GTK_LABEL (label), tmp);
}
@@ -1585,8 +1585,7 @@ process_operation (guchar op_code,
gtk_entry_set_max_length (GTK_ENTRY (entry), PW_ENTRY_SIZE);
gtk_entry_set_visibility (GTK_ENTRY (entry), FALSE);
gtk_widget_set_sensitive (entry, TRUE);
- gtk_widget_set_sensitive (ok_button, TRUE);
- gtk_widget_set_sensitive (cancel_button, TRUE);
+ gtk_widget_set_sensitive (ok_button, FALSE);
gtk_widget_grab_focus (entry);
gtk_window_set_focus (GTK_WINDOW (login), entry);
gtk_widget_show (entry);
@@ -1751,8 +1750,8 @@ process_operation (guchar op_code,
}
gtk_widget_set_sensitive (entry, TRUE);
- gtk_widget_set_sensitive (ok_button, TRUE);
- gtk_widget_set_sensitive (cancel_button, TRUE);
+ gtk_widget_set_sensitive (ok_button, FALSE);
+ gtk_widget_set_sensitive (start_again_button, FALSE);
if (browser_ok && gdm_config_get_bool (GDM_KEY_BROWSER))
gtk_widget_set_sensitive (GTK_WIDGET (browser), TRUE);
@@ -1929,10 +1928,11 @@ process_operation (guchar op_code,
}
-static void
+static int
gdm_login_browser_populate (void)
{
GList *li;
+ int i = 0;
for (li = users; li != NULL; li = li->next) {
GdmUser *usr = li->data;
@@ -1956,7 +1956,9 @@ gdm_login_browser_populate (void)
GREETER_ULIST_LABEL_COLUMN, label,
-1);
g_free (label);
+ i++;
}
+ return (i);
}
static void
@@ -1971,7 +1973,7 @@ user_selected (GtkTreeSelection *selection, gpointer data)
#endif
if (gtk_tree_selection_get_selected (selection, &tm, &iter)) {
- char *login;
+ char *login = NULL;
gtk_tree_model_get (tm, &iter, GREETER_ULIST_LOGIN_COLUMN,
&login, -1);
if (login != NULL) {
@@ -2223,8 +2225,10 @@ window_browser_event (GtkWidget *window, GdkEvent *event, gpointer data)
}
static gboolean
-key_press_event (GtkWidget *entry, GdkEventKey *event, gpointer data)
+key_release_event (GtkWidget *entry, GdkEventKey *event, gpointer data)
{
+ const char *login_string;
+
if ((event->keyval == GDK_Tab ||
event->keyval == GDK_KP_Tab) &&
(event->state & (GDK_CONTROL_MASK|GDK_MOD1_MASK|GDK_SHIFT_MASK)) == 0) {
@@ -2232,6 +2236,16 @@ key_press_event (GtkWidget *entry, GdkEventKey *event, gpointer data)
return TRUE;
}
+ /*
+ * Set ok button to sensitive only if there are characters in
+ * the entry field
+ */
+ login_string = gtk_entry_get_text (GTK_ENTRY (entry));
+ if (login_string != NULL && login_string[0] != '\0')
+ gtk_widget_set_sensitive (ok_button, TRUE);
+ else
+ gtk_widget_set_sensitive (ok_button, FALSE);
+
return FALSE;
}
@@ -2254,6 +2268,7 @@ gdm_set_welcomemsg (void)
static void
gdm_login_gui_init (void)
{
+ GtkTreeSelection *selection;
GtkWidget *frame1, *frame2, *ebox;
GtkWidget *mbox, *menu, *menubar, *item;
GtkWidget *stack, *hline1, *hline2, *handle;
@@ -2466,7 +2481,6 @@ gdm_login_gui_init (void)
if (browser_ok && gdm_config_get_bool (GDM_KEY_BROWSER)) {
int height;
- GtkTreeSelection *selection;
GtkTreeViewColumn *column;
browser = gtk_tree_view_new ();
@@ -2484,10 +2498,6 @@ gdm_login_gui_init (void)
G_CALLBACK (browser_change_focus),
NULL);
- browser_model = (GtkTreeModel *)gtk_list_store_new (3,
- GDK_TYPE_PIXBUF,
- G_TYPE_STRING,
- G_TYPE_STRING);
gtk_tree_view_set_model (GTK_TREE_VIEW (browser), browser_model);
column = gtk_tree_view_column_new_with_attributes
(_("Icon"),
@@ -2616,8 +2626,12 @@ gdm_login_gui_init (void)
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
entry = gtk_entry_new ();
- g_signal_connect (G_OBJECT (entry), "key_press_event",
- G_CALLBACK (key_press_event), NULL);
+ /*
+ * Connect this on key release so we can make the OK button
+ * sensitive based on whether the entry field has data.
+ */
+ g_signal_connect (G_OBJECT (entry), "key_release_event",
+ G_CALLBACK (key_release_event), NULL);
if (gdm_config_get_bool (GDM_KEY_ENTRY_INVISIBLE))
gtk_entry_set_invisible_char (GTK_ENTRY (entry), 0);
else if (gdm_config_get_bool (GDM_KEY_ENTRY_CIRCLES))
@@ -2687,12 +2701,12 @@ gdm_login_gui_init (void)
entry);
gtk_widget_show (ok_button);
- cancel_button = gtk_button_new_with_mnemonic (_("_Start Again"));
- GTK_WIDGET_UNSET_FLAGS (cancel_button, GTK_CAN_FOCUS);
- g_signal_connect (G_OBJECT (cancel_button), "clicked",
- G_CALLBACK (gdm_login_cancel_button_press),
+ start_again_button = gtk_button_new_with_mnemonic (_("_Start Again"));
+ GTK_WIDGET_UNSET_FLAGS (start_again_button, GTK_CAN_FOCUS);
+ g_signal_connect (G_OBJECT (start_again_button), "clicked",
+ G_CALLBACK (gdm_login_start_again_button_press),
entry);
- gtk_widget_show (cancel_button);
+ gtk_widget_show (start_again_button);
button_box = gtk_hbutton_box_new ();
gtk_button_box_set_layout (GTK_BUTTON_BOX (button_box),
@@ -2705,7 +2719,7 @@ gdm_login_gui_init (void)
gtk_button_box_set_child_secondary (GTK_BUTTON_BOX (button_box), help_button, TRUE);
#endif
- gtk_box_pack_end (GTK_BOX (button_box), GTK_WIDGET (cancel_button),
+ gtk_box_pack_end (GTK_BOX (button_box), GTK_WIDGET (start_again_button),
FALSE, TRUE, 0);
gtk_box_pack_end (GTK_BOX (button_box), GTK_WIDGET (ok_button),
FALSE, TRUE, 0);
@@ -2764,7 +2778,7 @@ gdm_login_gui_init (void)
if ( ! DOING_GDM_DEVELOPMENT) {
gtk_widget_set_sensitive (entry, FALSE);
gtk_widget_set_sensitive (ok_button, FALSE);
- gtk_widget_set_sensitive (cancel_button, FALSE);
+ gtk_widget_set_sensitive (start_again_button, FALSE);
}
gtk_widget_show_all (GTK_WIDGET (login));
@@ -2772,6 +2786,15 @@ gdm_login_gui_init (void)
gtk_table_set_col_spacings (GTK_TABLE (table), 0);
gtk_widget_hide (logo_frame);
}
+
+ if (browser_ok && gdm_config_get_bool (GDM_KEY_BROWSER)) {
+ /* Make sure userlist has no users selected */
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (browser));
+ gtk_tree_selection_unselect_all (selection);
+ if (selected_user)
+ g_free (selected_user);
+ selected_user = NULL;
+ }
}
static void
@@ -3382,10 +3405,22 @@ main (int argc, char *argv[])
}
}
- gdm_login_gui_init ();
+ if (browser_ok && gdm_config_get_bool (GDM_KEY_BROWSER)) {
+ /* Create browser_model before calling gdm_login_browser_populate */
+ browser_model = (GtkTreeModel *)gtk_list_store_new (3,
+ GDK_TYPE_PIXBUF,
+ G_TYPE_STRING,
+ G_TYPE_STRING);
+ /*
+ * Do not display face browser widget if no users, check this
+ * before callign gdm_login_gui_init ()
+ */
+ int num_users = gdm_login_browser_populate ();
+ if (num_users == 0)
+ browser_ok = FALSE;
+ }
- if (browser_ok && gdm_config_get_bool (GDM_KEY_BROWSER))
- gdm_login_browser_populate ();
+ gdm_login_gui_init ();
ve_signal_add (SIGHUP, gdm_reread_config, NULL);
@@ -3456,7 +3491,7 @@ main (int argc, char *argv[])
NULL /* data */,
NULL /* destroy_notify */);
- sid = g_signal_lookup ("key_press_event",
+ sid = g_signal_lookup ("key_release_event",
GTK_TYPE_WIDGET);
g_signal_add_emission_hook (sid,
0 /* detail */,
@@ -3486,7 +3521,7 @@ main (int argc, char *argv[])
NULL /* data */,
NULL /* destroy_notify */);
- sid = g_signal_lookup ("key_press_event",
+ sid = g_signal_lookup ("key_release_event",
GTK_TYPE_WIDGET);
g_signal_add_emission_hook (sid,
0 /* detail */,
diff --git a/gui/gdmsession.c b/gui/gdmsession.c
index da6c62ef..62be6380 100644
--- a/gui/gdmsession.c
+++ b/gui/gdmsession.c
@@ -107,7 +107,6 @@ gdm_session_list_from_hash_table_func (const char *key, const char *value,
*sessions = g_list_prepend (*sessions, g_strdup (key));
}
-
void
gdm_session_list_init ()
{
@@ -125,6 +124,7 @@ gdm_session_list_init ()
if (gdm_config_get_bool (GDM_KEY_SHOW_GNOME_FAILSAFE)) {
session = g_new0 (GdmSession, 1);
session->name = g_strdup (_("Failsafe _GNOME"));
+ session->clearname = g_strdup (_("Failsafe GNOME"));
session->comment = g_strdup (_("This is a failsafe session that will log you "
"into GNOME. No startup scripts will be read "
"and it is only to be used when you can't log "
@@ -137,6 +137,7 @@ gdm_session_list_init ()
/* Valgrind complains that the below is leaked */
session = g_new0 (GdmSession, 1);
session->name = g_strdup (_("Failsafe _Terminal"));
+ session->clearname = g_strdup (_("Failsafe Terminal"));
session->comment = g_strdup (_("This is a failsafe session that will log you "
"into a terminal. No startup scripts will be read "
"and it is only to be used when you can't log "
@@ -193,7 +194,8 @@ gdm_session_list_init ()
if (ve_config_get_bool (cfg, "Desktop Entry/Hidden=false")) {
session = g_new0 (GdmSession, 1);
- session->name = "foo";
+ session->name = g_strdup (dent->d_name);
+ session->clearname = NULL;
g_hash_table_insert (sessnames, g_strdup (dent->d_name), session);
ve_config_destroy (cfg);
dent = readdir (sessdir);
@@ -205,7 +207,8 @@ gdm_session_list_init ()
char *full = g_find_program_in_path (tryexec);
if (full == NULL) {
session = g_new0 (GdmSession, 1);
- session->name = "foo";
+ session->name = g_strdup (dent->d_name);
+ session->clearname = NULL;
g_hash_table_insert (sessnames, g_strdup (dent->d_name),
session);
g_free (tryexec);
@@ -225,7 +228,8 @@ gdm_session_list_init ()
if G_UNLIKELY (ve_string_empty (exec) || ve_string_empty (name)) {
session = g_new0 (GdmSession, 1);
- session->name = "foo";
+ session->name = g_strdup (dent->d_name);
+ session->clearname = NULL;
g_hash_table_insert (sessnames, g_strdup (dent->d_name), session);
g_free (exec);
g_free (name);
@@ -259,8 +263,9 @@ gdm_session_list_init ()
}
session = g_new0 (GdmSession, 1);
- session->name = g_strdup (name);
- session->comment = g_strdup (comment);
+ session->name = g_strdup (name);
+ session->clearname = NULL;
+ session->comment = g_strdup (comment);
g_hash_table_insert (sessnames, g_strdup (dent->d_name), session);
g_free (exec);
g_free (comment);
@@ -291,9 +296,10 @@ gdm_session_list_init ()
if (gdm_config_get_bool (GDM_KEY_SHOW_GNOME_FAILSAFE)) {
- session = g_new0 (GdmSession, 1);
- session->name = g_strdup (_("Failsafe _GNOME"));
- session->comment = g_strdup (_("This is a failsafe session that will log you "
+ session = g_new0 (GdmSession, 1);
+ session->name = g_strdup (_("Failsafe _GNOME"));
+ session->clearname = g_strdup (_("Failsafe GNOME"));
+ session->comment = g_strdup (_("This is a failsafe session that will log you "
"into GNOME. No startup scripts will be read "
"and it is only to be used when you can't log "
"in otherwise. GNOME will use the 'Default' "
@@ -303,9 +309,10 @@ gdm_session_list_init ()
}
if (gdm_config_get_bool (GDM_KEY_SHOW_XTERM_FAILSAFE)) {
- session = g_new0 (GdmSession, 1);
- session->name = g_strdup (_("Failsafe _Terminal"));
- session->comment = g_strdup (_("This is a failsafe session that will log you "
+ session = g_new0 (GdmSession, 1);
+ session->name = g_strdup (_("Failsafe _Terminal"));
+ session->clearname = g_strdup (_("Failsafe Terminal"));
+ session->comment = g_strdup (_("This is a failsafe session that will log you "
"into a terminal. No startup scripts will be read "
"and it is only to be used when you can't log "
"in otherwise. To exit the terminal, "
diff --git a/gui/gdmsession.h b/gui/gdmsession.h
index d17839d8..737692d7 100644
--- a/gui/gdmsession.h
+++ b/gui/gdmsession.h
@@ -29,6 +29,7 @@
typedef struct {
char *name;
+ char *clearname;
char *comment;
} GdmSession;
diff --git a/gui/greeter/greeter.c b/gui/greeter/greeter.c
index 7601b012..6f2d4007 100644
--- a/gui/greeter/greeter.c
+++ b/gui/greeter/greeter.c
@@ -1077,6 +1077,7 @@ main (int argc, char *argv[])
}
gdm_common_setup_background_color (bg_color);
greeter_session_init ();
+ greeter_language_initialize_model ();
ve_signal_add (SIGHUP, greeter_reread_config, NULL);
diff --git a/gui/greeter/greeter_action_language.c b/gui/greeter/greeter_action_language.c
index f50ad898..2ca83867 100644
--- a/gui/greeter/greeter_action_language.c
+++ b/gui/greeter/greeter_action_language.c
@@ -27,29 +27,32 @@
#include "gdmcommon.h"
#include "gdmconfig.h"
#include "gdmlanguages.h"
+
#include "greeter.h"
#include "greeter_configuration.h"
#include "greeter_item_pam.h"
#include "greeter_action_language.h"
+#include "greeter_parser.h"
+#include "greeter_item_customlist.h"
#define LAST_LANGUAGE "Last"
#define DEFAULT_LANGUAGE "Default"
-enum {
- LOCALE_COLUMN,
- TRANSLATED_NAME_COLUMN,
- UNTRANSLATED_NAME_COLUMN,
- NUM_COLUMNS
-};
+static GtkWidget *tv = NULL;
+static GtkListStore *lang_model = NULL;
+static GtkWidget *dialog = NULL;
+static gchar *current_language = NULL;
+static gchar *dialog_selected_language = NULL;
+static gint savelang = GTK_RESPONSE_NO;
-static GtkListStore *lang_model = NULL;
-static GtkWidget *dialog = NULL;
-static gint savelang = GTK_RESPONSE_NO;
-static gchar *current_language = NULL;
-static gchar *dialog_selected_language = NULL;
+GtkListStore *
+greeter_language_get_model (void)
+{
+ return lang_model;
+}
-static void
-greeter_langauge_initialize_model (void)
+void
+greeter_language_initialize_model (void)
{
GList *list, *li;
GtkTreeIter iter;
@@ -63,7 +66,7 @@ greeter_langauge_initialize_model (void)
gtk_list_store_append (lang_model, &iter);
gtk_list_store_set (lang_model, &iter,
- TRANSLATED_NAME_COLUMN, _("Last Language"),
+ TRANSLATED_NAME_COLUMN, _("Last language"),
UNTRANSLATED_NAME_COLUMN, NULL,
LOCALE_COLUMN, LAST_LANGUAGE,
-1);
@@ -206,18 +209,9 @@ tree_row_activated (GtkTreeView *view,
}
}
-/*
- * The button with this handler appears in the F10 menu, so it
- * cannot depend on callback data being passed in.
- */
-void
-greeter_language_handler (GreeterItemInfo *info, gpointer user_data)
+static void
+greeter_language_setup_treeview (void)
{
- GreeterItemInfo *entry_info = greeter_lookup_id ("user-pw-entry");
- GtkWidget *entry = GNOME_CANVAS_WIDGET (entry_info->item)->widget;
-
- GtkWidget *view = NULL;
-
if (dialog == NULL)
{
GtkWidget *main_vbox;
@@ -264,20 +258,20 @@ greeter_language_handler (GreeterItemInfo *info, gpointer user_data)
gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
gtk_box_pack_start (GTK_BOX (main_vbox),
label, FALSE, FALSE, 0);
- view = gtk_tree_view_new ();
- gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (view), TRUE);
- gtk_label_set_mnemonic_widget (GTK_LABEL (label), view);
+ tv = gtk_tree_view_new ();
+ gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (tv), TRUE);
+ gtk_label_set_mnemonic_widget (GTK_LABEL (label), tv);
/* FIXME: we should handle this better, but things really look
* bad if we aren't always LTR */
- gtk_widget_set_direction (view, GTK_TEXT_DIR_LTR);
- gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (view), FALSE);
- gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view),
+ gtk_widget_set_direction (tv, GTK_TEXT_DIR_LTR);
+ gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (tv), FALSE);
+ gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tv),
GTK_DIALOG_MODAL,
NULL,
gtk_cell_renderer_text_new (),
"text", TRANSLATED_NAME_COLUMN,
NULL);
- gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view),
+ gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tv),
GTK_DIALOG_MODAL,
NULL,
gtk_cell_renderer_text_new (),
@@ -289,41 +283,99 @@ greeter_language_handler (GreeterItemInfo *info, gpointer user_data)
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow),
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);
- gtk_container_add (GTK_CONTAINER (swindow), view);
+ gtk_container_add (GTK_CONTAINER (swindow), tv);
gtk_box_pack_start (GTK_BOX (main_vbox),
swindow, TRUE, TRUE, 0);
gtk_window_set_default_size (GTK_WINDOW (dialog),
MIN (400, gdm_wm_screen.width),
MIN (600, gdm_wm_screen.height));
- g_signal_connect (G_OBJECT (gtk_tree_view_get_selection (GTK_TREE_VIEW (view))),
+ g_signal_connect (G_OBJECT (gtk_tree_view_get_selection (GTK_TREE_VIEW (tv))),
"changed",
(GCallback) selection_changed,
NULL);
- g_signal_connect (G_OBJECT (view),
+ g_signal_connect (G_OBJECT (tv),
"row_activated",
(GCallback) tree_row_activated,
NULL);
- gtk_widget_show_all (dialog);
- gdm_wm_center_window (GTK_WINDOW (dialog));
+ gtk_tree_view_set_model (GTK_TREE_VIEW (tv),
+ GTK_TREE_MODEL (lang_model));
}
+}
+
+void
+greeter_language_set (char *language)
+{
+ char *locale;
+ GtkTreeIter iter = {0};
+
+ g_free (current_language);
+ current_language = g_strdup (language);
+
+ if (dialog == NULL)
+ greeter_language_setup_treeview ();
+
+ if (language == NULL)
+ return;
+
+ greeter_custom_set_language (language);
+
+ GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tv));
+ gtk_tree_selection_unselect_all (selection);
+
+ if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (lang_model), &iter)) {
+ do {
+ gtk_tree_model_get (GTK_TREE_MODEL (lang_model), &iter, LOCALE_COLUMN, &locale, -1);
+ if (locale != NULL && strcmp (locale, language) == 0) {
+ GtkTreePath *path = gtk_tree_model_get_path (GTK_TREE_MODEL (lang_model), &iter);
+
+ gtk_tree_selection_select_iter (selection, &iter);
+ gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (tv), path, NULL, FALSE, 0.0, 0.0);
+ gtk_tree_path_free (path);
+ break;
+ }
+ } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (lang_model), &iter));
+ }
+}
+
+/*
+ * The button with this handler appears in the F10 menu, so it
+ * cannot depend on callback data being passed in.
+ */
+void
+greeter_language_handler (GreeterItemInfo *info, gpointer user_data)
+{
+ if (dialog == NULL)
+ greeter_language_setup_treeview ();
+
+ gtk_widget_show_all (dialog);
+ gdm_wm_center_window (GTK_WINDOW (dialog));
+
gdm_wm_no_login_focus_push ();
- if (view != NULL)
+ if (tv != NULL)
{
GtkTreeSelection *selection;
gtk_widget_show_now (dialog);
- greeter_langauge_initialize_model ();
- gtk_tree_view_set_model (GTK_TREE_VIEW (view),
- GTK_TREE_MODEL (lang_model));
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
- if (selection != NULL)
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tv));
+ if (selection == NULL)
gtk_tree_selection_select_path (selection, gtk_tree_path_new_first ());
+ else
+ {
+ GtkTreeIter iter;
+ GtkTreePath *path;
+ GtkTreeModel *tm = GTK_TREE_MODEL (lang_model);
+
+ gtk_tree_selection_get_selected (selection, &tm, &iter);
+ path = gtk_tree_model_get_path (GTK_TREE_MODEL (lang_model), &iter);
+ gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (tv), path, NULL, FALSE, 0.0, 0.0);
+ gtk_tree_path_free (path);
+ }
}
switch (gtk_dialog_run (GTK_DIALOG (dialog)))
{
case GTK_RESPONSE_OK:
if (dialog_selected_language)
- current_language = g_strdup (dialog_selected_language);
+ greeter_language_set ((char *) dialog_selected_language);
break;
case GTK_RESPONSE_CANCEL:
default:
diff --git a/gui/greeter/greeter_action_language.h b/gui/greeter/greeter_action_language.h
index 37a6b542..26e30fe5 100644
--- a/gui/greeter/greeter_action_language.h
+++ b/gui/greeter/greeter_action_language.h
@@ -21,10 +21,19 @@
#include "greeter_item.h"
+enum {
+ LOCALE_COLUMN,
+ TRANSLATED_NAME_COLUMN,
+ UNTRANSLATED_NAME_COLUMN,
+ NUM_COLUMNS
+};
+
+void greeter_language_initialize_model (void);
gint greeter_language_get_save_language (void);
gchar *greeter_language_get_language (const char *old_language);
void greeter_language_handler (GreeterItemInfo *info,
- gpointer user_data);
-
+ gpointer user_data);
+GtkListStore *greeter_language_get_model (void);
+void greeter_language_set (char *language);
#endif
diff --git a/gui/greeter/greeter_canvas_item.c b/gui/greeter/greeter_canvas_item.c
index 15387e3d..72175b56 100644
--- a/gui/greeter/greeter_canvas_item.c
+++ b/gui/greeter/greeter_canvas_item.c
@@ -34,6 +34,7 @@
#include "greeter_canvas_item.h"
#include "greeter_configuration.h"
#include "greeter_canvas_text.h"
+#include "greeter_parser.h"
static void
apply_tint (GdkPixbuf *pixbuf, guint32 tint_color)
@@ -505,22 +506,37 @@ greeter_item_create_canvas_item (GreeterItemInfo *item)
/* Note a list type must be setup later and we will add the list store
* to it then, depending on the type. Likely userlist is the
* only type we support */
- list = gtk_tree_view_new ();
- swin = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (swin),
+ if (item->data.list.combo_type) {
+ list = gtk_combo_box_new_text ();
+
+ item->item = gnome_canvas_item_new (group,
+ GNOME_TYPE_CANVAS_WIDGET,
+ "widget", list,
+ "x", x1,
+ "y", y1,
+ "height", (double)rect.height,
+ "width", (double)rect.width,
+ NULL);
+ } else {
+ list = gtk_tree_view_new ();
+
+ swin = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (swin),
GTK_SHADOW_NONE);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swin),
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swin),
GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
- gtk_container_add (GTK_CONTAINER (swin), list);
- item->item = gnome_canvas_item_new (group,
- GNOME_TYPE_CANVAS_WIDGET,
- "widget", swin,
- "x", x1,
- "y", y1,
- "height", (double)rect.height,
- "width", (double)rect.width,
- NULL);
+ gtk_container_add (GTK_CONTAINER (swin), list);
+
+ item->item = gnome_canvas_item_new (group,
+ GNOME_TYPE_CANVAS_WIDGET,
+ "widget", swin,
+ "x", x1,
+ "y", y1,
+ "height", (double)rect.height,
+ "width", (double)rect.width,
+ NULL);
+ }
break;
}
diff --git a/gui/greeter/greeter_item.h b/gui/greeter/greeter_item.h
index ec7fd6aa..1f6c9e0b 100644
--- a/gui/greeter/greeter_item.h
+++ b/gui/greeter/greeter_item.h
@@ -145,8 +145,8 @@ struct _GreeterItemInfo {
GList *fixed_children;
union {
- /* Note: we want to have alphas, colors and have_color coincide for all types
- that have it */
+ /* Note: we want to have alphas, colors and have_color coincide for
+ * all types that have it */
#define GREETER_ITEM_TYPE_IS_TEXT(info) ((info)->item_type == GREETER_ITEM_TYPE_LABEL || (info)->item_type == GREETER_ITEM_TYPE_ENTRY)
struct {
guint8 alphas[GREETER_ITEM_STATE_MAX];
@@ -180,6 +180,7 @@ struct _GreeterItemInfo {
/* If this is a custom list, then these are the items
to pick from */
GList *items;
+ gboolean combo_type;
} list;
#define GREETER_ITEM_TYPE_IS_RECT(info) ((info)->item_type == GREETER_ITEM_TYPE_RECT)
diff --git a/gui/greeter/greeter_item_customlist.c b/gui/greeter/greeter_item_customlist.c
index 235f8743..152abf7f 100644
--- a/gui/greeter/greeter_item_customlist.c
+++ b/gui/greeter/greeter_item_customlist.c
@@ -18,15 +18,31 @@
#include "config.h"
+#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include "gdm.h"
#include "gdmconfig.h"
+#include "gdmsession.h"
#include "greeter_item.h"
#include "greeter_configuration.h"
#include "greeter_item_customlist.h"
#include "greeter_parser.h"
+#include "greeter_session.h"
+#include "greeter_action_language.h"
+
+/*
+ * Keep track of the session/language widgets so we can
+ * set their values when the session/language dialogs are
+ * changed.
+ */
+static GtkWidget *session_widget = NULL;
+static GtkWidget *language_widget = NULL;
+static gchar *session_key = NULL;
+
+extern GList *sessions;
+extern GHashTable *sessnames;
enum
{
@@ -34,34 +50,180 @@ enum
GREETER_LIST_ID
};
-static void
-row_selected (GtkTreeSelection *selection, gpointer data)
+/*
+ * This function sets the custom list when the session list has changed in
+ * the session dialog (launched from session button or F10 menu).
+ */
+void
+greeter_custom_set_session (gchar *session)
{
- GtkTreeModel *tm = NULL;
- GtkTreeIter iter = {0};
- GreeterItemInfo *item = data;
- char *id = NULL;
- char *file;
+ GList *tmp;
+ int i=0;
- if (DOING_GDM_DEVELOPMENT)
+ /*
+ * Since the sessions are created before the session list is generated,
+ * keep track of the session and set active row when it is setup. This
+ * function will get a NULL when the session is initialized to NULL
+ * at startup, so just return.
+ */
+ if (session == NULL)
return;
+ else
+ {
+ /*
+ * If the session_widget hasn't been setup yet (which it won't be when
+ * the greeter_sessioninit function is called, then just store the
+ * session and we'll set the value when the combo box is initialized later.
+ */
+ g_free (session_key);
+ session_key = g_strdup (session);
+ }
- if (ve_string_empty (item->id))
- return;
+ /* Do nothing if there is no session widget */
+ if (session_widget == NULL)
+ return;
- if (gtk_tree_selection_get_selected (selection, &tm, &iter))
+ /* Last isn't in the session list, so handle separate. */
+ if (strcmp (session, LAST_SESSION) == 0)
{
- gtk_tree_model_get (tm, &iter, GREETER_LIST_ID,
- &id, -1);
+ if (GTK_IS_COMBO_BOX (session_widget))
+ {
+ gtk_combo_box_set_active (GTK_COMBO_BOX (session_widget), 0);
+ }
+ else if (GTK_IS_SCROLLED_WINDOW (session_widget) &&
+ GTK_IS_TREE_VIEW (GTK_BIN (session_widget)->child))
+ {
+ GtkTreeView *tv = GTK_TREE_VIEW (GTK_BIN (session_widget)->child);
+ GtkTreeModel *tm = gtk_tree_view_get_model (tv);
+ GtkTreeSelection *selection = gtk_tree_view_get_selection (tv);
+ GtkTreeIter loopiter;
+
+ if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (tm), &loopiter))
+ gtk_tree_selection_select_iter (selection, &loopiter);
+ }
}
- file = g_strdup_printf ("%s/%s.GreeterInfo",
- ve_sure_string (gdm_config_get_string (GDM_KEY_SERV_AUTHDIR)),
- ve_sure_string (g_getenv ("DISPLAY")));
+ /*
+ * Handle for either combo box or list style, depending on which is being
+ * used.
+ . */
+ if (GTK_IS_COMBO_BOX (session_widget))
+ {
+ for (tmp = sessions; tmp != NULL; tmp = tmp->next)
+ {
+ char *file;
- gdm_set_servauth (file, item->id, id);
+ i++;
+ file = tmp->data;
+ if (strcmp (session, file) == 0)
+ {
+ gtk_combo_box_set_active (GTK_COMBO_BOX (session_widget), i);
+ break;
+ }
+ }
+ }
+ else if (GTK_IS_SCROLLED_WINDOW (session_widget) &&
+ GTK_IS_TREE_VIEW (GTK_BIN (session_widget)->child))
+ {
+ GtkTreeView *tv = GTK_TREE_VIEW (GTK_BIN (session_widget)->child);
+ GtkTreeModel *tm = gtk_tree_view_get_model (tv);
+ GtkTreeSelection *selection = gtk_tree_view_get_selection (tv);
+ GtkTreeIter loopiter;
+
+ if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (tm), &loopiter))
+ {
+ do
+ {
+ char *file;
+
+ gtk_tree_model_get (GTK_TREE_MODEL (tm), &loopiter, GREETER_LIST_ID, &file, -1);
+ if (file != NULL && strcmp (session, file) == 0)
+ {
+ GtkTreePath *path = gtk_tree_model_get_path (tm, &loopiter);
+
+ gtk_tree_selection_select_iter (selection, &loopiter);
+ gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (tv),
+ path, NULL,
+ FALSE, 0.0, 0.0);
+ gtk_tree_path_free (path);
+ break;
+ }
+ } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (tm), &loopiter));
+ }
+ }
}
+/*
+ * This function sets the custom list when the language list has changed in
+ * the language dialog (launched from language button or F10 menu).
+ */
+void
+greeter_custom_set_language (gchar *language)
+{
+ GtkListStore *lang_model = greeter_language_get_model ();
+ GtkTreeIter iter;
+ gboolean valid;
+ char *name, *locale_name;
+ int i=0;
+
+ /* Do nothing if there is no language widget */
+ if (language_widget == NULL)
+ return;
+
+ /*
+ * Handle for either combo box or list style, depending on which is being
+ * used.
+ . */
+ if (GTK_IS_COMBO_BOX (session_widget))
+ {
+ valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (lang_model),
+ &iter);
+ while (valid)
+ {
+ gtk_tree_model_get (GTK_TREE_MODEL (lang_model), &iter,
+ LOCALE_COLUMN, &locale_name, -1);
+
+ if (strcmp (language, locale_name) == 0)
+ {
+ gtk_combo_box_set_active (GTK_COMBO_BOX (language_widget), i);
+ break;
+ }
+ valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (lang_model), &iter);
+ i++;
+ }
+ }
+ else if (GTK_IS_SCROLLED_WINDOW (language_widget) &&
+ GTK_IS_TREE_VIEW (GTK_BIN (language_widget)->child))
+ {
+ GtkTreeView *tv = GTK_TREE_VIEW (GTK_BIN (language_widget)->child);
+ GtkTreeModel *tm = gtk_tree_view_get_model (tv);
+ GtkTreeSelection *selection = gtk_tree_view_get_selection (tv);
+ GtkTreeIter loopiter;
+
+ if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (tm), &loopiter))
+ {
+ do
+ {
+ char *locale_file;
+
+ gtk_tree_model_get (GTK_TREE_MODEL (tm), &loopiter, GREETER_LIST_ID, &locale_file, -1);
+ if (locale_file != NULL && strcmp (language, locale_file) == 0)
+ {
+ GtkTreePath *path = gtk_tree_model_get_path (tm, &loopiter);
+
+ gtk_tree_selection_select_iter (selection, &loopiter);
+ gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (tv),
+ path, NULL,
+ FALSE, 0.0, 0.0);
+ gtk_tree_path_free (path);
+ break;
+ }
+ } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (tm), &loopiter));
+ }
+ }
+}
+
+/* Helper function to set custom list values */
static void
populate_list (GtkTreeModel *tm, GtkTreeSelection *selection, GList *list_items)
{
@@ -69,25 +231,315 @@ populate_list (GtkTreeModel *tm, GtkTreeSelection *selection, GList *list_items)
for (li = list_items; li != NULL; li = li->next)
{
- GreeterItemListItem *litem = li->data;
GtkTreeIter iter = {0};
+ GreeterItemListItem *litem = li->data;
gtk_list_store_append (GTK_LIST_STORE (tm), &iter);
gtk_list_store_set (GTK_LIST_STORE (tm), &iter,
GREETER_LIST_TEXT, litem->text,
- GREETER_LIST_ID, litem->id,
+ GREETER_LIST_ID, litem->id,
-1);
- /* select first item */
- if (li == list_items)
- gtk_tree_selection_select_iter (selection, &iter);
}
}
+/* Helper function to set session values */
+static void
+populate_session (GObject * object)
+{
+ GList *tmp;
+
+ /* Last isn't in the session list, so add separate. */
+ if (GTK_IS_COMBO_BOX (object))
+ gtk_combo_box_append_text (GTK_COMBO_BOX (object), _("Last session"));
+ else if (GTK_IS_TREE_MODEL (object))
+ {
+ GtkTreeIter loopiter;
+ GtkTreeModel *tm = GTK_TREE_MODEL (object);
+ gchar *to_display;
+
+ gtk_list_store_append (GTK_LIST_STORE (tm), &loopiter);
+
+ gtk_list_store_set (GTK_LIST_STORE (tm), &loopiter,
+ GREETER_LIST_TEXT, _("Last session"),
+ GREETER_LIST_ID, LAST_SESSION,
+ -1);
+ }
+
+ /* Loop through the sessions and set the custom list values. */
+ for (tmp = sessions; tmp != NULL; tmp = tmp->next)
+ {
+ GdmSession *session;
+ char *file;
+
+ file = (char *) tmp->data;
+ session = g_hash_table_lookup (sessnames, file);
+
+ if (GTK_IS_COMBO_BOX (object))
+ {
+ if (session->clearname != NULL)
+ gtk_combo_box_append_text (GTK_COMBO_BOX (object), (session->clearname));
+ else
+ gtk_combo_box_append_text (GTK_COMBO_BOX (object), (session->name));
+ }
+ else if (GTK_IS_TREE_MODEL (object))
+ {
+ GtkTreeIter loopiter;
+ GtkTreeModel *tm = GTK_TREE_MODEL (object);
+ gchar *to_display;
+
+ gtk_list_store_append (GTK_LIST_STORE (tm), &loopiter);
+ if (session->clearname != NULL)
+ to_display = session->clearname;
+ else
+ to_display = session->name;
+
+ gtk_list_store_set (GTK_LIST_STORE (tm), &loopiter,
+ GREETER_LIST_TEXT, to_display,
+ GREETER_LIST_ID, file,
+ -1);
+ }
+ }
+
+ /*
+ * Set the session if one exists, this will calback and set the
+ * custom list
+ */
+ if (session_key != NULL)
+ greeter_custom_set_session (session_key);
+}
+
+/* Helper function to set language values */
+static void
+populate_language (GObject *object)
+{
+ GtkListStore *lang_model = greeter_language_get_model ();
+ GtkTreeIter iter;
+ char *name, *untranslated, *display_name, *locale_name;
+ gboolean valid;
+
+ valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (lang_model),
+ &iter);
+ while (valid)
+ {
+ gtk_tree_model_get (GTK_TREE_MODEL (lang_model), &iter,
+ TRANSLATED_NAME_COLUMN, &name,
+ UNTRANSLATED_NAME_COLUMN, &untranslated,
+ LOCALE_COLUMN, &locale_name, -1);
+
+ if (untranslated)
+ display_name = g_strdup_printf ("%s (%s)", name, untranslated);
+ else
+ display_name = g_strdup (name);
+
+ if (GTK_IS_COMBO_BOX (object))
+ gtk_combo_box_append_text (GTK_COMBO_BOX (object), display_name);
+ else if (GTK_IS_TREE_MODEL (object))
+ {
+ GtkTreeIter loopiter;
+ GtkTreeModel *tm = GTK_TREE_MODEL (object);
+
+ gtk_list_store_append (GTK_LIST_STORE (tm), &loopiter);
+ gtk_list_store_set (GTK_LIST_STORE (tm), &loopiter,
+ GREETER_LIST_TEXT, display_name,
+ GREETER_LIST_ID, locale_name,
+ -1);
+ }
+ valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (lang_model), &iter);
+ }
+}
+
+/* Callback helper function to set session value */
+void
+combo_session_selected (char *session_val)
+{
+ GList *tmp;
+ char *file;
+
+ /* Last isn't in the session list, so add separate. */
+ if (strcmp (session_val, _("Last session")) == 0)
+ greeter_set_session (LAST_SESSION);
+ else
+ {
+ /*
+ * Loop through the sessions to find the row the
+ * user has selected, and set that session.
+ */
+ for (tmp = sessions; tmp != NULL; tmp = tmp->next)
+ {
+ GdmSession *session;
+ char *name;
+
+ file = tmp->data;
+ session = g_hash_table_lookup (sessnames, file);
+
+ if (session->clearname)
+ name = session->clearname;
+ else
+ name = session->name;
+
+ if (strcmp (name, session_val) == 0)
+ {
+ greeter_set_session (file);
+ break;
+ }
+ }
+ }
+}
+
+/* Callback function for combo style custom lists */
+static void
+combo_selected (GtkComboBox *combo, GreeterItemInfo *item)
+{
+ GList *tmp;
+ char *id = NULL;
+ char *file;
+ char *active;
+
+ if (ve_string_empty (item->id))
+ return;
+
+ active = gtk_combo_box_get_active_text (combo);
+
+ if (strcmp (item->id, "session") == 0)
+ {
+ combo_session_selected (active);
+ }
+ else if (strcmp (item->id, "language") == 0)
+ {
+ /*
+ * Since combo boxes can't store the ID value, have to do some
+ * extra work to figure out which row is selected.
+ */
+ GtkListStore *lang_model = greeter_language_get_model ();
+ GtkTreeIter iter;
+ char *name, *untranslated, *display_name, *locale_name;
+ gboolean valid;
+
+ valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (lang_model),
+ &iter);
+ while (valid)
+ {
+ gtk_tree_model_get (GTK_TREE_MODEL (lang_model), &iter,
+ TRANSLATED_NAME_COLUMN, &name,
+ UNTRANSLATED_NAME_COLUMN, &untranslated,
+ LOCALE_COLUMN, &locale_name, -1);
+
+ if (untranslated)
+ display_name = g_strdup_printf ("%s (%s)", name, untranslated);
+ else
+ display_name = g_strdup (name);
+
+ if (strcmp (display_name, active) == 0)
+ {
+ greeter_language_set (locale_name);
+ break;
+ }
+ g_free (display_name);
+ valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (lang_model), &iter);
+ }
+ }
+ else
+ {
+ if (DOING_GDM_DEVELOPMENT)
+ return;
+
+ id = gtk_combo_box_get_active_text (combo);
+ file = g_strdup_printf ("%s/%s.GreeterInfo",
+ ve_sure_string (gdm_config_get_string (GDM_KEY_SERV_AUTHDIR)),
+ ve_sure_string (g_getenv ("DISPLAY")));
+
+ gdm_save_customlist_data (file, item->id, id);
+ }
+}
+
+/* Setup combo sytle custom list */
+static void
+setup_combo_customlist (GtkComboBox *combo, GreeterItemInfo *item)
+{
+ GList *li;
+
+ g_signal_connect (G_OBJECT (combo), "changed",
+ G_CALLBACK (combo_selected), item);
+
+ if (strcmp (item->id, "session") == 0)
+ {
+ populate_session (G_OBJECT (combo));
+ /*
+ * Do not select since the session_init will initialize the
+ * value and cause the combo list to get set without needing
+ * to do it here.
+ */
+ }
+ else if (strcmp (item->id, "language") == 0)
+ {
+ populate_language (G_OBJECT (combo));
+ /* Select first */
+ gtk_combo_box_set_active (combo, 0);
+ }
+ else
+ {
+ for (li = item->data.list.items; li != NULL; li = li->next)
+ {
+ GreeterItemListItem *litem = li->data;
+ gtk_combo_box_append_text (combo, litem->text);
+ }
+ /* Select first */
+ gtk_combo_box_set_active (combo, 0);
+ }
+}
+
+/* Callback function for list style custom lists */
+static void
+list_selected (GtkTreeSelection *selection, GreeterItemInfo *item)
+{
+ GtkTreeModel *tm = NULL;
+ GtkTreeIter iter = {0};
+ char *id = NULL;
+ char *file;
+
+ if (ve_string_empty (item->id))
+ return;
+
+ if (gtk_tree_selection_get_selected (selection, &tm, &iter))
+ {
+ gtk_tree_model_get (tm, &iter, GREETER_LIST_ID,
+ &id, -1);
+ }
+
+ /*
+ * Note for session and language we are using the id to store the
+ * value to pass in.
+ */
+ if (strcmp (item->id, "session") == 0)
+ {
+ if (id != NULL)
+ greeter_set_session (id);
+ }
+ else if (strcmp (item->id, "language") == 0)
+ {
+ if (id != NULL)
+ greeter_language_set (id);
+ }
+ else
+ {
+ if (DOING_GDM_DEVELOPMENT)
+ return;
+
+ file = g_strdup_printf ("%s/%s.GreeterInfo",
+ ve_sure_string (gdm_config_get_string (GDM_KEY_SERV_AUTHDIR)),
+ ve_sure_string (g_getenv ("DISPLAY")));
+
+ gdm_save_customlist_data (file, item->id, id);
+ }
+}
+
+/* Setup custom list style */
static void
setup_customlist (GtkWidget *tv, GreeterItemInfo *item)
{
GtkTreeModel *tm;
GtkTreeViewColumn *column;
GtkTreeSelection *selection;
+ GtkTreeIter iter = {0};
gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (tv),
FALSE);
@@ -95,7 +547,7 @@ setup_customlist (GtkWidget *tv, GreeterItemInfo *item)
gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
g_signal_connect (selection, "changed",
- G_CALLBACK (row_selected),
+ G_CALLBACK (list_selected),
item);
tm = (GtkTreeModel *)gtk_list_store_new (2,
@@ -110,9 +562,38 @@ setup_customlist (GtkWidget *tv, GreeterItemInfo *item)
NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW (tv), column);
- populate_list (tm, selection, item->data.list.items);
+ if (strcmp (item->id, "session") == 0)
+ {
+ populate_session (G_OBJECT (tm));
+ /*
+ * Do not select since the session_init will initialize the
+ * value and cause the combo list to get set without needing
+ * to do it here.
+ */
+ }
+ else if (strcmp (item->id, "language") == 0)
+ {
+ populate_language (G_OBJECT (tm));
+
+ /* Select first item */
+ if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (tm), &iter))
+ gtk_tree_selection_select_iter (selection, &iter);
+ }
+ else
+ {
+ populate_list (tm, selection, item->data.list.items);
+
+ /* Select first item */
+ if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (tm), &iter))
+ gtk_tree_selection_select_iter (selection, &iter);
+ }
}
+/*
+ * This function initializes all custom lists aside from
+ * the userlist (face browser), which is handled
+ * separately.
+ */
gboolean
greeter_item_customlist_setup (void)
{
@@ -128,12 +609,29 @@ greeter_item_customlist_setup (void)
GNOME_IS_CANVAS_WIDGET (info->item))
{
GtkWidget *sw = GNOME_CANVAS_WIDGET (info->item)->widget;
+
+ /*
+ * Store these so that when the values change in the
+ * F10 session/language dialogs, we can easily modify
+ * them.
+ */
+ if (strcmp (info->id, "session") == 0)
+ session_widget = sw;
+ else if (strcmp (info->id, "language") == 0)
+ language_widget = sw;
+
+ /* If combo or list style, process appropriately */
if (GTK_IS_SCROLLED_WINDOW (sw) &&
GTK_IS_TREE_VIEW (GTK_BIN (sw)->child))
{
setup_customlist (GTK_BIN (sw)->child, info);
}
+ else if (GTK_IS_COMBO_BOX (sw))
+ {
+ setup_combo_customlist (GTK_COMBO_BOX (sw), info);
+ }
}
}
return TRUE;
}
+
diff --git a/gui/greeter/greeter_item_customlist.h b/gui/greeter/greeter_item_customlist.h
index 9259bfac..b3ecb951 100644
--- a/gui/greeter/greeter_item_customlist.h
+++ b/gui/greeter/greeter_item_customlist.h
@@ -22,5 +22,7 @@
#include "greeter_item.h"
gboolean greeter_item_customlist_setup (void);
+void greeter_custom_set_session (gchar *session);
+void greeter_custom_set_language (gchar *language);
#endif
diff --git a/gui/greeter/greeter_item_ulist.c b/gui/greeter/greeter_item_ulist.c
index fd13da7f..988040bf 100644
--- a/gui/greeter/greeter_item_ulist.c
+++ b/gui/greeter/greeter_item_ulist.c
@@ -66,8 +66,10 @@ void
greeter_item_ulist_unset_selected_user (void)
{
GtkTreeSelection *selection;
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (user_list));
- gtk_tree_selection_unselect_all (selection);
+ if (user_list != NULL) {
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (user_list));
+ gtk_tree_selection_unselect_all (selection);
+ }
if (selected_user != NULL)
g_free (selected_user);
diff --git a/gui/greeter/greeter_parser.c b/gui/greeter/greeter_parser.c
index ad59a316..e4b0f3e9 100644
--- a/gui/greeter/greeter_parser.c
+++ b/gui/greeter/greeter_parser.c
@@ -1457,6 +1457,22 @@ parse_list (xmlNodePtr node,
GError **error)
{
xmlNodePtr child;
+ xmlChar *prop;
+
+ info->data.list.combo_type = FALSE;
+ prop = xmlGetProp (node,(const xmlChar *) "combo");
+ if (prop)
+ {
+ if (strcmp ((char *) prop, "true") == 0)
+ {
+ info->data.list.combo_type = TRUE;
+ }
+ else if (strcmp ((char *) prop, "false") == 0)
+ {
+ info->data.list.combo_type = FALSE;
+ }
+ xmlFree (prop);
+ }
child = node->children;
while (child)
@@ -1494,15 +1510,28 @@ parse_list (xmlNodePtr node,
child = child->next;
}
- if (info->data.list.items != NULL) {
- if G_UNLIKELY (strcmp (info->id, "userlist") == 0) {
+ if ((strcmp (info->id, "userlist") == 0) && (info->data.list.combo_type == TRUE)) {
g_set_error (error,
GREETER_PARSER_ERROR,
GREETER_PARSER_ERROR_BAD_SPEC,
- "List of id userlist cannot have custom list items");
+ "userlist doest not support combo style");
+ return FALSE;
+ } else if (info->data.list.items != NULL) {
+
+ if G_UNLIKELY (strcmp (info->id, "userlist") == 0 ||
+ strcmp (info->id, "session") == 0 ||
+ strcmp (info->id, "language") == 0) {
+ g_set_error (error,
+ GREETER_PARSER_ERROR,
+ GREETER_PARSER_ERROR_BAD_SPEC,
+ "List of id userlist, session, and language cannot have custom list items");
return FALSE;
}
custom_items = g_list_append (custom_items, info);
+
+ } else if (strcmp (info->id, "session") == 0 ||
+ strcmp (info->id, "language") == 0) {
+ custom_items = g_list_append (custom_items, info);
}
return TRUE;
diff --git a/gui/greeter/greeter_session.c b/gui/greeter/greeter_session.c
index 070dea80..91bc7066 100644
--- a/gui/greeter/greeter_session.c
+++ b/gui/greeter/greeter_session.c
@@ -40,14 +40,21 @@
#include "greeter_events.h"
#include "greeter_parser.h"
-static GtkWidget *session_dialog;
-static GSList *session_group = NULL;
-
-extern GList *sessions;
+static GtkWidget *session_dialog;
+static GSList *session_group = NULL;
+extern GList *sessions;
extern GHashTable *sessnames;
-extern gchar *default_session;
-extern char *current_session;
-extern gboolean session_dir_whacked_out;
+extern gchar *default_session;
+extern char *current_session;
+extern gboolean session_dir_whacked_out;
+
+void
+greeter_set_session (char *session)
+{
+ g_free (current_session);
+ current_session = g_strdup (session);
+ greeter_custom_set_session (session);
+}
void
greeter_session_init (void)
@@ -67,8 +74,7 @@ greeter_session_init (void)
int num = 1;
char *label;
- g_free (current_session);
- current_session = NULL;
+ greeter_set_session (NULL);
session_dialog = dialog = gtk_dialog_new ();
if (tooltips == NULL)
@@ -118,7 +124,7 @@ greeter_session_init (void)
if (gdm_config_get_bool (GDM_KEY_SHOW_LAST_SESSION))
{
- current_session = g_strdup (LAST_SESSION);
+ greeter_set_session (LAST_SESSION);
radio = gtk_radio_button_new_with_mnemonic (session_group, _("_Last session"));
g_object_set_data (G_OBJECT (radio),
@@ -201,11 +207,9 @@ static void
greeter_session_handler (GreeterItemInfo *info,
gpointer user_data)
{
- GreeterItemInfo *entry_info = greeter_lookup_id ("user-pw-entry");
- GtkWidget *entry = GNOME_CANVAS_WIDGET (entry_info->item)->widget;
GSList *tmp;
int ret;
-
+
/* Select the proper session */
tmp = session_group;
while (tmp != NULL)
@@ -242,12 +246,10 @@ greeter_session_handler (GreeterItemInfo *info,
GtkWidget *w = tmp->data;
const char *n;
-
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w)))
{
n = g_object_get_data (G_OBJECT (w), SESSION_NAME);
- g_free (current_session);
- current_session = g_strdup (n);
+ greeter_set_session ((char *)n);
break;
}
diff --git a/gui/greeter/greeter_session.h b/gui/greeter/greeter_session.h
index 7bef0854..43cf8f72 100644
--- a/gui/greeter/greeter_session.h
+++ b/gui/greeter/greeter_session.h
@@ -21,5 +21,6 @@
void greeter_session_init (void);
void greeter_item_session_setup (void);
+void greeter_set_session (char *session);
#endif /* __GREETER_SESSION_H__ */