From 92e9d17e094c123afc6057b8914aa5c837430bdc Mon Sep 17 00:00:00 2001 From: Pierre Kisters <1524059+lhns@users.noreply.github.com> Date: Thu, 1 Oct 2026 17:57:31 +0200 Subject: [PATCH] Launchers: a neutral example app in docs and tests The Nix-package launcher example in docs and option examples is now Signal (pkgs.signal-desktop, desktop ID "signal", sgnl:// and signalcaptcha:// handlers). The check uses a made-up org.example.App from a fake package (fake store path), covering the same Exec, action, MimeType, source and missing-entry cases. Screenshots: placeholder Steam account IDs in the docs, option example and check. --- docs/launchers.md | 10 +++---- docs/screenshots.md | 2 +- modules/launchers.nix | 12 ++++---- modules/launchers/check.nix | 28 +++++++++---------- .../expected/com.anthropic.Claude.desktop | 26 ----------------- .../fixtures/expected/org.example.App.desktop | 26 +++++++++++++++++ .../sources/com.anthropic.Claude.desktop | 25 ----------------- .../fixtures/sources/org.example.App.desktop | 25 +++++++++++++++++ modules/launchers/lib.nix | 2 +- modules/screenshots.nix | 2 +- modules/screenshots/check.nix | 8 +++--- 11 files changed, 83 insertions(+), 83 deletions(-) delete mode 100644 modules/launchers/fixtures/expected/com.anthropic.Claude.desktop create mode 100644 modules/launchers/fixtures/expected/org.example.App.desktop delete mode 100644 modules/launchers/fixtures/sources/com.anthropic.Claude.desktop create mode 100644 modules/launchers/fixtures/sources/org.example.App.desktop diff --git a/docs/launchers.md b/docs/launchers.md index d7812da..85a8d9c 100644 --- a/docs/launchers.md +++ b/docs/launchers.md @@ -27,7 +27,7 @@ the Frame's [two sessions](../README.md#two-sessions): reads through the Secret Service `org.freedesktop.secrets` (KRDC: "Password not found"). - **Login callbacks:** SSO logins come back through a URL scheme - (`io.element.desktop://`, `claude://`) opened by the portal. Unless the app + (`io.element.desktop://`, `signalcaptcha://`) opened by the portal. Unless the app is the default and a recommended handler, the portal opens an app chooser, which isn't shown in VR. @@ -80,11 +80,11 @@ A program from a Nix package, from the package's own entry ```nix { pkgs, ... }: { - home.packages = [ pkgs.claude-desktop ]; - steamFrame.launchers."com.anthropic.Claude" = { - source.package = pkgs.claude-desktop; + home.packages = [ pkgs.signal-desktop ]; + steamFrame.launchers.signal = { + source.package = pkgs.signal-desktop; keyring = { enable = true; electron = true; }; - defaultFor = [ "x-scheme-handler/claude" ]; # login callback + defaultFor = [ "x-scheme-handler/sgnl" "x-scheme-handler/signalcaptcha" ]; }; } ``` diff --git a/docs/screenshots.md b/docs/screenshots.md index 00f70cf..b080a80 100644 --- a/docs/screenshots.md +++ b/docs/screenshots.md @@ -25,7 +25,7 @@ in `…/760/screenshots.vdf`). The JPG is the only copy that stays. ```nix steamFrame.screenshots.enable = true; -# steamFrame.screenshots.steamUserId = "80511808"; # optional +# steamFrame.screenshots.steamUserId = "12345678"; # optional ``` The account ID is found at runtime: the account last logged in to Steam diff --git a/modules/launchers.nix b/modules/launchers.nix index 7792265..1bef6e8 100644 --- a/modules/launchers.nix +++ b/modules/launchers.nix @@ -41,10 +41,10 @@ let keyring = { enable = true; electron = true; }; defaultFor = [ "x-scheme-handler/element" "x-scheme-handler/io.element.desktop" ]; }; - steamFrame.launchers."com.anthropic.Claude" = { - source.package = pkgs.claude-desktop; + steamFrame.launchers.signal = { + source.package = pkgs.signal-desktop; keyring = { enable = true; electron = true; }; - defaultFor = [ "x-scheme-handler/claude" ]; + defaultFor = [ "x-scheme-handler/sgnl" ]; }; (schemeHandlers = [ "x" ] -> defaultFor = [ "x-scheme-handler/x" ]; flatpakArgs, args, mimeTypes, settings keep their meaning; name, icon, @@ -63,10 +63,10 @@ in { defaultFor = [ "x-scheme-handler/element" "x-scheme-handler/io.element.desktop" ]; }; "org.kde.krdc".keyring.enable = true; - "com.anthropic.Claude" = { - source.package = pkgs.claude-desktop; + signal = { + source.package = pkgs.signal-desktop; keyring = { enable = true; electron = true; }; - defaultFor = [ "x-scheme-handler/claude" ]; + defaultFor = [ "x-scheme-handler/sgnl" ]; }; } ''; diff --git a/modules/launchers/check.nix b/modules/launchers/check.nix index 51d8a93..a1387ce 100644 --- a/modules/launchers/check.nix +++ b/modules/launchers/check.nix @@ -1,8 +1,8 @@ # Checks of steamFrame.launchers (lib.nix, rewrite.awk, generate.sh) on # copies of real entries (fixtures/sources: Element, KRDC, Firefox, gedit # (DBusActivatable) from /var/lib/flatpak, Jellyfin from the user -# installation, Claude from the claude-desktop package) and two made-up ones -# (quoting, an Exec without anchor): +# installation) and three made-up ones (quoting, an Exec without anchor, an +# Electron app from a fake package): # - the rewritten entries equal fixtures/expected (X-SteamFrameNix-Source # compared separately) and pass desktop-file-validate; # - the generator: unchanged sources change nothing (mtimes kept, no touch of @@ -19,9 +19,9 @@ let src = ./fixtures/sources; shim = "/nix/store/00000000000000000000000000000000-mpv-hwdec-shim"; - fakeClaude = pkgs.runCommand "claude-desktop-fixture" { } '' + fakeApp = pkgs.runCommand "example-app-fixture" { } '' mkdir -p $out/share/applications - cp ${src}/com.anthropic.Claude.desktop $out/share/applications/ + cp ${src}/org.example.App.desktop $out/share/applications/ ''; noEntry = pkgs.runCommand "no-entry-fixture" { } "mkdir -p $out/share/applications"; @@ -58,10 +58,10 @@ let args = [ "a b" "50%" "q\"uote" "$HOME" "back\\slash" "back`tick" "" ]; settings.Keywords = "x;"; }; - "com.anthropic.Claude" = { - source.package = fakeClaude; + "org.example.App" = { + source.package = fakeApp; keyring = { enable = true; electron = true; }; - defaultFor = [ "x-scheme-handler/claude" ]; + defaultFor = [ "x-scheme-handler/example" ]; }; }; } ]; @@ -81,14 +81,14 @@ let applicationsDir = "/nonexistent"; exportDirs = [ "/nonexistent" ]; }; - claude = L.packageEntry all."com.anthropic.Claude"; - missing = pkgs.testers.testBuildFailure (L.packageEntry (all."com.anthropic.Claude" // { - source = all."com.anthropic.Claude".source // { package = noEntry; }; + app = L.packageEntry all."org.example.App"; + missing = pkgs.testers.testBuildFailure (L.packageEntry (all."org.example.App" // { + source = all."org.example.App".source // { package = noEntry; }; })); in pkgs.runCommand "launchers-check" { nativeBuildInputs = [ generator pkgs.desktop-file-utils pkgs.diffutils ]; - passthru = { inherit generator claude; }; + passthru = { inherit generator app; }; } '' set -euo pipefail fail() { echo "FAIL: $*" >&2; exit 1; } @@ -127,12 +127,12 @@ pkgs.runCommand "launchers-check" { [ $id = org.example.NoAnchor ] && continue cp $out_dir/$id.desktop $out/actual/ done - cp ${claude} $out/actual/com.anthropic.Claude.desktop + cp ${app} $out/actual/org.example.App.desktop grep -qx "X-SteamFrameNix-Source=$root/user/org.jellyfin.JellyfinDesktop.desktop" $out/actual/org.jellyfin.JellyfinDesktop.desktop \ || fail "Jellyfin not from the user installation" grep -qx "X-SteamFrameNix-Source=$root/system/org.kde.krdc.desktop" $out/actual/org.kde.krdc.desktop || fail "KRDC source" grep -qx "X-SteamFrameNix-Source=${src}/org.example.Quoting.desktop" $out/actual/org.example.Quoting.desktop || fail "file source" - grep -qx "X-SteamFrameNix-Source=${fakeClaude}/share/applications/com.anthropic.Claude.desktop" $out/actual/com.anthropic.Claude.desktop || fail "package source" + grep -qx "X-SteamFrameNix-Source=${fakeApp}/share/applications/org.example.App.desktop" $out/actual/org.example.App.desktop || fail "package source" sed -i 's|^X-SteamFrameNix-Source=.*|X-SteamFrameNix-Source=@SOURCE@|' $out/actual/*.desktop desktop-file-validate --no-hints $out/actual/*.desktop || fail "desktop-file-validate" for f in ${./fixtures/expected}/*.desktop; do @@ -185,7 +185,7 @@ pkgs.runCommand "launchers-check" { [ "$(mt $root/apps)" != 1000000000 ] || fail "removal didn't touch the applications dir" # a package without the entry: the build fails - [ -e ${missing}/testBuildFailure.log ] && grep -q "has no share/applications/com.anthropic.Claude.desktop" ${missing}/testBuildFailure.log \ + [ -e ${missing}/testBuildFailure.log ] && grep -q "has no share/applications/org.example.App.desktop" ${missing}/testBuildFailure.log \ || fail "package without the entry built" echo ok '' diff --git a/modules/launchers/fixtures/expected/com.anthropic.Claude.desktop b/modules/launchers/fixtures/expected/com.anthropic.Claude.desktop deleted file mode 100644 index 022d8c4..0000000 --- a/modules/launchers/fixtures/expected/com.anthropic.Claude.desktop +++ /dev/null @@ -1,26 +0,0 @@ -[Desktop Entry] -Name=Claude -Comment=Desktop application for Claude.ai -GenericName=AI Assistant -Keywords=AI;Chat;Assistant;Claude;Code;LLM; -Exec=env DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus /nix/store/8cc1cplpbdlsqy4x0v1c9w66w3dq80w4-claude-desktop-2.7032.0/bin/claude-desktop --password-store=kwallet6 %U -Icon=claude-desktop -Type=Application -StartupNotify=true -# Matches the Wayland app_id / X11 WM_CLASS Chromium derives from -# package.json desktopName, so docks group windows under this entry. -StartupWMClass=com.anthropic.Claude -# second-instance just focuses mainWindow; suppress GNOME's default "New Window" item -SingleMainWindow=true -Categories=Utility;Development; -MimeType=x-scheme-handler/claude; -Actions=NewChat;NewCode; -X-SteamFrameNix-Source=@SOURCE@ - -[Desktop Action NewChat] -Name=New Chat -Exec=env DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus /nix/store/8cc1cplpbdlsqy4x0v1c9w66w3dq80w4-claude-desktop-2.7032.0/bin/claude-desktop --password-store=kwallet6 "claude://claude.ai/new?surface=chat&source=desktop_action" - -[Desktop Action NewCode] -Name=New Claude Code Session -Exec=env DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus /nix/store/8cc1cplpbdlsqy4x0v1c9w66w3dq80w4-claude-desktop-2.7032.0/bin/claude-desktop --password-store=kwallet6 "claude://code/new?source=desktop_action" diff --git a/modules/launchers/fixtures/expected/org.example.App.desktop b/modules/launchers/fixtures/expected/org.example.App.desktop new file mode 100644 index 0000000..411b5ae --- /dev/null +++ b/modules/launchers/fixtures/expected/org.example.App.desktop @@ -0,0 +1,26 @@ +[Desktop Entry] +Name=Example App +Comment=A made-up Electron app from a Nix package +GenericName=Example +Keywords=Example;Test; +Exec=env DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus /nix/store/00000000000000000000000000000000-example-app-1.0/bin/example-app --password-store=kwallet6 %U +Icon=example-app +Type=Application +StartupNotify=true +# Matches the Wayland app_id / X11 WM_CLASS Electron derives from +# package.json desktopName, so docks group windows under this entry. +StartupWMClass=org.example.App +# second-instance just focuses the main window +SingleMainWindow=true +Categories=Utility;Development; +MimeType=x-scheme-handler/example; +Actions=NewWindow;NewSession; +X-SteamFrameNix-Source=@SOURCE@ + +[Desktop Action NewWindow] +Name=New Window +Exec=env DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus /nix/store/00000000000000000000000000000000-example-app-1.0/bin/example-app --password-store=kwallet6 "example://app/new?surface=window&source=desktop_action" + +[Desktop Action NewSession] +Name=New Example Session +Exec=env DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus /nix/store/00000000000000000000000000000000-example-app-1.0/bin/example-app --password-store=kwallet6 "example://session/new?source=desktop_action" diff --git a/modules/launchers/fixtures/sources/com.anthropic.Claude.desktop b/modules/launchers/fixtures/sources/com.anthropic.Claude.desktop deleted file mode 100644 index 5cc5dfb..0000000 --- a/modules/launchers/fixtures/sources/com.anthropic.Claude.desktop +++ /dev/null @@ -1,25 +0,0 @@ -[Desktop Entry] -Name=Claude -Comment=Desktop application for Claude.ai -GenericName=AI Assistant -Keywords=AI;Chat;Assistant;Claude;Code;LLM; -Exec=/nix/store/8cc1cplpbdlsqy4x0v1c9w66w3dq80w4-claude-desktop-2.7032.0/bin/claude-desktop %U -Icon=claude-desktop -Type=Application -StartupNotify=true -# Matches the Wayland app_id / X11 WM_CLASS Chromium derives from -# package.json desktopName, so docks group windows under this entry. -StartupWMClass=com.anthropic.Claude -# second-instance just focuses mainWindow; suppress GNOME's default "New Window" item -SingleMainWindow=true -Categories=Utility;Development; -MimeType=x-scheme-handler/claude; -Actions=NewChat;NewCode; - -[Desktop Action NewChat] -Name=New Chat -Exec=/nix/store/8cc1cplpbdlsqy4x0v1c9w66w3dq80w4-claude-desktop-2.7032.0/bin/claude-desktop "claude://claude.ai/new?surface=chat&source=desktop_action" - -[Desktop Action NewCode] -Name=New Claude Code Session -Exec=/nix/store/8cc1cplpbdlsqy4x0v1c9w66w3dq80w4-claude-desktop-2.7032.0/bin/claude-desktop "claude://code/new?source=desktop_action" diff --git a/modules/launchers/fixtures/sources/org.example.App.desktop b/modules/launchers/fixtures/sources/org.example.App.desktop new file mode 100644 index 0000000..47456d5 --- /dev/null +++ b/modules/launchers/fixtures/sources/org.example.App.desktop @@ -0,0 +1,25 @@ +[Desktop Entry] +Name=Example App +Comment=A made-up Electron app from a Nix package +GenericName=Example +Keywords=Example;Test; +Exec=/nix/store/00000000000000000000000000000000-example-app-1.0/bin/example-app %U +Icon=example-app +Type=Application +StartupNotify=true +# Matches the Wayland app_id / X11 WM_CLASS Electron derives from +# package.json desktopName, so docks group windows under this entry. +StartupWMClass=org.example.App +# second-instance just focuses the main window +SingleMainWindow=true +Categories=Utility;Development; +MimeType=x-scheme-handler/example; +Actions=NewWindow;NewSession; + +[Desktop Action NewWindow] +Name=New Window +Exec=/nix/store/00000000000000000000000000000000-example-app-1.0/bin/example-app "example://app/new?surface=window&source=desktop_action" + +[Desktop Action NewSession] +Name=New Example Session +Exec=/nix/store/00000000000000000000000000000000-example-app-1.0/bin/example-app "example://session/new?source=desktop_action" diff --git a/modules/launchers/lib.nix b/modules/launchers/lib.nix index 991121e..6735f9a 100644 --- a/modules/launchers/lib.nix +++ b/modules/launchers/lib.nix @@ -45,7 +45,7 @@ in rec { package = lib.mkOption { type = lib.types.nullOr lib.types.package; default = null; - example = lib.literalExpression "pkgs.claude-desktop"; + example = lib.literalExpression "pkgs.signal-desktop"; description = '' Nix package whose `share/applications/.desktop` is rewritten at build time (the build fails if it has none). diff --git a/modules/screenshots.nix b/modules/screenshots.nix index ecff34c..06657c3 100644 --- a/modules/screenshots.nix +++ b/modules/screenshots.nix @@ -25,7 +25,7 @@ in { steamUserId = lib.mkOption { type = lib.types.nullOr (lib.types.strMatching "[1-9][0-9]*"); default = null; - example = "80511808"; + example = "12345678"; description = '' Steam account ID: the folder name in ~/.local/share/Steam/userdata. `null`: the account last logged in, found at runtime. diff --git a/modules/screenshots/check.nix b/modules/screenshots/check.nix index e24a550..a8038a6 100644 --- a/modules/screenshots/check.nix +++ b/modules/screenshots/check.nix @@ -19,16 +19,16 @@ pkgs.runCommand "screenshots-check" { nativeBuildInputs = [ script ]; } '' 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 + mkdir -p run $S/config $S/userdata/0 $S/userdata/12345678 # the only account folder ("0" is not an account) - steam-frame-nix-screenshots; expect 80511808 "userdata" + steam-frame-nix-screenshots; expect 12345678 "userdata" # MostRecent wins over a later timestamp cat > $S/config/loginusers.vdf <<'VDF' "users" { - "76561198040777536" + "76561197972611406" { "AccountName" "a" "MostRecent" "1" @@ -42,7 +42,7 @@ pkgs.runCommand "screenshots-check" { nativeBuildInputs = [ script ]; } '' } } VDF - steam-frame-nix-screenshots; expect 80511808 "MostRecent" + steam-frame-nix-screenshots; expect 12345678 "MostRecent" # unchanged: not rewritten res=$(steam-frame-nix-screenshots 2>&1); [ -z "$res" ] || fail "rewrote: $res"