summaryrefslogtreecommitdiff
path: root/src/login/logind-session.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/login/logind-session.c')
-rw-r--r--src/login/logind-session.c31
1 files changed, 26 insertions, 5 deletions
diff --git a/src/login/logind-session.c b/src/login/logind-session.c
index fcc1901ed6..eea0bfb85b 100644
--- a/src/login/logind-session.c
+++ b/src/login/logind-session.c
@@ -100,6 +100,8 @@ void session_free(Session *s) {
if (s->seat) {
if (s->seat->active == s)
s->seat->active = NULL;
+ if (s->seat->pending_switch == s)
+ s->seat->pending_switch = NULL;
LIST_REMOVE(Session, sessions_by_seat, s->seat->sessions, s);
}
@@ -375,21 +377,40 @@ int session_load(Session *s) {
}
int session_activate(Session *s) {
+ unsigned int num_pending;
+
assert(s);
assert(s->user);
- if (s->vtnr <= 0)
- return -ENOTSUP;
-
if (!s->seat)
return -ENOTSUP;
if (s->seat->active == s)
return 0;
- assert(seat_has_vts(s->seat));
+ /* on seats with VTs, we let VTs manage session-switching */
+ if (seat_has_vts(s->seat)) {
+ if (s->vtnr <= 0)
+ return -ENOTSUP;
+
+ return chvt(s->vtnr);
+ }
- return chvt(s->vtnr);
+ /* On seats without VTs, we implement session-switching in logind. We
+ * try to pause all session-devices and wait until the session
+ * controller acknowledged them. Once all devices are asleep, we simply
+ * switch the active session and be done.
+ * We save the session we want to switch to in seat->pending_switch and
+ * seat_complete_switch() will perform the final switch. */
+
+ s->seat->pending_switch = s;
+
+ /* if no devices are running, immediately perform the session switch */
+ num_pending = session_device_try_pause_all(s);
+ if (!num_pending)
+ seat_complete_switch(s->seat);
+
+ return 0;
}
static int session_link_x11_socket(Session *s) {