4 Commits
Author SHA1 Message Date
bod09andClaude Opus 5.5 85c733eb29 Release notes from the tag message instead of a generated commit list
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 18:53:51 +01:00
bod09andClaude Opus 5.5 9641c757ac README: install via Konsole's Paste button; drop the keyboard tip
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 23:40:33 +01:00
bod09andClaude Opus 5.5 e9be271e9f Reach the real user service manager from Desktop Mode's nested session
Konsole on the Frame runs with XDG_RUNTIME_DIR=/run/user/1000/nested_plasma
and a private D-Bus, so systemctl --user failed in the installer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 23:36:38 +01:00
bod09andClaude Opus 5.5 30d05c25d4 README: short install address and copy tip
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 23:26:11 +01:00
4 changed files with 26 additions and 6 deletions

No files matched your search

+4 -2
View File
@@ -1,4 +1,6 @@
# Build and test every push; publish a release for every v* tag. # Build and test every push; publish a release for every v* tag. The
# release notes are the annotated tag's message: write them for users
# (what changed for them), not as a commit list.
# The release package is built the same way on every push, so a tag never # The release package is built the same way on every push, so a tag never
# ships something that has not been built before. # ships something that has not been built before.
name: build name: build
@@ -32,5 +34,5 @@ jobs:
env: env:
GH_TOKEN: ${{ github.token }} GH_TOKEN: ${{ github.token }}
run: | run: |
gh release create "$GITHUB_REF_NAME" --title "$GITHUB_REF_NAME" --generate-notes \ gh release create "$GITHUB_REF_NAME" --title "$GITHUB_REF_NAME" --notes-from-tag \
dist/frame-autopass-aarch64.tar.gz dist/frame-autopass-aarch64.tar.gz.sha256 dist/install.sh dist/frame-autopass-aarch64.tar.gz dist/frame-autopass-aarch64.tar.gz.sha256 dist/install.sh
+9 -1
View File
@@ -23,12 +23,20 @@ nothing at all while passthrough is not showing.
## Install ## Install
On the headset, switch to Desktop Mode, open **Konsole** and paste: On the headset, switch to Desktop Mode, copy the command below (copy button
on the right of the box), open **Konsole** and click **Paste** at the top
right, then press Enter:
```sh ```sh
curl -fsSL https://github.com/bod09/frame-autopass/releases/latest/download/install.sh | bash curl -fsSL https://github.com/bod09/frame-autopass/releases/latest/download/install.sh | bash
``` ```
Or the short version, easier to type in VR:
```sh
curl -L bod09.github.io/frame-autopass/i | bash
```
That's it. It starts automatically whenever SteamVR runs, from now on. That's it. It starts automatically whenever SteamVR runs, from now on.
The installer checks that the Arcturus module is present, downloads the The installer checks that the Arcturus module is present, downloads the
+6
View File
@@ -21,6 +21,12 @@ fail() { printf 'frame-autopass: %s\n' "$*" >&2; exit 1; }
[ "$(uname -m)" = "aarch64" ] || fail "this is for the Steam Frame (aarch64); this machine is $(uname -m)." [ "$(uname -m)" = "aarch64" ] || fail "this is for the Steam Frame (aarch64); this machine is $(uname -m)."
command -v systemctl >/dev/null || fail "systemd not found." command -v systemctl >/dev/null || fail "systemd not found."
# Desktop Mode on the Frame runs Konsole in a nested session with its own
# XDG_RUNTIME_DIR and D-Bus, where `systemctl --user` cannot reach the real
# user service manager. Always talk to the login session's one.
export XDG_RUNTIME_DIR="/run/user/$(id -u)"
export DBUS_SESSION_BUS_ADDRESS="unix:path=$XDG_RUNTIME_DIR/bus"
if ! grep -qs arcimx616 /sys/class/video4linux/*/name; then if ! grep -qs arcimx616 /sys/class/video4linux/*/name; then
fail "the Arcturus Vision colour module was not found. frame-autopass switches between that module fail "the Arcturus Vision colour module was not found. frame-autopass switches between that module
and the built-in IR cameras, so it needs the module attached." and the built-in IR cameras, so it needs the module attached."
+7 -3
View File
@@ -54,9 +54,12 @@ std::string unit_path() {
return base + "/systemd/user/" + kUnit; return base + "/systemd/user/" + kUnit;
} }
// Runs `systemctl --user ARGS...`, returns its exit code. // Runs `systemctl --user ARGS...`, returns its exit code. Always against
// the login session's user manager: Desktop Mode on the Frame runs Konsole
// in a nested session whose XDG_RUNTIME_DIR and D-Bus cannot reach it.
int systemctl(std::initializer_list<const char*> args, bool quiet = false) { int systemctl(std::initializer_list<const char*> args, bool quiet = false) {
std::string cmd = "systemctl --user"; const std::string run = "/run/user/" + std::to_string(::getuid());
std::string cmd = "XDG_RUNTIME_DIR=" + run + " DBUS_SESSION_BUS_ADDRESS=unix:path=" + run + "/bus systemctl --user";
for (const char* a : args) cmd += std::string(" ") + a; for (const char* a : args) cmd += std::string(" ") + a;
if (quiet) cmd += " >/dev/null 2>&1"; if (quiet) cmd += " >/dev/null 2>&1";
const int rc = std::system(cmd.c_str()); const int rc = std::system(cmd.c_str());
@@ -204,7 +207,8 @@ int report() {
section(&out, "date", "date"); section(&out, "date", "date");
section(&out, "SteamOS", "grep -E '^(VERSION_ID|BUILD_ID)=' /etc/os-release"); section(&out, "SteamOS", "grep -E '^(VERSION_ID|BUILD_ID)=' /etc/os-release");
section(&out, "SteamVR", "cat /opt/steamvr/bin/version.txt; grep -m1 -E 'cv: version [0-9]' ~/.local/share/Steam/logs/vrserver.txt"); section(&out, "SteamVR", "cat /opt/steamvr/bin/version.txt; grep -m1 -E 'cv: version [0-9]' ~/.local/share/Steam/logs/vrserver.txt");
section(&out, "unit", std::string("systemctl --user status --no-pager ") + kUnit + " | head -5"); section(&out, "unit", "XDG_RUNTIME_DIR=/run/user/" + std::to_string(::getuid()) +
" systemctl --user status --no-pager " + kUnit + " | head -5");
section(&out, "status", "cat " + autopass::status_path()); section(&out, "status", "cat " + autopass::status_path());
section(&out, "config", "cat " + autopass::conf_path() + " 2>/dev/null || echo '(defaults)'"); section(&out, "config", "cat " + autopass::conf_path() + " 2>/dev/null || echo '(defaults)'");
section(&out, "crash guard", "cat " + autopass::crash_guard_path() + " 2>/dev/null || echo '(empty)'"); section(&out, "crash guard", "cat " + autopass::crash_guard_path() + " 2>/dev/null || echo '(empty)'");