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

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