GNOME #583856
Novell #439918

Index: gdm-3.0.0/gui/simple-greeter/gdm-greeter-login-window.c
===================================================================
--- gdm-3.0.0.orig/gui/simple-greeter/gdm-greeter-login-window.c	2011-04-04 16:37:16.000000000 +0200
+++ gdm-3.0.0/gui/simple-greeter/gdm-greeter-login-window.c	2011-05-04 22:40:43.980253960 +0200
@@ -131,8 +131,18 @@ struct GdmGreeterLoginWindowPrivate
 
         guint            login_button_handler_id;
         guint            start_session_handler_id;
+
+        GSList          *message_queue;
+        guint            message_timeout_id;
+        gboolean         session_ready_to_start;
 };
 
+typedef struct {
+        char            *message_text;
+        guint            timeout_seconds;
+        gboolean         needs_beep;
+} QueuedMessage;
+
 enum {
         PROP_0,
         PROP_DISPLAY_IS_LOCAL,
@@ -225,6 +235,65 @@ set_message (GdmGreeterLoginWindow *logi
 }
 
 static void
+free_queued_message (QueuedMessage *msg)
+{
+        g_free (msg->message_text);
+        g_free (msg);
+}
+
+static void
+purge_message_queue (GdmGreeterLoginWindow *login_window)
+{
+        g_slist_free_full (login_window->priv->message_queue, (GDestroyNotify) free_queued_message);
+        if (login_window->priv->message_timeout_id) {
+                g_source_remove (login_window->priv->message_timeout_id);
+                login_window->priv->message_timeout_id = 0;
+        }
+}
+
+static gboolean
+message_set_or_timeout (GdmGreeterLoginWindow *login_window)
+{
+        QueuedMessage *msg;
+        if (login_window->priv->message_queue) {
+                msg = (QueuedMessage *)login_window->priv->message_queue->data;
+                set_message (login_window, msg->message_text);
+                login_window->priv->message_timeout_id = g_timeout_add_seconds (msg->timeout_seconds, (GSourceFunc)message_set_or_timeout, login_window);
+                if (msg->needs_beep)
+                        gdk_window_beep (gtk_widget_get_window (GTK_WIDGET (login_window)));
+                free_queued_message (msg);
+                login_window->priv->message_queue = g_slist_delete_link (login_window->priv->message_queue,
+                                                                         login_window->priv->message_queue);
+        } else {
+                set_message (login_window, "");
+                login_window->priv->message_timeout_id = 0;
+                if (login_window->priv->session_ready_to_start) {
+                        /* All messages have been shown, proceed */
+                        g_signal_emit (login_window, signals[START_SESSION], 0);
+                }
+        }
+        return FALSE;
+}
+
+static void
+queue_message (GdmGreeterLoginWindow *login_window,
+               const char            *text,
+               guint                  timeout_seconds,
+               gboolean               needs_beep)
+{
+        QueuedMessage *msg = g_new0 (QueuedMessage, 1);
+        msg->message_text = g_strdup (text);
+        msg->timeout_seconds = timeout_seconds;
+        msg->needs_beep = needs_beep;
+
+        login_window->priv->message_queue = g_slist_append (login_window->priv->message_queue, msg);
+        if (login_window->priv->message_timeout_id == 0) {
+                message_set_or_timeout (login_window);
+        }
+}
+
+
+static void
 on_user_interaction (GdmGreeterLoginWindow *login_window)
 {
         g_debug ("GdmGreeterLoginWindow: user is interacting with session!\n");
@@ -640,6 +709,9 @@ reset_dialog (GdmGreeterLoginWindow *log
 
         login_window->priv->num_queries = 0;
 
+        purge_message_queue (login_window);
+        login_window->priv->session_ready_to_start = FALSE;
+
         if (dialog_mode == MODE_SELECTION) {
                 if (login_window->priv->timed_login_enabled) {
                         gdm_chooser_widget_set_item_timer (GDM_CHOOSER_WIDGET (login_window->priv->user_chooser),
@@ -763,7 +835,7 @@ gdm_greeter_login_window_info (GdmGreete
 
         g_debug ("GdmGreeterLoginWindow: info: %s", text);
 
-        set_message (GDM_GREETER_LOGIN_WINDOW (login_window), text);
+        queue_message (GDM_GREETER_LOGIN_WINDOW (login_window), text, 2, FALSE);
         maybe_show_cancel_button (login_window);
 
         return TRUE;
@@ -778,8 +850,7 @@ gdm_greeter_login_window_problem (GdmGre
         g_debug ("GdmGreeterLoginWindow: problem: %s", text);
         maybe_show_cancel_button (login_window);
 
-        set_message (GDM_GREETER_LOGIN_WINDOW (login_window), text);
-        gdk_window_beep (gtk_widget_get_window (GTK_WIDGET (login_window)));
+        queue_message (GDM_GREETER_LOGIN_WINDOW (login_window), text, 3, TRUE);
 
         return TRUE;
 }
@@ -834,7 +905,12 @@ gdm_greeter_login_window_start_session_w
 {
         if (login_window->priv->is_interactive) {
                 g_debug ("GdmGreeterLoginWindow: starting session");
-                g_signal_emit (login_window, signals[START_SESSION], 0);
+                if (login_window->priv->message_timeout_id) {
+                        /* Wait for all PAM messages to be displayed */
+                        login_window->priv->session_ready_to_start = TRUE;
+                } else {
+                        g_signal_emit (login_window, signals[START_SESSION], 0);
+                }
         } else {
                 g_debug ("GdmGreeterLoginWindow: not starting session since "
                          "user hasn't had an opportunity to pick language "
@@ -1799,6 +1875,8 @@ gdm_greeter_login_window_finalize (GObje
                 g_object_unref (login_window->priv->client);
         }
 
+        purge_message_queue (login_window);
+
         G_OBJECT_CLASS (gdm_greeter_login_window_parent_class)->finalize (object);
 }
 
