[gdm/multi-stack: 31/35] Add delay when showing messages (needs split)



commit 26e4410292beca92834144f538f8b425b1a66888
Author: Ray Strode <rstrode redhat com>
Date:   Wed Aug 4 18:03:52 2010 -0400

    Add delay when showing messages (needs split)
    
    Previously, there were times when the user would be unable
    to read messages, because they would blink by so fast.
    
    This jumble of assorted changes (which needs to be split up)
    adds some queueing and timeouts to make sure the messages stay on
    screen for a sufficient amount of time.

 gui/simple-greeter/gdm-greeter-login-window.c      |  119 ++++++++++++++++++--
 .../libgdmsimplegreeter/gdm-conversation.c         |   17 +++
 .../libgdmsimplegreeter/gdm-conversation.h         |    2 +
 .../fingerprint/gdm-fingerprint-extension.c        |   20 ++++
 .../plugins/password/gdm-password-extension.c      |   20 ++++
 .../plugins/smartcard/gdm-smartcard-extension.c    |   19 +++
 6 files changed, 187 insertions(+), 10 deletions(-)
---
diff --git a/gui/simple-greeter/gdm-greeter-login-window.c b/gui/simple-greeter/gdm-greeter-login-window.c
index 7d63761..8db6a55 100644
--- a/gui/simple-greeter/gdm-greeter-login-window.c
+++ b/gui/simple-greeter/gdm-greeter-login-window.c
@@ -137,6 +137,9 @@ struct GdmGreeterLoginWindowPrivate
 
         guint            login_button_handler_id;
         guint            start_session_handler_id;
