Skip to content

Preserve quoted launch options when editing CrossOver settings - #11

Merged
NotProtonNot merged 0 commit into
NotProtonNot:dev-1.1.0from
LaganYT:fix/quoted-launch-options
Oct 7, 2026
Merged

NotProtonNot merged 0 commit into
NotProtonNot:dev-1.1.0from
LaganYT:fix/quoted-launch-options

Conversation

@LaganYT

@LaganYT LaganYT commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Rebased onto dev. It now uses dev's shell-based launch handling (e9f97f7).

Editing CrossOver settings now handles quoted and escaped launch-option assignments while preserving unrelated text. Only unquoted NAME=value tokens before %command% count as assignments, because that's what the shell treats as environment. Tokens after %command% are game arguments and are left alone. Duplicate assignments use the last value, matching the shell.

When the options have no %command%, Steam passes them to the game, so the panel reads nothing from them. Writing a setting adds %command% the way dev already does. Leading assignments written by earlier versions of this panel are still cleaned up.

Unfinished quotes or escapes, shell operators (; & | < > ( ) ` #) and unquoted line breaks disable editing, with a message explaining how to restore it. The panel can't safely tell what the shell will run in those cases.

 edit CrossOver setting
- split launch options on spaces and rebuild tokens
+ decode quotes to identify assignments before %command%
+ replace matching assignments using their original spans
+ preserve game arguments and unrelated environment values

Evidence

  • Before: MTL_HUD_ENABLED="1" %command% appeared unchecked, removing a quoted assignment containing spaces could leave part of its value behind, and %command% --title MTL_HUD_ENABLED=1 showed the toggle as on (and turning it off deleted the game argument).
    After: regression tests in launch-options.js check these cases in both supported Steam UI shapes: quoted values, escapes, quoted names, duplicate assignments, game arguments after %command%, options without %command%, backend switching, shell operators and incomplete input.
  • behavior.js now puts %command% on its fixtures, since on dev assignments without it are game arguments.
  • make all panel-behavior webpatch-fixtures passes.
  • Not yet re-tested live in Steam on dev. The earlier live test was against the old compat_run.sh path.

Merge Danger

Door: two-way

Revert the commit to restore the previous panel behavior. No migrations or launcher changes.

Blast Radius: compatibility

Changes affect launch-option reads and writes from the injected CrossOver controls in both supported Steam UI layouts.

@LaganYT

LaganYT commented Sep 30, 2026

Copy link
Copy Markdown
Contributor Author

I am having claude code review this pr as i make changes for code quality

@LaganYT LaganYT left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review pass 1: make all, make panel-behavior and make webpatch-fixtures pass locally, and the tokenizer handles every quote and escape case in the tests. I found one behavior mismatch with compat_run.sh, one open question about Steam's tokenizer, and one whitespace nit. Details are inline.

Comment thread dylib/feats/webpatch.c Resolved
Comment thread dylib/feats/webpatch.c Resolved
Comment thread dylib/feats/webpatch.c Resolved
@LaganYT

LaganYT commented Sep 30, 2026

Copy link
Copy Markdown
Contributor Author

Live Steam results on macOS, using Zuma Deluxe (3330) with the notproton compat tool. Steam's argv comes from console_log.txt and the run script's view from notproton-run.log.

1. Quoting: Steam decodes the options the way sh does, so the panel's tokenizer matches.

SDL_NPA="1" SDL_NPB='1' SDL_NPC=\1 SDL_NPE="a b" … %command% "MTL_NPD=1" MTL_NPF='x y' MTL_NPG="x y" MTL_NPH=x\ y --np-arg "two words" was spawned as:

SDL_NPA=1 | SDL_NPB=1 | SDL_NPC=1 | SDL_NPE=a b | … | …/notproton/./run | waitforexitandrun | …/Zuma.exe | MTL_NPD=1 | MTL_NPF=x y | MTL_NPG=x y | MTL_NPH=x y | --np-arg | two words

2. Assignments before %command% break the launch. Steam on macOS doesn't treat leading NAME=VALUE as environment. It spawns the first token as the program:

MTL_HUD_ENABLED=1 %command%
→ Failed to spawn process / LaunchApp failed with AppError_46 with "OS Error 260"

The panel wrote exactly this whenever the options contained %command%, because it always prepended. That behavior dates from before this PR, and the %command% stays last test in switching.js asserted it.

3. Assignments after %command% work. %command% "MTL_NPD=1" MTL_HUD_ENABLED='1' MTL_NPH=x\ y --np-arg "two words" launched and gave:

launch_env= MTL_NPD=1 MTL_HUD_ENABLED=1 MTL_NPH=x y
=== launching (waitforexitandrun): …/wine …/Zuma.exe --np-arg two words ===

Fixed in 90551b3: when %command% is present, new assignments are inserted right after it (and a replaced assignment moves there). Without %command% the panel still prepends, because Steam appends those options to the run script's arguments. switching.js now asserts that %command% comes first.

@LaganYT

LaganYT commented Sep 30, 2026

Copy link
Copy Markdown
Contributor Author

Live panel test: deployed 90551b3 into Steam with make deploy, then drove the real Properties → Compatibility page for Zuma Deluxe (3330) through the CEF debugger (clicking the panel's DOM nodes and reading appDetailsStore.GetAppDetails(3330).strLaunchOptions).

Starting options Action Result
%command% Metal HUD on %command% MTL_HUD_ENABLED=1, toggle checked
%command% MTL_HUD_ENABLED=1 Metal HUD off %command%
%command% MTL_HUD_ENABLED='1' --x "a b" (read) toggle checked
same Metal HUD off %command% --x "a b"
%command% --title "unfinished (read) status message shown, 5/5 controls disabled
same click Metal HUD options unchanged

Launching with the options the panel wrote (%command% MTL_HUD_ENABLED=1) works: Steam spawned …/run waitforexitandrun …/Zuma.exe MTL_HUD_ENABLED=1, the run log shows launch_env= MTL_HUD_ENABLED=1, and Zuma.exe started. Before 90551b3 the panel would have written MTL_HUD_ENABLED=1 %command%, which fails with OS Error 260.

@LaganYT
LaganYT marked this pull request as ready for review September 30, 2026 16:38
@LaganYT

LaganYT commented Sep 30, 2026

Copy link
Copy Markdown
Contributor Author

@NotProtonNot This pr is ready for review :)

@LaganYT

LaganYT commented Sep 30, 2026

Copy link
Copy Markdown
Contributor Author

Roadmap: this PR contributes to two items on the Roadmap (short term):

  • "Better support for setting environmental variables" (the part that ships alongside non-Preview CrossOver support): the panel now reads and writes environment settings the way Steam on macOS actually passes them. Quoted and escaped values are recognized, settings go after %command% (where they take effect, instead of failing with OS Error 260), game arguments are left untouched, and malformed options disable editing instead of being corrupted.
  • Feedback on "CrossOver settings are shown as launch options for a game": it keeps that design, but removes the main ways it broke once users added their own launch options.

It doesn't fully complete either item. Non-Preview CrossOver support and the rest of the environment-variable work are still the maintainer's (per #7).

@NotProtonNot

Copy link
Copy Markdown
Owner

Is this still relevant with the changes in the dev branch? Haven't had a second to review it so I am asking. If you don't know/haven't looked at the dev branch, no big deal - I'll look tomorrow.

@LaganYT

LaganYT commented Oct 3, 2026

Copy link
Copy Markdown
Contributor Author

Partially. Dev's shell-based launch handling (e9f97f7) makes the "assignments after %command%" parts of this PR wrong, so I'll drop those two commits. The panel on dev still splits on spaces, though, so quoted values, duplicate assignments, and toggles matching game args after %command% are still broken. I'll rebase onto dev with just the quote-aware parsing, limited to the part before %command%.

@LaganYT
LaganYT force-pushed the fix/quoted-launch-options branch from 90551b3 to 84f1b0d Compare October 3, 2026 23:34
@LaganYT
LaganYT changed the base branch from main to dev October 3, 2026 23:34
@NotProtonNot

NotProtonNot commented Oct 3, 2026 •

Copy link
Copy Markdown
Owner

Partially. Dev's shell-based launch handling (e9f97f7) makes the "assignments after %command%" parts of this PR wrong, so I'll drop those two commits. The panel on dev still splits on spaces, though, so quoted values, duplicate assignments, and toggles matching game args after %command% are still broken. I'll rebase onto dev with just the quote-aware parsing, limited to the part before %command%.

It's still early. There is still work to do, including with the toggles. Talk to me about the "duplicate assignments" and "quoted values" stuff, what do you mean exactly?

@LaganYT

LaganYT commented Oct 3, 2026

Copy link
Copy Markdown
Contributor Author

Concrete cases. I ran dev's emitted panel through the panel-behavior test setup and the options through /bin/sh -c with env standing in for the game:

Quoted values. The panel splits on spaces and reads the raw text after NAME=.

  • MTL_HUD_ENABLED="1" %command%: the shell exports MTL_HUD_ENABLED=1, but the panel reads "1" with the quotes, so the HUD toggle shows off.
  • A value with a space breaks writes. With CX_GRAPHICS_BACKEND=dxmt DXMT_METALFX_SPATIAL_SWAPCHAIN=1 DXMT_CONFIG="d3d11.metalSpatialUpscaleFactor=2.0 d3d11.foo=1" %command%, switching to DXVK writes CX_GRAPHICS_BACKEND=dxvk d3d11.foo=1" %command%. The shell then fails with unexpected EOF while looking for matching `"', so the game doesn't launch.

Duplicate assignments. With MTL_HUD_ENABLED=1 MTL_HUD_ENABLED=0 %command%, the shell exports 0 because the last one wins. The panel uses find, which takes the first, so the toggle shows on. Writes are fine because they remove every copy. This only comes up with hand-edited options, so it's minor.

Game arguments. %command% --title MTL_HUD_ENABLED=1 shows the HUD toggle as on. Turning it off writes %command% --title, which deletes the game's argument.

The PR branch gets all of these right. Happy to adjust when you get to the toggle work.

@NotProtonNot
NotProtonNot force-pushed the fix/quoted-launch-options branch from f94eb37 to 614d455 Compare October 7, 2026 00:38
@NotProtonNot
NotProtonNot changed the base branch from dev to dev-1.1.0 October 7, 2026 00:39
@NotProtonNot
NotProtonNot merged commit f1cc360 into NotProtonNot:dev-1.1.0 Oct 7, 2026
2 checks passed
@NotProtonNot

Copy link
Copy Markdown
Owner

Merge complete :)

@LaganYT
LaganYT deleted the fix/quoted-launch-options branch October 7, 2026 14:44
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