Document the patch calling convention once in lib/default.nix; patch
headers say what, target, hook, state and contracts. Comments only, no
code changes.
Runtime patches no longer use webpack module ids or minified export
names, which change with every Steam UI build:
- modules/lib/finders.js: finder library (getWebpackRequire,
findModule/findExport by source text and shape, resolveAll with a
per-page cache, findFiberUp/findFiberDown/findInReactTree), installed
once per page as window.__sfuiFind.
- modules/lib/signatures.json: the signatures, per patch, shared by the
patches and the checker. lib/default.nix mkPatch wraps a patch
`(find, sigs, opts) => ...` with the library, its signatures and
options; exposed as steamFrame.uiPatches.lib.
- Keyboard patch (VERSION 10): layouts module, current/enabled layout
getters, arrow keys, VR keyboard status and VirtualKeyboardManager are
found by signature; if one doesn't match it reports which and leaves
Steam untouched. unpatch.js uses references the patch remembered.
The helper logs inject results when they change.
- launcher-menu launch/pinned-desktop use the library's fiber helpers;
launch no longer depends on the bar popup's window name.
- scripts/check-signatures.mjs (+ webpack-modules.mjs): extracts module
factories from the installed bundles without a browser and checks
every signature (found / ambiguous / missing, with module ids and
export names). README: "Finders and signatures", "After a Steam update".
Stock, clicking a program in the VR dashboard's "+" menu only calls
SteamClient.Apps.LaunchNonSteamApp; the menu stays open until the
program's window appears, so users click again and launch it twice.
New launch/ patch (SharedJSContext) wraps LaunchNonSteamApp, whose only
caller is this menu: closeOnLaunch closes the menu through the "+" bar
button's own popup handle right after a launch; launchDebounce ignores
repeated launches of the same command line within N seconds (logged to
the steam-ui-patches journal). Both opt-in, like the other launcherMenu
options.