From 74ee77717df7ec27d83f1d2d8c499c0e22b4b17d Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Fri, 31 Aug 2018 15:33:00 -0400 Subject: local-display-factory: defer killing greeter until new session registers At the moment we kill the greeter the second the VT change to the new session happens. That can cause flicker if the new session doesn't take over the display quickly enough. This commit defers killing the greeter until the new display registers. Closes https://gitlab.gnome.org/GNOME/gdm/issues/413 --- daemon/gdm-display.h | 1 + daemon/gdm-local-display-factory.c | 43 ++++++++++++++++++++++++++++++++------ 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/daemon/gdm-display.h b/daemon/gdm-display.h index 6d5e88df..33dc3be4 100644 --- a/daemon/gdm-display.h +++ b/daemon/gdm-display.h @@ -40,6 +40,7 @@ typedef enum { GDM_DISPLAY_UNMANAGED = 0, GDM_DISPLAY_PREPARED, GDM_DISPLAY_MANAGED, + GDM_DISPLAY_WAITING_TO_FINISH, GDM_DISPLAY_FINISHED, GDM_DISPLAY_FAILED, } GdmDisplayStatus; diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c index 7ec998ef..5ec94ce7 100644 --- a/daemon/gdm-local-display-factory.c +++ b/daemon/gdm-local-display-factory.c @@ -268,6 +268,36 @@ gdm_local_display_factory_create_transient_display (GdmLocalDisplayFactory *fact return ret; } +static gboolean +finish_display_on_seat_if_waiting (GdmDisplayStore *display_store, + GdmDisplay *display, + const char *seat_id) +{ + if (gdm_display_get_status (display) != GDM_DISPLAY_WAITING_TO_FINISH) + return FALSE; + + g_debug ("GdmLocalDisplayFactory: finish background display\n"); + gdm_display_stop_greeter_session (display); + gdm_display_unmanage (display); + gdm_display_finish (display); + + return FALSE; +} + +static void +finish_waiting_displays_on_seat (GdmLocalDisplayFactory *factory, + const char *seat_id) +{ + GdmDisplayStore *store; + + store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); + + gdm_display_store_foreach (store, + (GdmDisplayStoreFunc) finish_display_on_seat_if_waiting, + (gpointer) + seat_id); +} + static void on_display_status_changed (GdmDisplay *display, GParamSpec *arg1, @@ -346,6 +376,9 @@ on_display_status_changed (GdmDisplay *display, case GDM_DISPLAY_PREPARED: break; case GDM_DISPLAY_MANAGED: + finish_waiting_displays_on_seat (factory, seat_id); + break; + case GDM_DISPLAY_WAITING_TO_FINISH: break; default: g_assert_not_reached (); @@ -583,7 +616,7 @@ lookup_by_session_id (const char *id, } static void -maybe_stop_greeter_display (GdmDisplay *display) +maybe_stop_greeter_in_background (GdmDisplay *display) { g_autofree char *display_session_type = NULL; @@ -603,10 +636,8 @@ maybe_stop_greeter_display (GdmDisplay *display) return; } - g_debug ("GdmLocalDisplayFactory: killing login window since its now unused"); - gdm_display_stop_greeter_session (display); - gdm_display_unmanage (display); - gdm_display_finish (display); + g_debug ("GdmLocalDisplayFactory: killing login window once its unused"); + g_object_set (G_OBJECT (display), "status", GDM_DISPLAY_WAITING_TO_FINISH, NULL); } static gboolean @@ -700,7 +731,7 @@ on_vt_changed (GIOChannel *source, (gpointer) login_session_id); if (display != NULL) - maybe_stop_greeter_display (display); + maybe_stop_greeter_in_background (display); } else { g_debug ("GdmLocalDisplayFactory: VT not switched from login window"); } -- cgit v1.2.1