Skip to content

Per-game activity, part 1: Steam downloads and removals per game - #53

Merged
sevenns merged 8 commits into
release/v0.9.0from
feature/per-game-activity
Oct 5, 2026
Merged

sevenns merged 8 commits into
release/v0.9.0from
feature/per-game-activity

Conversation

@sevenns

@sevenns sevenns commented Oct 5, 2026

Copy link
Copy Markdown
Owner

Per-game activity, part 1: Steam downloads and removals per game

Background operations move out of the single global AppState into a registry of activities keyed by game id. This PR covers the Steam half: every available Steam game is polled at once, so a download, an update or a removal is visible on its own game from the moment the launcher starts, and it no longer blocks selecting, installing or launching other games. It replaces the stopgap from ce6dd03 (alpha.5), which pinned the state on the downloading game.

What changes

  • Activity registry (src/shared/activity.ts, src/main/activity-registry.ts): GameActivity per game id. Pushes a full snapshot on activity:update and seeds via activity:request. Only real changes are announced.
  • SteamActivityWatch (replaces steam-install-watch.ts): one recursive timer over all available Steam games. Per tick it does one locateSteam plus one library listing (steamInstallStatuses batch in steam.ts). The cadence comes from PLAYHOOK_STEAM_POLL_MS (default 5000). scanNow() runs after a card or PC library load, card removal, steam://install and steam://uninstall.
    • absent → downloading: steam-installing. installed → downloading: steam-updating, and finishing it sends no "installed" notification.
    • Completion notifies only for its own game, exactly once.
    • The game of the busy session never gets an activity: Steam updating a game before launch keeps "Launching...". The pre-session status is applied after the session ends.
    • A game that leaves the list is cleaned out of the registry and the pending uninstall requests.
    • When Steam can't be found, the last known statuses are kept instead of reading every game as removed.
  • Controller: steamBusyId is gone. onGameChanged(id) rebuilds GameInfo and re-checks the state after the await before replacing it; otherwise it only refreshes the browse info of the game on screen. isBusy(id?). A game with an activity is not launched or uninstalled; another game's activity doesn't matter.
  • GameInfo loses steamInstalling / steamPaused / steamPausedProgress / steamUninstalling.
  • Renderer: the status line, the gear (data-busy), the new data-activity attribute, the Details install toggle and the Play button come from the activity of the game on screen. The carousel and library pulse every busy game (setBusyGames). Customize's Delete / Move gate is by id.
  • i18n: removed errors.steamBusyOther, added launcher.state.updating / updatingPaused (en + ru).

Tests

  • New: test/activity-registry.test.ts, test/steam-activity-watch.test.ts (the whole transition table, two parallel downloads, uninstall request and timeout, the session game, cleanup), test/state-view.test.ts.
  • test/game-controller.test.ts: a download is visible at startup without action:select; selecting another game during a download; launching another game during a download and its completion mid-session (the state journal is untouched); update without a notification; Steam uninstall as an activity.
  • test/renderer/controls.test.ts: the focus ring and Play with an activity on the game on screen vs another game's activity.
  • typecheck, lint, vitest (1388) and npm run build are green locally.

Not covered here

  • Manual check on the Deck and desktop (stage 1 checklist): three Steam downloads, then a restart shows three indicators at once; launching during downloads; a completion notification for an unselected game; an auto-update shows "Updating..."; launching a game Steam decided to update shows "Launching...".
  • Pre-existing, not touched: onSelectRequested does not re-validate the state after its awaits, so a very fast Play right after entering a detail screen could be overwritten by the late select.
  • Part 2 (background install/uninstall jobs, installers, actions by id, cleanup) follows in the same branch after this one is merged.

@sevenns
sevenns merged commit 0dfbabd into release/v0.9.0 Oct 5, 2026
6 checks passed
@sevenns
sevenns deleted the feature/per-game-activity branch October 5, 2026 12:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant