From c4338596bcf9564720daecb05f4a1fe9b9a16fae Mon Sep 17 00:00:00 2001 From: Joan Torres Lopez Date: Fri, 14 Nov 2025 16:33:33 +0100 Subject: [PATCH] Improve plymouth handling Now plymouth will quit even when monitor is not connected. Resolves: https://issues.redhat.com/browse/RHEL-86140 --- ...Revert-hack-that-quits-plymouth-late.patch | 365 ++++++++++++++++++ gdm.spec | 4 + 2 files changed, 369 insertions(+) create mode 100644 0001-Revert-hack-that-quits-plymouth-late.patch diff --git a/0001-Revert-hack-that-quits-plymouth-late.patch b/0001-Revert-hack-that-quits-plymouth-late.patch new file mode 100644 index 0000000..a10b981 --- /dev/null +++ b/0001-Revert-hack-that-quits-plymouth-late.patch @@ -0,0 +1,365 @@ +From 8a91856f4020657adcbba67482daa6db373e8ed6 Mon Sep 17 00:00:00 2001 +From: Adrian Vovk +Date: Thu, 1 May 2025 15:42:49 -0400 +Subject: [PATCH 1/2] Revert hack that quits plymouth late + +Reverts 2cbd7ad1f66d0a757c1d2217705436aa1beca76a + +Fixes #375 + +Part-of: +--- + daemon/gdm-manager.c | 27 ++++++++------------------- + 1 file changed, 8 insertions(+), 19 deletions(-) + +diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c +index e455dad36..0913f7a50 100644 +--- a/daemon/gdm-manager.c ++++ b/daemon/gdm-manager.c +@@ -175,7 +175,7 @@ plymouth_prepare_for_transition (void) + } + } + +-static gboolean ++static void + plymouth_quit_with_transition (void) + { + gboolean res; +@@ -187,8 +187,6 @@ plymouth_quit_with_transition (void) + g_warning ("Could not quit plymouth: %s", error->message); + g_error_free (error); + } +- +- return G_SOURCE_REMOVE; + } + + static void +@@ -1506,6 +1504,13 @@ on_display_status_changed (GdmDisplay *display, + if (g_strcmp0 (session_class, "greeter") == 0) + set_up_session (manager, display); + } ++ ++#ifdef WITH_PLYMOUTH ++ if (status == GDM_DISPLAY_MANAGED && quit_plymouth) { ++ plymouth_quit_with_transition (); ++ manager->plymouth_is_running = FALSE; ++ } ++#endif + break; + case GDM_DISPLAY_FAILED: + case GDM_DISPLAY_UNMANAGED: +@@ -1892,15 +1897,6 @@ on_user_session_started (GdmSession *session, + { + g_debug ("GdmManager: session started %d", pid); + add_session_record (manager, session, pid, SESSION_RECORD_LOGIN); +- +-#ifdef WITH_PLYMOUTH +- if (g_strcmp0 (service_name, "gdm-autologin") == 0) { +- if (manager->plymouth_is_running) { +- g_timeout_add_seconds (20, (GSourceFunc) plymouth_quit_with_transition, NULL); +- manager->plymouth_is_running = FALSE; +- } +- } +-#endif + } + + static void +@@ -2124,13 +2120,6 @@ on_session_client_connected (GdmSession *session, + return; + } + +-#ifdef WITH_PLYMOUTH +- if (manager->plymouth_is_running) { +- plymouth_quit_with_transition (); +- manager->plymouth_is_running = FALSE; +- } +-#endif +- + g_object_get (G_OBJECT (display), "allow-timed-login", &allow_timed_login, NULL); + + if (!allow_timed_login) { +-- +2.51.0 + + +From deeb4b8aba46e37a1f6dcb85252ed713183cb170 Mon Sep 17 00:00:00 2001 +From: Adrian Vovk +Date: Thu, 1 May 2025 16:13:53 -0400 +Subject: [PATCH 2/2] manager: Combine register display with register session + +Before we'd always register the display as soon as the session was +started. However, this is too early for Wayland! The compositor might +not have completely initialized its Wayland connection yet, so the +display isn't really open. + +The "register display" should happen when the compositor is up and +running. This occurs when it calls RegisterSession, so it makes sense +to combine both. + +This helps on terminating plymouthd when the new session has been +started, and also kill background greeters. + +Part-of: +--- + daemon/gdm-local-display-factory.c | 30 ++++--------------- + daemon/gdm-manager.c | 47 ++++++------------------------ + daemon/gdm-manager.xml | 3 -- + daemon/gdm-wayland-session.c | 31 -------------------- + daemon/gdm-x-session.c | 32 -------------------- + 5 files changed, 15 insertions(+), 128 deletions(-) + +diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c +index 2d4f2c0..63117e1 100644 +--- a/daemon/gdm-local-display-factory.c ++++ b/daemon/gdm-local-display-factory.c +@@ -515,25 +515,6 @@ on_finish_waiting_for_seat0_displays_timeout (GdmLocalDisplayFactory *factory) + return G_SOURCE_REMOVE; + } + +-static void +-on_session_registered_cb (GObject *gobject, +- GParamSpec *pspec, +- gpointer user_data) +-{ +- GdmDisplay *display = GDM_DISPLAY (gobject); +- GdmLocalDisplayFactory *factory = GDM_LOCAL_DISPLAY_FACTORY (user_data); +- gboolean registered; +- +- g_object_get (display, "session-registered", ®istered, NULL); +- +- if (!registered) +- return; +- +- g_debug ("GdmLocalDisplayFactory: session registered on display, looking for any background displays to kill"); +- +- finish_waiting_displays_on_seat (factory, "seat0"); +-} +- + static void + on_display_status_changed (GdmDisplay *display, + GParamSpec *arg1, +@@ -548,6 +529,7 @@ on_display_status_changed (GdmDisplay *display, + char *session_id = NULL; + gboolean is_initial = TRUE; + gboolean is_local = TRUE; ++ gboolean registered = FALSE; + + + if (!factory->is_started) +@@ -618,11 +600,11 @@ on_display_status_changed (GdmDisplay *display, + break; + case GDM_DISPLAY_MANAGED: + #if defined(ENABLE_USER_DISPLAY_SERVER) +- g_signal_connect_object (display, +- "notify::session-registered", +- G_CALLBACK (on_session_registered_cb), +- factory, +- 0); ++ g_object_get (display, "session-registered", ®istered, NULL); ++ if (registered) { ++ g_debug ("GdmLocalDisplayFactory: session registered on display, looking for any background displays to kill"); ++ finish_waiting_displays_on_seat (factory, "seat0"); ++ } + #endif + break; + case GDM_DISPLAY_WAITING_TO_FINISH: +diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c +index a99e6b5..ff04203 100644 +--- a/daemon/gdm-manager.c ++++ b/daemon/gdm-manager.c +@@ -732,7 +732,7 @@ find_user_session_for_display (GdmManager *self, + } + + static gboolean +-gdm_manager_handle_register_display (GdmDBusManager *manager, ++gdm_manager_handle_register_session (GdmDBusManager *manager, + GDBusMethodInvocation *invocation, + GVariant *details) + { +@@ -744,15 +744,15 @@ gdm_manager_handle_register_display (GdmDBusManager *manager, + GVariantIter iter; + char *key = NULL; + char *value = NULL; +- char *x11_display_name = NULL; +- char *tty = NULL; +- +- g_debug ("GdmManager: trying to register new display"); ++ g_autofree char *x11_display_name = NULL; ++ g_autofree char *tty = NULL; + + sender = g_dbus_method_invocation_get_sender (invocation); + connection = g_dbus_method_invocation_get_connection (invocation); + get_display_and_details_for_bus_sender (self, connection, sender, &display, NULL, NULL, &tty, NULL, NULL, NULL, NULL); + ++ g_debug ("GdmManager: trying to register new session on display %p", display); ++ + if (display == NULL) { + g_dbus_method_invocation_return_error_literal (invocation, + G_DBUS_ERROR, +@@ -792,38 +792,10 @@ gdm_manager_handle_register_display (GdmDBusManager *manager, + } + } + +- g_object_set (G_OBJECT (display), "status", GDM_DISPLAY_MANAGED, NULL); +- +- gdm_dbus_manager_complete_register_display (GDM_DBUS_MANAGER (manager), +- invocation); +- +- g_clear_pointer (&x11_display_name, g_free); +- g_clear_pointer (&tty, g_free); +- return TRUE; +-} +- +-static gboolean +-gdm_manager_handle_register_session (GdmDBusManager *manager, +- GDBusMethodInvocation *invocation, +- GVariant *details) +-{ +- GdmManager *self = GDM_MANAGER (manager); +- GdmDisplay *display = NULL; +- const char *sender; +- GDBusConnection *connection; +- +- sender = g_dbus_method_invocation_get_sender (invocation); +- connection = g_dbus_method_invocation_get_connection (invocation); +- +- get_display_and_details_for_bus_sender (self, connection, sender, &display, +- NULL, NULL, NULL, NULL, NULL, NULL, NULL); +- +- g_debug ("GdmManager: trying to register new session on display %p", display); +- +- if (display != NULL) +- g_object_set (G_OBJECT (display), "session-registered", TRUE, NULL); +- else +- g_debug ("GdmManager: No display, not registering"); ++ g_object_set (G_OBJECT (display), ++ "status", GDM_DISPLAY_MANAGED, ++ "session-registered", TRUE, ++ NULL); + + gdm_dbus_manager_complete_register_session (GDM_DBUS_MANAGER (manager), + invocation); +@@ -1242,7 +1214,6 @@ gdm_manager_handle_open_reauthentication_channel (GdmDBusManager *manager + static void + manager_interface_init (GdmDBusManagerIface *interface) + { +- interface->handle_register_display = gdm_manager_handle_register_display; + interface->handle_register_session = gdm_manager_handle_register_session; + interface->handle_open_session = gdm_manager_handle_open_session; + interface->handle_open_reauthentication_channel = gdm_manager_handle_open_reauthentication_channel; +diff --git a/daemon/gdm-manager.xml b/daemon/gdm-manager.xml +index 92ef1d0..aba079a 100644 +--- a/daemon/gdm-manager.xml ++++ b/daemon/gdm-manager.xml +@@ -1,9 +1,6 @@ + + + +- +- +- + + + +diff --git a/daemon/gdm-wayland-session.c b/daemon/gdm-wayland-session.c +index d0404d2..d4d1edd 100644 +--- a/daemon/gdm-wayland-session.c ++++ b/daemon/gdm-wayland-session.c +@@ -404,29 +404,6 @@ wait_on_subprocesses (State *state) + } + } + +-static gboolean +-register_display (State *state, +- GCancellable *cancellable) +-{ +- GError *error = NULL; +- gboolean registered = FALSE; +- GVariantBuilder details; +- +- g_variant_builder_init (&details, G_VARIANT_TYPE ("a{ss}")); +- g_variant_builder_add (&details, "{ss}", "session-type", "wayland"); +- +- registered = gdm_dbus_manager_call_register_display_sync (state->display_manager_proxy, +- g_variant_builder_end (&details), +- cancellable, +- &error); +- if (error != NULL) { +- g_debug ("Could not register display: %s", error->message); +- g_error_free (error); +- } +- +- return registered; +-} +- + static void + init_state (State **state) + { +@@ -584,14 +561,6 @@ main (int argc, + if (!connect_to_display_manager (state)) + goto out; + +- ret = register_display (state, state->cancellable); +- +- if (!ret) { +- g_printerr ("Unable to register display with display manager\n"); +- exit_status = EX_SOFTWARE; +- goto out; +- } +- + if (register_session) { + g_debug ("gdm-wayland-session: Will register session in %d seconds", REGISTER_SESSION_TIMEOUT); + state->register_session_id = g_timeout_add_seconds (REGISTER_SESSION_TIMEOUT, +diff --git a/daemon/gdm-x-session.c b/daemon/gdm-x-session.c +index 0b07ab5..36b3975 100644 +--- a/daemon/gdm-x-session.c ++++ b/daemon/gdm-x-session.c +@@ -757,30 +757,6 @@ wait_on_subprocesses (State *state) + } + } + +-static gboolean +-register_display (State *state, +- GCancellable *cancellable) +-{ +- GError *error = NULL; +- gboolean registered = FALSE; +- GVariantBuilder details; +- +- g_variant_builder_init (&details, G_VARIANT_TYPE ("a{ss}")); +- g_variant_builder_add (&details, "{ss}", "session-type", "x11"); +- g_variant_builder_add (&details, "{ss}", "x11-display-name", state->display_name); +- +- registered = gdm_dbus_manager_call_register_display_sync (state->display_manager_proxy, +- g_variant_builder_end (&details), +- cancellable, +- &error); +- if (error != NULL) { +- g_debug ("Could not register display: %s", error->message); +- g_error_free (error); +- } +- +- return registered; +-} +- + static void + init_state (State **state) + { +@@ -953,14 +929,6 @@ main (int argc, + if (!connect_to_display_manager (state)) + goto out; + +- ret = register_display (state, state->cancellable); +- +- if (!ret) { +- g_printerr ("Unable to register display with display manager\n"); +- exit_status = EX_SOFTWARE; +- goto out; +- } +- + ret = spawn_session (state, run_script, state->cancellable); + + if (!ret) { +-- +2.51.0 + diff --git a/gdm.spec b/gdm.spec index a6602d6..9509421 100644 --- a/gdm.spec +++ b/gdm.spec @@ -45,6 +45,10 @@ Patch: 0001-manager-Quit-plymouth-when-no-local-display-is-avail.patch # https://gitlab.gnome.org/GNOME/gdm/-/merge_requests/288 Patch: 0001-Introduce-gdm-new-session-tool.patch +# RHEL-86140 +# https://gitlab.gnome.org/GNOME/gdm/-/merge_requests/285 +Patch: 0001-Revert-hack-that-quits-plymouth-late.patch + BuildRequires: dconf BuildRequires: desktop-file-utils BuildRequires: gettext-devel