diff --git a/0001-gdm-session-Force-reuse-vt-mode-for-legacy-Xorg-mode.patch b/0001-gdm-session-Force-reuse-vt-mode-for-legacy-Xorg-mode.patch
index c2f7806..4b71ddd 100644
--- a/0001-gdm-session-Force-reuse-vt-mode-for-legacy-Xorg-mode.patch
+++ b/0001-gdm-session-Force-reuse-vt-mode-for-legacy-Xorg-mode.patch
@@ -1,7 +1,7 @@
 From bcab8852cf7249a2220f6c737f7bb8a17b99249a Mon Sep 17 00:00:00 2001
 From: rpm-build <rpm-build>
 Date: Mon, 27 Nov 2023 15:29:09 -0500
-Subject: [PATCH] gdm-session: Force reuse vt mode for legacy Xorg mode
+Subject: [PATCH 1/2] gdm-session: Force reuse vt mode for legacy Xorg mode
 
 In the legacy Xorg mode, the X session and user session are
 supposed to use the same VT.
diff --git a/0001-local-display-factory-Stall-startup-until-main-graph.patch b/0001-local-display-factory-Stall-startup-until-main-graph.patch
index 33a411c..d88da45 100644
--- a/0001-local-display-factory-Stall-startup-until-main-graph.patch
+++ b/0001-local-display-factory-Stall-startup-until-main-graph.patch
@@ -1,4 +1,4 @@
-From e5b3467412874d27c311253e3d5d7e65a61d12a4 Mon Sep 17 00:00:00 2001
+From e88779b0785fe781608b10478ae092e8fd79ae0b Mon Sep 17 00:00:00 2001
 From: Ray Strode <rstrode@redhat.com>
 Date: Tue, 1 Mar 2022 13:25:02 -0500
 Subject: [PATCH 1/4] local-display-factory: Stall startup until main graphics
@@ -27,13 +27,13 @@ up and running before proceeding to start a login screen.
 
 Closes: https://gitlab.gnome.org/GNOME/gdm/-/issues/763
 ---
- daemon/gdm-local-display-factory.c | 164 ++++++++++++++++++++++++++---
+ daemon/gdm-local-display-factory.c | 168 ++++++++++++++++++++++++++---
  daemon/meson.build                 |   4 +
  meson.build                        |   2 +
- 4 files changed, 159 insertions(+), 12 deletions(-)
+ 3 files changed, 162 insertions(+), 12 deletions(-)
 
 diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c
-index c00e1c47..0b1d3482 100644
+index ca14c31f5..56be1d9db 100644
 --- a/daemon/gdm-local-display-factory.c
 +++ b/daemon/gdm-local-display-factory.c
 @@ -1,100 +1,112 @@
@@ -398,7 +398,7 @@ index c00e1c47..0b1d3482 100644
                          }
  
                          g_debug ("GdmLocalDisplayFactory: Assuming we can use seat0 for X11 even though system says it doesn't support graphics!");
