Initial FrameAssistant baseline from the vrdashboard template

Template stripped to the overlay platform (examples, demo UI and Frame
test package removed), renamed to FrameAssistant, and working rules for
the project recorded in CLAUDE.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-05 00:06:58 +02:00
co-authored by Claude Opus 5.5
commit 4a5b09053e
63 changed files with 5193 additions and 0 deletions
+71
View File
@@ -0,0 +1,71 @@
# Steam Frame
How to build, deploy and run dashboards on the Steam Frame, and what was learned on the
device. Facts below were verified on a Frame with SteamOS `holo` 0.4.3 (system Qt 6.8.0,
Adreno 750 GPU with Mesa Turnip).
## Building
Frame builds run in a Debian container (Docker or Podman), either cross-compiled on an x86_64
PC (no emulation) or natively on the Frame:
```sh
scripts/container-build.sh cross # on the PC → build/cross-arm64/stage
scripts/container-build.sh native # on the Frame itself (podman/distrobox)
scripts/container-build.sh cross-bundle # fallback variant, Qt bundled
scripts/container-build.sh cross shell # a shell in the build container
```
**System Qt (default).** Builds use SteamOS's own Qt; packages are about 3 MB.
- The container builds against Debian's Qt 6.8.2; at runtime the Frame's Qt 6.8.0 is used.
Qt keeps binary compatibility within 6.8, as long as the program uses no Qt-internal API.
- **QML is compiled to bytecode only** (`VRDASH_QML_BYTECODE_ONLY`), because Qt's QML-to-C++
compiler output is tied to the exact Qt version.
- The binary then needs only the stable Qt API, `qt_version_tag` (Qt ≥ 6.8), and Qt's Vulkan
wrapper functions. Verified with an Arch container frozen at Qt 6.8.0 and on the Frame.
- After a SteamOS update with a different Qt, rebuild, or use the bundled variant.
**Bundled Qt (fallback, `-bundle` modes, about 46 MB).**
- Qt, its plugins and QML modules, and their non-system dependencies are copied next to the
program (`cmake/BundleQt.cmake`).
- The GPU and display stack (GL/EGL, Vulkan loader, Wayland, X11, libffi, glibc) always comes
from SteamOS; bundling it would break GPU access.
- The Debian copyright files of all bundled libraries are included, as their licenses require.
## Packaging and deploying
```sh
scripts/package-release.sh # → dist/<exe>-<version>-linux-arm64/ + .tar.gz
scripts/package-release.sh --bundle-qt # → …-linux-arm64-bundled
scripts/deploy-to-frame.sh steamos@<frame> # rsync the newest package to ~/<exe>, run install.sh
```
A release folder contains the program, `install.sh` (install or update: stops a running
instance, registers with SteamVR, starts it), `uninstall.sh`, `README.txt` and the licenses.
SteamVR stores the folder's absolute path, so after moving the folder, run `install.sh`
again.
Without the deploy script: copy the `.tar.gz`, unpack it on the Frame, run `./install.sh`
(SteamVR must be running). Over SSH this works too: SteamVR starts the dashboard itself.
## What the Frame requires (all handled by the overlay platform)
| Finding | Consequence |
|---------|-------------|
| SteamVR is installed system-wide under `/opt/steamvr`; its log is `~/.local/share/Steam/logs/vrserver.txt` | Look there when a manifest or start fails |
| The manifest needs **`binary_path_linux_arm`**; entries with only `binary_path_linux` are silently skipped ("must specify binary_path") | The manifest template picks the key from the target architecture |
| SteamVR refuses **`VRApplication_Utility`** (`VRInitError_Init_NotAvailableToUtilityApps`) | Manifest commands connect as `VRApplication_Background` (needs a running SteamVR, never starts one) |
| An executable named **`vrdashboard`** is taken for SteamVR's own dashboard (its watchdog then "restarts" it) | Executable `frame-assistant`; CMake rejects SteamVR process names |
| **OpenGL runs through zink** on Vulkan (no native GL driver for the Adreno) | Vulkan is the default: 1.01 ms vs 1.89 ms per frame (`--benchmark`, 1600×1000) |
| OpenVR must shut down **before** the graphics device is destroyed | Teardown order in `DashboardApplication::runOverlay()` (else a crash at exit with Vulkan) |
| Qt needs a display connection even for off-screen rendering; over SSH none is set | SteamVR-launched instances inherit it; over SSH, set `DISPLAY=:0` |
| Process names are cut to 15 characters | Scripts find running instances by command line, not by name |
| Floated/pinned dashboard tabs stay visible and operable in games | Rendering follows the overlay's visibility, not the dashboard's |
## Notes
- **The Frame's package repositories** in `/etc/pacman.conf` are private (URLs marked
"DO_NOT_SHARE"). Don't put them into scripts or this repository.
- **Valve's public Holo Core preview container** (`registry.gitlab.steamos.cloud/holo/
holo-core-aarch64-preview/base-devel`) ships Qt 6.10, newer than the Frame's 6.8. It is not
usable for system-Qt builds.