[gdm] Make greeter window more clear when disable_user_list == TRUE



commit 5f8723c4fccff6aed79edbe635e3e16fa74a42d1
Author: Ray Strode <rstrode redhat com>
Date:   Thu Jul 16 17:05:17 2009 -0400

    Make greeter window more clear when disable_user_list == TRUE
    
    Previously it would show a lone "Other..." menu item that the user
    was expected to click on.  Now, instead it provides a "Log In"
    button.
    
    This commit is based almost entirely on a patch by:
    
    Philip Spencer <pspencer fields utoronto ca>
    
    From:
    
    http://bugzilla.gnome.org/show_bug.cgi?id=568323

 gui/simple-greeter/gdm-chooser-widget.c          |   28 +++++++-
 gui/simple-greeter/gdm-greeter-login-window.c    |   83 ++++++++++++++++++++-
 gui/simple-greeter/gdm-greeter-session.c         |   15 ++++-
 gui/simple-greeter/gdm-simple-greeter.schemas.in |   12 +++-
 gui/simple-greeter/gdm-user-chooser-widget.c     |   54 ++++++++++++--
 5 files changed, 176 insertions(+), 16 deletions(-)
---
diff --git a/gui/simple-greeter/gdm-chooser-widget.c b/gui/simple-greeter/gdm-chooser-widget.c
index f0298c6..07de612 100644
--- a/gui/simple-greeter/gdm-chooser-widget.c
+++ b/gui/simple-greeter/gdm-chooser-widget.c
@@ -104,7 +104,8 @@ struct GdmChooserWidgetPrivate
 enum {
         PROP_0,
         PROP_INACTIVE_TEXT,
-        PROP_ACTIVE_TEXT
+        PROP_ACTIVE_TEXT,
+        PROP_LIST_VISIBLE
 };
 
 enum {
@@ -593,6 +594,17 @@ update_separator_visibility (GdmChooserWidget *widget)
 }
 
 static void
+update_chooser_visibility (GdmChooserWidget *widget)
+{
+        if (gdm_chooser_widget_get_number_of_items (widget) > 0) {
+                gtk_widget_show (widget->priv->scrollable_widget);
+        } else {
+                gtk_widget_hide (widget->priv->scrollable_widget);
+        }
+        g_object_notify (G_OBJECT (widget), "list-visible");
+}
+
+static void
 set_inactive_items_visible (GdmChooserWidget *widget,
                             gboolean          should_show)
 {
@@ -1147,6 +1159,9 @@ gdm_chooser_widget_get_property (GObject        *object,
         case PROP_ACTIVE_TEXT:
                 g_value_set_string (value, self->priv->active_text);
                 break;
+        case PROP_LIST_VISIBLE:
+                g_value_set_boolean (value, GTK_WIDGET_VISIBLE (self->priv->scrollable_widget));
+                break;
         default:
                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                 break;
@@ -1319,6 +1334,14 @@ gdm_chooser_widget_class_init (GdmChooserWidgetClass *klass)
                                                               (G_PARAM_READWRITE |
                                                                G_PARAM_CONSTRUCT)));
 
+        g_object_class_install_property (object_class,
+                                         PROP_LIST_VISIBLE,
+                                         g_param_spec_boolean ("list-visible",
+                                                              _("List Visible"),
+                                                              _("Whether or not the chooser list is visible"),
+                                                              TRUE,
+                                                              G_PARAM_READABLE));
+
         g_type_class_add_private (klass, sizeof (GdmChooserWidgetPrivate));
 }
 
@@ -1771,7 +1794,6 @@ gdm_chooser_widget_init (GdmChooserWidget *widget)
         add_frame (widget);
 
         widget->priv->scrollable_widget = gdm_scrollable_widget_new ();
-        gtk_widget_show (widget->priv->scrollable_widget);
         gtk_container_add (GTK_CONTAINER (widget->priv->frame_alignment),
                            widget->priv->scrollable_widget);
 
@@ -2055,6 +2077,7 @@ gdm_chooser_widget_add_item (GdmChooserWidget *widget,
                                            -1);
 
         move_cursor_to_top (widget);
+        update_chooser_visibility (widget);
 }
 
 void
@@ -2103,6 +2126,7 @@ gdm_chooser_widget_remove_item (GdmChooserWidget *widget,
         gtk_list_store_remove (widget->priv->list_store, &iter);
 
         move_cursor_to_top (widget);
+        update_chooser_visibility (widget);
 }
 
 gboolean