-@@ -1138,113 +1240,151 @@ on_vt_changed (GIOChannel    *source,
+@@ -1138,113 +1244,151 @@ on_vt_changed (GIOChannel    *source,
                                  if (factory->wait_to_finish_timeout_id != 0) {
                                           g_debug ("GdmLocalDisplayFactory: deferring previous login screen clean up operation");
                                           g_source_remove (factory->wait_to_finish_timeout_id);
@@ -551,7 +551,7 @@ index c00e1c47..0b1d3482 100644
  on_display_added (GdmDisplayStore        *display_store,
                    const char             *id,
 diff --git a/daemon/meson.build b/daemon/meson.build
-index 2e61b644..41f30abe 100644
+index 2e61b6447..41f30abef 100644
 --- a/daemon/meson.build
 +++ b/daemon/meson.build
 @@ -177,37 +177,41 @@ gdm_daemon_sources = files(
@@ -597,7 +597,7 @@ index 2e61b644..41f30abe 100644
    install_dir: get_option('sbindir')
  )
 diff --git a/meson.build b/meson.build
-index 02d609dc..05d8da41 100644
+index 02d609dc0..05d8da412 100644
 --- a/meson.build
 +++ b/meson.build
 @@ -11,60 +11,61 @@ i18n = import('i18n')
@@ -725,5 +725,5 @@ index 02d609dc..05d8da41 100644
    subdir('chooser')
  endif
 -- 
-2.34.1
+2.40.0
 
diff --git a/0002-local-display-factory-Fix-user-switching-with-legacy.patch b/0002-local-display-factory-Fix-user-switching-with-legacy.patch
new file mode 100644
index 0000000..42465d5
--- /dev/null
+++ b/0002-local-display-factory-Fix-user-switching-with-legacy.patch
@@ -0,0 +1,384 @@
+From 510566699c480226b189215c6222f7e72979baf8 Mon Sep 17 00:00:00 2001
+From: Ray Strode <rstrode@redhat.com>
+Date: Wed, 22 May 2024 14:05:20 -0400
+Subject: [PATCH 2/2] 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 | 78 +++++++++++++++++++++---------
+ 1 file changed, 54 insertions(+), 24 deletions(-)
+
+diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c
+index 7447b985a..4efbf0a6d 100644
+--- a/daemon/gdm-local-display-factory.c
++++ b/daemon/gdm-local-display-factory.c
+@@ -331,118 +331,131 @@ gdm_local_display_factory_get_session_types (GdmLocalDisplayFactory *factory,
+         if (display_server_enabled (factory, fallback_display_server))
+                 g_ptr_array_add (session_types_array, (gpointer) get_session_type_for_display_server (factory, fallback_display_server));
+ 
+         if (session_types_array->len == 0)
+                 return NULL;
+ 
+         g_ptr_array_add (session_types_array, NULL);
+ 
+         session_types = g_strdupv ((char **) session_types_array->pdata);
+ 
+         return session_types;
+ }
+ 
+ static void
+ on_display_disposed (GdmLocalDisplayFactory *factory,
+                      GdmDisplay             *display)
+ {
+         g_debug ("GdmLocalDisplayFactory: Display %p disposed", display);
+ }
+ 
+ static void
+ store_display (GdmLocalDisplayFactory *factory,
+                GdmDisplay             *display)
+ {
+         GdmDisplayStore *store;
+ 
+         store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (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 \
+   --type=method_call --print-reply --reply-timeout=2000 \
+   /org/gnome/DisplayManager/Manager \
+   org.gnome.DisplayManager.Manager.GetDisplays
+ */
+ gboolean
+ gdm_local_display_factory_create_transient_display (GdmLocalDisplayFactory *factory,
+                                                     char                  **id,
+                                                     GError                **error)
+ {
+         gboolean         ret;
+         GdmDisplay      *display = NULL;
+         gboolean         is_initial = FALSE;
+         const char      *session_type;
+         g_autofree gchar *preferred_display_server = NULL;
+ 
+         g_return_val_if_fail (GDM_IS_LOCAL_DISPLAY_FACTORY (factory), FALSE);
+ 
+         ret = FALSE;
+ 
+         g_debug ("GdmLocalDisplayFactory: Creating transient display");
+ 
+         preferred_display_server = get_preferred_display_server (factory);
+ 
+ #ifdef ENABLE_USER_DISPLAY_SERVER
+         if (g_strcmp0 (preferred_display_server, "wayland") == 0 ||
+             g_strcmp0 (preferred_display_server, "xorg") == 0) {
+                 g_auto(GStrv) session_types = NULL;
+ 
+                 session_types = gdm_local_display_factory_get_session_types (factory, FALSE);
+ 
+                 if (session_types == NULL) {
+                         g_set_error_literal (error,
+                                              GDM_DISPLAY_ERROR,
+                                              GDM_DISPLAY_ERROR_GENERAL,
+                                              "Both Wayland and Xorg are unavailable");
+                         return FALSE;
+                 }
+ 
+                 display = gdm_local_display_new ();
+                 g_object_set (G_OBJECT (display),
+                               "session-type", session_types[0],
+                               "supported-session-types", session_types,
+                               NULL);
+                 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,
+                                      GDM_DISPLAY_ERROR,
+                                      GDM_DISPLAY_ERROR_GENERAL,
+                                      "Invalid preferred display server configured");
+                 return FALSE;
+         }
+ 
+         g_object_set (display,
+                       "seat-id", "seat0",
+                       "allow-timed-login", FALSE,
+                       "is-initial", is_initial,
+                       NULL);
+ 
+         store_display (factory, display);
+ 
+         if (! gdm_display_manage (display)) {
+                 display = NULL;
+                 goto out;
+         }
+ 
+         if (! gdm_display_get_id (display, id, NULL)) {
+                 display = NULL;
+                 goto out;
+         }
+ 
+         ret = TRUE;
+  out:
+         /* ref either held by store or not at all */
+@@ -591,70 +604,87 @@ on_display_status_changed (GdmDisplay             *display,
+         case GDM_DISPLAY_WAITING_TO_FINISH:
+                 break;
+         default:
+                 g_assert_not_reached ();
+                 break;
+         }
+ 
+         g_free (seat_id);
+         g_free (session_type);
+         g_free (session_class);
+ }
+ 
+ static gboolean
+ lookup_by_seat_id (const char *id,
+                    GdmDisplay *display,
+                    gpointer    user_data)
+ {
+         const char *looking_for = user_data;
+         char *current;
+         gboolean res;
+ 
+         g_object_get (G_OBJECT (display), "seat-id", &current, NULL);
+ 
+         res = g_strcmp0 (current, looking_for) == 0;
+ 
+         g_free(current);
+ 
+         return res;
+ }
+ 
++static gboolean
++lookup_initial_display (const char *id,
++		        GdmDisplay *display)
++{
++        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,
+                                     gpointer    user_data)
+ {
+         int status;
+ 
+         status = gdm_display_get_status (display);
+ 
+-        if (status != GDM_DISPLAY_PREPARED)
++        if (status != GDM_DISPLAY_PREPARED && 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)
+ {
+         g_autoptr (GUdevEnumerator) enumerator = NULL;
+         GList *devices;
+         GList *node;
+ 
+         gboolean is_settled = FALSE;
+ 
+         if (factory->seat0_has_platform_graphics) {
+                 g_debug ("GdmLocalDisplayFactory: udev settled, platform graphics enabled.");
+                 return TRUE;
+         }
+ 
+         if (factory->seat0_has_boot_up_graphics) {
+                 g_debug ("GdmLocalDisplayFactory: udev settled, boot up graphics available.");
+                 return TRUE;
+         }
+ 
+         if (factory->seat0_graphics_check_timed_out) {
+                 g_debug ("GdmLocalDisplayFactory: udev timed out, proceeding anyway.");
+                 return TRUE;
+         }
+ 
+@@ -834,115 +864,115 @@ ensure_display_for_seat (GdmLocalDisplayFactory *factory,
+                                         /* It is not yet time to force X11 fallback. */
+                                         g_debug ("GdmLocalDisplayFactory: seat0 display requested when there is no graphics support before graphics check timeout.");
+                                 }
+ 
+                                 return;
+                         }
+ 
+                         g_debug ("GdmLocalDisplayFactory: Assuming we can use seat0 for X11 even though system says it doesn't support graphics!");
+                         g_debug ("GdmLocalDisplayFactory: This might indicate an issue where the framebuffer device is not tagged as master-of-seat in udev.");
+                         seat_supports_graphics = TRUE;
+                         wayland_enabled = FALSE;
+                         g_strfreev (session_types);
+                         session_types = g_strdupv ((char **) legacy_session_types);
+                 } else {
+                         g_clear_handle_id (&factory->seat0_graphics_check_timeout_id, g_source_remove);
+                 }
+         }
+ 
+         if (!seat_supports_graphics)
+                 return;
+ 
+         if (session_types != NULL)
+                 g_debug ("GdmLocalDisplayFactory: %s login display for seat %s requested",
+                          session_types[0], seat_id);
+         else if (g_strcmp0 (preferred_display_server, "legacy-xorg") == 0)
+                 g_debug ("GdmLocalDisplayFactory: Legacy Xorg login display for seat %s requested",
+                          seat_id);
+ 
+         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) {
++		display = gdm_display_store_find (store, lookup_prepared_display_by_seat_id, (gpointer) seat_id);
++		if (display != NULL && g_strcmp0 (preferred_display_server, "legacy-xorg") == 0) {
++                        GdmDisplay *initial_display = NULL;
++
++                        initial_display = gdm_display_store_find (store, lookup_initial_display, (gpointer) NULL);
++
++			if (initial_display == NULL)
++				display = NULL;
++		}
++	} else {
+                 display = gdm_display_store_find (store, lookup_by_seat_id, (gpointer) seat_id);
++	}
+ 
+         /* Ensure we don't create the same display more than once */
+         if (display != NULL) {
+                 g_debug ("GdmLocalDisplayFactory: display already created");
+                 return;
+         }
+ 
+         /* If we already have a login window, switch to it */
+         if (gdm_get_login_window_session_id (seat_id, &login_session_id)) {
+                 GdmDisplay *display;
+ 
+                 display = gdm_display_store_find (store,
+                                                   lookup_by_session_id,
+                                                   (gpointer) login_session_id);
+                 if (display != NULL &&
+                     (gdm_display_get_status (display) == GDM_DISPLAY_MANAGED ||
+                      gdm_display_get_status (display) == GDM_DISPLAY_WAITING_TO_FINISH)) {
+                         g_object_set (G_OBJECT (display), "status", GDM_DISPLAY_MANAGED, NULL);
+                         g_debug ("GdmLocalDisplayFactory: session %s found, activating.",
+                                  login_session_id);
+                         gdm_activate_session_by_id (factory->connection, seat_id, login_session_id);
+                         return;
+                 }
+         }
+ 
+         g_debug ("GdmLocalDisplayFactory: Adding display on seat %s", seat_id);
+ 
+ #ifdef ENABLE_USER_DISPLAY_SERVER
+         if (g_strcmp0 (preferred_display_server, "wayland") == 0 ||
+             g_strcmp0 (preferred_display_server, "xorg") == 0) {
+                 if (is_seat0) {
+                         display = gdm_local_display_new ();
+                         g_object_set (G_OBJECT (display),
+                                       "session-type", session_types[0],
+                                       "supported-session-types", session_types,
+                                       NULL);
+                 }
+         }
+ #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);
+ 
+         store_display (factory, display);
+ 
+         /* let store own the ref */
+         g_object_unref (display);
+ 
+         if (! gdm_display_manage (display)) {
+                 gdm_display_unmanage (display);
+         }
+ 
+         return;
+ }
+ 
+ static void
+ delete_display (GdmLocalDisplayFactory *factory,
+                 const char             *seat_id) {
+ 
+         GdmDisplayStore *store;
+ 
+         g_debug ("GdmLocalDisplayFactory: Removing used_display_numbers on seat %s", seat_id);
+ 
+         store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory));
+         gdm_display_store_foreach_remove (store, lookup_by_seat_id, (gpointer) seat_id);
+ }
+ 
+ static gboolean
+ gdm_local_display_factory_sync_seats (GdmLocalDisplayFactory *factory)
+-- 
+2.40.0
+
diff --git a/gdm.spec b/gdm.spec
index d8bf536..3a58c2a 100644
--- a/gdm.spec
+++ b/gdm.spec
@@ -11,7 +11,7 @@
 Name: gdm
 Epoch: 1
 Version: 40.1
