Blame SOURCES/0019-local-display-factory-don-t-jump-to-failed-display.patch

a1b388
From fe680d77cff9272843cb171c7e590c239f7afe5a Mon Sep 17 00:00:00 2001
a1b388
From: Ray Strode <rstrode@redhat.com>
a1b388
Date: Thu, 9 Aug 2018 12:32:31 -0400
a1b388
Subject: [PATCH 19/51] local-display-factory: don't jump to failed display
a1b388
a1b388
Since commit 5e737a57 `create_display` will jump to any
a1b388
already running login screen if it can find one.
a1b388
a1b388
Right now if a display fails we call `create_display` to
a1b388
create a new one.  It will look for any already running
a1b388
login screen and find the recently failed display.
a1b388
a1b388
This commit make sure we never jump to a display that isn't
a1b388
in good working order.
a1b388
---
a1b388
 daemon/gdm-local-display-factory.c | 19 +++++++++++++++----
a1b388
 1 file changed, 15 insertions(+), 4 deletions(-)
a1b388
a1b388
diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c
a1b388
index 9f377ba9a..c58de9c17 100644
a1b388
--- a/daemon/gdm-local-display-factory.c
a1b388
+++ b/daemon/gdm-local-display-factory.c
a1b388
@@ -60,60 +60,63 @@ struct GdmLocalDisplayFactoryPrivate
a1b388
         guint            num_failures;
a1b388
 
a1b388
         guint            seat_new_id;
a1b388
         guint            seat_removed_id;
a1b388
 
a1b388
 #if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER)
a1b388
         char            *tty_of_active_vt;
a1b388
         guint            active_vt_watch_id;
a1b388
 #endif
a1b388
 };
a1b388
 
a1b388
 enum {
a1b388
         PROP_0,
a1b388
 };
a1b388
 
a1b388
 static void     gdm_local_display_factory_class_init    (GdmLocalDisplayFactoryClass *klass);
a1b388
 static void     gdm_local_display_factory_init          (GdmLocalDisplayFactory      *factory);
a1b388
 static void     gdm_local_display_factory_finalize      (GObject                     *object);
a1b388
 
a1b388
 static GdmDisplay *create_display                       (GdmLocalDisplayFactory      *factory,
a1b388
                                                          const char                  *seat_id,
a1b388
                                                          const char                  *session_type,
a1b388
                                                          gboolean                    initial_display);
a1b388
 
a1b388
 static void     on_display_status_changed               (GdmDisplay                  *display,
a1b388
                                                          GParamSpec                  *arg1,
a1b388
                                                          GdmLocalDisplayFactory      *factory);
a1b388
 
a1b388
 static gboolean gdm_local_display_factory_sync_seats    (GdmLocalDisplayFactory *factory);
a1b388
 static gpointer local_display_factory_object = NULL;
a1b388
+static gboolean lookup_by_session_id (const char *id,
a1b388
+                                      GdmDisplay *display,
a1b388
+                                      gpointer    user_data);
a1b388
 
a1b388
 G_DEFINE_TYPE (GdmLocalDisplayFactory, gdm_local_display_factory, GDM_TYPE_DISPLAY_FACTORY)
a1b388
 
a1b388
 GQuark
a1b388
 gdm_local_display_factory_error_quark (void)
a1b388
 {
a1b388
         static GQuark ret = 0;
a1b388
         if (ret == 0) {
a1b388
                 ret = g_quark_from_static_string ("gdm_local_display_factory_error");
a1b388
         }
a1b388
 
a1b388
         return ret;
a1b388
 }
a1b388
 
a1b388
 static void
a1b388
 listify_hash (gpointer    key,
a1b388
               GdmDisplay *display,
a1b388
               GList     **list)
a1b388
 {
a1b388
         *list = g_list_prepend (*list, key);
a1b388
 }
a1b388
 
a1b388
 static int
a1b388
 sort_nums (gpointer a,
a1b388
            gpointer b)
