From 35b6c835fd24645d42119e82d78b9608209198c2 Mon Sep 17 00:00:00 2001 From: enricobuehler Date: Mon, 27 Jul 2026 01:43:40 +0200 Subject: [PATCH] docs: on a gamescope session the display outranks the end-game setting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On-glass on .41: with `game_on_session_end: keep` — "leave it running, nothing is ever closed" — a deliberate stop ended the game, and a drop ended it ~14 s later. Both times the LEASE did the right thing (no `ending the launched game` line); the game died because the virtual display was torn down, and a nested launch runs inside that gamescope. So on a dedicated gamescope session the game's lifetime IS the display's, and keep-alive decides it — not this setting: * a deliberate stop skips the linger by design, so the game goes at once, * a drop lingers the keep-alive window, then takes the game with it, * only keep-alive Forever actually keeps it — and `always` still ends it at the reconnect window, which is the documented precedence and was verified (a `forever`-pinned display released at grace expiry, 60.006 s). That makes the console's promise untrue on the most common Linux setup, so the card now says so for every option rather than only warning about `always`, and the docs get the three cases as a table. Worded so a non-gamescope host reads it and moves on — a desktop-session launch is an ordinary process and none of it applies. Not changing behavior here: making `keep` pin the display would pit it against "a stop must not leave a ghost display", and which wins is a product call rather than something to decide silently mid-test. web: codegen + tsc + biome clean, en/de complete. docs-site: build + tsc clean. --- docs-site/content/docs/virtual-displays.md | 17 +++++++++++++++++ web/messages/de.json | 3 ++- web/messages/en.json | 3 ++- web/src/sections/Displays/SessionGameCard.tsx | 8 ++++++++ 4 files changed, 29 insertions(+), 2 deletions(-) diff --git a/docs-site/content/docs/virtual-displays.md b/docs-site/content/docs/virtual-displays.md index a7261ce8..00f312a5 100644 --- a/docs-site/content/docs/virtual-displays.md +++ b/docs-site/content/docs/virtual-displays.md @@ -179,6 +179,23 @@ shutdown — and only forces the issue after ten seconds of being ignored. > (5 minutes). A display set to **Forever** stays up regardless of what happens to the game — a > pinned display is a deliberate "this box is a game host" choice, and closing a game doesn't undo it. +### On a gamescope session, the display has the final say + +When a launch gets its **own gamescope** — a dedicated game session, the usual setup on a Steam Deck +or a Bazzite couch box — the game runs *inside* the streamed display. So it lives exactly as long as +that display does, and **Keep alive decides that, not the setting above**: + +| you disconnect by | what happens to the game | +|---|---| +| pressing **Stop** (or the console's stop) | the display tears down at once — keep-alive is deliberately skipped for a real stop — and the game goes with it, even on *Leave it running* | +| dropping out (network, sleep) | the display lingers for your keep-alive window, then tears down; the game ends with it | +| dropping out, keep-alive **Forever** | the display is pinned, so the game genuinely survives — and *Always close it* still ends it when the reconnect window closes | + +So on a gamescope box, "leave the game running after I disconnect" means **keep-alive Forever** (or a +window long enough to come back in), not just this setting. On a desktop session — KWin, GNOME, Sway — +the game is an ordinary process next to your desktop and none of this applies; the setting above is +the whole story. + ### Automation The host publishes `game.running` and `game.exited` events (the latter says whether the player quit diff --git a/web/messages/de.json b/web/messages/de.json index 30ccc018..052577af 100644 --- a/web/messages/de.json +++ b/web/messages/de.json @@ -413,5 +413,6 @@ "session_game_grace": "Zeitfenster für die Rückkehr", "session_game_grace_help": "Wie lange ein verschwundener Client Zeit hat zurückzukommen, bevor sein Spiel geschlossen wird. Die Konsole zeigt den Countdown; eine neue Verbindung bricht ihn ab.", "session_game_saved": "Sitzungs- und Spieleinstellungen gespeichert", - "session_game_inert": "Dieser Host kann keine Spiele starten – hier bewirken diese Einstellungen nichts" + "session_game_inert": "Dieser Host kann keine Spiele starten – hier bewirken diese Einstellungen nichts", + "session_game_nested_note": "In einer gamescope-Spielsitzung läuft das Spiel *innerhalb* der gestreamten Anzeige und lebt daher genau so lange wie diese – das entscheidet „Offen halten“ oben, nicht diese Einstellung. Ein bewusstes Stoppen reißt die Anzeige sofort ab und nimmt das Spiel mit, egal was du hier wählst." } diff --git a/web/messages/en.json b/web/messages/en.json index 3b0eebeb..30587018 100644 --- a/web/messages/en.json +++ b/web/messages/en.json @@ -413,5 +413,6 @@ "session_game_grace": "Reconnect window", "session_game_grace_help": "How long a client that vanished has to come back before its game is closed. The console shows the countdown, and reconnecting cancels it.", "session_game_saved": "Session and game settings saved", - "session_game_inert": "This host has no way to launch games, so these settings do nothing here" + "session_game_inert": "This host has no way to launch games, so these settings do nothing here", + "session_game_nested_note": "On a gamescope game session the game runs *inside* the streamed display, so it lives exactly as long as that display does — which is what Keep alive above decides, not this setting. A deliberate Stop tears that display down at once and takes the game with it, whichever option you pick here." } diff --git a/web/src/sections/Displays/SessionGameCard.tsx b/web/src/sections/Displays/SessionGameCard.tsx index acf3b7ef..ee56a51f 100644 --- a/web/src/sections/Displays/SessionGameCard.tsx +++ b/web/src/sections/Displays/SessionGameCard.tsx @@ -116,6 +116,14 @@ export const SessionGameCard: FC = () => { {m.session_game_always_warning()}

)} + {/* Shown for every option, including "leave it running": on a nested + gamescope launch the game IS inside the streamed display, so the + display's own keep-alive outranks anything chosen here — verified + on glass (.41), where a deliberate stop ended the game under + `keep`. Worded so a non-gamescope host reads it and moves on. */} +

+ {m.session_game_nested_note()} +

{(server.game_on_session_end ?? "keep") === "always" && (