diff options
author | Ray Strode <rstrode@redhat.com> | 2018-08-31 15:33:00 -0400 |
---|---|---|
committer | Ray Strode <rstrode@redhat.com> | 2018-08-31 16:56:47 -0400 |
commit | 74ee77717df7ec27d83f1d2d8c499c0e22b4b17d (patch) | |
tree | 30f1856536f9c68129ac4632473b848a9a5480dc | |
parent | 708618746683ea086068e2498fd1c69917c6189a (diff) | |
download | gdm-74ee77717df7ec27d83f1d2d8c499c0e22b4b17d.tar.gz |
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
-rw-r--r-- | daemon/gdm-display.h | 1 | ||||
-rw-r--r-- | 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"); } |