summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRay Strode <rstrode@redhat.com>2017-04-04 17:07:04 -0400
committerRay Strode <rstrode@redhat.com>2017-04-12 09:47:09 -0400
commit22c332baaf8ad6d7082c5b01250bae70934c2fd1 (patch)
tree19b5c8cb20128aa37614ab8e648191075bc1a8a1
parentfc22e7091ef526d5defa53adc806a66e751377f1 (diff)
downloadgdm-22c332baaf8ad6d7082c5b01250bae70934c2fd1.tar.gz
manager: make sure we end up on a login screen
If we're running in legacy mode where VT1 is not necessarily a login screen, then we can end up in a situation where logging out leaves us sitting on the wrong vt. 1) log in to user 1 on vt 1 2) switch user to login screen on vt 2 and log in as user 2 on vt 2 3) switch user to login screen on vt 3 and unlock user 1 back on vt 1 4) log out of user 1 on vt 1 5) now sitting at blank vt 1 This commit makes sure in that case we jump to a login screen https://bugzilla.gnome.org/show_bug.cgi?id=780914
-rw-r--r--daemon/gdm-manager.c128
1 files changed, 128 insertions, 0 deletions
diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c
index c3bcfec9..5d4d6c29 100644
--- a/daemon/gdm-manager.c
+++ b/daemon/gdm-manager.c
@@ -1315,6 +1315,133 @@ maybe_start_pending_initial_login (GdmManager *manager,
g_free (user_session_seat_id);
}
+static gboolean
+get_login_window_session_id (const char *seat_id,
+ char **session_id)
+{
+ gboolean ret;
+ int res, i;
+ char **sessions;
+ char *service_id;
+ char *service_class;
+ char *state;
+
+ res = sd_seat_get_sessions (seat_id, &sessions, NULL, NULL);
+ if (res < 0) {
+ g_debug ("Failed to determine sessions: %s", strerror (-res));
+ return FALSE;
+ }
+
+ if (sessions == NULL || sessions[0] == NULL) {
+ *session_id = NULL;
+ ret = TRUE;
+ goto out;
+ }
+
+ for (i = 0; sessions[i]; i ++) {
+
+ res = sd_session_get_class (sessions[i], &service_class);
+ if (res < 0) {
+ g_debug ("failed to determine class of session %s: %s", sessions[i], strerror (-res));
+ ret = FALSE;
+ goto out;
+ }
+
+ if (strcmp (service_class, "greeter") != 0) {
+ free (service_class);
+ continue;
+ }
+
+ free (service_class);
+
+ ret = sd_session_get_state (sessions[i], &state);
+ if (ret < 0) {
+ g_debug ("failed to determine state of session %s: %s", sessions[i], strerror (-res));
+ ret = FALSE;
+ goto out;
+ }
+
+ if (g_strcmp0 (state, "closing") == 0) {
+ free (state);
+ continue;
+ }
+ free (state);
+
+ res = sd_session_get_service (sessions[i], &service_id);
+ if (res < 0) {
+ g_debug ("failed to determine service of session %s: %s", sessions[i], strerror (-res));
+ ret = FALSE;
+ goto out;
+ }
+
+ if (strcmp (service_id, "gdm-launch-environment") == 0) {
+ *session_id = g_strdup (sessions[i]);
+ ret = TRUE;
+
+ free (service_id);
+ goto out;
+ }
+
+ free (service_id);
+ }
+
+ *session_id = NULL;
+ ret = TRUE;
+
+out:
+ if (sessions) {
+ for (i = 0; sessions[i]; i ++) {
+ free (sessions[i]);
+ }
+
+ free (sessions);
+ }
+
+ return ret;
+}
+
+static void
+activate_login_window_session_on_seat (GdmManager *self,
+ const char *seat_id)
+{
+ char *session_id;
+
+ if (!get_login_window_session_id (seat_id, &session_id)) {
+ return;
+ }
+
+ activate_session_id (self, seat_id, session_id);
+}
+
+static void
+maybe_activate_other_session (GdmManager *self,
+ GdmDisplay *old_display)
+{
+ char *seat_id = NULL;
+ char *session_id;
+ int ret;
+
+ g_object_get (G_OBJECT (old_display),
+ "seat-id", &seat_id,
+ NULL);
+
+ ret = sd_seat_get_active (seat_id, &session_id, NULL);
+
+ if (ret == 0) {
+ GdmDisplay *display;
+
+ display = gdm_display_store_find (self->priv->display_store,
+ lookup_by_session_id,
+ (gpointer) session_id);
+
+ if (display == NULL) {
+ activate_login_window_session_on_seat (self, seat_id);
+ }
+ }
+
+ g_free (seat_id);
+}
+
static const char *
get_username_for_greeter_display (GdmManager *manager,
GdmDisplay *display)
@@ -1557,6 +1684,7 @@ on_display_status_changed (GdmDisplay *display,
manager->priv->ran_once = TRUE;
}
maybe_start_pending_initial_login (manager, display);
+ maybe_activate_other_session (manager, display);
break;
default:
break;