Blame SOURCES/0001-local-display-factory-don-t-spawn-login-screen-if-ba.patch

ca70cf
From 02429cabcddd3a12e0cddd975820b37e8440f1c7 Mon Sep 17 00:00:00 2001
ca70cf
From: Ray Strode <rstrode@redhat.com>
ca70cf
Date: Wed, 22 May 2019 10:53:12 -0400
ca70cf
Subject: [PATCH] local-display-factory: don't spawn login screen if background
ca70cf
 session dies
ca70cf
ca70cf
At the moment gdm conjures up a login screen any time a user session
ca70cf
exits.
ca70cf
ca70cf
This is the right behavior if the user explicitly logs out, but if an
ca70cf
admin is killing a session on a background VT, then going to the login
ca70cf
screen is wrong.
ca70cf
ca70cf
This commit changes the code to detect when the killed session is in
ca70cf
the foreground, and only then bring up a login screen.
ca70cf
---
ca70cf
 daemon/gdm-local-display-factory.c | 24 +++++++++++++++++++++++-
ca70cf
 1 file changed, 23 insertions(+), 1 deletion(-)
ca70cf
ca70cf
diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c
ca70cf
index cf4f5095c..6856d30d0 100644
ca70cf
--- a/daemon/gdm-local-display-factory.c
ca70cf
+++ b/daemon/gdm-local-display-factory.c
ca70cf
@@ -227,137 +227,159 @@ gdm_local_display_factory_create_transient_display (GdmLocalDisplayFactory *fact
ca70cf
 
ca70cf
         store_display (factory, display);
ca70cf
 
ca70cf
         if (! gdm_display_manage (display)) {
ca70cf
                 display = NULL;
ca70cf
                 goto out;
ca70cf
         }
ca70cf
 
ca70cf
         if (! gdm_display_get_id (display, id, NULL)) {
ca70cf
                 display = NULL;
ca70cf
                 goto out;
ca70cf
         }
ca70cf
 
ca70cf
         ret = TRUE;
ca70cf
  out:
ca70cf
         /* ref either held by store or not at all */
ca70cf
         g_object_unref (display);
ca70cf
 
ca70cf
         return ret;
ca70cf
 }
ca70cf
 
ca70cf
 static void
ca70cf
 on_display_status_changed (GdmDisplay             *display,
ca70cf
                            GParamSpec             *arg1,
ca70cf
                            GdmLocalDisplayFactory *factory)
ca70cf
 {
ca70cf
         int              status;
ca70cf
         GdmDisplayStore *store;
ca70cf
         int              num;
ca70cf
         char            *seat_id = NULL;
ca70cf
+        char            *session_id = NULL;
ca70cf
         char            *session_type = NULL;
ca70cf
         char            *session_class = NULL;
ca70cf
         gboolean         is_initial = TRUE;
ca70cf
         gboolean         is_local = TRUE;
ca70cf
+        int              ret;
ca70cf
 
ca70cf
         num = -1;
ca70cf
         gdm_display_get_x11_display_number (display, &num, NULL);
ca70cf
 
ca70cf
         store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory));
ca70cf
 
ca70cf
         g_object_get (display,
ca70cf
                       "seat-id", &seat_id,
ca70cf
+                      "session-id", &session_id,
ca70cf
                       "is-initial", &is_initial,
ca70cf
                       "is-local", &is_local,
ca70cf
                       "session-type", &session_type,
ca70cf
                       "session-class", &session_class,
ca70cf
                       NULL);
ca70cf
 
ca70cf
         status = gdm_display_get_status (display);
ca70cf
 
ca70cf
         g_debug ("GdmLocalDisplayFactory: display status changed: %d", status);
