fix(gamescope): the takeover no longer kills the host it is running in

Field report, Nobara + 0.20.0: switching into Game Mode mid-stream
disconnects the client and the box never lights up again. His journal has
the whole mechanism, ten seconds apart:

  12:34:18.9  freed Steam: stopped the display manager for this stream
  12:34:29.0  systemd[1685]: Stopping punktfunk-host.service

Stopping the display manager ends the user's last login session. The
packaged host is a `systemd --user` unit, so logind then stops
user@1000.service once UserStopDelaySec elapses — 10s by default on Nobara
— and takes the host with it. The stream dies, the scheduled restore never
runs, and the display manager stays down with nothing left to restart it:
a black box that needs a VT to recover. Exactly the two symptoms reported,
and the intermittency is just whether an active Gaming Mode session was
there to trigger the takeover at all.

It never showed on the repro VM because lingering was enabled there for the
earlier sessionless tests (`Linger=yes` — confirmed on the VM today), which
is precisely the thing that breaks the dependency: logind keeps the user
manager alive with no session. Our KDE/GNOME/Arch setup guides already ask
for it; his box, following the KDE route, did not have it.

So the takeover now ensures lingering BEFORE it touches the display
manager: `loginctl enable-linger` directly (allow_active in logind's own
policy — verified working unprivileged on Nobara), else the packaged helper
gains a `linger` verb that enables it for PKEXEC_UID alone, never a
caller-named user. If neither works the takeover is refused with an
actionable error and managed degrades to attach — mirroring the box's own
session is strictly better than a screen that needs a VT. Hosts that cannot
be reached this way (root, a system unit) skip the check: the cgroup test
is a pure `cgroup_under_user_manager` with a unit test, matched against the
real shapes on a Nobara box (`user@1000.service/app.slice/...` vs a
`session-N.scope`).

Also documents the requirement in the gamescope guide's Nobara section.

Checked on Linux: clippy -D warnings, 78 tests, rustfmt; helper verified
with `sh -n`, and the linger enable/disable round-trip run live on the
Nobara VM.
This commit is contained in:
2026-07-27 19:04:20 +02:00
parent eae1837a3a
commit f3615f83a5
3 changed files with 135 additions and 6 deletions
+8
View File
@@ -69,6 +69,14 @@ depends on the display manager driving the autologin:
restart ever loses its privilege mid-restore, `PUNKTFUNK_RECOVER_SESSION_CMD` (see
[Configuration](/docs/configuration)) is fired as the fallback.
**Lingering is required here**, and the host turns it on for you the first time it takes the box
over. Stopping the display manager ends your last login session, and without
`loginctl enable-linger` logind stops your `systemd --user` manager about ten seconds later —
taking the host with it, mid-stream, with the display manager down and nothing left to bring it
back. If lingering can't be enabled the host refuses the takeover and degrades to attach instead
(above) rather than risk that. Run `sudo loginctl enable-linger "$USER"` once, as the setup guides
ask; `loginctl disable-linger "$USER"` reverts it.
With the takeover authorized the **in-stream session switch round-trips** in managed mode:
Steam's "Switch to Desktop" inside the streamed Game Mode returns the box to its desktop session
and the stream follows it there; the desktop's "Return to Gaming Mode" switches it forward again.