mirror of
https://github.com/lhns/steam-frame-nix.git
synced 2026-10-06 01:00:13 +02:00
SteamOS's steamvr.service runs `rm -rf ~/.cache/SteamVR` on every SteamVR start, which deletes vrwebhelper's browser profile and with it the localStorage frame-controls kept its placements in, so they were lost on every SteamVR restart and reboot. steam-ui-patches: per-patch persistent state (`state = true`). The injector keeps ~/.local/state/steam-frame-nix/ui-patches/<name>.json, seeds window.__sfuiStore in a fresh page before the patch runs and writes the file (atomically, on change, name-checked, max 64 KiB) when the page calls the CDP binding __sfuiStoreSave. frame-controls v5: placements saved there (v4 localStorage copy migrated once, then removed). steam-close-button v8: "Steam hidden" saved there; a restored hidden state hides Steam once if SteamVR already shows it when the patch attaches (or first shows it before the patch sees Steam's frame). README: "Changes outside Nix" lists the directory; install.sh uninstall removes it.
58 lines
2.7 KiB
Nix
58 lines
2.7 KiB
Nix
# Shared helpers of the runtime Steam UI patches:
|
|
# - finders.js: signature-based lookup of webpack modules/exports and fibers;
|
|
# - signatures.json: per-patch signatures, also read by
|
|
# scripts/check-signatures.mjs (run it after a Steam update);
|
|
# - hooks.js: one shared wrapper per hooked method (e.g. SendMessage);
|
|
# - mkPatch: builds the expression the injector evaluates.
|
|
#
|
|
# Patch convention: a patch file is a function expression
|
|
# (find, sigs, opts, hooks) => <status string or Promise of one>
|
|
# (trailing parameters may be omitted), called as
|
|
# (<patch>)(<finders.js>, <signatures>, <opts>, <hooks.js>)
|
|
# with find = lib/finders.js, sigs = its module signatures, opts = the JSON
|
|
# options from its module, hooks = lib/hooks.js. The injector re-evaluates it
|
|
# on every new JS context and periodically, so it must be idempotent: keep
|
|
# state on a window.__sfui* global (or on the wrapped function), return
|
|
# "unchanged" when already applied (not logged) and tear down/re-apply when
|
|
# its VERSION or options differ. Bump VERSION whenever the patch code changes.
|
|
# A matching unpatch.js (plain expression) reverts it when the service stops.
|
|
# State that must outlive the page (SteamVR restarts, reboots) goes through
|
|
# window.__sfuiStore (patch registered with state = true; injector.mjs).
|
|
# Patches needing none of the arguments may be plain expressions without
|
|
# mkPatch (e.g. launcher-menu/order).
|
|
{ pkgs }:
|
|
let
|
|
sigFile = builtins.fromJSON (builtins.readFile ./signatures.json);
|
|
in {
|
|
signatures = sigFile;
|
|
finders = ./finders.js;
|
|
hooks = ./hooks.js;
|
|
|
|
# name: file name (and default signatures entry); src: the patch file;
|
|
# signatures: `sigs` (default: signatures.json entry `name`, else none);
|
|
# opts: JSON-serialisable options; extraArgs: files or derivations with JS
|
|
# expressions passed as further arguments after hooks (built with
|
|
# runCommand, so they may be build outputs, e.g. generated data).
|
|
mkPatch = { name, src, signatures ? sigFile.patches.${name}.modules or { }, opts ? { }, extraArgs ? [ ] }:
|
|
if extraArgs == [ ] then
|
|
pkgs.writeText "${name}.js" ''
|
|
(${builtins.readFile src}
|
|
)(${builtins.readFile ./finders.js}
|
|
, ${builtins.toJSON signatures}
|
|
, ${builtins.toJSON opts}
|
|
, ${builtins.readFile ./hooks.js}
|
|
)
|
|
''
|
|
else
|
|
pkgs.runCommand "${name}.js" { } ''
|
|
{
|
|
echo '('; cat ${src}; echo ')('; cat ${./finders.js}
|
|
echo ','; echo ${pkgs.lib.escapeShellArg (builtins.toJSON signatures)}
|
|
echo ','; echo ${pkgs.lib.escapeShellArg (builtins.toJSON opts)}
|
|
echo ','; cat ${./hooks.js}
|
|
for f in ${pkgs.lib.escapeShellArgs (map (f: "${f}") extraArgs)}; do echo ','; cat "$f"; done
|
|
echo ')'
|
|
} > $out
|
|
'';
|
|
}
|