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

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