Blob Blame History Raw
From a45940c9eb4ac9874e4bd2d6374b0d855d8954fe Mon Sep 17 00:00:00 2001
From: "Jasper St. Pierre" <jstpierre@mecheye.net>
Date: Thu, 13 Feb 2014 14:52:49 -0500
Subject: [PATCH 1/4] display: Clean up get_timed_login_details

Make it properly log itself as a GdmDisplay method, and use
local variables to ensure that callers can pass NULL.
---
 daemon/gdm-display.c | 34 ++++++++++++++++++++++++++--------
 1 file changed, 26 insertions(+), 8 deletions(-)

diff --git a/daemon/gdm-display.c b/daemon/gdm-display.c
index 352dd92..5d06036 100644
--- a/daemon/gdm-display.c
+++ b/daemon/gdm-display.c
@@ -426,20 +426,38 @@ gdm_display_real_get_timed_login_details (GdmDisplay *display,
 
 gboolean
 gdm_display_get_timed_login_details (GdmDisplay *display,
-                                     gboolean   *enabled,
-                                     char      **username,
-                                     int        *delay,
+                                     gboolean   *out_enabled,
+                                     char      **out_username,
+                                     int        *out_delay,
                                      GError    **error)
 {
+        gboolean enabled;
+        char *username;
+        int delay;
+
         g_return_val_if_fail (GDM_IS_DISPLAY (display), FALSE);
 
-        GDM_DISPLAY_GET_CLASS (display)->get_timed_login_details (display, enabled, username, delay);
+        GDM_DISPLAY_GET_CLASS (display)->get_timed_login_details (display, &enabled, &username, &delay);
 
-        g_debug ("GdmSlave: Got timed login details for display %s: %d '%s' %d",
+        g_debug ("GdmDisplay: Got timed login details for display %s: %d '%s' %d",
                  display->priv->x11_display_name,
-                 *enabled,
-                 *username ? *username : "(null)",
-                 *delay);
+                 enabled,
+                 username,
+                 delay);
+
+        if (out_enabled) {
+                *out_enabled = enabled;
+        }
+
+        if (out_username) {
+                *out_username = username;
+        } else {
+                g_free (username);
+        }
+
+        if (out_delay) {
+                *out_delay = delay;
+        }
 
         return TRUE;
 }
-- 
1.8.3.1


From ab639086db4f694722fa1c83046bfc503e790894 Mon Sep 17 00:00:00 2001
From: Vadim Rutkovsky <vrutkovs@redhat.com>
Date: Fri, 30 May 2014 20:33:49 +0200
Subject: [PATCH 2/4] Add debug messages for timed login

---
 daemon/gdm-session.c      | 1 +
 daemon/gdm-simple-slave.c | 2 ++
 2 files changed, 3 insertions(+)

diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c
index 4a749d3..6a7d570 100644
--- a/daemon/gdm-session.c
+++ b/daemon/gdm-session.c
@@ -2604,6 +2604,7 @@ gdm_session_request_timed_login (GdmSession *self,
                                  const char *username,
                                  int         delay)
 {
+        g_debug ("GdmSession: requesting timed login");
         if (self->priv->greeter_interface != NULL) {
                 gdm_dbus_greeter_emit_timed_login_requested (self->priv->greeter_interface,
                                                              username,
diff --git a/daemon/gdm-simple-slave.c b/daemon/gdm-simple-slave.c
index d83216b..f08f7ad 100644
--- a/daemon/gdm-simple-slave.c
+++ b/daemon/gdm-simple-slave.c
@@ -721,6 +721,7 @@ on_ready_to_request_timed_login (GdmSession         *session,
                                  GSimpleAsyncResult *result,
                                  gpointer           *user_data)
 {
+        g_debug ("GdmSimpleSlave: ready to request timed login");
         int delay = GPOINTER_TO_INT (user_data);
         GCancellable *cancellable;
         char         *username;
@@ -754,6 +755,7 @@ on_ready_to_request_timed_login (GdmSession         *session,
 static gboolean
 on_wait_for_greeter_timeout (GSimpleAsyncResult *result)
 {
+        g_debug ("GdmSimpleSlave: wait for greeter timeout");
         g_simple_async_result_complete (result);
 
         return FALSE;
-- 
1.8.3.1


From ad879ccbfb4bfc0908b0ca3d256c42d034ae16c7 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Thu, 5 Jun 2014 17:01:48 -0400
Subject: [PATCH 3/4] manager: close up timed login race

Previously we would emit the timed-login-requested signal after the
client connects, which might be before it was listening for the
signal.

Now we only emit the signal in direct response to a GetTimedLoginDetails
call, which we make implicitly when the appropiate proxy interface is
set up.

https://bugzilla.gnome.org/show_bug.cgi?id=680348
---
 daemon/gdm-session.c      | 44 ++++++++++++++++++-----
 daemon/gdm-session.h      |  2 +-
 daemon/gdm-session.xml    |  5 +++
 daemon/gdm-simple-slave.c | 92 +----------------------------------------------
 gui/libgdm/gdm-client.c   | 23 ++++++++++++
 5 files changed, 65 insertions(+), 101 deletions(-)

diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c
index 6a7d570..e2e357f 100644
--- a/daemon/gdm-session.c
+++ b/daemon/gdm-session.c
@@ -89,6 +89,10 @@ struct _GdmSessionPrivate
         char                *selected_user;
         char                *user_x11_authority_file;
 
+        char                *timed_login_username;
+        int                  timed_login_delay;
+        GList               *pending_timed_login_invocations;
+
         GHashTable          *conversations;
 
         GdmSessionConversation *session_conversation;
@@ -1319,6 +1323,27 @@ gdm_session_handle_client_start_session_when_ready (GdmDBusGreeter        *greet
 }
 
 static gboolean
+gdm_session_handle_get_timed_login_details (GdmDBusGreeter        *greeter_interface,
+                                            GDBusMethodInvocation *invocation,
+                                            GdmSession            *self)
+{
+
+        if (self->priv->greeter_interface != NULL) {
+                gdm_dbus_greeter_complete_get_timed_login_details (greeter_interface,
+                                                                   invocation,
+                                                                   self->priv->timed_login_username != NULL,
+                                                                   self->priv->timed_login_username != NULL? self->priv->timed_login_username : "",
+                                                                   self->priv->timed_login_delay);
+                if (self->priv->timed_login_username != NULL) {
+                        gdm_dbus_greeter_emit_timed_login_requested (self->priv->greeter_interface,
+                                                                     self->priv->timed_login_username,
+                                                                     self->priv->timed_login_delay);
+                }
+        }
+        return TRUE;
+}
+
+static gboolean
 gdm_session_handle_client_begin_auto_login (GdmDBusGreeter        *greeter_interface,
                                             GDBusMethodInvocation *invocation,
                                             const char            *username,
@@ -1395,6 +1420,10 @@ export_greeter_interface (GdmSession      *self,
                           "handle-start-session-when-ready",
                           G_CALLBACK (gdm_session_handle_client_start_session_when_ready),
                           self);
+        g_signal_connect (greeter_interface,
+                          "handle-get-timed-login-details",
+                          G_CALLBACK (gdm_session_handle_get_timed_login_details),
+                          self);
 
         g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (greeter_interface),
                                           connection,
@@ -2600,16 +2629,13 @@ gdm_session_reset (GdmSession *self)
 }
 
 void
-gdm_session_request_timed_login (GdmSession *self,
-                                 const char *username,
-                                 int         delay)
+gdm_session_set_timed_login_details (GdmSession *self,
+                                     const char *username,
+                                     int         delay)
 {
-        g_debug ("GdmSession: requesting timed login");
-        if (self->priv->greeter_interface != NULL) {
-                gdm_dbus_greeter_emit_timed_login_requested (self->priv->greeter_interface,
-                                                             username,
-                                                             delay);
-        }
+        g_debug ("GdmSession: timed login details %s %d", username, delay);
+        self->priv->timed_login_username = g_strdup (username);
+        self->priv->timed_login_delay = delay;
 }
 
 gboolean
diff --git a/daemon/gdm-session.h b/daemon/gdm-session.h
index 8b93e2c..14a1721 100644
--- a/daemon/gdm-session.h
+++ b/daemon/gdm-session.h
@@ -158,7 +158,7 @@ void              gdm_session_select_user                 (GdmSession *session,
                                                            const char *username);
 void              gdm_session_cancel                      (GdmSession *session);
 void              gdm_session_reset                       (GdmSession *session);
-void              gdm_session_request_timed_login         (GdmSession *session,
+void              gdm_session_set_timed_login_details     (GdmSession *session,
                                                            const char *username,
                                                            int         delay);
 gboolean          gdm_session_client_is_connected         (GdmSession *session);
diff --git a/daemon/gdm-session.xml b/daemon/gdm-session.xml
index cf3103a..756346d 100644
--- a/daemon/gdm-session.xml
+++ b/daemon/gdm-session.xml
@@ -88,6 +88,11 @@
     <method name="BeginAutoLogin">
       <arg name="username" direction="in" type="s"/>
     </method>
+    <method name="GetTimedLoginDetails">
+      <arg name="enabled" direction="out" type="b"/>
+      <arg name="username" direction="out" type="s"/>
+      <arg name="delay" direction="out" type="i"/>
+    </method>
     <method name="StartSessionWhenReady">
       <arg name="service_name" direction="in" type="s"/>
       <arg name="should_start_session" direction="in" type="b"/>
diff --git a/daemon/gdm-simple-slave.c b/daemon/gdm-simple-slave.c
index f08f7ad..e0e82c7 100644
--- a/daemon/gdm-simple-slave.c
+++ b/daemon/gdm-simple-slave.c
@@ -717,51 +717,6 @@ on_session_client_ready_for_session_to_start (GdmSession      *session,
 }
 
 static void
-on_ready_to_request_timed_login (GdmSession         *session,
-                                 GSimpleAsyncResult *result,
-                                 gpointer           *user_data)
-{
-        g_debug ("GdmSimpleSlave: ready to request timed login");
-        int delay = GPOINTER_TO_INT (user_data);
-        GCancellable *cancellable;
-        char         *username;
-
-        cancellable = g_object_get_data (G_OBJECT (result),
-                                         "cancellable");
-        if (g_cancellable_is_cancelled (cancellable)) {
-                return;
-        }
-
-        username = g_simple_async_result_get_source_tag (result);
-
-        gdm_session_request_timed_login (session, username, delay);
-
-        g_object_weak_unref (G_OBJECT (session),
-                             (GWeakNotify)
-                             g_cancellable_cancel,
-                             cancellable);
-        g_object_weak_unref (G_OBJECT (session),
-                             (GWeakNotify)
-                             g_object_unref,
-                             cancellable);
-        g_object_weak_unref (G_OBJECT (session),
-                             (GWeakNotify)
-                             g_free,
-                             username);
-
-        g_free (username);
-}
-
-static gboolean
-on_wait_for_greeter_timeout (GSimpleAsyncResult *result)
-{
-        g_debug ("GdmSimpleSlave: wait for greeter timeout");
-        g_simple_async_result_complete (result);
-
-        return FALSE;
-}
-
-static void
 on_session_client_connected (GdmSession          *session,
                              GCredentials        *credentials,
                              GPid                 pid_of_client,
@@ -790,53 +745,8 @@ on_session_client_connected (GdmSession          *session,
                 return;
         }
 
-        /* temporary hack to fix timed login
-         * http://bugzilla.gnome.org/680348
-         */
         if (delay > 0) {
-                GSimpleAsyncResult *result;
-                GCancellable       *cancellable;
-                guint               timeout_id;
-                gpointer            source_tag;
-
-                delay = MAX (delay, 4);
-
-                cancellable = g_cancellable_new ();
-                source_tag = g_strdup (username);
-                result = g_simple_async_result_new (G_OBJECT (session),
-                                                    (GAsyncReadyCallback)
-                                                    on_ready_to_request_timed_login,
-                                                    GINT_TO_POINTER (delay),
-                                                    source_tag);
-                g_simple_async_result_set_check_cancellable (result, cancellable);
-                g_object_set_data (G_OBJECT (result),
-                                   "cancellable",
-                                   cancellable);
-
-                timeout_id = g_timeout_add_seconds_full (delay - 2,
-                                                         G_PRIORITY_DEFAULT,
-                                                         (GSourceFunc)
-                                                         on_wait_for_greeter_timeout,
-                                                         g_object_ref (result),
-                                                         (GDestroyNotify)
-                                                         g_object_unref);
-                g_cancellable_connect (cancellable,
-                                       G_CALLBACK (g_source_remove),
-                                       GINT_TO_POINTER (timeout_id),
-                                       NULL);
-
-                g_object_weak_ref (G_OBJECT (session),
-                                   (GWeakNotify)
-                                   g_cancellable_cancel,
-                                   cancellable);
-                g_object_weak_ref (G_OBJECT (session),
-                                   (GWeakNotify)
-                                   g_object_unref,
-                                   cancellable);
-                g_object_weak_ref (G_OBJECT (session),
-                                   (GWeakNotify)
-                                   g_free,
-                                   source_tag);
+                gdm_session_set_timed_login_details (session, username, delay);
         }
 
         g_free (username);
diff --git a/gui/libgdm/gdm-client.c b/gui/libgdm/gdm-client.c
index 4542c3e..e1188e5 100644
--- a/gui/libgdm/gdm-client.c
+++ b/gui/libgdm/gdm-client.c
@@ -794,6 +794,26 @@ gdm_client_get_user_verifier_finish (GdmClient       *client,
 }
 
 static void
+on_timed_login_details_got (GdmGreeter   *greeter,
+                            GAsyncResult *result)
+{
+        gdm_greeter_call_get_timed_login_details_finish (greeter, NULL, NULL, NULL, result, NULL);
+}
+
+static void
+query_for_timed_login_requested_signal (GdmGreeter *greeter)
+{
+        /* This just makes sure a timed-login-requested signal gets fired
+         * off if appropriate.
+         */
+        gdm_greeter_call_get_timed_login_details (greeter,
+                                                  NULL,
+                                                  (GAsyncReadyCallback)
+                                                  on_timed_login_details_got,
+                                                  NULL);
+}
+
+static void
 on_greeter_proxy_created (GObject            *source,
                           GAsyncResult       *result,
                           GSimpleAsyncResult *operation_result)
@@ -813,6 +833,8 @@ on_greeter_proxy_created (GObject            *source,
                                                    (GDestroyNotify)
                                                    g_object_unref);
         g_simple_async_result_complete_in_idle (operation_result);
+
+        query_for_timed_login_requested_signal (greeter);
 }
 
 static void
@@ -980,6 +1002,7 @@ gdm_client_get_greeter_sync (GdmClient     *client,
                                    (GWeakNotify)
                                    g_clear_object,
                                    &client->priv->connection);
+                query_for_timed_login_requested_signal (client->priv->greeter);
         }
 
         return client->priv->greeter;
-- 
1.8.3.1


From 35d66c9d4cf54d3e480c399b045468547a0818a8 Mon Sep 17 00:00:00 2001
From: Philippe Troin <phil@fifi.org>
Date: Tue, 2 Sep 2014 15:28:17 -0400
Subject: [PATCH 4/4] daemon: allow multiple time logins to work

GDM currently lumps timed login with autologin when deciding whether or
not to skip it, if it's already happened once this boot.

That's the wrong behavior, and indeed will create a confused experience,
because it's not what the login screen provided by gnome-shell
expects.

This commit allows timed login to work after the user logs out.

https://bugzilla.gnome.org/show_bug.cgi?id=732774
---
 daemon/gdm-simple-slave.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/daemon/gdm-simple-slave.c b/daemon/gdm-simple-slave.c
index e0e82c7..5057eb4 100644
--- a/daemon/gdm-simple-slave.c
+++ b/daemon/gdm-simple-slave.c
@@ -650,13 +650,14 @@ static void
 start_autologin_conversation_if_necessary (GdmSimpleSlave  *slave)
 {
         gboolean enabled;
+        int delay = 0;
 
-        if (g_file_test (GDM_RAN_ONCE_MARKER_FILE, G_FILE_TEST_EXISTS)) {
+        gdm_slave_get_timed_login_details (GDM_SLAVE (slave), &enabled, NULL, &delay);
+
+        if (delay == 0 && g_file_test (GDM_RAN_ONCE_MARKER_FILE, G_FILE_TEST_EXISTS)) {
                 return;
         }
 
-        gdm_slave_get_timed_login_details (GDM_SLAVE (slave), &enabled, NULL, NULL);
-
         if (!enabled) {
                 return;
         }
-- 
1.8.3.1