a1b388
 {
a1b388
         guint32 num_a;
a1b388
         guint32 num_b;
a1b388
 
a1b388
         num_a = GPOINTER_TO_UINT (a);
a1b388
@@ -370,66 +373,74 @@ lookup_by_seat_id (const char *id,
a1b388
 
a1b388
         g_object_get (G_OBJECT (display), "seat-id", &current, NULL);
a1b388
 
a1b388
         res = g_strcmp0 (current, looking_for) == 0;
a1b388
 
a1b388
         g_free(current);
a1b388
 
a1b388
         return res;
a1b388
 }
a1b388
 
a1b388
 static GdmDisplay *
a1b388
 create_display (GdmLocalDisplayFactory *factory,
a1b388
                 const char             *seat_id,
a1b388
                 const char             *session_type,
a1b388
                 gboolean                initial)
a1b388
 {
a1b388
         GdmDisplayStore *store;
a1b388
         GdmDisplay      *display = NULL;
a1b388
         char            *active_session_id = NULL;
a1b388
         int              ret;
a1b388
 
a1b388
         store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory));
a1b388
 
a1b388
         ret = sd_seat_get_active (seat_id, &active_session_id, NULL);
a1b388
 
a1b388
         if (ret == 0) {
a1b388
                 char *login_session_id = NULL;
a1b388
 
a1b388
                 /* If we already have a login window, switch to it */
a1b388
                 if (gdm_get_login_window_session_id (seat_id, &login_session_id)) {
a1b388
-                        if (g_strcmp0 (active_session_id, login_session_id) != 0) {
a1b388
-                                gdm_activate_session_by_id (factory->priv->connection, seat_id, login_session_id);
a1b388
+                        GdmDisplay *display;
a1b388
+
a1b388
+                        display = gdm_display_store_find (store,
a1b388
+                                                          lookup_by_session_id,
a1b388
+                                                          (gpointer) login_session_id);
a1b388
+                        if (display != NULL && gdm_display_get_status (display) == GDM_DISPLAY_MANAGED) {
a1b388
+                                if (g_strcmp0 (active_session_id, login_session_id) != 0) {
a1b388
+                                        gdm_activate_session_by_id (factory->priv->connection, seat_id, login_session_id);
a1b388
+                                }
a1b388
+                                g_clear_pointer (&login_session_id, g_free);
a1b388
+                                g_clear_pointer (&active_session_id, g_free);
a1b388
+                                return NULL;
a1b388
                         }
a1b388
                         g_clear_pointer (&login_session_id, g_free);
a1b388
-                        g_clear_pointer (&active_session_id, g_free);
a1b388
-                        return NULL;
a1b388
                 }
a1b388
                 g_clear_pointer (&active_session_id, g_free);
a1b388
         } else if (!sd_seat_can_multi_session (seat_id)) {
a1b388
                 /* Ensure we don't create the same display more than once */
a1b388
                 display = gdm_display_store_find (store, lookup_by_seat_id, (gpointer) seat_id);
a1b388
 
a1b388
                 if (display != NULL) {
a1b388
                         return NULL;
a1b388
                 }
a1b388
         }
a1b388
 
a1b388
         g_debug ("GdmLocalDisplayFactory: Adding display on seat %s", seat_id);
a1b388
 
a1b388
 #ifdef ENABLE_USER_DISPLAY_SERVER
a1b388
         if (g_strcmp0 (seat_id, "seat0") == 0) {
a1b388
                 display = gdm_local_display_new ();
a1b388
                 if (session_type != NULL) {
a1b388
                         g_object_set (G_OBJECT (display), "session-type", session_type, NULL);
a1b388
                 }
a1b388
         }
a1b388
 #endif
a1b388
 
a1b388
         if (display == NULL) {
a1b388
                 guint32 num;
a1b388
 
a1b388
                 num = take_next_display_number (factory);
a1b388
 
a1b388
                 display = gdm_legacy_display_new (num);
a1b388
         }
a1b388
 
a1b388
-- 
a1b388
2.27.0
a1b388