From 510566699c480226b189215c6222f7e72979baf8 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Wed, 22 May 2024 14:05:20 -0400 Subject: [PATCH 2/4] local-display-factory: Fix user switching with legacy xorg legacy-xorg sessions currently fail to completely user switch. This is because the wrong session types are attached to the generated login screen display. This commit refactors the code so the same session types are used for user switching as are used for the initial login. --- daemon/gdm-local-display-factory.c | 103 ++++++++++++++++++++++------- 1 file changed, 78 insertions(+), 25 deletions(-) diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c index 7447b98..34842a7 100644 --- a/daemon/gdm-local-display-factory.c +++ b/daemon/gdm-local-display-factory.c @@ -358,6 +358,26 @@ store_display (GdmLocalDisplayFactory *factory, gdm_display_store_add (store, display); } +static GdmDisplay * +create_legacy_xorg_display (GdmLocalDisplayFactory *factory) +{ + guint32 display_number; + const char *session_types[] = { "x11", NULL }; + GdmDisplay *display; + + display_number = take_next_display_number (factory); + + g_debug ("GdmLocalDisplayFactory: Creating legacy Xorg display at :%d", display_number); + + display = gdm_legacy_display_new (display_number); + g_object_set (G_OBJECT (display), + "session-type", session_types[0], + "supported-session-types", session_types, + NULL); + + return display; +} + /* Example: dbus-send --system --dest=org.gnome.DisplayManager \ @@ -407,15 +427,8 @@ gdm_local_display_factory_create_transient_display (GdmLocalDisplayFactory *fact is_initial = TRUE; } #endif - if (g_strcmp0 (preferred_display_server, "legacy-xorg") == 0) { - if (display == NULL) { - guint32 num; - - num = take_next_display_number (factory); - - display = gdm_legacy_display_new (num); - } - } + if (g_strcmp0 (preferred_display_server, "legacy-xorg") == 0) + display = create_legacy_xorg_display (factory); if (display == NULL) { g_set_error_literal (error, @@ -618,6 +631,24 @@ lookup_by_seat_id (const char *id, return res; } +static gboolean +lookup_initial_display (const char *id, + GdmDisplay *display, + gpointer user_data) +{ + gboolean is_initial = FALSE; + int status; + + status = gdm_display_get_status (display); + + if (status != GDM_DISPLAY_PREPARED && status != GDM_DISPLAY_MANAGED) + return FALSE; + + g_object_get (G_OBJECT (display), "is-initial", &is_initial, NULL); + + return is_initial; +} + static gboolean lookup_prepared_display_by_seat_id (const char *id, GdmDisplay *display, @@ -633,6 +664,21 @@ lookup_prepared_display_by_seat_id (const char *id, return lookup_by_seat_id (id, display, user_data); } +static gboolean +lookup_managed_display_by_seat_id (const char *id, + GdmDisplay *display, + gpointer user_data) +{ + int status; + + status = gdm_display_get_status (display); + + if (status != GDM_DISPLAY_MANAGED) + return FALSE; + + return lookup_by_seat_id (id, display, user_data); +} + #ifdef HAVE_UDEV static gboolean udev_is_settled (GdmLocalDisplayFactory *factory) @@ -740,6 +786,7 @@ ensure_display_for_seat (GdmLocalDisplayFactory *factory, int ret; gboolean seat_supports_graphics; gboolean is_seat0; + gboolean is_initial; g_auto (GStrv) session_types = NULL; const char *legacy_session_types[] = { "x11", NULL }; GdmDisplayStore *store; @@ -861,10 +908,25 @@ ensure_display_for_seat (GdmLocalDisplayFactory *factory, store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); - if (is_seat0) - display = gdm_display_store_find (store, lookup_prepared_display_by_seat_id, (gpointer) seat_id); - else + if (is_seat0) { + if (g_strcmp0 (preferred_display_server, "legacy-xorg") == 0) { + GdmDisplay *initial_display = NULL; + + display = gdm_display_store_find (store, lookup_managed_display_by_seat_id, (gpointer) seat_id); + initial_display = gdm_display_store_find (store, lookup_initial_display, (gpointer) NULL); + + if (initial_display == NULL || factory->active_vt != GDM_INITIAL_VT) + display = NULL; + + is_initial = initial_display == NULL; + } else { + display = gdm_display_store_find (store, lookup_prepared_display_by_seat_id, (gpointer) seat_id); + is_initial = TRUE; + } + } else { display = gdm_display_store_find (store, lookup_by_seat_id, (gpointer) seat_id); + is_initial = FALSE; + } /* Ensure we don't create the same display more than once */ if (display != NULL) { @@ -905,20 +967,11 @@ ensure_display_for_seat (GdmLocalDisplayFactory *factory, } #endif - if (display == NULL) { - guint32 num; - - num = take_next_display_number (factory); - - display = gdm_legacy_display_new (num); - g_object_set (G_OBJECT (display), - "session-type", legacy_session_types[0], - "supported-session-types", legacy_session_types, - NULL); - } + if (display == NULL) + display = create_legacy_xorg_display (factory); g_object_set (display, "seat-id", seat_id, NULL); - g_object_set (display, "is-initial", is_seat0, NULL); + g_object_set (display, "is-initial", is_initial, NULL); store_display (factory, display);