ca70cf
         switch (status) {
ca70cf
         case GDM_DISPLAY_FINISHED:
ca70cf
                 /* remove the display number from factory->priv->used_display_numbers
ca70cf
                    so that it may be reused */
ca70cf
                 if (num != -1) {
ca70cf
                         g_hash_table_remove (factory->priv->used_display_numbers, GUINT_TO_POINTER (num));
ca70cf
                 }
ca70cf
                 gdm_display_store_remove (store, display);
ca70cf
 
ca70cf
                 /* if this is a local display, recreate the display so
ca70cf
                  * a new login screen comes up if one is missing.
ca70cf
                  */
ca70cf
                 if (is_local && g_strcmp0 (session_class, "greeter") != 0) {
ca70cf
+                        g_autofree char *active_session = NULL;
ca70cf
+
ca70cf
                         /* reset num failures */
ca70cf
                         factory->priv->num_failures = 0;
ca70cf
 
ca70cf
-                        create_display (factory, seat_id, session_type, is_initial);
ca70cf
+                        ret = sd_seat_get_active (seat_id, &active_session, NULL);
ca70cf
+
ca70cf
+                        if (ret == 0) {
ca70cf
+                                g_autofree char *state = NULL;
ca70cf
+                                ret = sd_session_get_state (active_session, &state);
ca70cf
+                                if (ret != 0 ||
ca70cf
+                                    g_strcmp0 (state, "closing") == 0 ||
ca70cf
+                                    g_strcmp0 (active_session, session_id) == 0) {
ca70cf
+                                        g_clear_pointer (&active_session, free);
ca70cf
+                                }
ca70cf
+                        }
ca70cf
+
ca70cf
+                        /* If this died in the foreground leaving us on a blank vt,
ca70cf
+                           start a new login screen */
ca70cf
+                        if (!sd_seat_can_multi_session (seat_id) || active_session == NULL) {
ca70cf
+                                create_display (factory, seat_id, session_type, is_initial);
ca70cf
+                        }
ca70cf
                 }
ca70cf
                 break;
ca70cf
         case GDM_DISPLAY_FAILED:
ca70cf
                 /* leave the display number in factory->priv->used_display_numbers
ca70cf
                    so that it doesn't get reused */
ca70cf
                 gdm_display_store_remove (store, display);
ca70cf
 
ca70cf
                 /* Create a new equivalent display if it was static */
ca70cf
                 if (is_local) {
ca70cf
 
ca70cf
                         factory->priv->num_failures++;
ca70cf
 
ca70cf
                         if (factory->priv->num_failures > MAX_DISPLAY_FAILURES) {
ca70cf
                                 /* oh shit */
ca70cf
                                 g_warning ("GdmLocalDisplayFactory: maximum number of X display failures reached: check X server log for errors");
ca70cf
                         } else {
ca70cf
 #ifdef ENABLE_WAYLAND_SUPPORT
ca70cf
                                 if (g_strcmp0 (session_type, "wayland") == 0) {
ca70cf
                                         g_free (session_type);
ca70cf
                                         session_type = NULL;
ca70cf
                                 }
ca70cf
 
ca70cf
 #endif
ca70cf
                                 create_display (factory, seat_id, session_type, is_initial);
ca70cf
                         }
ca70cf
                 }
ca70cf
                 break;
ca70cf
         case GDM_DISPLAY_UNMANAGED:
ca70cf
                 break;
ca70cf
         case GDM_DISPLAY_PREPARED:
ca70cf
                 break;
ca70cf
         case GDM_DISPLAY_MANAGED:
ca70cf
                 break;
ca70cf
         default:
ca70cf
                 g_assert_not_reached ();
ca70cf
                 break;
ca70cf
         }
ca70cf
 
ca70cf
         g_free (seat_id);
ca70cf
+        g_free (session_id);
ca70cf
         g_free (session_type);
ca70cf
         g_free (session_class);
ca70cf
 }
ca70cf
 
ca70cf
 static gboolean
ca70cf
 lookup_by_seat_id (const char *id,
ca70cf
                    GdmDisplay *display,
ca70cf
                    gpointer    user_data)
ca70cf
 {
ca70cf
         const char *looking_for = user_data;
ca70cf
         char *current;
ca70cf
         gboolean res;
ca70cf
 
ca70cf
         g_object_get (G_OBJECT (display), "seat-id", &current, NULL);
ca70cf
 
ca70cf
         res = g_strcmp0 (current, looking_for) == 0;
ca70cf
 
ca70cf
         g_free(current);
ca70cf
 
ca70cf
         return res;
ca70cf
 }
ca70cf
 
ca70cf
 static gboolean
ca70cf
 activate_session_id (GdmLocalDisplayFactory *self,
ca70cf
                      const char             *seat_id,
ca70cf
                      const char             *session_id)
ca70cf
 {
ca70cf
         GError *error = NULL;
ca70cf
         GVariant *reply;
ca70cf
 
ca70cf
-- 
ca70cf
2.21.0
ca70cf