-Release: 24%{?dist}
+Release: 25%{?dist}
 Summary: The GNOME Display Manager
 
 License: GPLv2+
@@ -43,8 +43,6 @@ Patch60001: 0001-session-settings-Fetch-session-from-user-even-if-use.patch
 
 Patch70001: 0001-manager-Fix-btmp-record-accounting.patch
 
-Patch80001: 0001-gdm-session-Force-reuse-vt-mode-for-legacy-Xorg-mode.patch
-
 Patch80002: 0001-session-settings-Explicitly-cache-remote-users.patch
 
 # Latest udev rules and support code
@@ -53,6 +51,9 @@ Patch90002: 0002-common-Add-API-to-reload-settings-from-disk.patch
 Patch90003: 0003-common-Reload-settings-when-graphics-initialize.patch
 Patch90004: 0004-data-Use-latest-upstream-udev-rules.patch
 
+Patch100001: 0001-gdm-session-Force-reuse-vt-mode-for-legacy-Xorg-mode.patch
+Patch100002: 0002-local-display-factory-Fix-user-switching-with-legacy.patch
+
 # Non-upstreamable workarounds
 Patch66610001: 0001-data-reap-gdm-sessions-on-shutdown.patch
 
@@ -355,6 +356,10 @@ dconf update || :
 %{_libdir}/pkgconfig/gdm-pam-extensions.pc
 
 %changelog
+* Wed May 01 2024 Ray Strode <rstrode@redhat.com> - 40.1-25
+- Fix user switching with PreferredDisplayServer=legacy-xorg
+  Related: RHEL-29845
+
 * Tue Jan 16 2024 Andrew Lukoshko <alukoshko@almalinux.org> - 40.1-24
 - Explicitly cache remote users
   Resolves: RHEL-21791