# Steam Frame port: requirements Goal: OVRAS runs natively on the Steam Frame (SteamOS, aarch64) as a SteamVR dashboard tab. - The work happens on the internal branch `steamframe`, based on upstream's `qt6` branch (commit `2d4db7e`). - Changes may later go back upstream as pull requests. That decision is made once something runs. - **Hence: the change set against `qt6` stays minimal.** ## Background - **Proton:** The Windows build runs on the Frame through Proton. Its laser y-axis is mirrored, which makes it unusable. Running x86 code under emulation plus Wine is also inefficient. - **State of `qt6`:** Upstream's `qt6` branch (Qt 6.8, CMake) doesn't build on Linux yet. Its rendering uses QRhi, which is private Qt API (`Qt_6_PRIVATE_API`). - **Template:** The author's vrdashboard template (FrameAssistant commit `4a5b090`) is verified on the Frame. It serves as a source of knowledge and of individual, self-contained parts: render backends, build container, packaging scripts. It does not replace OVRAS's platform layer. ## Decisions | Date | Decision | |---|---| | 2026-10-07 | Internal fork, Frame only. Windows and upstream pull requests are evaluated once something runs. | | 2026-10-07 | Minimal change set against `qt6`, rather than rebuilding OVRAS on the template. | | 2026-10-07 | Only public Qt API: rendering without QRhi, QML compiled to bytecode only. | | 2026-10-07 | Manifest installation tries `Utility` first, then `Background`, on every platform. | | 2026-10-07 | Vulkan is an additional render path, selected by a command-line option. OpenGL stays the default. | | 2026-10-07 | Frame differences are switched by one build option. In the code they are capability constants, named by capability. | | 2026-10-07 | OVRAS's code style everywhere, including template code that comes in. Only changed lines get formatted. | | 2026-10-07 | Windows (render path, build) stays open until the upstream evaluation. | | 2026-10-07 | Every code change gets comments that explain it fully, but directly and concisely. | | 2026-10-07 | The app key stays `steam.overlay.1009850`; the Proton build gets uninstalled. | ## Iteration 1: native start on the Frame | # | Requirement | Acceptance criterion | |---|---|---| | R1 | Linux-only build: cross-build for aarch64 against the Frame's system Qt 6.8, plus an x86_64 build for development. Only public Qt API. | The container build succeeds. The package contains no Qt. `objdump -T` shows no `Qt_6_PRIVATE_API` symbols except `QVulkan*`. | | R2 | Runs natively on the Frame as a dashboard tab, with install, auto-start and uninstall. | After `deploy-to-frame.sh` the tab appears and starts by itself after a reboot. Quitting doesn't crash. | | R3 | Rendering: OpenGL by default, Vulkan as an additional path via a command-line option. Render only on change, capped at 60 fps. | Both paths show every page correctly. With Vulkan, `container-test.sh` reports no validation messages. | | R4 | Input: laser the right way up, scrolling, text fields via OVRAS's existing SteamVR keyboard handling. OVRAS's SteamVR Input actions work. | Every page can be operated. An OVRAS action (e.g. push-to-talk) arrives. | | R6 | Throttled tick: a fixed 11 ms timer (as in the template) instead of 1 ms polling. | Idle CPU load is measured and documented. There is no comparison with the Proton build. | | R7 | OVRAS doesn't change the play area at start-up. Today `MoveCenterTabController::zeroOffsets()` commits the working copy as the live chaperone (`CommitWorkingCopy(Live)` in `updateChaperoneResetData()`) and creates a chaperone autosave profile. On the Frame this shifts the play area at start. | After starting OVRAS on the Frame, the play area is where it was before. The log shows no `CommitWorkingCopy`. | R5 (hiding features) was moved to iteration 2; the number stays reserved. **Not in iteration 1:** - hiding or disabling features - checking features one by one - replacements for the playspace features - the template's D-pad navigation - Windows - upstream pull requests ## Iteration 2 (planned) | # | Requirement | Acceptance criterion | |---|---|---| | R5 | Hide features per the feature classification below. Features that don't work make no `IVRChaperoneSetup` zero-pose calls. | The affected pages/groups are hidden; no chaperone-setup calls appear in the log. | Then check features one by one and re-enable them. ## Feature classification (basis for R5) Native in SteamVR: according to SteamVR's release notes up to 2.17 / 2.18 beta and Valve's Steam Frame guide (researched 2026-10-07). | Group | Features | Plan | |---|---|---| | Native in SteamVR | Wall height, fade distance, style, center marker, brightness, supersampling, motion smoothing, supersample filtering, audio devices and mirror, performance graph, do not disturb, pairing, tracker battery, recenter, native chaperone import; also Oculus SDK block and restart SteamVR (Windows only), multiple drivers | Hide | | Only in OVRAS, useful on the Frame | Proximity warnings, dim when crouching, push-to-talk/-mute, mic mute when the HMD is taken off, audio and video profiles, color tint, media keys (MPRIS), alarm clock, statistics, per-game bindings | Keep; check one by one | | Doesn't work, needs a replacement | Space drag/turn, gravity, height toggle, offsets, fix floor, chaperone profiles (geometry), all rotation features | Disable for now | | Questionable | Keyboard input; cord untangling and rotation counter (the Frame is wireless) | Disable for now |