diff options
-rw-r--r-- | daemon/gdm-session-worker.c | 93 | ||||
-rw-r--r-- | daemon/meson.build | 7 | ||||
-rw-r--r-- | daemon/org.freedesktop.DBus.xml | 12 |
3 files changed, 96 insertions, 16 deletions
diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c index d2cfde51..36c3e5df 100644 --- a/daemon/gdm-session-worker.c +++ b/daemon/gdm-session-worker.c @@ -66,6 +66,7 @@ #include "gdm-pam-extensions.h" #endif +#include "gdm-dbus-glue.h" #include "gdm-session-worker.h" #include "gdm-session-glue.h" #include "gdm-session.h" @@ -1051,18 +1052,6 @@ gdm_session_worker_uninitialize_pam (GdmSessionWorker *worker, gdm_session_worker_stop_auditor (worker); - /* If user-display-server is not enabled the login_vt is always - * identical to the session_vt. So in that case we never need to - * do a VT switch. */ -#ifdef ENABLE_USER_DISPLAY_SERVER - if (g_strcmp0 (worker->priv->display_seat_id, "seat0") == 0) { - /* Switch to the login VT if we are not the login screen. */ - if (worker->priv->session_vt != GDM_INITIAL_VT) { - jump_to_vt (worker, GDM_INITIAL_VT); - } - } -#endif - worker->priv->session_vt = 0; g_debug ("GdmSessionWorker: state NONE"); @@ -1776,6 +1765,53 @@ run_script (GdmSessionWorker *worker, } static void +wait_until_dbus_signal_emission_to_manager_finishes (GdmSessionWorker *worker) +{ + g_autoptr (GdmDBusPeer) peer_proxy = NULL; + g_autoptr (GError) error = NULL; + gboolean pinged; + + peer_proxy = gdm_dbus_peer_proxy_new_sync (worker->priv->connection, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, + NULL, + "/org/freedesktop/DBus", + NULL, + &error); + + if (peer_proxy == NULL) { + g_debug ("GdmSessionWorker: could not create peer proxy to daemon: %s", + error->message); + return; + } + + pinged = gdm_dbus_peer_call_ping_sync (peer_proxy, NULL, &error); + + if (!pinged) { + g_debug ("GdmSessionWorker: could not ping daemon: %s", + error->message); + return; + } +} + +static void +jump_back_to_initial_vt (GdmSessionWorker *worker) +{ + if (worker->priv->session_vt == 0) + return; + + if (worker->priv->session_vt == GDM_INITIAL_VT) + return; + + if (g_strcmp0 (worker->priv->display_seat_id, "seat0") != 0) + return; + +#ifdef ENABLE_USER_DISPLAY_SERVER + jump_to_vt (worker, GDM_INITIAL_VT); + worker->priv->session_vt = 0; +#endif +} + +static void session_worker_child_watch (GPid pid, int status, GdmSessionWorker *worker) @@ -1789,18 +1825,40 @@ session_worker_child_watch (GPid pid, : WIFSIGNALED (status) ? WTERMSIG (status) : -1); - gdm_session_worker_uninitialize_pam (worker, PAM_SUCCESS); + worker->priv->child_pid = -1; + worker->priv->child_watch_id = 0; + run_script (worker, GDMCONFDIR "/PostSession"); + gdm_dbus_worker_emit_session_exited (GDM_DBUS_WORKER (worker), worker->priv->service, status); killpg (pid, SIGHUP); - worker->priv->child_pid = -1; - worker->priv->child_watch_id = 0; - run_script (worker, GDMCONFDIR "/PostSession"); + /* FIXME: It's important to give the manager an opportunity to process the + * session-exited emission above before switching VTs. + * + * This is because switching VTs makes the manager try to put a login screen + * up on VT 1, but it may actually want to try to auto login again in response + * to session-exited. + * + * This function just does a manager roundtrip over the bus to make sure the + * signal has been dispatched before jumping. + * + * Ultimately, we may want to improve the manager<->worker interface. + * + * See: + * + * https://gitlab.gnome.org/GNOME/gdm/-/merge_requests/123 + * + * for some ideas and more discussion. + * + */ + wait_until_dbus_signal_emission_to_manager_finishes (worker); + + jump_back_to_initial_vt (worker); } static void @@ -2424,6 +2482,7 @@ gdm_session_worker_open_session (GdmSessionWorker *worker, out: if (error_code != PAM_SUCCESS) { gdm_session_worker_uninitialize_pam (worker, error_code); + worker->priv->session_vt = 0; return FALSE; } @@ -3549,6 +3608,8 @@ gdm_session_worker_finalize (GObject *object) gdm_session_worker_uninitialize_pam (worker, PAM_SUCCESS); } + jump_back_to_initial_vt (worker); + g_object_unref (worker->priv->user_settings); g_free (worker->priv->service); g_free (worker->priv->x11_display_name); diff --git a/daemon/meson.build b/daemon/meson.build index 72c7c3c1..2e61b644 100644 --- a/daemon/meson.build +++ b/daemon/meson.build @@ -1,4 +1,10 @@ # D-Bus interfaces +dbus_gen = gnome.gdbus_codegen('gdm-dbus-glue', + 'org.freedesktop.DBus.xml', + namespace: 'GdmDBus', + interface_prefix: 'org.freedesktop.DBus', + autocleanup: 'all', +) display_dbus_gen = gnome.gdbus_codegen('gdm-display-glue', 'gdm-display.xml', namespace: 'GdmDBus', @@ -87,6 +93,7 @@ gdm_session_worker_src = [ 'gdm-session-worker-job.c', 'gdm-session-worker-common.c', 'gdm-dbus-util.c', + dbus_gen, session_dbus_gen, session_worker_dbus_gen, gdm_session_enums, diff --git a/daemon/org.freedesktop.DBus.xml b/daemon/org.freedesktop.DBus.xml new file mode 100644 index 00000000..5e0814bd --- /dev/null +++ b/daemon/org.freedesktop.DBus.xml @@ -0,0 +1,12 @@ +<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" +"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> +<node> + <interface name="org.freedesktop.DBus.Peer"> + <method name="GetMachineId"> + <arg direction="out" type="s"/> + </method> + <method name="Ping"> + </method> + </interface> +</node> + |