fix(host/linux): survive and self-heal dead gamescope sessions on headless SteamOS boxes

Three fixes for the "most connects simply fail" trap on a SteamOS host
with no physical display (VM testbox, panel-less mini PC):

- restore path: skip the restore-to-physical-panel when no DRM connector
  reports a connected display — removing the headless drop-in and
  restarting gamescope-session.target on such a box just crash-loops
  gamescope and strands every later connect on "no usable compositor".
  Keep the headless session (and the takeover state) instead.
- connect path: when no live graphical session exists but the MANAGED
  gamescope infra is present (SteamOS gamescope-session / Bazzite
  session-plus), route to the gamescope takeover — which rebuilds the
  session at the client's mode — instead of failing the connect.
- error delivery: a session-setup failure used to just drop the QUIC
  connection, reaching the client as "control stream finished mid-frame"
  (indistinguishable from transport trouble). Close with a typed
  setup-failed code (0x68, RejectedSetupFailed = -29) carrying the error
  text, and give the client handshake/pairing error paths a short grace
  for the CONNECTION_CLOSE to beat the stream error it caused.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-22 09:50:30 +02:00
co-authored by Claude Fable 5
parent 87e7c82cbc
commit 2562663fc6
11 changed files with 177 additions and 13 deletions
+2
View File
@@ -61,6 +61,7 @@ pub enum PunktfunkStatus {
RejectedSuperseded = -26,
RejectedWireVersion = -27,
RejectedBusy = -28,
RejectedSetupFailed = -29,
Panic = -99,
}
@@ -89,6 +90,7 @@ impl PunktfunkError {
R::Superseded => PunktfunkStatus::RejectedSuperseded,
R::WireVersionMismatch => PunktfunkStatus::RejectedWireVersion,
R::Busy => PunktfunkStatus::RejectedBusy,
R::SetupFailed => PunktfunkStatus::RejectedSetupFailed,
}
}
}