feat(host): game-mode integration + dedicated game sessions
Implements design/gamemode-and-dedicated-sessions.md (Parts A1-A5 + B0-B2):
reconciles the merged display-management registry with session-mobile
Bazzite/SteamOS hosts and adds a per-launch dedicated gamescope mode.
- A1 DisplayOwnership {Owned,External,SessionManaged} + poolable_now(): the
registry pools only what it owns, so gamescope managed/attach outputs are no
longer double-owned by the registry AND the gamescope restore worker (fixes
the game-mode-reconnect stale-node wedge).
- A2 validated reuse: (backend,mode,launch,epoch) reuse key + kept_display_alive
liveness probe + reused_gen/mark_failed on a reused-display first-frame failure.
- A3 policy-driven managed restore (keep_alive replaces the hardcoded 5s debounce;
forever = held = gaming-rig truthful) + crash-restore persist + SIGKILL teardown
(kill_unit, applied to our transient unit AND the autologin stop -- validated
live on .181 to avoid the F44 GPU-context leak).
- A4 session epoch: observe_session_instance bumps the epoch + invalidate_backend
on a desktop-compositor instance change; gamescope spawns are exempt.
- A5 per-spawn log + PID-scoped gamescope node discovery.
- B0 game_session {auto,dedicated} policy (top-level, preset-orthogonal) +
pick_gamescope_mode dedicated_launch + steam -silent command shaping.
- B1 free the autologin Steam before a dedicated Steam spawn (single-instance).
- B2 game-exit -> APP_EXITED_CLOSE_CODE (0x52) clean session end.
Adversarially reviewed (11 findings fixed). Validated on glass (.181 Bazzite F44,
RTX 4090): dedicated spawn streams a real game smoothly; keep-alive reuse; the
SIGKILL fix avoids the F44 vkCreateDevice leak. Workspace green
(build / test --workspace / clippy -D warnings / fmt), OpenAPI + C header
regenerated, web console tsc + vite build green. clients/probe: bump the
no-video timeout 8s->45s for gamescope cold starts.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -33,7 +33,11 @@
|
||||
|
||||
Companion docs: `design/implementation-plan.md` §6 (virtual displays), `design/vrr-plan.md`
|
||||
(pacing — out of scope here), `design/gamescope-multiuser.md` (per-session isolation — adjacent,
|
||||
not required).
|
||||
not required), **`design/gamemode-and-dedicated-sessions.md`** (PLANNED — reconciles this layer
|
||||
with session-mobile Bazzite/SteamOS hosts: display **ownership classes** so the registry stops
|
||||
pooling gamescope managed/attach outputs it doesn't own, validated reuse + invalidation, the
|
||||
§5.1 "policy replaces the managed 5 s debounce" promise actually implemented, and the dedicated
|
||||
per-launch gamescope game sessions built on it).
|
||||
|
||||
## 1. Goal
|
||||
|
||||
@@ -590,7 +594,12 @@ out per-host instead of lying:
|
||||
|
||||
The **attach** gamescope sub-mode never owns the display (it mirrors a foreign gamescope) — the
|
||||
registry records it as an unmanaged pass-through slot: no keep-alive, no topology, no identity,
|
||||
conflict = join-only. That's just codifying reality.
|
||||
conflict = join-only. That's just codifying reality. **Gap (2026-07-05):** the shipped registry
|
||||
does NOT implement this row — it pools every `remote_fd == None` output, including the
|
||||
managed/attach/SteamOS paths' unit-keepalive outputs, which double-owns the managed session
|
||||
against the gamescope module's own restore worker (stale-node reuse wedge on game-mode
|
||||
reconnect). The fix — explicit display **ownership classes** + registry-owned managed-session
|
||||
restore — is designed in `design/gamemode-and-dedicated-sessions.md` Part A.
|
||||
|
||||
## 8. Management API, web console, tray
|
||||
|
||||
|
||||
Reference in New Issue
Block a user