[gdm/wip/fix-login-screan-reaping] local-display-factory: reap login session on vt switch to registered session



commit 2f5c9a9c287219f39974e7736d44d04e46fed32c
Author: Ray Strode <rstrode redhat com>
Date:   Wed Sep 4 11:04:11 2019 -0400

    local-display-factory: reap login session on vt switch to registered session
    
    Since commit 1c061b84ffc3e874da825982d18d970556ff74bb we reap the login
    screen after the user logs into a session, instead of after a timeout.
    
    Unfortunately, that means we no longer reap the login screen when
    unlocking a session.
    
    This commit adds back the timeout in the case seat0 is switched to a
    registered login session.
    
    Closes https://gitlab.gnome.org/GNOME/gdm/issues/509

 daemon/gdm-local-display-factory.c | 76 +++++++++++++++++++++++++++++++++++---
 1 file changed, 71 insertions(+), 5 deletions(-)
---
diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c
index ee41308b..da1093bb 100644
--- a/daemon/gdm-local-display-factory.c
+++ b/daemon/gdm-local-display-factory.c
@@ -66,6 +66,7 @@ struct _GdmLocalDisplayFactory
 #if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER)
         unsigned int     active_vt;
         guint            active_vt_watch_id;
+        guint            wait_to_finish_timeout_id;
 #endif
 };
 
@@ -297,6 +298,14 @@ finish_waiting_displays_on_seat (GdmLocalDisplayFactory *factory,
                                    seat_id);
 }
 
+static gboolean
+on_finish_waiting_for_seat0_displays_timeout (GdmLocalDisplayFactory *factory)
+{
+        g_debug ("GdmLocalDisplayFactory: timeout following VT switch to registered session complete, 
looking for any background displays to kill");
+        finish_waiting_displays_on_seat (factory, "seat0");
+        return G_SOURCE_REMOVE;
+}
+
 static void
 on_session_registered_cb (GObject *gobject,
                           GParamSpec *pspec,
@@ -628,6 +637,29 @@ lookup_by_session_id (const char *id,
         return g_strcmp0 (current, looking_for) == 0;
 }
 
+static gboolean
+lookup_by_tty (const char *id,
+              GdmDisplay *display,
+              gpointer    user_data)
+{
+        const char *tty_to_find = user_data;
+        g_autofree char *tty_to_check = NULL;
+        const char *session_id;
+        int ret;
+
+        session_id = gdm_display_get_session_id (display);
+
+        if (!session_id)
+                return FALSE;
+
+        ret = sd_session_get_tty (session_id, &tty_to_check);
+
+        if (ret != 0)
+                return FALSE;
+
+        return g_strcmp0 (tty_to_check, tty_to_find) == 0;
+}
+
 #if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER)
 static void
 maybe_stop_greeter_in_background (GdmLocalDisplayFactory *factory,
@@ -669,11 +701,12 @@ on_vt_changed (GIOChannel    *source,
                GIOCondition   condition,
                GdmLocalDisplayFactory *factory)
 {
+        GdmDisplayStore *store;
         GIOStatus status;
         g_autofree char *tty_of_active_vt = NULL;
         g_autofree char *login_session_id = NULL;
         g_autofree char *active_session_id = NULL;
-        unsigned int previous_vt, new_vt;
+        unsigned int previous_vt, new_vt, login_window_vt = 0;
         const char *session_type = NULL;
         int ret, n_returned;
 
@@ -739,21 +772,19 @@ on_vt_changed (GIOChannel    *source,
         g_debug ("GdmLocalDisplayFactory: VT changed from %u to %u",
                  previous_vt, factory->active_vt);
 
+        store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory));
+
         /* if the old VT was running a wayland login screen kill it
          */
         if (gdm_get_login_window_session_id ("seat0", &login_session_id)) {
-                unsigned int login_window_vt;
-
                 ret = sd_session_get_vt (login_session_id, &login_window_vt);
                 if (ret == 0 && login_window_vt != 0) {
                         g_debug ("GdmLocalDisplayFactory: VT of login window is %u", login_window_vt);
                         if (login_window_vt == previous_vt) {
-                                GdmDisplayStore *store;
                                 GdmDisplay *display;
 
                                 g_debug ("GdmLocalDisplayFactory: VT switched from login window");
 
-                                store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY 
(factory));
                                 display = gdm_display_store_find (store,
                                                                   lookup_by_session_id,
                                                                   (gpointer) login_session_id);
@@ -765,6 +796,37 @@ on_vt_changed (GIOChannel    *source,
                 }
         }
 
+        /* If we jumped to a registered user session, we can kill
+         * the login screen (after a suitable timeout to avoid flicker)
+         */
+        if (factory->active_vt != login_window_vt) {
+                GdmDisplay *display;
+
+                display = gdm_display_store_find (store,
+                                                  lookup_by_tty,
+                                                  (gpointer) tty_of_active_vt);
+
+                if (display != NULL) {
+                        gboolean registered;
+
+                        g_object_get (display, "session-registered", &registered, NULL);
+
+                        if (registered) {
+                                g_debug ("GdmLocalDisplayFactory: switched to registered user session, so 
reaping login screen in %d seconds",
+                                         WAIT_TO_FINISH_TIMEOUT);
+                                if (factory->wait_to_finish_timeout_id != 0) {
+                                         g_debug ("GdmLocalDisplayFactory: deferring previous login screen 
clean up operation");
+                                         g_source_remove (factory->wait_to_finish_timeout_id);
+                                }
+
+                                factory->wait_to_finish_timeout_id = g_timeout_add_seconds 
(WAIT_TO_FINISH_TIMEOUT,
+                                                                                            (GSourceFunc)
+                                                                                            
on_finish_waiting_for_seat0_displays_timeout,
+                                                                                            factory);
+                        }
+                }
+        }
+
         /* if user jumped back to initial vt and it's empty put a login screen
          * on it (unless a login screen is already running elsewhere, then
          * jump to that login screen)
@@ -843,6 +905,10 @@ gdm_local_display_factory_stop_monitor (GdmLocalDisplayFactory *factory)
                 g_source_remove (factory->active_vt_watch_id);
                 factory->active_vt_watch_id = 0;
         }
+        if (factory->wait_to_finish_timeout_id != 0) {
+                g_source_remove (factory->wait_to_finish_timeout_id);
+                factory->wait_to_finish_timeout_id = 0;
+        }
 #endif
 }
 


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