[gdm: 1/2] daemon: Move the waiting the session to have taken over the fb to gdm-local-display-factory
- From: Ray Strode <halfline src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gdm: 1/2] daemon: Move the waiting the session to have taken over the fb to gdm-local-display-factory
- Date: Wed, 12 Sep 2018 18:05:34 +0000 (UTC)
commit cda8de29cb4448b06fca805856a225659c6dc1c1
Author: Hans de Goede <hdegoede redhat com>
Date: Tue Sep 4 10:56:45 2018 +0200
daemon: Move the waiting the session to have taken over the fb to gdm-local-display-factory
Commit 708618746683 ("gdm-wayland-session,gdm-x-session: register after
delay") delayed displays changing their status from PREPARED to MANAGED
so that their status would not change until the session has had a change
to install its own framebuffer and tell the GPU to scanout this new fb.
Commit 74ee77717df7 ("local-display-factory: defer killing greeter until
new session registers") uses this to avoid a flicker when transitioning
from the greeter to the user-session by deferring the stopping of the
greeter-session until the new display moves to the MANAGED state.
But this only works when transitioning to a new user-session, when moving
to an existing user-session (fast user switching) the display already
is in MANAGED state and instead of deferring the stopping of the greeter
commit 74ee77717df7 causes us to now never stop the greeter-session.
This commit fixes this by starting a timeout when switching away from
the initial-vt and letting that timeout stop the greeter-session.
This commit removes the finish_waiting_displays_on_seat() call when the
display's status changes to MANAGED, so that we still only have one code
path stopping the greeter and not two.
This means we also no longer need to delay registering the display. So this
commit removes the code adding the delay (reverts commit 74ee77717df7).
Note this commit uses a delay of 10 seconds, rather then 2 seconds. The
transition to a new user-session takes about 8 seconds on my budget
Apollo Lake based laptop (with SSD).
Note this all really is a workaround, the proper solution for this would
be able to tell the kernel to keep the greeter framebuffer around until
a new framebuffer is installed. There is a patch to add a new unref_fb
ioctl for this: https://www.spinics.net/lists/dri-devel/msg140912.html .
We need to get this patch upstream and teach mutter to use it.
daemon/gdm-local-display-factory.c | 29 ++++++++++++++++++++++++++---
daemon/gdm-wayland-session.c | 23 +++++++----------------
daemon/gdm-x-session.c | 25 ++++++++-----------------
3 files changed, 41 insertions(+), 36 deletions(-)
---
diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c
index b0b818e5..c15a9a65 100644
--- a/daemon/gdm-local-display-factory.c
+++ b/daemon/gdm-local-display-factory.c
@@ -49,6 +49,7 @@
#define GDM_MANAGER_DBUS_NAME "org.gnome.DisplayManager.LocalDisplayFactory"
#define MAX_DISPLAY_FAILURES 5
+#define WAIT_TO_FINISH_TIMEOUT 10 /* seconds */
struct GdmLocalDisplayFactoryPrivate
{
@@ -65,6 +66,7 @@ struct GdmLocalDisplayFactoryPrivate
#if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER)
char *tty_of_active_vt;
guint active_vt_watch_id;
+ guint wait_to_finish_timeout_id;
#endif
};
@@ -376,7 +378,6 @@ 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;
@@ -615,8 +616,17 @@ lookup_by_session_id (const char *id,
}
#if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER)
+static gboolean
+wait_to_finish_timeout (GdmLocalDisplayFactory *factory)
+{
+ finish_waiting_displays_on_seat (factory, "seat0");
+ factory->priv->wait_to_finish_timeout_id = 0;
+ return G_SOURCE_REMOVE;
+}
+
static void
-maybe_stop_greeter_in_background (GdmDisplay *display)
+maybe_stop_greeter_in_background (GdmLocalDisplayFactory *factory,
+ GdmDisplay *display)
{
g_autofree char *display_session_type = NULL;
@@ -638,6 +648,15 @@ maybe_stop_greeter_in_background (GdmDisplay *display)
g_debug ("GdmLocalDisplayFactory: killing login window once its unused");
g_object_set (G_OBJECT (display), "status", GDM_DISPLAY_WAITING_TO_FINISH, NULL);
+
+ /* We stop the greeter after a timeout to avoid flicker */
+ if (factory->priv->wait_to_finish_timeout_id != 0)
+ g_source_remove (factory->priv->wait_to_finish_timeout_id);
+
+ factory->priv->wait_to_finish_timeout_id =
+ g_timeout_add_seconds (WAIT_TO_FINISH_TIMEOUT,
+ (GSourceFunc)wait_to_finish_timeout,
+ factory);
}
static gboolean
@@ -731,7 +750,7 @@ on_vt_changed (GIOChannel *source,
(gpointer) login_session_id);
if (display != NULL)
- maybe_stop_greeter_in_background (display);
+ maybe_stop_greeter_in_background (factory, display);
} else {
g_debug ("GdmLocalDisplayFactory: VT not switched from login window");
}
@@ -825,6 +844,10 @@ gdm_local_display_factory_stop_monitor (GdmLocalDisplayFactory *factory)
factory->priv->seat_removed_id = 0;
}
#if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER)
+ if (factory->priv->wait_to_finish_timeout_id != 0) {
+ g_source_remove (factory->priv->wait_to_finish_timeout_id);
+ factory->priv->wait_to_finish_timeout_id = 0;
+ }
if (factory->priv->active_vt_watch_id) {
g_source_remove (factory->priv->active_vt_watch_id);
factory->priv->active_vt_watch_id = 0;
diff --git a/daemon/gdm-wayland-session.c b/daemon/gdm-wayland-session.c
index de1991b3..94f49e19 100644
--- a/daemon/gdm-wayland-session.c
+++ b/daemon/gdm-wayland-session.c
@@ -454,21 +454,6 @@ on_sigterm (State *state)
return G_SOURCE_CONTINUE;
}
-static gboolean
-on_registration_delay_complete (State *state)
-{
- gboolean ret;
-
- ret = register_display (state, state->cancellable);
-
- if (!ret) {
- g_printerr ("Unable to register display with display manager\n");
- g_main_loop_quit (state->main_loop);
- }
-
- return G_SOURCE_REMOVE;
-}
-
int
main (int argc,
char **argv)
@@ -543,7 +528,13 @@ main (int argc,
goto out;
}
- g_timeout_add_seconds (2, (GSourceFunc) on_registration_delay_complete, state);
+ ret = register_display (state, state->cancellable);
+
+ if (!ret) {
+ g_printerr ("Unable to register display with display manager\n");
+ exit_status = EX_SOFTWARE;
+ goto out;
+ }
g_main_loop_run (state->main_loop);
diff --git a/daemon/gdm-x-session.c b/daemon/gdm-x-session.c
index 412999cf..3b2fcef4 100644
--- a/daemon/gdm-x-session.c
+++ b/daemon/gdm-x-session.c
@@ -810,21 +810,6 @@ on_sigterm (State *state)
return G_SOURCE_CONTINUE;
}
-static gboolean
-on_registration_delay_complete (State *state)
-{
- gboolean ret;
-
- ret = register_display (state, state->cancellable);
-
- if (!ret) {
- g_printerr ("Unable to register display with display manager\n");
- g_main_loop_quit (state->main_loop);
- }
-
- return G_SOURCE_REMOVE;
-}
-
int
main (int argc,
char **argv)
@@ -911,6 +896,14 @@ main (int argc,
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) {
@@ -919,8 +912,6 @@ main (int argc,
goto out;
}
- g_timeout_add_seconds (2, (GSourceFunc) on_registration_delay_complete, state);
-
g_main_loop_run (state->main_loop);
/* Only use exit status of session if we're here because it exit */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]