Skip to content

feat(steam): Launch Options selector in the STEAM dropdown#1

Open
Leb-Sun wants to merge 7 commits into
mainfrom
claude/winnative-steam-launch-options-0oluek
Open

feat(steam): Launch Options selector in the STEAM dropdown#1
Leb-Sun wants to merge 7 commits into
mainfrom
claude/winnative-steam-launch-options-0oluek

Conversation

@Leb-Sun

@Leb-Sun Leb-Sun commented Jun 9, 2026

Copy link
Copy Markdown
Owner

Adds a "Launch Options" item to the STEAM menu on the game detail screen that lists the game's appinfo config.launch entries (e.g. ARK's "Launch ARK (No BattlEye)") with a checkmark on the current choice. Selecting one persists as the game's default:

  • exe -> shortcut extra launch_exe_path + container.executablePath (the priority resolveRelativeGameExe already honors; non-default exes ride the existing WN_STEAM_DIRECT_EXE override)
  • the option's own arguments -> new shortcut extra launch_exe_args, kept separate from the user's custom execArgs

LaunchInfo gains an arguments field (defaulted, so cached appinfo JSON stays decodable) parsed from appinfo config/launch/arguments.

A shared SteamUtils.combineSteamLaunchArgs joins option args with custom args across all three launch channels (direct command line, ColdClientLoader.ini ExeCommandLine, localconfig.vdf LaunchOptions / GetLaunchCommandLine). It honors Steam's %command% placeholder in custom args. The steam-env warm stamp now includes the effective LaunchOptions line so a changed selection re-runs the localconfig edit, and warm launches re-push the per-process launch command line.

The submenu reuses the existing StoreSourceActionPopup surface and StoreSourceMenuItem styling; hidden unless the game is installed and has 2+ distinct options.

https://claude.ai/code/session_01EUsZxzAWCjSh8LYRS9W3vT

claude added 5 commits June 19, 2026 00:50
Adds a "Launch Options" item to the STEAM menu on the game detail
screen that lists the game's appinfo config.launch entries (e.g.
ARK's "Launch ARK (No BattlEye)") with a checkmark on the current
choice. Selecting one persists as the game's default:

- exe -> shortcut extra launch_exe_path + container.executablePath
  (the priority resolveRelativeGameExe already honors; non-default
  exes ride the existing WN_STEAM_DIRECT_EXE override)
- the option's own arguments -> new shortcut extra launch_exe_args,
  kept separate from the user's custom execArgs

LaunchInfo gains an `arguments` field (defaulted, so cached appinfo
JSON stays decodable) parsed from appinfo config/launch/arguments.

A shared SteamUtils.combineSteamLaunchArgs joins option args with
custom args across all three launch channels (direct command line,
ColdClientLoader.ini ExeCommandLine, localconfig.vdf LaunchOptions /
GetLaunchCommandLine). It honors Steam's %command% placeholder in
custom args. The steam-env warm stamp now includes the effective
LaunchOptions line so a changed selection re-runs the localconfig
edit, and warm launches re-push the per-process launch command line.

The submenu reuses the existing StoreSourceActionPopup surface and
StoreSourceMenuItem styling; hidden unless the game is installed and
has 2+ distinct options.

https://claude.ai/code/session_01EUsZxzAWCjSh8LYRS9W3vT
The v1 selector only existed on the store detail screen
(StoreGameDetailScreen); tapping an installed game in the library
grid opens LibraryGameDetailDialog -> LibraryGameLaunchScreen, which
has its own duplicated STEAM dropdown - so the feature was invisible
from the library. Mirror the submenu there (same two-page popup,
using this screen's Launch* styling) and wire it in
LibraryGameDetailDialog for Steam games only.

Also fix two latent issues that could hide or weaken the selector:

- Cached appinfo rows predate LaunchInfo.arguments, so options that
  differ only by args deduped down to one entry and fell under the
  2-option visibility gate. Dedup now includes the option label, and
  both dialogs do a two-phase load: show cached options immediately,
  then SteamService.refreshAppInfoFromPics (new public wrapper around
  fetchLatestSteamAppInfo + persistLatestSteamAppInfo) re-fetches the
  app's PICS appinfo and reloads, healing upgraded installs on first
  open.

- Extracted the option-list builder and selection persistence into
  shared UnifiedActivity helpers used by both screens, replacing
  GameManagerDialog's inline copies.

https://claude.ai/code/session_01EUsZxzAWCjSh8LYRS9W3vT
The in-popup submenu rendered as an awkward full-width overlay. Replace
it with a centered modal window that follows the Workshop window's
design language: dimmed scrim, 560dp-max rounded Surface, header with
an accent icon badge + LAUNCH OPTIONS overline + game title + count
chip + close button, and a divided row list. Rows show the option label
with its executable/arguments as the secondary line; tapping persists
the selection and moves the check mark.

- New LaunchOptionsScreen.kt mirroring WorkshopScreen's palette and
  layout (all vector icons; no new drawable assets needed).
- Both STEAM dropdowns return to a flat menu whose "Launch Options"
  item opens the window (showLaunchOptions/onLaunchOptions params
  replace the list plumbing through the SourceTags).
- LaunchOptionsDialog host added next to WorkshopDialog in both
  GameManagerDialog and LibraryGameDetailDialog.

https://claude.ai/code/session_01EUsZxzAWCjSh8LYRS9W3vT
Findings from a full-branch review applied:

- PICS appinfo re-fetch now runs once per app per process (retried on
  failure) instead of on every game-detail open, and the two-phase
  load + refresh logic is shared by both dialogs via
  loadSteamLaunchOptionsRefreshing — drops a network round-trip and a
  duplicate shortcut scan from repeat opens.
- LaunchOptionsDialog owns selection persistence (appId +
  onSelectionSaved), removing the duplicated persist lambda from both
  host sites.
- XServerDisplayActivity: single combineWithSelectedLaunchArgs
  resolver replaces the getExtra+combine pattern repeated across the
  direct-launch and both ColdClient INI sites.
- Steam-env stamp stores the raw effective LaunchOptions line instead
  of its hashCode — exact equality, no silent collision skips.
- StoreLaunchOptionItem moved to LaunchOptionsScreen.kt where the
  picker lives.

https://claude.ai/code/session_01EUsZxzAWCjSh8LYRS9W3vT
getSelectedLaunchOption ran ContainerManager().loadShortcuts() on every
game-detail open. Each Shortcut constructed that way decodes the full
cover-art bitmap, runs PE icon extraction over the game exe and can
rewrite .desktop files — a large transient heap spike and a write race
against the UI's own shortcut reads, just to fetch two strings.

New readSteamShortcutExtras parses the [Extra Data] section straight
from the .desktop files and returns the owning container dir; the
container.executablePath fallback is read from the .container config
JSON directly. The heavyweight findSteamShortcut path remains only in
setSelectedLaunchOption, which must materialize the shortcut to write.

https://claude.ai/code/session_01EJFSZYUPkR1Cwer6CC2cNa
@Leb-Sun Leb-Sun force-pushed the claude/winnative-steam-launch-options-0oluek branch from 474c19b to 7dcf506 Compare June 19, 2026 00:54
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.

2 participants