mirror of
https://github.com/lhns/steam-frame-nix.git
synced 2026-10-06 04:04:16 +02:00
steamFrame.launchers.<desktop ID> takes the app's own entry (a Flatpak's
export, a Nix package's or a host file) and rewrites only its command lines
(hostEnv, env, flatpakArgs, args, wrappers) and the keys asked for
(mimeTypes, defaultFor, settings), so name, icon, translations and actions
stay the app's and follow its updates.
- Package entries are rewritten at build time; Flatpak/host file entries at
runtime by steam-frame-nix-launchers into
<session.runtimeDir>/steam-frame-nix/applications (tmpfs), on switch, at
login and when Flatpak installs/updates apps (path unit); the Home Manager
links point there.
- keyring.{enable,electron} replaces steamFrame.keyring.{flatpaks,programs}
(clean break: the old options fail with the new form).
- Firefox's launcher is the Flatpak's entry with the profile wrapper in
front (no --profile for the profile manager); Jellyfin's hardware
decoding sets flatpakArgs and env.
- cleanup --all removes the tmpfs entries.
- Check on copies of the real Element, KRDC, Firefox, gedit, Jellyfin and
Claude entries, quoting and generator behaviour.
237 lines
13 KiB
Nix
237 lines
13 KiB
Nix
# Checks of `install.sh cleanup` on fake home and runtime dirs: every
|
|
# artifact any version wrote (removed or restored) next to look-alikes that
|
|
# aren't ours (left alone), --dry-run changes nothing, a second run changes
|
|
# nothing, SteamVR running defers the debugger key to a runtime drop-in.
|
|
{ pkgs }:
|
|
let
|
|
cleanup = pkgs.callPackage ./package.nix { };
|
|
in
|
|
pkgs.runCommand "cleanup-check" { nativeBuildInputs = [ cleanup pkgs.jq ]; } ''
|
|
set -euo pipefail
|
|
fail() { echo "FAIL: $*" >&2; exit 1; }
|
|
export HOME XDG_RUNTIME_DIR STEAM_FRAME_NIX_RUNTIME_DIR STEAM_FRAME_NIX_SYSTEMCTL
|
|
unset XDG_STATE_HOME XDG_DATA_HOME XDG_CONFIG_HOME
|
|
|
|
# systemctl stub: SteamVR's state from $STUB/state, calls logged.
|
|
STUB=$PWD/stub; mkdir -p $STUB
|
|
cat > $STUB/systemctl <<'SH'
|
|
#!/usr/bin/env bash
|
|
echo "$*" >> "$STUB/log"
|
|
case "$*" in *"show -p ActiveState --value steamvr.service"*) cat "$STUB/state" ;; esac
|
|
SH
|
|
chmod +x $STUB/systemctl
|
|
sed -i "1s|.*|#!${pkgs.bash}/bin/bash|" $STUB/systemctl
|
|
export STUB
|
|
STEAM_FRAME_NIX_SYSTEMCTL=$STUB/systemctl
|
|
|
|
fresh() {
|
|
root=$PWD/$1; rm -rf $root; mkdir -p $root/home $root/run
|
|
HOME=$root/home XDG_RUNTIME_DIR=$root/run STEAM_FRAME_NIX_RUNTIME_DIR=$root/run
|
|
: > $STUB/log; echo inactive > $STUB/state
|
|
S=$HOME/.local/state/steam-frame-nix
|
|
V=$HOME/.config/openvr/config/steamvr.vrsettings
|
|
I=$HOME/.local/share/icons/hicolor/scalable/apps
|
|
F=$HOME/.var/app/org.mozilla.firefox/config/mozilla/firefox
|
|
O=$HOME/.local/share/flatpak/overrides
|
|
mkdir -p $S/ui-patches ''${V%/*} $I $F $O
|
|
}
|
|
snap() { (cd $root && find . -printf '%p %y %m %l %T@\n' | sort; find . -type f -exec sha256sum {} + | sort) ; }
|
|
has() { grep -qF -- "$2" <<< "$1" || fail "output lacks '$2':"$'\n'"$1"; }
|
|
hasnt() { ! grep -qF -- "$2" <<< "$1" || fail "output has '$2':"$'\n'"$1"; }
|
|
gone() { for p; do [ ! -e "$p" ] && [ ! -L "$p" ] || fail "still there: $p"; done; }
|
|
there() { for p; do [ -e "$p" ] || [ -L "$p" ] || fail "missing: $p"; done; }
|
|
noop() { # a further run changes nothing
|
|
local before; before=$(snap); res=$(steam-frame-nix-cleanup "$@")
|
|
[ "$(snap)" = "$before" ] || fail "second run changed files"
|
|
! grep -Eq '^ +(removed|rewrote|wrote|migrated|touched) | restored \(' <<< "$res" || fail "second run acted:"$'\n'"$res"
|
|
}
|
|
|
|
# --- A: --all, SteamVR stopped: everything ---
|
|
fresh a
|
|
printf '{\n "VRWebHelper" : {\n "DebuggerEnabled" : true,\n "DebuggerPort" : 8087\n },\n "steamvr" : {}\n}\n' > $V
|
|
chmod 600 $V
|
|
touch $S/steamvr-debugger # marker of the first version
|
|
mkdir -p $root/run/steam-frame-nix $root/run/systemd/user/steamvr.service.d
|
|
echo old > $root/run/steam-frame-nix/steamvr-debugger-restore
|
|
mkdir -p $root/run/steam-frame-nix/applications # steamFrame.launchers
|
|
echo '[Desktop Entry]' > $root/run/steam-frame-nix/applications/im.riot.Riot.desktop
|
|
echo x > $root/run/steam-frame-nix/applications/.im.riot.Riot.desktop.sum
|
|
: > $root/run/steam-frame-nix/applications/.lock
|
|
echo old > $root/run/systemd/user/steamvr.service.d/50-steam-frame-nix-debugger.conf
|
|
echo keep > $root/run/systemd/user/steamvr.service.d/other.conf
|
|
ln -s /nix/store/00000000000000000000000000000000-breeze-icons-6.30.0/share/icons/breeze/apps/64/utilities-terminal.svg $I/utilities-terminal.svg
|
|
ln -s /nix/store/00000000000000000000000000000000-home-manager-files/.local/share/icons/hicolor/scalable/apps/hm.svg $I/hm.svg
|
|
ln -s /somewhere/else.svg $I/other.svg
|
|
printf 'utilities-terminal\n' > $S/icon-fallbacks
|
|
mkdir -p $F/desktop $F/a.default $F/b.old $F/c.mine $F/d.busy $F/e.fresh
|
|
ln -s /app/etc/firefox/steam-frame-nix-desktop-user.js $F/desktop/user.js
|
|
printf 'user_pref("full-screen-api.ignore-widgets", false);\nuser_pref("other", 1);\n' > $F/desktop/prefs.js
|
|
printf '%s\nuser_pref("a.b", true);\n' '// Managed by steam-frame-nix (steamFrame.firefox); rewritten on switch.' > $F/a.default/user.js
|
|
printf 'user_pref("a.b", true);\nuser_pref("c.d", 2);\n' > $F/a.default/prefs.js
|
|
ln -s /nix/store/00000000000000000000000000000000-firefox-user.js $F/b.old/user.js
|
|
echo 'user_pref("mine", 1);' > $F/c.mine/user.js
|
|
printf '%s\nuser_pref("a.b", true);\n' '// Managed by steam-frame-nix (steamFrame.firefox); rewritten on switch.' > $F/d.busy/user.js
|
|
printf 'user_pref("a.b", true);\n' > $F/d.busy/prefs.js; touch $F/d.busy/.parentlock
|
|
ln -s /app/etc/firefox/steam-frame-nix-desktop-user.js $F/e.fresh/user.js
|
|
printf '[Context]\ndevices=all;\nfilesystems=/nix/store/00000000000000000000000000000000-mpv-hwdec-shim:ro;xdg-music:ro;\n\n[Environment]\nLD_PRELOAD=/nix/store/00000000000000000000000000000000-mpv-hwdec-shim/lib/mpv-hwdec-shim.so\nSFN_MPV_HWDEC=v4l2m2m-copy,auto-copy\nFOO=bar\n' > $O/org.jellyfin.JellyfinDesktop
|
|
printf '[Context]\ndevices=all;\n' > $O/org.example.Other
|
|
mkdir -p $HOME/.var/app/org.jellyfin.JellyfinDesktop
|
|
echo so > $HOME/.var/app/org.jellyfin.JellyfinDesktop/mpv-hwdec-shim.so; touch $S/jellyfin-hwdec-shim
|
|
echo '{"a":1}' > $S/ui-patches/frame-controls.json; echo '{' > $S/ui-patches/vr-cat.json.tmp
|
|
echo mine > $S/ui-patches/notes.txt
|
|
|
|
exec 9< $F/d.busy/.parentlock # Firefox "uses" d.busy
|
|
before=$(snap)
|
|
res=$(steam-frame-nix-cleanup --dry-run --all)
|
|
[ "$(snap)" = "$before" ] || fail "--dry-run changed files"
|
|
has "$res" "would remove $I/utilities-terminal.svg"
|
|
has "$res" "would restore VRWebHelper.DebuggerEnabled"
|
|
hasnt "$res" "removed "
|
|
! grep -q daemon-reload $STUB/log || fail "--dry-run reloaded systemd"
|
|
|
|
res=$(steam-frame-nix-cleanup --all); echo "$res"
|
|
# debugger: key gone (value before: absent), other keys kept, 3-space indent, mode kept
|
|
[ "$(jq -c .VRWebHelper $V)" = '{"DebuggerPort":8087}' ] || fail "vrsettings: $(cat $V)"
|
|
grep -q '^ "VRWebHelper"' $V || fail "indent"
|
|
[ "$(stat -c %a $V)" = 600 ] || fail "mode"
|
|
gone $S/steamvr-debugger $S/steamvr-debugger.armed $root/run/steam-frame-nix \
|
|
$root/run/systemd/user/steamvr.service.d/50-steam-frame-nix-debugger.conf
|
|
there $root/run/systemd/user/steamvr.service.d/other.conf
|
|
grep -q daemon-reload $STUB/log || fail "no daemon-reload after removing the drop-in"
|
|
# icons
|
|
gone $I/utilities-terminal.svg $S/icon-fallbacks
|
|
there $I/hm.svg $I/other.svg
|
|
has "$res" "left alone: $F/c.mine/user.js"
|
|
# firefox
|
|
gone $F/desktop/user.js $F/a.default/user.js $F/b.old/user.js $F/e.fresh
|
|
[ "$(cat $F/desktop/prefs.js)" = 'user_pref("other", 1);' ] || fail "desktop prefs.js: $(cat $F/desktop/prefs.js)"
|
|
[ "$(cat $F/a.default/prefs.js)" = 'user_pref("c.d", 2);' ] || fail "a.default prefs.js"
|
|
there $F/c.mine/user.js $F/d.busy/user.js
|
|
grep -q a.b $F/d.busy/prefs.js || fail "busy profile changed"
|
|
has "$res" "deferred: $F/d.busy/user.js: Firefox is using profile d.busy"
|
|
# jellyfin
|
|
[ "$(cat $O/org.jellyfin.JellyfinDesktop)" = "$(printf '[Context]\nfilesystems=xdg-music:ro;\n\n[Environment]\nFOO=bar')" ] \
|
|
|| fail "override: $(cat $O/org.jellyfin.JellyfinDesktop)"
|
|
has "$res" "devices=all goes too"
|
|
there $O/org.example.Other
|
|
gone $HOME/.var/app/org.jellyfin.JellyfinDesktop/mpv-hwdec-shim.so $S/jellyfin-hwdec-shim
|
|
# ui state: ours gone, foreign file kept (so the dirs stay)
|
|
gone $S/ui-patches/frame-controls.json $S/ui-patches/vr-cat.json.tmp
|
|
there $S/ui-patches/notes.txt
|
|
noop --all
|
|
exec 9<&-
|
|
res=$(steam-frame-nix-cleanup --all)
|
|
gone $F/d.busy/user.js
|
|
[ ! -s $F/d.busy/prefs.js ] || [ -z "$(tr -d '[:space:]' < $F/d.busy/prefs.js)" ] || fail "busy prefs.js after close"
|
|
rm $S/ui-patches/notes.txt
|
|
res=$(steam-frame-nix-cleanup --all)
|
|
gone $S
|
|
there $HOME/.local/share/icons/hicolor/scalable/apps/hm.svg
|
|
noop --all
|
|
echo "A ok"
|
|
|
|
# --- B: SteamVR running: deferred to the runtime drop-in ---
|
|
fresh b
|
|
printf '{\n "VRWebHelper" : {\n "DebuggerEnabled" : true\n }\n}\n' > $V
|
|
echo false > $S/steamvr-debugger.armed
|
|
echo active > $STUB/state
|
|
res=$(steam-frame-nix-cleanup --all); echo "$res"
|
|
has "$res" "deferred: VRWebHelper.DebuggerEnabled"
|
|
[ "$(jq .VRWebHelper.DebuggerEnabled $V)" = true ] || fail "changed while running"
|
|
there $S/steamvr-debugger.armed $root/run/steam-frame-nix/steamvr-debugger-restore
|
|
grep -qx 'ExecStopPost=-/usr/bin/bash %t/steam-frame-nix/steamvr-debugger-restore' \
|
|
$root/run/systemd/user/steamvr.service.d/50-steam-frame-nix-debugger.conf || fail "drop-in"
|
|
[ "$(grep -c daemon-reload $STUB/log)" = 1 ] || fail "daemon-reload count"
|
|
noop --all
|
|
[ "$(grep -c daemon-reload $STUB/log)" = 1 ] || fail "second run reloaded again"
|
|
# SteamVR stops: ExecStopPost runs the script
|
|
bash $root/run/steam-frame-nix/steamvr-debugger-restore
|
|
[ "$(jq -c .VRWebHelper $V)" = '{"DebuggerEnabled":false}' ] || fail "restore: $(cat $V)"
|
|
gone $S/steamvr-debugger.armed
|
|
echo inactive > $STUB/state
|
|
res=$(steam-frame-nix-cleanup --all)
|
|
gone $root/run/steam-frame-nix $root/run/systemd $S
|
|
noop --all
|
|
echo "B ok"
|
|
|
|
# --- C: --orphans with keeps ---
|
|
fresh c
|
|
printf '{"VRWebHelper":{"DebuggerEnabled":true}}\n' > $V
|
|
echo absent > $S/steamvr-debugger.armed
|
|
mkdir -p $F/desktop $F/x.default
|
|
ln -s /app/etc/firefox/steam-frame-nix-desktop-user.js $F/desktop/user.js
|
|
touch $F/desktop/.parentlock; exec 8< $F/desktop/.parentlock # the wrapper's, Firefox running
|
|
ln -s /app/etc/firefox/steam-frame-nix-desktop-user.js $F/x.default/user.js
|
|
printf '[Context]\ndevices=all;\nfilesystems=/nix/store/00000000000000000000000000000000-mpv-hwdec-shim:ro;\n\n[Environment]\nLD_PRELOAD=/nix/store/00000000000000000000000000000000-mpv-hwdec-shim/lib/mpv-hwdec-shim.so\nSFN_MPV_HWDEC=x\n' > $O/org.jellyfin.JellyfinDesktop
|
|
mkdir -p $HOME/.var/app/org.jellyfin.JellyfinDesktop
|
|
echo so > $HOME/.var/app/org.jellyfin.JellyfinDesktop/mpv-hwdec-shim.so # no marker: not ours
|
|
echo '{"a":1}' > $S/ui-patches/frame-controls.json; echo '{}' > $S/ui-patches/vr-cat.json
|
|
echo '{' > $S/ui-patches/x.json.tmp; touch -d '-1 hour' $S/ui-patches/x.json.tmp
|
|
echo '{' > $S/ui-patches/y.json.tmp # being written: kept
|
|
echo active > $STUB/state
|
|
res=$(steam-frame-nix-cleanup --orphans --keep debugger); echo "$res"
|
|
hasnt "$res" "deferred" # kept: the next start re-arms it
|
|
there $root/run/systemd/user/steamvr.service.d/50-steam-frame-nix-debugger.conf $S/steamvr-debugger.armed
|
|
there $F/desktop/user.js $S/ui-patches/frame-controls.json $S/ui-patches/vr-cat.json $S/ui-patches/y.json.tmp
|
|
gone $F/x.default/user.js $O/org.jellyfin.JellyfinDesktop $S/ui-patches/x.json.tmp
|
|
there $HOME/.var/app/org.jellyfin.JellyfinDesktop/mpv-hwdec-shim.so
|
|
has "$res" "left alone: $HOME/.var/app/org.jellyfin.JellyfinDesktop/mpv-hwdec-shim.so"
|
|
noop --orphans --keep debugger
|
|
# SteamVR stopped (e.g. after a power loss): the key is restored, hook kept
|
|
echo inactive > $STUB/state
|
|
res=$(steam-frame-nix-cleanup --orphans --keep debugger)
|
|
[ "$(jq -c . $V)" = '{}' ] || fail "orphans restore: $(cat $V)"
|
|
gone $S/steamvr-debugger.armed
|
|
there $root/run/systemd/user/steamvr.service.d/50-steam-frame-nix-debugger.conf
|
|
# debugger no longer kept: runtime pieces go
|
|
res=$(steam-frame-nix-cleanup --orphans)
|
|
gone $root/run/steam-frame-nix $root/run/systemd
|
|
noop --orphans
|
|
there $S/ui-patches/frame-controls.json $HOME/.local/share/icons/hicolor/scalable/apps # not ours
|
|
exec 8<&- # Firefox closed
|
|
res=$(steam-frame-nix-cleanup --orphans)
|
|
gone $F/desktop/user.js
|
|
! steam-frame-nix-cleanup --all --keep debugger 2>/dev/null || fail "--all --keep accepted"
|
|
! steam-frame-nix-cleanup --orphans --keep bogus 2>/dev/null || fail "unknown --keep accepted"
|
|
echo "C ok"
|
|
|
|
# --- D: the user's own key is never touched ---
|
|
fresh d
|
|
printf '{"VRWebHelper":{"DebuggerEnabled":true}}\n' > $V
|
|
res=$(steam-frame-nix-cleanup --all)
|
|
has "$res" "left alone: VRWebHelper.DebuggerEnabled = true"
|
|
[ "$(jq -c . $V)" = '{"VRWebHelper":{"DebuggerEnabled":true}}' ] || fail "user's key changed"
|
|
echo "D ok"
|
|
|
|
# --- E: steamvr-debugger-arm (before each SteamVR start) ---
|
|
arm() { bash ${../../install.sh} steamvr-debugger-arm; }
|
|
fresh e
|
|
printf '{\n "steamvr" : {}\n}\n' > $V
|
|
echo activating > $STUB/state
|
|
res=$(arm); echo "$res"
|
|
[ "$(cat $S/steamvr-debugger.armed)" = absent ] || fail "armed"
|
|
[ "$(jq -c .VRWebHelper $V)" = '{"DebuggerEnabled":true}' ] || fail "arm: $(cat $V)"
|
|
there $root/run/steam-frame-nix/steamvr-debugger-restore
|
|
[ "$(grep -c daemon-reload $STUB/log)" = 1 ] || fail "arm reload"
|
|
before=$(snap); res=$(arm)
|
|
[ "$(snap)" = "$before" ] || fail "second arm changed files"
|
|
[ "$(grep -c daemon-reload $STUB/log)" = 1 ] || fail "second arm reloaded"
|
|
bash $root/run/steam-frame-nix/steamvr-debugger-restore # SteamVR stops
|
|
[ "$(jq -c . $V)" = '{"steamvr":{}}' ] || fail "arm restore: $(cat $V)"
|
|
gone $S/steamvr-debugger.armed
|
|
res=$(arm) # restart: armed again
|
|
[ "$(cat $S/steamvr-debugger.armed)" = absent ] || fail "re-arm"
|
|
bash $root/run/steam-frame-nix/steamvr-debugger-restore
|
|
# the user's own true: never armed, never restored
|
|
printf '{"VRWebHelper":{"DebuggerEnabled":true}}\n' > $V
|
|
res=$(arm); has "$res" "not set by steam-frame-nix"
|
|
gone $S/steamvr-debugger.armed
|
|
# no file yet: created, and removed again if nothing else was added
|
|
rm $V; res=$(arm)
|
|
[ "$(cat $S/steamvr-debugger.armed)" = nofile ] || fail "nofile"
|
|
bash $root/run/steam-frame-nix/steamvr-debugger-restore
|
|
gone $V $S/steamvr-debugger.armed
|
|
echo "E ok"
|
|
touch $out
|
|
''
|