Blame SOURCES/0030-daemon-Move-the-waiting-the-session-to-have-taken-ov.patch

400dab
From 0ff911467265831006aac6216060dbecff84c1cb Mon Sep 17 00:00:00 2001
400dab
From: Hans de Goede <hdegoede@redhat.com>
400dab
Date: Tue, 4 Sep 2018 10:56:45 +0200
400dab
Subject: [PATCH 30/51] daemon: Move the waiting the session to have taken over
400dab
 the fb to gdm-local-display-factory
400dab
400dab
Commit 708618746683 ("gdm-wayland-session,gdm-x-session: register after
400dab
delay") delayed displays changing their status from PREPARED to MANAGED
400dab
so that their status would not change until the session has had a change
400dab
to install its own framebuffer and tell the GPU to scanout this new fb.
400dab
400dab
Commit 74ee77717df7 ("local-display-factory: defer killing greeter until
400dab
new session registers") uses this to avoid a flicker when transitioning
400dab
from the greeter to the user-session by deferring the stopping of the
400dab
greeter-session until the new display moves to the MANAGED state.
400dab
400dab
But this only works when transitioning to a new user-session, when moving
400dab
to an existing user-session (fast user switching) the display already
400dab
is in MANAGED state and instead of deferring the stopping of the greeter
400dab
commit 74ee77717df7 causes us to now never stop the greeter-session.
400dab
400dab
This commit fixes this by starting a timeout when switching away from
400dab
the initial-vt and letting that timeout stop the greeter-session.
400dab
400dab
This commit removes the finish_waiting_displays_on_seat() call when the
400dab
display's status changes to MANAGED, so that we still only have one code
400dab
path stopping the greeter and not two.
400dab
400dab
This means we also no longer need to delay registering the display. So this
400dab
commit removes the code adding the delay (reverts commit 74ee77717df7).
400dab
400dab
Note this commit uses a delay of 10 seconds, rather then 2 seconds. The
400dab
transition to a new user-session takes about 8 seconds on my budget
400dab
Apollo Lake based laptop (with SSD).
400dab
400dab
Note this all really is a workaround, the proper solution for this would
400dab
be able to tell the kernel to keep the greeter framebuffer around until
400dab
a new framebuffer is installed. There is a patch to add a new unref_fb
400dab
ioctl for this: https://www.spinics.net/lists/dri-devel/msg140912.html .
400dab
We need to get this patch upstream and teach mutter to use it.
400dab
---
400dab
 daemon/gdm-local-display-factory.c | 29 ++++++++++++++++++++++++++---
400dab
 daemon/gdm-wayland-session.c       | 23 +++++++----------------
400dab
 daemon/gdm-x-session.c             | 25 ++++++++-----------------
400dab
 3 files changed, 41 insertions(+), 36 deletions(-)
400dab
400dab
diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c
400dab
index bc6ac6855..be6b377be 100644
400dab
--- a/daemon/gdm-local-display-factory.c
400dab
+++ b/daemon/gdm-local-display-factory.c
400dab
@@ -22,76 +22,78 @@
400dab
 
400dab
 #include <stdlib.h>
400dab
 #include <stdio.h>
400dab
 
400dab
 #include <glib.h>
400dab
 #include <glib/gi18n.h>
400dab
 #include <glib-object.h>
400dab
 #include <gio/gio.h>
400dab
 
400dab
 #include <systemd/sd-login.h>
400dab
 
400dab
 #include "gdm-common.h"
400dab
 #include "gdm-manager.h"
400dab
 #include "gdm-display-factory.h"
400dab
 #include "gdm-local-display-factory.h"
400dab
 #include "gdm-local-display-factory-glue.h"
400dab
 
400dab
 #include "gdm-settings-keys.h"
400dab
 #include "gdm-settings-direct.h"
400dab
 #include "gdm-display-store.h"
400dab
 #include "gdm-local-display.h"
400dab
 #include "gdm-legacy-display.h"
400dab
 
400dab
 #define GDM_LOCAL_DISPLAY_FACTORY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_LOCAL_DISPLAY_FACTORY, GdmLocalDisplayFactoryPrivate))
400dab
 
400dab
 #define GDM_DBUS_PATH                       "/org/gnome/DisplayManager"
400dab
 #define GDM_LOCAL_DISPLAY_FACTORY_DBUS_PATH GDM_DBUS_PATH "/LocalDisplayFactory"
400dab
 #define GDM_MANAGER_DBUS_NAME               "org.gnome.DisplayManager.LocalDisplayFactory"
400dab
 
400dab
 #define MAX_DISPLAY_FAILURES 5
400dab
+#define WAIT_TO_FINISH_TIMEOUT 10 /* seconds */
400dab
 
400dab
 struct GdmLocalDisplayFactoryPrivate
400dab
 {
400dab
         GdmDBusLocalDisplayFactory *skeleton;
400dab
         GDBusConnection *connection;
400dab
         GHashTable      *used_display_numbers;
400dab
 
400dab
         /* FIXME: this needs to be per seat? */
400dab
         guint            num_failures;
400dab
 
400dab
         guint            seat_new_id;
400dab
         guint            seat_removed_id;
400dab
 
400dab
 #if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER)
400dab
         char            *tty_of_active_vt;
400dab
         guint            active_vt_watch_id;
400dab
+        guint            wait_to_finish_timeout_id;
400dab
 #endif
400dab
 };
400dab
 
400dab
 enum {
400dab
         PROP_0,
400dab
 };
400dab
 
400dab
 static void     gdm_local_display_factory_class_init    (GdmLocalDisplayFactoryClass *klass);
400dab
 static void     gdm_local_display_factory_init          (GdmLocalDisplayFactory      *factory);
400dab
 static void     gdm_local_display_factory_finalize      (GObject                     *object);
400dab
 
400dab
 static GdmDisplay *create_display                       (GdmLocalDisplayFactory      *factory,
400dab
                                                          const char                  *seat_id,
400dab
                                                          const char                  *session_type,
400dab
                                                          gboolean                    initial_display);
400dab
 
400dab
 static void     on_display_status_changed               (GdmDisplay                  *display,
400dab
                                                          GParamSpec                  *arg1,
400dab
                                                          GdmLocalDisplayFactory      *factory);
400dab
 
400dab
 static gboolean gdm_local_display_factory_sync_seats    (GdmLocalDisplayFactory *factory);
400dab
 static gpointer local_display_factory_object = NULL;
400dab
 static gboolean lookup_by_session_id (const char *id,
400dab
                                       GdmDisplay *display,
400dab
                                       gpointer    user_data);
400dab
 
400dab
 G_DEFINE_TYPE (GdmLocalDisplayFactory, gdm_local_display_factory, GDM_TYPE_DISPLAY_FACTORY)
400dab
 
400dab
 GQuark
400dab
 gdm_local_display_factory_error_quark (void)
400dab
@@ -354,61 +356,60 @@ on_display_status_changed (GdmDisplay             *display,
400dab
                 /* Create a new equivalent display if it was static */
400dab
                 if (is_local) {
400dab
 
400dab
                         factory->priv->num_failures++;
400dab
 
400dab
                         if (factory->priv->num_failures > MAX_DISPLAY_FAILURES) {
400dab
                                 /* oh shit */
400dab
                                 g_warning ("GdmLocalDisplayFactory: maximum number of X display failures reached: check X server log for errors");
400dab
                         } else {
400dab
 #ifdef ENABLE_WAYLAND_SUPPORT
400dab
                                 if (g_strcmp0 (session_type, "wayland") == 0) {
400dab
                                         g_free (session_type);
400dab
                                         session_type = NULL;
400dab
 
400dab
                                         /* workaround logind race for now
400dab
                                          * bug 1643874
400dab
                                          */
400dab
                                         g_usleep (2 * G_USEC_PER_SEC);
400dab
                                 }
400dab
 
400dab
 #endif
400dab
                                 create_display (factory, seat_id, session_type, is_initial);
400dab
                         }
400dab
                 }
400dab
                 break;
400dab
         case GDM_DISPLAY_UNMANAGED:
400dab
                 break;
400dab
         case GDM_DISPLAY_PREPARED:
400dab
                 break;
400dab
         case GDM_DISPLAY_MANAGED:
400dab
-                finish_waiting_displays_on_seat (factory, seat_id);
400dab
                 break;
400dab
         case GDM_DISPLAY_WAITING_TO_FINISH:
400dab
                 break;
400dab
         default:
400dab
                 g_assert_not_reached ();
400dab
                 break;
400dab
         }
400dab
 
400dab
         g_free (seat_id);
400dab
         g_free (session_type);
400dab
         g_free (session_class);
400dab
 }
400dab
 
400dab
 static gboolean
400dab
 lookup_by_seat_id (const char *id,
400dab
                    GdmDisplay *display,
400dab
                    gpointer    user_data)
400dab
 {
400dab
         const char *looking_for = user_data;
400dab
         char *current;
400dab
         gboolean res;
400dab
 
400dab
         g_object_get (G_OBJECT (display), "seat-id", &current, NULL);
400dab
 
400dab
         res = g_strcmp0 (current, looking_for) == 0;
400dab
 
400dab
         g_free(current);
400dab
 
400dab
         return res;
400dab
 }
400dab
@@ -593,83 +594,101 @@ on_seat_new (GDBusConnection *connection,
400dab
 }
400dab
 
400dab
 static void
400dab
 on_seat_removed (GDBusConnection *connection,
400dab
                  const gchar     *sender_name,
400dab
                  const gchar     *object_path,
400dab
                  const gchar     *interface_name,
400dab
                  const gchar     *signal_name,
400dab
                  GVariant        *parameters,
400dab
                  gpointer         user_data)
400dab
 {
400dab
         const char *seat;
400dab
 
400dab
         g_variant_get (parameters, "(&s&o)", &seat, NULL);
400dab
         delete_display (GDM_LOCAL_DISPLAY_FACTORY (user_data), seat);
400dab
 }
400dab
 
400dab
 #if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER)
400dab
 static gboolean
400dab
 lookup_by_session_id (const char *id,
400dab
                       GdmDisplay *display,
400dab
                       gpointer    user_data)
400dab
 {
400dab
         const char *looking_for = user_data;
400dab
         const char *current;
400dab
 
400dab
         current = gdm_display_get_session_id (display);
400dab
         return g_strcmp0 (current, looking_for) == 0;
400dab
 }
400dab
 
400dab
+static gboolean
400dab
+wait_to_finish_timeout (GdmLocalDisplayFactory *factory)
400dab
+{
400dab
+        finish_waiting_displays_on_seat (factory, "seat0");
400dab
+        factory->priv->wait_to_finish_timeout_id = 0;
400dab
+        return G_SOURCE_REMOVE;
400dab
+}
400dab
+
400dab
 static void
400dab
-maybe_stop_greeter_in_background (GdmDisplay *display)
400dab
+maybe_stop_greeter_in_background (GdmLocalDisplayFactory *factory,
400dab
+                                  GdmDisplay             *display)
400dab
 {
400dab
         g_autofree char *display_session_type = NULL;
400dab
 
400dab
         if (gdm_display_get_status (display) != GDM_DISPLAY_MANAGED) {
400dab
                 g_debug ("GdmLocalDisplayFactory: login window not in managed state, so ignoring");
400dab
                 return;
400dab
         }
400dab
 
400dab
         g_object_get (G_OBJECT (display),
400dab
                       "session-type", &display_session_type,
400dab
                       NULL);
400dab
 
400dab
         /* we can only stop greeter for wayland sessions, since
400dab
          * X server would jump back on exit */
400dab
         if (g_strcmp0 (display_session_type, "wayland") != 0) {
400dab
                 g_debug ("GdmLocalDisplayFactory: login window is running on Xorg, so ignoring");
400dab
                 return;
400dab
         }
400dab
 
400dab
         g_debug ("GdmLocalDisplayFactory: killing login window once its unused");
400dab
         g_object_set (G_OBJECT (display), "status", GDM_DISPLAY_WAITING_TO_FINISH, NULL);
400dab
+
400dab
+        /* We stop the greeter after a timeout to avoid flicker */
400dab
+        if (factory->priv->wait_to_finish_timeout_id != 0)
400dab
+                g_source_remove (factory->priv->wait_to_finish_timeout_id);
400dab
+
400dab
+        factory->priv->wait_to_finish_timeout_id =
400dab
+                g_timeout_add_seconds (WAIT_TO_FINISH_TIMEOUT,
400dab
+                                       (GSourceFunc)wait_to_finish_timeout,
400dab
+                                       factory);
400dab
 }
400dab
 
400dab
 static gboolean
400dab
 on_vt_changed (GIOChannel    *source,
400dab
                GIOCondition   condition,
400dab
                GdmLocalDisplayFactory *factory)
400dab
 {
400dab
         GIOStatus status;
400dab
         static const char *tty_of_initial_vt = "tty" GDM_INITIAL_VT;
400dab
         g_autofree char *tty_of_previous_vt = NULL;
400dab
         g_autofree char *tty_of_active_vt = NULL;
400dab
         g_autofree char *login_session_id = NULL;
400dab
         g_autofree char *active_session_id = NULL;
400dab
         const char *session_type = NULL;
400dab
         int ret;
400dab
 
400dab
         g_debug ("GdmLocalDisplayFactory: received VT change event");
400dab
         g_io_channel_seek_position (source, 0, G_SEEK_SET, NULL);
400dab
 
400dab
         if (condition & G_IO_PRI) {
400dab
                 g_autoptr (GError) error = NULL;
400dab
                 status = g_io_channel_read_line (source, &tty_of_active_vt, NULL, NULL, &error);
400dab
 
400dab
                 if (error != NULL) {
400dab
                         g_warning ("could not read active VT from kernel: %s", error->message);
400dab
                 }
400dab
                 switch (status) {
400dab
                         case G_IO_STATUS_ERROR:
400dab
                             return G_SOURCE_REMOVE;
400dab
                         case G_IO_STATUS_EOF:
400dab
@@ -709,61 +728,61 @@ on_vt_changed (GIOChannel    *source,
400dab
                 return G_SOURCE_CONTINUE;
400dab
         }
400dab
 
400dab
         g_debug ("GdmLocalDisplayFactory: VT changed from %s to %s",
400dab
                  tty_of_previous_vt, factory->priv->tty_of_active_vt);
400dab
 
400dab
         /* if the old VT was running a wayland login screen kill it
400dab
          */
400dab
         if (gdm_get_login_window_session_id ("seat0", &login_session_id)) {
400dab
                 unsigned int vt;
400dab
 
400dab
                 ret = sd_session_get_vt (login_session_id, &vt;;
400dab
                 if (ret == 0 && vt != 0) {
400dab
                         g_autofree char *tty_of_login_window_vt = NULL;
400dab
 
400dab
                         tty_of_login_window_vt = g_strdup_printf ("tty%u", vt);
400dab
 
400dab
                         g_debug ("GdmLocalDisplayFactory: tty of login window is %s", tty_of_login_window_vt);
400dab
                         if (g_strcmp0 (tty_of_login_window_vt, tty_of_previous_vt) == 0) {
400dab
                                 GdmDisplayStore *store;
400dab
                                 GdmDisplay *display;
400dab
 
400dab
                                 g_debug ("GdmLocalDisplayFactory: VT switched from login window");
400dab
 
400dab
                                 store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory));
400dab
                                 display = gdm_display_store_find (store,
400dab
                                                                   lookup_by_session_id,
400dab
                                                                   (gpointer) login_session_id);
400dab
 
400dab
                                 if (display != NULL)
400dab
-                                        maybe_stop_greeter_in_background (display);
400dab
+                                        maybe_stop_greeter_in_background (factory, display);
400dab
                         } else {
400dab
                                 g_debug ("GdmLocalDisplayFactory: VT not switched from login window");
400dab
                         }
400dab
                 }
400dab
         }
400dab
 
400dab
         /* if user jumped back to initial vt and it's empty put a login screen
400dab
          * on it (unless a login screen is already running elsewhere, then
400dab
          * jump to that login screen)
400dab
          */
400dab
         if (strcmp (factory->priv->tty_of_active_vt, tty_of_initial_vt) != 0) {
400dab
                 g_debug ("GdmLocalDisplayFactory: active VT is not initial VT, so ignoring");
400dab
                 return G_SOURCE_CONTINUE;
400dab
         }
400dab
 
400dab
         ret = sd_seat_get_active ("seat0", &active_session_id, NULL);
400dab
 
400dab
         if (ret == 0) {
400dab
                 g_autofree char *state = NULL;
400dab
                 ret = sd_session_get_state (active_session_id, &state);
400dab
 
400dab
                 /* if there's something already running on the active VT then bail */
400dab
                 if (ret == 0 && g_strcmp0 (state, "closing") != 0) {
400dab
                         g_debug ("GdmLocalDisplayFactory: initial VT is in use, so ignoring");
400dab
                         return G_SOURCE_CONTINUE;
400dab
                 }
400dab
         }
400dab
 
400dab
         if (gdm_local_display_factory_use_wayland ())
400dab
                 session_type = "wayland";
400dab
@@ -803,60 +822,64 @@ gdm_local_display_factory_start_monitor (GdmLocalDisplayFactory *factory)
400dab
                                                                              g_object_unref);
400dab
 
400dab
 #if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER)
400dab
         io_channel = g_io_channel_new_file ("/sys/class/tty/tty0/active", "r", NULL);
400dab
 
400dab
         if (io_channel != NULL) {
400dab
                 factory->priv->active_vt_watch_id =
400dab
                         g_io_add_watch (io_channel,
400dab
                                         G_IO_PRI,
400dab
                                         (GIOFunc)
400dab
                                         on_vt_changed,
400dab
                                         factory);
400dab
         }
400dab
 #endif
400dab
 }
400dab
 
400dab
 static void
400dab
 gdm_local_display_factory_stop_monitor (GdmLocalDisplayFactory *factory)
400dab
 {
400dab
         if (factory->priv->seat_new_id) {
400dab
                 g_dbus_connection_signal_unsubscribe (factory->priv->connection,
400dab
                                                       factory->priv->seat_new_id);
400dab
                 factory->priv->seat_new_id = 0;
400dab
         }
400dab
         if (factory->priv->seat_removed_id) {
400dab
                 g_dbus_connection_signal_unsubscribe (factory->priv->connection,
400dab
                                                       factory->priv->seat_removed_id);
400dab
                 factory->priv->seat_removed_id = 0;
400dab
         }
400dab
 #if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER)
400dab
+        if (factory->priv->wait_to_finish_timeout_id != 0) {
400dab
+                g_source_remove (factory->priv->wait_to_finish_timeout_id);
400dab
+                factory->priv->wait_to_finish_timeout_id = 0;
400dab
+        }
400dab
         if (factory->priv->active_vt_watch_id) {
400dab
                 g_source_remove (factory->priv->active_vt_watch_id);
400dab
                 factory->priv->active_vt_watch_id = 0;
400dab
         }
400dab
 
400dab
         g_clear_pointer (&factory->priv->tty_of_active_vt, g_free);
400dab
 #endif
400dab
 }
400dab
 
400dab
 static void
400dab
 on_display_added (GdmDisplayStore        *display_store,
400dab
                   const char             *id,
400dab
                   GdmLocalDisplayFactory *factory)
400dab
 {
400dab
         GdmDisplay *display;
400dab
 
400dab
         display = gdm_display_store_lookup (display_store, id);
400dab
 
400dab
         if (display != NULL) {
400dab
                 g_signal_connect_object (display, "notify::status",
400dab
                                          G_CALLBACK (on_display_status_changed),
400dab
                                          factory,
400dab
                                          0);
400dab
 
400dab
                 g_object_weak_ref (G_OBJECT (display), (GWeakNotify)on_display_disposed, factory);
400dab
         }
400dab
 }
400dab
 
400dab
 static void
400dab
 on_display_removed (GdmDisplayStore        *display_store,
400dab
diff --git a/daemon/gdm-wayland-session.c b/daemon/gdm-wayland-session.c
400dab
index de1991b34..94f49e19c 100644
400dab
--- a/daemon/gdm-wayland-session.c
400dab
+++ b/daemon/gdm-wayland-session.c
400dab
@@ -427,75 +427,60 @@ init_state (State **state)
400dab
         static State state_allocation;
400dab
 
400dab
         *state = &state_allocation;
400dab
 }
400dab
 
400dab
 static void
400dab
 clear_state (State **out_state)
400dab
 {
400dab
         State *state = *out_state;
400dab
 
400dab
         g_clear_object (&state->cancellable);
400dab
         g_clear_object (&state->bus_connection);
400dab
         g_clear_object (&state->session_subprocess);
400dab
         g_clear_pointer (&state->environment, g_strfreev);
400dab
         g_clear_pointer (&state->main_loop, g_main_loop_unref);
400dab
         *out_state = NULL;
400dab
 }
400dab
 
400dab
 static gboolean
400dab
 on_sigterm (State *state)
400dab
 {
400dab
         g_cancellable_cancel (state->cancellable);
400dab
 
400dab
         if (g_main_loop_is_running (state->main_loop)) {
400dab
                 g_main_loop_quit (state->main_loop);
400dab
         }
400dab
 
400dab
         return G_SOURCE_CONTINUE;
400dab
 }
400dab
 
400dab
-static gboolean
400dab
-on_registration_delay_complete (State *state)
400dab
-{
400dab
-        gboolean ret;
400dab
-
400dab
-        ret = register_display (state, state->cancellable);
400dab
-
400dab
-        if (!ret) {
400dab
-                g_printerr ("Unable to register display with display manager\n");
400dab
-                g_main_loop_quit (state->main_loop);
400dab
-        }
400dab
-
400dab
-        return G_SOURCE_REMOVE;
400dab
-}
400dab
-
400dab
 int
400dab
 main (int    argc,
400dab
       char **argv)
400dab
 {
400dab
         State           *state = NULL;
400dab
         GOptionContext  *context = NULL;
400dab
         static char    **args = NULL;
400dab
         gboolean         debug = FALSE;
400dab
         gboolean         ret;
400dab
         int              exit_status = EX_OK;
400dab
         static GOptionEntry entries []   = {
400dab
                 { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &args, "", "" },
400dab
                 { NULL }
400dab
         };
400dab
 
400dab
         bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
400dab
         textdomain (GETTEXT_PACKAGE);
400dab
         setlocale (LC_ALL, "");
400dab
 
400dab
         gdm_log_init ();
400dab
 
400dab
         context = g_option_context_new (_("GNOME Display Manager Wayland Session Launcher"));
400dab
         g_option_context_add_main_entries (context, entries, NULL);
400dab
 
400dab
         g_option_context_parse (context, &argc, &argv, NULL);
400dab
         g_option_context_free (context);
400dab
 
400dab
         if (args == NULL || args[0] == NULL || args[1] != NULL) {
400dab
                 g_warning ("gdm-wayland-session takes one argument (the session)");
400dab
                 exit_status = EX_USAGE;
400dab
@@ -516,49 +501,55 @@ main (int    argc,
400dab
         }
400dab
 
400dab
         gdm_settings_direct_get_boolean (GDM_KEY_DEBUG, &debug);
400dab
         state->debug_enabled = debug;
400dab
 
400dab
         gdm_log_set_debug (debug);
400dab
 
400dab
         state->main_loop = g_main_loop_new (NULL, FALSE);
400dab
         state->cancellable = g_cancellable_new ();
400dab
 
400dab
         g_unix_signal_add (SIGTERM, (GSourceFunc) on_sigterm, state);
400dab
 
400dab
         ret = spawn_bus (state, state->cancellable);
400dab
 
400dab
         if (!ret) {
400dab
                 g_printerr ("Unable to run session message bus\n");
400dab
                 exit_status = EX_SOFTWARE;
400dab
                 goto out;
400dab
         }
400dab
 
400dab
         import_environment (state, state->cancellable);
400dab
 
400dab
         ret = spawn_session (state, state->cancellable);
400dab
 
400dab
         if (!ret) {
400dab
                 g_printerr ("Unable to run session\n");
400dab
                 exit_status = EX_SOFTWARE;
400dab
                 goto out;
400dab
         }
400dab
 
400dab
-        g_timeout_add_seconds (2, (GSourceFunc) on_registration_delay_complete, state);
400dab
+        ret = register_display (state, state->cancellable);
400dab
+
400dab
+        if (!ret) {
400dab
+                g_printerr ("Unable to register display with display manager\n");
400dab
+                exit_status = EX_SOFTWARE;
400dab
+                goto out;
400dab
+        }
400dab
 
400dab
         g_main_loop_run (state->main_loop);
400dab
 
400dab
         /* Only use exit status of session if we're here because it exit */
400dab
 
400dab
         if (state->session_subprocess == NULL) {
400dab
                 exit_status = state->session_exit_status;
400dab
         }
400dab
 
400dab
 out:
400dab
         if (state != NULL) {
400dab
                 signal_subprocesses (state);
400dab
                 wait_on_subprocesses (state);
400dab
                 clear_state (&state);
400dab
         }
400dab
 
400dab
         return exit_status;
400dab
 }
400dab
diff --git a/daemon/gdm-x-session.c b/daemon/gdm-x-session.c
400dab
index 412999cf5..3b2fcef47 100644
400dab
--- a/daemon/gdm-x-session.c
400dab
+++ b/daemon/gdm-x-session.c
400dab
@@ -783,75 +783,60 @@ init_state (State **state)
400dab
 }
400dab
 
400dab
 static void
400dab
 clear_state (State **out_state)
400dab
 {
400dab
         State *state = *out_state;
400dab
 
400dab
         g_clear_object (&state->cancellable);
400dab
         g_clear_object (&state->bus_connection);
400dab
         g_clear_object (&state->session_subprocess);
400dab
         g_clear_object (&state->x_subprocess);
400dab
         g_clear_pointer (&state->environment, g_strfreev);
400dab
         g_clear_pointer (&state->auth_file, g_free);
400dab
         g_clear_pointer (&state->display_name, g_free);
400dab
         g_clear_pointer (&state->main_loop, g_main_loop_unref);
400dab
         *out_state = NULL;
400dab
 }
400dab
 
400dab
 static gboolean
400dab
 on_sigterm (State *state)
400dab
 {
400dab
         g_cancellable_cancel (state->cancellable);
400dab
 
400dab
         if (g_main_loop_is_running (state->main_loop)) {
400dab
                 g_main_loop_quit (state->main_loop);
400dab
         }
400dab
 
400dab
         return G_SOURCE_CONTINUE;
400dab
 }
400dab
 
400dab
-static gboolean
400dab
-on_registration_delay_complete (State *state)
400dab
-{
400dab
-        gboolean ret;
400dab
-
400dab
-        ret = register_display (state, state->cancellable);
400dab
-
400dab
-        if (!ret) {
400dab
-                g_printerr ("Unable to register display with display manager\n");
400dab
-                g_main_loop_quit (state->main_loop);
400dab
-        }
400dab
-
400dab
-        return G_SOURCE_REMOVE;
400dab
-}
400dab
-
400dab
 int
400dab
 main (int    argc,
400dab
       char **argv)
400dab
 {
400dab
         State           *state = NULL;
400dab
         GOptionContext  *context = NULL;
400dab
         static char    **args = NULL;
400dab
         static gboolean  run_script = FALSE;
400dab
         static gboolean  allow_remote_connections = FALSE;
400dab
         gboolean         debug = FALSE;
400dab
         gboolean         ret;
400dab
         int              exit_status = EX_OK;
400dab
         static GOptionEntry entries []   = {
400dab
                 { "run-script", 'r', 0, G_OPTION_ARG_NONE, &run_script, N_("Run program through /etc/gdm/Xsession wrapper script"), NULL },
400dab
                 { "allow-remote-connections", 'a', 0, G_OPTION_ARG_NONE, &allow_remote_connections, N_("Listen on TCP socket"), NULL },
400dab
                 { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &args, "", "" },
400dab
                 { NULL }
400dab
         };
400dab
 
400dab
         bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
400dab
         textdomain (GETTEXT_PACKAGE);
400dab
         setlocale (LC_ALL, "");
400dab
 
400dab
         gdm_log_init ();
400dab
 
400dab
         context = g_option_context_new (_("GNOME Display Manager X Session Launcher"));
400dab
         g_option_context_add_main_entries (context, entries, NULL);
400dab
 
400dab
         g_option_context_parse (context, &argc, &argv, NULL);
400dab
         g_option_context_free (context);
400dab
@@ -884,57 +869,63 @@ main (int    argc,
400dab
         state->cancellable = g_cancellable_new ();
400dab
 
400dab
         g_unix_signal_add (SIGTERM, (GSourceFunc) on_sigterm, state);
400dab
 
400dab
         ret = spawn_x_server (state, allow_remote_connections, state->cancellable);
400dab
 
400dab
         if (!ret) {
400dab
                 g_printerr ("Unable to run X server\n");
400dab
                 exit_status = EX_SOFTWARE;
400dab
                 goto out;
400dab
         }
400dab
 
400dab
         ret = spawn_bus (state, state->cancellable);
400dab
 
400dab
         if (!ret) {
400dab
                 g_printerr ("Unable to run session message bus\n");
400dab
                 exit_status = EX_SOFTWARE;
400dab
                 goto out;
400dab
         }
400dab
 
400dab
         import_environment (state, state->cancellable);
400dab
 
400dab
         ret = update_bus_environment (state, state->cancellable);
400dab
 
400dab
         if (!ret) {
400dab
                 g_printerr ("Unable to update bus environment\n");
400dab
                 exit_status = EX_SOFTWARE;
400dab
                 goto out;
400dab
         }
400dab
 
400dab
+        ret = register_display (state, state->cancellable);
400dab
+
400dab
+        if (!ret) {
400dab
+                g_printerr ("Unable to register display with display manager\n");
400dab
+                exit_status = EX_SOFTWARE;
400dab
+                goto out;
400dab
+        }
400dab
+
400dab
         ret = spawn_session (state, run_script, state->cancellable);
400dab
 
400dab
         if (!ret) {
400dab
                 g_printerr ("Unable to run session\n");
400dab
                 exit_status = EX_SOFTWARE;
400dab
                 goto out;
400dab
         }
400dab
 
400dab
-        g_timeout_add_seconds (2, (GSourceFunc) on_registration_delay_complete, state);
400dab
-
400dab
         g_main_loop_run (state->main_loop);
400dab
 
400dab
         /* Only use exit status of session if we're here because it exit */
400dab
 
400dab
         if (state->session_subprocess == NULL) {
400dab
                 exit_status = state->session_exit_status;
400dab
         }
400dab
 
400dab
 out:
400dab
         if (state != NULL) {
400dab
                 signal_subprocesses (state);
400dab
                 wait_on_subprocesses (state);
400dab
                 clear_state (&state);
400dab
         }
400dab
 
400dab
         return exit_status;
400dab
 }
400dab
-- 
400dab
2.27.0
400dab