mirror of
https://github.com/lhns/steam-frame-nix.git
synced 2026-10-06 01:00:13 +02:00
SteamVR screenshots linked into ~/Pictures
Steam keeps VR screenshots (Steam button + trigger) in ~/.local/share/Steam/userdata/<account ID>/760/remote/250820/screenshots, where Dolphin, Gwenview and the file pickers don't look. screenshots (module screenshots, opt-in) links ~/Pictures/<name> (default "SteamVR Screenshots") there. The account ID comes from steamUserId, or, unset, at runtime: the Home Manager link points to <runtimeDir>/steam-frame-nix/screenshots (tmpfs), which the oneshot user service steam-frame-nix-screenshots points to the account last logged in (loginusers.vdf MostRecent, else latest timestamp, else the only userdata folder), on switch, at login and when loginusers.vdf or userdata changes. install.sh cleanup knows the tmpfs link (--keep screenshots while used). Flake checks: account detection on fake Steam dirs; cleanup of the link.
This commit is contained in:
1 parent
b2babb3859
commit
26641d76a0
11 files changed
+301
-6
No files matched your search
@@ -57,6 +57,8 @@ pkgs.runCommand "cleanup-check" { nativeBuildInputs = [ cleanup pkgs.jq ]; } ''
|
||||
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
|
||||
ln -s $HOME/.local/share/Steam/userdata/1/760/remote/250820/screenshots \
|
||||
$root/run/steam-frame-nix/screenshots # steamFrame.screenshots
|
||||
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
|
||||
@@ -191,6 +193,17 @@ pkgs.runCommand "cleanup-check" { nativeBuildInputs = [ cleanup pkgs.jq ]; } ''
|
||||
exec 8<&- # Firefox closed
|
||||
res=$(steam-frame-nix-cleanup --orphans)
|
||||
gone $F/desktop/user.js
|
||||
# screenshots link: kept while used, a foreign link left alone
|
||||
mkdir -p $root/run/steam-frame-nix
|
||||
ln -s /x/userdata/1/760/remote/250820/screenshots $root/run/steam-frame-nix/screenshots
|
||||
res=$(steam-frame-nix-cleanup --orphans --keep screenshots)
|
||||
there $root/run/steam-frame-nix/screenshots
|
||||
res=$(steam-frame-nix-cleanup --orphans)
|
||||
gone $root/run/steam-frame-nix/screenshots
|
||||
ln -s /elsewhere $root/run/steam-frame-nix/screenshots
|
||||
res=$(steam-frame-nix-cleanup --orphans)
|
||||
has "$res" "left alone: $root/run/steam-frame-nix/screenshots"
|
||||
rm -r $root/run/steam-frame-nix
|
||||
! 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"
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
# ~/Pictures/<name>: a link to Steam's folder of SteamVR screenshots
|
||||
# (docs/screenshots.md). With steamUserId a plain Home Manager link; without,
|
||||
# it points to <session.runtimeDir>/steam-frame-nix/screenshots (tmpfs),
|
||||
# which steam-frame-nix-screenshots (screenshots/link.sh) points to the
|
||||
# current account's folder: on switch, at login and when loginusers.vdf or
|
||||
# userdata changes (path unit).
|
||||
{ config, lib, pkgs, ... }:
|
||||
let
|
||||
cfg = config.steamFrame.screenshots;
|
||||
session = config.steamFrame.session;
|
||||
steam = "${config.home.homeDirectory}/.local/share/Steam";
|
||||
detect = cfg.enable && cfg.steamUserId == null;
|
||||
script = import ./screenshots/package.nix { inherit lib pkgs steam; inherit (session) runtimeDir; };
|
||||
exe = lib.getExe script;
|
||||
in {
|
||||
imports = [ ./cleanup.nix ];
|
||||
|
||||
options.steamFrame.screenshots = {
|
||||
enable = lib.mkEnableOption "a link to the SteamVR screenshots in ~/Pictures";
|
||||
name = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "SteamVR Screenshots";
|
||||
description = "Name of the link in ~/Pictures.";
|
||||
};
|
||||
steamUserId = lib.mkOption {
|
||||
type = lib.types.nullOr (lib.types.strMatching "[1-9][0-9]*");
|
||||
default = null;
|
||||
example = "80511808";
|
||||
description = ''
|
||||
Steam account ID: the folder name in ~/.local/share/Steam/userdata.
|
||||
`null`: the account last logged in, found at runtime.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable (lib.mkMerge [
|
||||
{
|
||||
home.file."Pictures/${cfg.name}".source = config.lib.file.mkOutOfStoreSymlink
|
||||
(if detect then "${session.runtimeDir}/steam-frame-nix/screenshots"
|
||||
else "${steam}/userdata/${cfg.steamUserId}/760/remote/250820/screenshots");
|
||||
}
|
||||
(lib.mkIf detect {
|
||||
steamFrame.cleanup.keep = [ "screenshots" ];
|
||||
home.packages = [ script ];
|
||||
|
||||
systemd.user.services.steam-frame-nix-screenshots = {
|
||||
Unit.Description = "steam-frame-nix: link to the SteamVR screenshots of the current Steam account";
|
||||
Service = {
|
||||
Type = "oneshot";
|
||||
ExecStart = exe;
|
||||
};
|
||||
Install.WantedBy = [ "default.target" ];
|
||||
};
|
||||
systemd.user.paths.steam-frame-nix-screenshots = {
|
||||
Unit.Description = "steam-frame-nix: update the screenshots link when the Steam account changes";
|
||||
Path = {
|
||||
PathChanged = [ "${steam}/config/loginusers.vdf" "${steam}/userdata" ];
|
||||
Unit = "steam-frame-nix-screenshots.service";
|
||||
};
|
||||
Install.WantedBy = [ "default.target" ];
|
||||
};
|
||||
steamFrame.session.services.start = [ "steam-frame-nix-screenshots.path" ];
|
||||
|
||||
home.activation.steamFrameScreenshots = lib.hm.dag.entryAfter [ "linkGeneration" "steamFrameNixCleanup" ] ''
|
||||
if [[ -v DRY_RUN ]]; then
|
||||
echo "would run: ${exe}"
|
||||
else
|
||||
${exe}
|
||||
fi
|
||||
'';
|
||||
})
|
||||
]);
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
# Checks of steam-frame-nix-screenshots (link.sh) on fake Steam and runtime
|
||||
# dirs: account from loginusers.vdf (MostRecent, else latest timestamp),
|
||||
# else the only userdata folder, else no link (an old one removed); an
|
||||
# unchanged target isn't rewritten; no outer runtime dir is a no-op.
|
||||
{ pkgs }:
|
||||
let
|
||||
script = import ./package.nix {
|
||||
inherit (pkgs) lib; inherit pkgs;
|
||||
runtimeDir = "/nonexistent"; steam = "/nonexistent";
|
||||
};
|
||||
in
|
||||
pkgs.runCommand "screenshots-check" { nativeBuildInputs = [ script ]; } ''
|
||||
set -euo pipefail
|
||||
fail() { echo "FAIL: $*" >&2; exit 1; }
|
||||
export STEAM_FRAME_NIX_RUNTIME_DIR=$PWD/run STEAM_FRAME_NIX_STEAM_DIR=$PWD/steam
|
||||
S=$STEAM_FRAME_NIX_STEAM_DIR L=$STEAM_FRAME_NIX_RUNTIME_DIR/steam-frame-nix/screenshots
|
||||
target() { echo "$S/userdata/$1/760/remote/250820/screenshots"; }
|
||||
expect() { [ "$(readlink $L)" = "$(target $1)" ] || fail "$2: $(readlink $L || echo no link)"; }
|
||||
|
||||
steam-frame-nix-screenshots 2>&1 | grep -q "doesn't exist" || fail "no runtime dir"
|
||||
[ ! -e run ] || fail "runtime dir created"
|
||||
mkdir -p run $S/config $S/userdata/0 $S/userdata/80511808
|
||||
|
||||
# the only account folder ("0" is not an account)
|
||||
steam-frame-nix-screenshots; expect 80511808 "userdata"
|
||||
|
||||
# MostRecent wins over a later timestamp
|
||||
cat > $S/config/loginusers.vdf <<'VDF'
|
||||
"users"
|
||||
{
|
||||
"76561198040777536"
|
||||
{
|
||||
"AccountName" "a"
|
||||
"MostRecent" "1"
|
||||
"timestamp" "100"
|
||||
}
|
||||
"76561197960265729"
|
||||
{
|
||||
"AccountName" "b"
|
||||
"MostRecent" "0"
|
||||
"timestamp" "200"
|
||||
}
|
||||
}
|
||||
VDF
|
||||
steam-frame-nix-screenshots; expect 80511808 "MostRecent"
|
||||
# unchanged: not rewritten
|
||||
res=$(steam-frame-nix-screenshots 2>&1); [ -z "$res" ] || fail "rewrote: $res"
|
||||
|
||||
# no MostRecent (current Steam): latest timestamp
|
||||
sed -i '/MostRecent/d' $S/config/loginusers.vdf
|
||||
steam-frame-nix-screenshots; expect 1 "timestamp"
|
||||
|
||||
# nothing to go by: link removed
|
||||
rm $S/config/loginusers.vdf; mkdir $S/userdata/42
|
||||
steam-frame-nix-screenshots 2>&1 | grep -q "no Steam account" || fail "no warning"
|
||||
[ ! -L $L ] || fail "link kept"
|
||||
touch $out
|
||||
''
|
||||
@@ -0,0 +1,54 @@
|
||||
# steam-frame-nix-screenshots (the module prepends runtime, steam): points
|
||||
# <runtime>/steam-frame-nix/screenshots (tmpfs), where ~/Pictures/<name>
|
||||
# links, to the SteamVR screenshot folder of the Steam account last logged
|
||||
# in:
|
||||
# 1. the user marked MostRecent "1" in config/loginusers.vdf, else the one
|
||||
# with the latest "timestamp" (SteamID64 - 76561197960265728 = account
|
||||
# ID, the folder in userdata);
|
||||
# 2. else the only account folder in userdata;
|
||||
# 3. else no link (warning).
|
||||
# The link is replaced atomically and only when its target changes.
|
||||
link=$runtime/steam-frame-nix/screenshots
|
||||
log() { echo "steam-frame-nix-screenshots: $*" >&2; }
|
||||
|
||||
if [[ ! -d $runtime ]]; then
|
||||
log "$runtime doesn't exist (outer session not running?); skipped"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
id=''
|
||||
if [[ -f $steam/config/loginusers.vdf ]]; then
|
||||
id64=$(awk '
|
||||
{ gsub(/"/, " ") }
|
||||
$1 == "{" { depth++; next }
|
||||
$1 == "}" { depth--; next }
|
||||
depth == 1 && $1 ~ /^[0-9]+$/ && NF == 1 { user = $1; next }
|
||||
depth == 2 && tolower($1) == "mostrecent" && $2 == "1" { recent = user }
|
||||
depth == 2 && tolower($1) == "timestamp" && $2 + 0 > best { best = $2 + 0; latest = user }
|
||||
END { print recent != "" ? recent : latest }
|
||||
' "$steam/config/loginusers.vdf")
|
||||
if [[ $id64 =~ ^[0-9]{17}$ ]] && (( id64 > 76561197960265728 )); then
|
||||
id=$(( id64 - 76561197960265728 ))
|
||||
fi
|
||||
fi
|
||||
if [[ -z $id ]]; then
|
||||
dirs=()
|
||||
for d in "$steam"/userdata/*/; do
|
||||
d=${d%/}; d=${d##*/}
|
||||
[[ $d =~ ^[1-9][0-9]*$ ]] && dirs+=("$d")
|
||||
done
|
||||
(( ${#dirs[@]} == 1 )) && id=${dirs[0]}
|
||||
fi
|
||||
|
||||
if [[ -z $id ]]; then
|
||||
log "no Steam account found in $steam (log in to Steam, or set steamFrame.screenshots.steamUserId); no link"
|
||||
[[ -L $link ]] && rm -f "$link"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
target=$steam/userdata/$id/760/remote/250820/screenshots
|
||||
[[ -L $link && $(readlink "$link") == "$target" ]] && exit 0
|
||||
mkdir -p "${link%/*}"
|
||||
ln -sfn "$target" "$link.tmp.$$"
|
||||
mv -fT "$link.tmp.$$" "$link"
|
||||
log "$link -> $target"
|
||||
@@ -0,0 +1,11 @@
|
||||
# steam-frame-nix-screenshots: link.sh with the outer runtime dir and the
|
||||
# Steam directory (both overridable by environment, for the check).
|
||||
{ lib, pkgs, runtimeDir, steam }:
|
||||
pkgs.writeShellApplication {
|
||||
name = "steam-frame-nix-screenshots";
|
||||
runtimeInputs = [ pkgs.coreutils pkgs.gawk ];
|
||||
text = ''
|
||||
runtime=''${STEAM_FRAME_NIX_RUNTIME_DIR:-${lib.escapeShellArg runtimeDir}}
|
||||
steam=''${STEAM_FRAME_NIX_STEAM_DIR:-${lib.escapeShellArg steam}}
|
||||
'' + builtins.readFile ./link.sh;
|
||||
}
|
||||
Reference in new issue
Block a user