+
+        char            *service_name_of_session_ready_to_start;
+
 };
 
 enum {
@@ -173,6 +176,8 @@ static void     switch_mode                 (GdmGreeterLoginWindow *login_window
 static void     update_banner_message       (GdmGreeterLoginWindow *login_window);
 static void     gdm_greeter_login_window_start_session_when_ready (GdmGreeterLoginWindow *login_window,
                                                                    const char            *service_name);
+static void handle_stopped_conversation (GdmGreeterLoginWindow *login_window,
+                                         const char            *service_name);
 
 G_DEFINE_TYPE (GdmGreeterLoginWindow, gdm_greeter_login_window, GTK_TYPE_WINDOW)
 
@@ -231,6 +236,7 @@ set_task_conversation_message (GdmTaskList *task_list,
 {
 
         gdm_conversation_set_message (GDM_CONVERSATION (task), message);
+        g_object_set_data (G_OBJECT (task), "message-pending", GINT_TO_POINTER (TRUE));
         return FALSE;
 }
 
@@ -882,16 +888,12 @@ gdm_greeter_login_window_ready (GdmGreeterLoginWindow *login_window,
         return TRUE;
 }
 
-gboolean
-gdm_greeter_login_window_conversation_stopped (GdmGreeterLoginWindow *login_window,
-                                               const char            *service_name)
+static void
+handle_stopped_conversation (GdmGreeterLoginWindow *login_window,
+                             const char            *service_name)
 {
         GdmTask *task;
 
-        g_return_val_if_fail (GDM_IS_GREETER_LOGIN_WINDOW (login_window), FALSE);
-
-        g_debug ("GdmGreeterLoginWindow: conversation '%s' has stopped", service_name);
-
         /* If the password conversation failed, then start over
          *
          * FIXME: we need to get this policy out of the source code
@@ -899,13 +901,15 @@ gdm_greeter_login_window_conversation_stopped (GdmGreeterLoginWindow *login_wind
         if (strcmp (service_name, "gdm-password") == 0) {
                 g_debug ("GdmGreeterLoginWindow: main conversation failed, starting over");
                 restart_conversations (login_window);
-                return TRUE;
+                return;
         }
 
         task = find_task_with_service_name (login_window, service_name);
 
         if (task != NULL) {
                 gdm_conversation_reset (GDM_CONVERSATION (task));
+
+                g_object_set_data (G_OBJECT (task), "needs-to-be-stopped", GINT_TO_POINTER (FALSE));
                 g_object_unref (task);
         }
 
@@ -920,6 +924,34 @@ gdm_greeter_login_window_conversation_stopped (GdmGreeterLoginWindow *login_wind
         g_object_unref (task);
 
         update_conversation_list_visibility (login_window);
+}
+
+gboolean
+gdm_greeter_login_window_conversation_stopped (GdmGreeterLoginWindow *login_window,
+                                               const char            *service_name)
+{
+        GdmTask *task;
+        gboolean messages_pending;
+
+        g_return_val_if_fail (GDM_IS_GREETER_LOGIN_WINDOW (login_window), FALSE);
+
+        g_debug ("GdmGreeterLoginWindow: conversation '%s' has stopped", service_name);
+
+        task = gdm_task_list_get_active_task (GDM_TASK_LIST (login_window->priv->conversation_list));
+        if (task != NULL && task_has_service_name (GDM_TASK_LIST (login_window->priv->conversation_list), task, service_name)) {
+
+                messages_pending = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (task), "message-pending"));
+        } else {
+                messages_pending = FALSE;
+        }
+
+        if (!messages_pending) {
+                handle_stopped_conversation (login_window, service_name);
+        } else {
+                g_assert (task != NULL);
+
+                g_object_set_data (G_OBJECT (task), "needs-to-be-stopped", GINT_TO_POINTER (TRUE));
+        }
 
         return TRUE;
 }
@@ -931,6 +963,7 @@ restart_task_conversation (GdmTaskList           *task_list,
 {
         char *service_name;
 
+        g_object_set_data (G_OBJECT (task), "needs-to-be-stopped", GINT_TO_POINTER (FALSE));
         service_name = gdm_conversation_get_service_name (GDM_CONVERSATION (task));
         if (service_name != NULL) {
                 char *name;
@@ -959,6 +992,9 @@ gdm_greeter_login_window_reset (GdmGreeterLoginWindow *login_window)
                                     restart_task_conversation,
                                     login_window);
 
+        g_free (login_window->priv->service_name_of_session_ready_to_start);
+        login_window->priv->service_name_of_session_ready_to_start = NULL;
+
         return TRUE;
 }
 
@@ -976,6 +1012,7 @@ gdm_greeter_login_window_info (GdmGreeterLoginWindow *login_window,
         task = find_task_with_service_name (login_window, service_name);
 
         if (task != NULL) {
+                g_object_set_data (G_OBJECT (task), "message-pending", GINT_TO_POINTER (TRUE));
                 gdm_conversation_set_message (GDM_CONVERSATION (task),
                                               text);
                 show_task_actions (task);
@@ -999,6 +1036,7 @@ gdm_greeter_login_window_problem (GdmGreeterLoginWindow *login_window,
         task = find_task_with_service_name (login_window, service_name);
 
         if (task != NULL) {
+                g_object_set_data (G_OBJECT (task), "message-pending", GINT_TO_POINTER (TRUE));
                 gdm_conversation_set_message (GDM_CONVERSATION (task),
                                               text);
                 show_task_actions (task);
@@ -1094,12 +1132,40 @@ on_ready_to_start_session (GdmGreeterLoginWindow *login_window,
 }
 
 static void
+gdm_greeter_login_window_start_session (GdmGreeterLoginWindow *login_window)
+{
+        g_debug ("GdmGreeterLoginWindow: starting session");
+        g_signal_emit (login_window,
+                       signals[START_SESSION],
+                       0,
+                       login_window->priv->service_name_of_session_ready_to_start);
+        g_free (login_window->priv->service_name_of_session_ready_to_start);
+        login_window->priv->service_name_of_session_ready_to_start = NULL;
+}
+
+static void
 gdm_greeter_login_window_start_session_when_ready (GdmGreeterLoginWindow *login_window,
                                                    const char            *service_name)
 {
         if (login_window->priv->is_interactive) {
-                g_debug ("GdmGreeterLoginWindow: starting session");
-                g_signal_emit (login_window, signals[START_SESSION], 0, service_name);
+                gboolean messages_pending;
+                GdmTask *task;
+
+                set_sensitive (GDM_GREETER_LOGIN_WINDOW (login_window), FALSE);
+
+                task = find_task_with_service_name (login_window, service_name);
+
+                if (task != NULL) {
+                        messages_pending = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (task), "message-pending"));
+
+                } else {
+                        messages_pending = FALSE;
+                }
+
+                login_window->priv->service_name_of_session_ready_to_start = g_strdup (service_name);
+                if (!messages_pending) {
+                        gdm_greeter_login_window_start_session (login_window);
+                }
         } else {
                 g_debug ("GdmGreeterLoginWindow: not starting session since "
                          "user hasn't had an opportunity to pick language "
@@ -2215,6 +2281,35 @@ on_conversation_chose_user (GdmGreeterLoginWindow *login_window,
         return TRUE;
 }
 
+static void
+on_conversation_message_set (GdmGreeterLoginWindow *login_window,
+                             GdmConversation       *conversation)
+{
+        gboolean needs_to_be_stopped;
+
+        g_object_set_data (G_OBJECT (conversation), "message-pending", GINT_TO_POINTER (FALSE));
+
+        needs_to_be_stopped = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (conversation), "needs-to-be-stopped"));
+
+        if (needs_to_be_stopped) {
+                char *service_name;
+
+                service_name = gdm_conversation_get_service_name (conversation);
+                handle_stopped_conversation (login_window, service_name);
+                g_free (service_name);
+        }
+
+        if (login_window->priv->service_name_of_session_ready_to_start != NULL ) {
+                GdmTask *task;
+
+                task = gdm_task_list_get_active_task (GDM_TASK_LIST (login_window->priv->conversation_list));
+
+                if (task == GDM_TASK (conversation)) {
+                        gdm_greeter_login_window_start_session (login_window);
+                }
+        }
+}
+
 void
 gdm_greeter_login_window_remove_extension (GdmGreeterLoginWindow *login_window,
  GdmGreeterExtension *extension)
@@ -2377,6 +2472,10 @@ gdm_greeter_login_window_add_extension (GdmGreeterLoginWindow *login_window,
                                   "user-chosen",
                                   G_CALLBACK (on_conversation_chose_user),
                                   login_window);
+        g_signal_connect_swapped (GDM_CONVERSATION (extension),
+                                  "message-set",
+                                  G_CALLBACK (on_conversation_message_set),
+                                  login_window);
 
         g_debug ("GdmGreeterLoginWindow: new extension '%s - %s' added",
                 name, description);
diff --git a/gui/simple-greeter/libgdmsimplegreeter/gdm-conversation.c b/gui/simple-greeter/libgdmsimplegreeter/gdm-conversation.c
index ee763ef..a3514e8 100644
--- a/gui/simple-greeter/libgdmsimplegreeter/gdm-conversation.c
+++ b/gui/simple-greeter/libgdmsimplegreeter/gdm-conversation.c
@@ -32,6 +32,7 @@ enum {
         ANSWER,
         USER_CHOSEN,
         CANCEL,
+        MESSAGE_SET,
         LAST_SIGNAL
 };
 
@@ -92,6 +93,16 @@ gdm_conversation_class_init (gpointer g_iface)
                               NULL,
                               g_cclosure_marshal_VOID__VOID,
                               G_TYPE_NONE, 0);
+
+        signals [MESSAGE_SET] =
+                g_signal_new ("message-set",
+                              iface_type,
+                              G_SIGNAL_RUN_FIRST,
+                              G_STRUCT_OFFSET (GdmConversationIface, message_set),
+                              NULL,
+                              NULL,
+                              g_cclosure_marshal_VOID__VOID,
+                              G_TYPE_NONE, 0);
 }
 
 void
@@ -184,3 +195,9 @@ gdm_conversation_choose_user (GdmConversation *conversation,
 
         return was_chosen;
 }
+
+void
+gdm_conversation_message_set (GdmConversation *conversation)
+{
+        g_signal_emit (conversation, signals [MESSAGE_SET], 0);
+}
diff --git a/gui/simple-greeter/libgdmsimplegreeter/gdm-conversation.h b/gui/simple-greeter/libgdmsimplegreeter/gdm-conversation.h
index b37b21e..f76b18c 100644
--- a/gui/simple-greeter/libgdmsimplegreeter/gdm-conversation.h
+++ b/gui/simple-greeter/libgdmsimplegreeter/gdm-conversation.h
@@ -62,6 +62,7 @@ struct _GdmConversationIface
         char * (* answer)       (GdmConversation *conversation);
         void   (* cancel)       (GdmConversation *conversation);
         gboolean  (* user_chosen)  (GdmConversation *conversation);
+        void   (* message_set)  (GdmConversation *conversation);
 };
 
 GType  gdm_conversation_get_type     (void) G_GNUC_CONST;
@@ -87,6 +88,7 @@ void   gdm_conversation_answer (GdmConversation   *conversation,
 void   gdm_conversation_cancel (GdmConversation   *conversation);
 gboolean  gdm_conversation_choose_user (GdmConversation   *conversation,
                                         const char        *username);
+void gdm_conversation_message_set (GdmConversation *conversation);
 
 G_END_DECLS
 
diff --git a/gui/simple-greeter/plugins/fingerprint/gdm-fingerprint-extension.c b/gui/simple-greeter/plugins/fingerprint/gdm-fingerprint-extension.c
index 55f5d32..2f7e968 100644
--- a/gui/simple-greeter/plugins/fingerprint/gdm-fingerprint-extension.c
+++ b/gui/simple-greeter/plugins/fingerprint/gdm-fingerprint-extension.c
@@ -41,6 +41,8 @@ struct _GdmFingerprintExtensionPrivate
         GtkWidget *prompt_entry;
 
         guint      answer_pending : 1;
+
+        guint      message_timeout_id;
 };
 
 static void gdm_fingerprint_extension_finalize (GObject *object);
@@ -59,6 +61,17 @@ G_DEFINE_TYPE_WITH_CODE (GdmFingerprintExtension,
                          G_IMPLEMENT_INTERFACE (GDM_TYPE_CONVERSATION,
                                                 gdm_conversation_iface_init));
 
+static gboolean
+on_message_expired (GdmConversation *conversation)
+{
+        GdmFingerprintExtension *extension = GDM_FINGERPRINT_EXTENSION (conversation);
+        extension->priv->message_timeout_id = 0;
+
+        gdm_conversation_message_set (conversation);
+
+        return FALSE;
+}
+
 static void
 gdm_fingerprint_extension_set_message (GdmConversation *conversation,
                                        const char *message)
@@ -66,6 +79,11 @@ gdm_fingerprint_extension_set_message (GdmConversation *conversation,
         GdmFingerprintExtension *extension = GDM_FINGERPRINT_EXTENSION (conversation);
         gtk_widget_show (extension->priv->message_label);
         gtk_label_set_text (GTK_LABEL (extension->priv->message_label), message);
+
+        if (extension->priv->message_timeout_id  != 0) {
+                g_source_remove (extension->priv->message_timeout_id);
+        }
+        extension->priv->message_timeout_id = g_timeout_add_seconds (2, (GSourceFunc) on_message_expired, conversation);
 }
 
 static void
@@ -282,6 +300,8 @@ gdm_fingerprint_extension_class_init (GdmFingerprintExtensionClass *extension_cl
 static void
 gdm_fingerprint_extension_finalize (GObject *object)
 {
+        GdmFingerprintExtension *extension = GDM_FINGERPRINT_EXTENSION (object);
+        g_source_remove (extension->priv->message_timeout_id);
 }
 
 static void
diff --git a/gui/simple-greeter/plugins/password/gdm-password-extension.c b/gui/simple-greeter/plugins/password/gdm-password-extension.c
index 11a171c..5157ea2 100644
--- a/gui/simple-greeter/plugins/password/gdm-password-extension.c
+++ b/gui/simple-greeter/plugins/password/gdm-password-extension.c
@@ -40,6 +40,8 @@ struct _GdmPasswordExtensionPrivate
         GtkWidget *prompt_entry;
 
         guint      answer_pending : 1;
+
+        guint      message_timeout_id;
 };
 
 static void gdm_password_extension_finalize (GObject *object);
@@ -58,6 +60,16 @@ G_DEFINE_TYPE_WITH_CODE (GdmPasswordExtension,
                          G_IMPLEMENT_INTERFACE (GDM_TYPE_CONVERSATION,
                                                 gdm_conversation_iface_init));
 
+static gboolean
+on_message_expired (GdmConversation *conversation)
+{
+        GdmPasswordExtension *extension = GDM_PASSWORD_EXTENSION (conversation);
+        extension->priv->message_timeout_id = 0;
+
+        gdm_conversation_message_set (conversation);
+        return FALSE;
+}
+
 static void
 gdm_password_extension_set_message (GdmConversation *conversation,
                                     const char *message)
@@ -65,6 +77,11 @@ gdm_password_extension_set_message (GdmConversation *conversation,
         GdmPasswordExtension *extension = GDM_PASSWORD_EXTENSION (conversation);
         gtk_widget_show (extension->priv->message_label);
         gtk_label_set_text (GTK_LABEL (extension->priv->message_label), message);
+
+        if (extension->priv->message_timeout_id  != 0) {
+                g_source_remove (extension->priv->message_timeout_id);
+        }
+        extension->priv->message_timeout_id = g_timeout_add_seconds (2, (GSourceFunc) on_message_expired, conversation);
 }
 
 static void
@@ -251,6 +268,9 @@ gdm_password_extension_class_init (GdmPasswordExtensionClass *extension_class)
 static void
 gdm_password_extension_finalize (GObject *object)
 {
+
+        GdmPasswordExtension *extension = GDM_PASSWORD_EXTENSION (object);
+        g_source_remove (extension->priv->message_timeout_id);
 }
 
 static void
diff --git a/gui/simple-greeter/plugins/smartcard/gdm-smartcard-extension.c b/gui/simple-greeter/plugins/smartcard/gdm-smartcard-extension.c
index b40a21c..5e234b9 100644
--- a/gui/simple-greeter/plugins/smartcard/gdm-smartcard-extension.c
+++ b/gui/simple-greeter/plugins/smartcard/gdm-smartcard-extension.c
@@ -56,6 +56,8 @@ struct _GdmSmartcardExtensionPrivate
 
         guint      answer_pending : 1;
         guint      select_when_ready : 1;
+
+        guint      message_timeout_id;
 };
 
 static void gdm_smartcard_extension_finalize (GObject *object);
@@ -164,6 +166,16 @@ stop_watching_for_smartcards (GdmSmartcardExtension *extension)
         kill (extension->priv->worker_pid, SIGTERM);
 }
 
+static gboolean
+on_message_expired (GdmConversation *conversation)
+{
+        GdmSmartcardExtension *extension = GDM_SMARTCARD_EXTENSION (conversation);
+        extension->priv->message_timeout_id = 0;
+
+        gdm_conversation_message_set (conversation);
+        return FALSE;
+}
+
 static void
 gdm_smartcard_extension_set_message (GdmConversation *conversation,
                                      const char      *message)
@@ -171,6 +183,11 @@ gdm_smartcard_extension_set_message (GdmConversation *conversation,
         GdmSmartcardExtension *extension = GDM_SMARTCARD_EXTENSION (conversation);
         gtk_widget_show (extension->priv->message_label);
         gtk_label_set_text (GTK_LABEL (extension->priv->message_label), message);
+
+        if (extension->priv->message_timeout_id  != 0) {
+                g_source_remove (extension->priv->message_timeout_id);
+        }
+        extension->priv->message_timeout_id = g_timeout_add_seconds (2, (GSourceFunc) on_message_expired, conversation);
 }
 
 static void
@@ -428,6 +445,8 @@ gdm_smartcard_extension_finalize (GObject *object)
         if (extension->priv->worker_pid > 0) {
                 stop_watching_for_smartcards (extension);
         }
+
+        g_source_remove (extension->priv->message_timeout_id);
 }
 
 static void



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