diff --git a/gui/simple-greeter/gdm-greeter-login-window.c b/gui/simple-greeter/gdm-greeter-login-window.c
index 01596e8..13b317c 100644
--- a/gui/simple-greeter/gdm-greeter-login-window.c
+++ b/gui/simple-greeter/gdm-greeter-login-window.c
@@ -92,6 +92,7 @@
 #define KEY_GREETER_DIR             "/apps/gdm/simple-greeter"
 #define KEY_BANNER_MESSAGE_ENABLED  KEY_GREETER_DIR "/banner_message_enable"
 #define KEY_BANNER_MESSAGE_TEXT     KEY_GREETER_DIR "/banner_message_text"
+#define KEY_BANNER_MESSAGE_TEXT_NOCHOOSER     KEY_GREETER_DIR "/banner_message_text_nochooser"
 #define KEY_LOGO                    KEY_GREETER_DIR "/logo_icon_name"
 #define KEY_DISABLE_RESTART_BUTTONS KEY_GREETER_DIR "/disable_restart_buttons"
 #define GDM_GREETER_LOGIN_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_GREETER_LOGIN_WINDOW, GdmGreeterLoginWindowPrivate))
@@ -103,6 +104,7 @@ enum {
 
 enum {
         LOGIN_BUTTON_HIDDEN = 0,
+        LOGIN_BUTTON_START_OTHER,
         LOGIN_BUTTON_ANSWER_QUERY,
         LOGIN_BUTTON_TIMED_LOGIN
 };
@@ -114,6 +116,7 @@ struct GdmGreeterLoginWindowPrivate
         GtkWidget       *auth_banner_label;
         guint            display_is_local : 1;
         guint            is_interactive : 1;
+        guint            user_chooser_loaded : 1;
         GConfClient     *client;
 
         gboolean         banner_message_enabled;
@@ -160,6 +163,10 @@ static void     restart_timed_login_timeout (GdmGreeterLoginWindow *login_window
 static void     on_user_unchosen            (GdmUserChooserWidget *user_chooser,
                                              GdmGreeterLoginWindow *login_window);
 
+static void     switch_mode                 (GdmGreeterLoginWindow *login_window,
+                                             int                    number);
+static void     update_banner_message       (GdmGreeterLoginWindow *login_window);
+
 G_DEFINE_TYPE (GdmGreeterLoginWindow, gdm_greeter_login_window, GTK_TYPE_WINDOW)
 
 static void
@@ -407,6 +414,17 @@ on_login_button_clicked_timed_login (GtkButton             *button,
 
         _gdm_greeter_login_window_set_interactive (login_window, TRUE);
 }
+static void
+on_login_button_clicked_start_other (GtkButton             *button,
+                                     GdmGreeterLoginWindow *login_window)
+{
+        g_debug ("GdmGreeterLoginWindow: starting OTHER login");
+
+        g_signal_emit (G_OBJECT (login_window), signals[USER_SELECTED],
+                       0, GDM_USER_CHOOSER_USER_OTHER);
+        g_signal_emit (login_window, signals[BEGIN_VERIFICATION], 0);
+        switch_mode (login_window, MODE_AUTHENTICATION);
+}
 
 static void
 set_log_in_button_mode (GdmGreeterLoginWindow *login_window,
@@ -427,6 +445,10 @@ set_log_in_button_mode (GdmGreeterLoginWindow *login_window,
         case LOGIN_BUTTON_HIDDEN:
                 gtk_widget_hide (button);
                 break;
+        case LOGIN_BUTTON_START_OTHER:
+                login_window->priv->login_button_handler_id = g_signal_connect (button, "clicked", G_CALLBACK (on_login_button_clicked_start_other), login_window);
+                gtk_widget_show (button);
+                break;
         case LOGIN_BUTTON_ANSWER_QUERY:
                 login_window->priv->login_button_handler_id = g_signal_connect (button, "clicked", G_CALLBACK (on_login_button_clicked_answer_query), login_window);
                 gtk_widget_show (button);
@@ -441,6 +463,24 @@ set_log_in_button_mode (GdmGreeterLoginWindow *login_window,
         }
 }
 
+static void
+adjust_other_login_visibility(GdmGreeterLoginWindow *login_window)
+{
+        if (! login_window->priv->user_chooser_loaded) {
+                return;
+        }
+
+        if (login_window->priv->dialog_mode != MODE_SELECTION) {
+                return;
+        }
+
+        if (gdm_chooser_widget_get_number_of_items (GDM_CHOOSER_WIDGET (login_window->priv->user_chooser)) == 0) {
+                set_log_in_button_mode (login_window, LOGIN_BUTTON_START_OTHER);
+        } else {
+                set_log_in_button_mode (login_window, LOGIN_BUTTON_HIDDEN);
+        }
+}
+
 static gboolean
 can_suspend (GdmGreeterLoginWindow *login_window)
 {
@@ -708,7 +748,11 @@ reset_dialog (GdmGreeterLoginWindow *login_window)
         set_sensitive (login_window, TRUE);
         set_ready (login_window);
         set_focus (GDM_GREETER_LOGIN_WINDOW (login_window));
-        gdm_chooser_widget_propagate_pending_key_events (GDM_CHOOSER_WIDGET (login_window->priv->user_chooser));
+        update_banner_message (login_window);
+        adjust_other_login_visibility (login_window);
+        if (gdm_chooser_widget_get_number_of_items (GDM_CHOOSER_WIDGET (login_window->priv->user_chooser)) >= 1) {
+                gdm_chooser_widget_propagate_pending_key_events (GDM_CHOOSER_WIDGET (login_window->priv->user_chooser));
+        }
 }
 
 static void
@@ -1320,9 +1364,21 @@ shutdown_button_clicked (GtkButton             *button,
 }
 
 static void
+on_user_chooser_visibility_changed (GdmGreeterLoginWindow *login_window)
+{
+        update_banner_message (login_window);
+        adjust_other_login_visibility (login_window);
+}
+
+static void
 on_users_loaded (GdmUserChooserWidget  *user_chooser,
                  GdmGreeterLoginWindow *login_window)
 {
+        g_debug ("GdmGreeterLoginWindow: users loaded");
+        login_window->priv->user_chooser_loaded = TRUE;
+        update_banner_message (login_window);
+        adjust_other_login_visibility (login_window);
+
         gdm_chooser_widget_activate_if_one_item (GDM_CHOOSER_WIDGET (login_window->priv->user_chooser));
 }
 
@@ -1594,6 +1650,11 @@ load_theme (GdmGreeterLoginWindow *login_window)
                           G_CALLBACK (on_user_unchosen),
                           login_window);
 
+        g_signal_connect_swapped (login_window->priv->user_chooser,
+                                 "notify::list-visible",
+                                 G_CALLBACK (on_user_chooser_visibility_changed),
+                                 login_window);
+
         gtk_widget_show (login_window->priv->user_chooser);
 
         login_window->priv->auth_banner_label = glade_xml_get_widget (login_window->priv->xml, "auth-banner-label");
@@ -1711,9 +1772,23 @@ update_banner_message (GdmGreeterLoginWindow *login_window)
                 g_debug ("GdmGreeterLoginWindow: banner message disabled");
                 gtk_widget_hide (login_window->priv->auth_banner_label);
         } else {
-                char *message;
+                char *message = NULL;
                 error = NULL;
-                message = gconf_client_get_string (login_window->priv->client, KEY_BANNER_MESSAGE_TEXT, &error);
+                if (login_window->priv->user_chooser_loaded && gdm_chooser_widget_get_number_of_items (GDM_CHOOSER_WIDGET (login_window->priv->user_chooser)) == 0) {
+                        message = gconf_client_get_string (login_window->priv->client, KEY_BANNER_MESSAGE_TEXT_NOCHOOSER, &error);
+                        if (error != NULL) {
+                                g_debug("GdmGreeterLoginWindow: unable to get nochooser banner text: %s", error->message);
+                                g_error_free(error);
+                        }
+                }
+                error = NULL;
+                if (message == NULL) {
+                        message = gconf_client_get_string (login_window->priv->client, KEY_BANNER_MESSAGE_TEXT, &error);
+                        if (error != NULL) {
+                                g_debug("GdmGreeterLoginWindow: unable to get banner text: %s", error->message);
+                                g_error_free(error);
+                        }
+                }
                 if (message != NULL) {
                         char *markup;
                         markup = g_markup_printf_escaped ("<small><i>%s</i></small>", message);
@@ -1885,7 +1960,7 @@ on_gconf_key_changed (GConfClient           *client,
                         g_warning ("Error retrieving configuration key '%s': Invalid type",
                                    key);
                 }
-        } else if (strcmp (key, KEY_BANNER_MESSAGE_TEXT) == 0) {
+        } else if (strcmp (key, KEY_BANNER_MESSAGE_TEXT) == 0 || strcmp (key, KEY_BANNER_MESSAGE_TEXT_NOCHOOSER) == 0) {
                 if (login_window->priv->banner_message_enabled) {
                         update_banner_message (login_window);
                 }
diff --git a/gui/simple-greeter/gdm-greeter-session.c b/gui/simple-greeter/gdm-greeter-session.c
index 17afb4e..fe2de48 100644
--- a/gui/simple-greeter/gdm-greeter-session.c
+++ b/gui/simple-greeter/gdm-greeter-session.c
@@ -37,6 +37,7 @@
 #include "gdm-greeter-client.h"
 #include "gdm-greeter-panel.h"
 #include "gdm-greeter-login-window.h"
+#include "gdm-user-chooser-widget.h"
 
 #include "gdm-profile.h"
 
@@ -102,11 +103,23 @@ on_reset (GdmGreeterClient  *client,
 }
 
 static void
+show_or_hide_user_options (GdmGreeterSession *session,
+                           const char        *username)
+{
+    if (username != NULL && strcmp (username, GDM_USER_CHOOSER_USER_OTHER) != 0) {
+            gdm_greeter_panel_show_user_options (GDM_GREETER_PANEL (session->priv->panel));
+    } else {
+            gdm_greeter_panel_hide_user_options (GDM_GREETER_PANEL (session->priv->panel));
+    }
+}
+
+static void
 on_selected_user_changed (GdmGreeterClient  *client,
                           const char        *text,
                           GdmGreeterSession *session)
 {
         g_debug ("GdmGreeterSession: selected user changed: %s", text);
+        show_or_hide_user_options (session, text);
 }
 
 static void
@@ -240,7 +253,7 @@ on_select_user (GdmGreeterLoginWindow *login_window,
                 const char            *text,
                 GdmGreeterSession     *session)
 {
-        gdm_greeter_panel_show_user_options (GDM_GREETER_PANEL (session->priv->panel));
+        show_or_hide_user_options (session, text);
         gdm_greeter_client_call_select_user (session->priv->client,
                                              text);
 }
diff --git a/gui/simple-greeter/gdm-simple-greeter.schemas.in b/gui/simple-greeter/gdm-simple-greeter.schemas.in
index 270bb8c..f6e9a6b 100644
--- a/gui/simple-greeter/gdm-simple-greeter.schemas.in
+++ b/gui/simple-greeter/gdm-simple-greeter.schemas.in
@@ -1,6 +1,5 @@
 <gconfschemafile>
   <schemalist>
-
     <schema>
       <key>/schemas/apps/gdm/simple-greeter/debug</key>
       <applyto>/apps/gdm/simple-greeter/debug</applyto>
@@ -35,6 +34,17 @@
       </locale>
     </schema>
     <schema>
+      <key>/schemas/apps/gdm/simple-greeter/banner_message_text_nochooser</key>
+      <applyto>/apps/gdm/simple-greeter/banner_message_text_nochooser</applyto>
+      <owner>gdm-simple-greeter</owner>
+      <type>string</type>
+      <default></default>
+      <locale name="C">
+        <short>Banner message text when chooser is empty</short>
+        <long>Text banner message to show on the login window when the user chooser is empty, instead of banner_message_text.</long>
+      </locale>
+    </schema>
+    <schema>
       <key>/schemas/apps/gdm/simple-greeter/logo_icon_name</key>
       <applyto>/apps/gdm/simple-greeter/logo_icon_name</applyto>
       <owner>gdm-simple-greeter</owner>
diff --git a/gui/simple-greeter/gdm-user-chooser-widget.c b/gui/simple-greeter/gdm-user-chooser-widget.c
index b1cb281..90b523a 100644
--- a/gui/simple-greeter/gdm-user-chooser-widget.c
+++ b/gui/simple-greeter/gdm-user-chooser-widget.c
@@ -67,6 +67,8 @@ struct GdmUserChooserWidgetPrivate
         guint           show_user_auto : 1;
         guint           show_normal_users : 1;
 
+        guint           has_user_other : 1;
+
         guint           load_idle_id;
 };
 
@@ -83,6 +85,9 @@ static void     gdm_user_chooser_widget_finalize    (GObject                   *
 
 G_DEFINE_TYPE (GdmUserChooserWidget, gdm_user_chooser_widget, GDM_TYPE_CHOOSER_WIDGET)
 
+static void     add_user_other    (GdmUserChooserWidget *widget);
+static void     remove_user_other (GdmUserChooserWidget *widget);
+
 static int
 get_font_height_for_widget (GtkWidget *widget)
 {
@@ -123,8 +128,31 @@ get_icon_height_for_widget (GtkWidget *widget)
 }
 
 static void
+update_other_user_visibility (GdmUserChooserWidget *widget)
+{
+        if (!widget->priv->show_user_other) {
+                if (widget->priv->has_user_other) {
+                        remove_user_other (widget);
+                }
+
+                return;
+        }
+
+        if (gdm_chooser_widget_get_number_of_items (GDM_CHOOSER_WIDGET (widget)) == 1) {
+                /* we hide the Other user if it's the last one, and we show it
+                 * if there's another user */
+                if (widget->priv->has_user_other) {
+                        remove_user_other (widget);
+                } else {
+                        add_user_other (widget);
+                }
+        }
+}
+
+static void
 add_user_other (GdmUserChooserWidget *widget)
 {
+        widget->priv->has_user_other = TRUE;
         gdm_chooser_widget_add_item (GDM_CHOOSER_WIDGET (widget),
                                      GDM_USER_CHOOSER_USER_OTHER,
                                      NULL,
@@ -151,6 +179,7 @@ add_user_guest (GdmUserChooserWidget *widget)
                                      0,
                                      FALSE,
                                      TRUE);
+        update_other_user_visibility (widget);
 }
 
 static void
@@ -164,11 +193,13 @@ add_user_auto (GdmUserChooserWidget *widget)
                                      0,
                                      FALSE,
                                      TRUE);
+        update_other_user_visibility (widget);
 }
 
 static void
 remove_user_other (GdmUserChooserWidget *widget)
 {
+        widget->priv->has_user_other = FALSE;
         gdm_chooser_widget_remove_item (GDM_CHOOSER_WIDGET (widget),
                                         GDM_USER_CHOOSER_USER_OTHER);
 }
@@ -178,6 +209,7 @@ remove_user_guest (GdmUserChooserWidget *widget)
 {
         gdm_chooser_widget_remove_item (GDM_CHOOSER_WIDGET (widget),
                                         GDM_USER_CHOOSER_USER_GUEST);
+        update_other_user_visibility (widget);
 }
 
 static void
@@ -185,6 +217,7 @@ remove_user_auto (GdmUserChooserWidget *widget)
 {
         gdm_chooser_widget_remove_item (GDM_CHOOSER_WIDGET (widget),
                                         GDM_USER_CHOOSER_USER_AUTO);
+        update_other_user_visibility (widget);
 }
 
 void
@@ -195,11 +228,7 @@ gdm_user_chooser_widget_set_show_user_other (GdmUserChooserWidget *widget,
 
         if (widget->priv->show_user_other != show_user) {
                 widget->priv->show_user_other = show_user;
-                if (show_user) {
-                        add_user_other (widget);
-                } else {
-                        remove_user_other (widget);
-                }
+                update_other_user_visibility (widget);
         }
 }
 
@@ -374,6 +403,8 @@ add_user (GdmUserChooserWidget *widget,
         if (pixbuf != NULL) {
                 g_object_unref (pixbuf);
         }
+
+        update_other_user_visibility (widget);
 }
 
 static void
@@ -405,6 +436,8 @@ on_user_removed (GdmUserManager       *manager,
 
         gdm_chooser_widget_remove_item (GDM_CHOOSER_WIDGET (widget),
                                         user_name);
+
+        update_other_user_visibility (widget);
 }
 
 static void
@@ -448,8 +481,7 @@ on_users_loaded (GdmUserManager       *manager,
                  GdmUserChooserWidget *widget)
 {
         GSList *users;
-
-        widget->priv->loaded = TRUE;
+        gboolean list_visible;
 
         g_debug ("GdmUserChooserWidget: Users loaded");
 
@@ -459,7 +491,12 @@ on_users_loaded (GdmUserManager       *manager,
                 users = g_slist_delete_link (users, users);
         }
 
-        gtk_widget_grab_focus (GTK_WIDGET (widget));
+        g_object_get (G_OBJECT (widget), "list-visible", &list_visible, NULL);
+
+        if (list_visible) {
+                gtk_widget_grab_focus (GTK_WIDGET (widget));
+        }
+        widget->priv->loaded = TRUE;
 
         gdm_chooser_widget_loaded (GDM_CHOOSER_WIDGET (widget));
 }
@@ -510,6 +547,7 @@ gdm_user_chooser_widget_constructor (GType                  type,
                                                                                                               n_construct_properties,
                                                                                                               construct_properties));
 
+        widget->priv->has_user_other = FALSE;
         widget->priv->show_normal_users = !is_user_list_disabled (widget);
 
         widget->priv->load_idle_id = g_idle_add ((GSourceFunc)load_users, widget);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]