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

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