summaryrefslogtreecommitdiff
path: root/daemon/gdm-local-display-factory.c
diff options
context:
space:
mode:
authorRay Strode <rstrode@redhat.com>2019-09-04 11:04:11 -0400
committerRay Strode <rstrode@redhat.com>2019-09-04 11:09:15 -0400
commit2f5c9a9c287219f39974e7736d44d04e46fed32c (patch)
tree0a2383a843250f40b9565d028f8dceb5d973939b /daemon/gdm-local-display-factory.c
parent2b9c18732b29261242b31444da8ecfa67b89d441 (diff)
downloadgdm-2f5c9a9c287219f39974e7736d44d04e46fed32c.tar.gz
local-display-factory: reap login session on vt switch to registered session
Since commit 1c061b84ffc3e874da825982d18d970556ff74bb we reap the login screen after the user logs into a session, instead of after a timeout. Unfortunately, that means we no longer reap the login screen when unlocking a session. This commit adds back the timeout in the case seat0 is switched to a registered login session. Closes https://gitlab.gnome.org/GNOME/gdm/issues/509
Diffstat (limited to 'daemon/gdm-local-display-factory.c')
-rw-r--r--daemon/gdm-local-display-factory.c76
1 files changed, 71 insertions, 5 deletions
diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c
index ee41308b..da1093bb 100644
--- a/daemon/gdm-local-display-factory.c
+++ b/daemon/gdm-local-display-factory.c
@@ -66,6 +66,7 @@ struct _GdmLocalDisplayFactory
#if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER)
unsigned int active_vt;
guint active_vt_watch_id;
+ guint wait_to_finish_timeout_id;
#endif
};
@@ -297,6 +298,14 @@ finish_waiting_displays_on_seat (GdmLocalDisplayFactory *factory,
seat_id);
}
+static gboolean
+on_finish_waiting_for_seat0_displays_timeout (GdmLocalDisplayFactory *factory)
+{
+ g_debug ("GdmLocalDisplayFactory: timeout following VT switch to registered session complete, looking for any background displays to kill");
+ finish_waiting_displays_on_seat (factory, "seat0");
+ return G_SOURCE_REMOVE;
+}
+
static void
on_session_registered_cb (GObject *gobject,
GParamSpec *pspec,
@@ -628,6 +637,29 @@ lookup_by_session_id (const char *id,
return g_strcmp0 (current, looking_for) == 0;
}
+static gboolean
+lookup_by_tty (const char *id,
+ GdmDisplay *display,
+ gpointer user_data)
+{
+ const char *tty_to_find = user_data;
+ g_autofree char *tty_to_check = NULL;
+ const char *session_id;
+ int ret;
+
+ session_id = gdm_display_get_session_id (display);
+
+ if (!session_id)
+ return FALSE;
+
+ ret = sd_session_get_tty (session_id, &tty_to_check);
+
+ if (ret != 0)
+ return FALSE;
+
+ return g_strcmp0 (tty_to_check, tty_to_find) == 0;
+}
+
#if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER)
static void
maybe_stop_greeter_in_background (GdmLocalDisplayFactory *factory,
@@ -669,11 +701,12 @@ on_vt_changed (GIOChannel *source,
GIOCondition condition,
GdmLocalDisplayFactory *factory)
{
+ GdmDisplayStore *store;
GIOStatus status;
g_autofree char *tty_of_active_vt = NULL;
g_autofree char *login_session_id = NULL;
g_autofree char *active_session_id = NULL;
- unsigned int previous_vt, new_vt;
+ unsigned int previous_vt, new_vt, login_window_vt = 0;
const char *session_type = NULL;
int ret, n_returned;
@@ -739,21 +772,19 @@ on_vt_changed (GIOChannel *source,
g_debug ("GdmLocalDisplayFactory: VT changed from %u to %u",
previous_vt, factory->active_vt);
+ store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory));
+
/* if the old VT was running a wayland login screen kill it
*/
if (gdm_get_login_window_session_id ("seat0", &login_session_id)) {
- unsigned int login_window_vt;
-
ret = sd_session_get_vt (login_session_id, &login_window_vt);
if (ret == 0 && login_window_vt != 0) {
g_debug ("GdmLocalDisplayFactory: VT of login window is %u", login_window_vt);
if (login_window_vt == previous_vt) {
- GdmDisplayStore *store;
GdmDisplay *display;
g_debug ("GdmLocalDisplayFactory: VT switched from login window");
- store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory));
display = gdm_display_store_find (store,
lookup_by_session_id,
(gpointer) login_session_id);
@@ -765,6 +796,37 @@ on_vt_changed (GIOChannel *source,
}
}
+ /* If we jumped to a registered user session, we can kill
+ * the login screen (after a suitable timeout to avoid flicker)
+ */
+ if (factory->active_vt != login_window_vt) {
+ GdmDisplay *display;
+
+ display = gdm_display_store_find (store,
+ lookup_by_tty,
+ (gpointer) tty_of_active_vt);
+
+ if (display != NULL) {
+ gboolean registered;
+
+ g_object_get (display, "session-registered", &registered, NULL);
+
+ if (registered) {
+ g_debug ("GdmLocalDisplayFactory: switched to registered user session, so reaping login screen in %d seconds",
+ WAIT_TO_FINISH_TIMEOUT);
+ 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);
+ }
+
+ factory->wait_to_finish_timeout_id = g_timeout_add_seconds (WAIT_TO_FINISH_TIMEOUT,
+ (GSourceFunc)
+ on_finish_waiting_for_seat0_displays_timeout,
+ factory);
+ }
+ }
+ }
+
/* if user jumped back to initial vt and it's empty put a login screen
* on it (unless a login screen is already running elsewhere, then
* jump to that login screen)
@@ -843,6 +905,10 @@ gdm_local_display_factory_stop_monitor (GdmLocalDisplayFactory *factory)
g_source_remove (factory->active_vt_watch_id);
factory->active_vt_watch_id = 0;
}
+ if (factory->wait_to_finish_timeout_id != 0) {
+ g_source_remove (factory->wait_to_finish_timeout_id);
+ factory->wait_to_finish_timeout_id = 0;
+ }
#endif
}