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

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