mirror of
https://github.com/saphid/chromium-webxr-steam-frame.git
synced 2026-10-06 05:02:49 +02:00
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
207 lines
9.1 KiB
Markdown
207 lines
9.1 KiB
Markdown
# Chromium with WebXR for the Steam Frame
|
|
|
|
A build recipe and installer for **Chromium with immersive WebXR on Valve's
|
|
Steam Frame** headset. Press the
|
|
**Enter VR** button on a WebXR site and it opens in the headset, through
|
|
SteamVR, as a full VR experience.
|
|
|
|
The Chromium that SteamOS offers (Flathub) can't do this. Websites see
|
|
`navigator.xr`, but `isSessionSupported("immersive-vr")` returns `false`, so
|
|
VR buttons are greyed out or missing. Upstream Chromium only wires up its
|
|
OpenXR backend on Windows and Android. This repo builds Chromium with the
|
|
in-progress Linux OpenXR changes, adds a small fix so it works with SteamVR,
|
|
and installs it on the Frame as a normal app in your Steam library.
|
|
|
|
## What you can do with it
|
|
|
|
The web has a lot of VR content that only needs a browser:
|
|
|
|
- **360° and 3D video.** Travel, nature, concerts, sports and documentaries
|
|
from players that support WebXR, shown around you instead of in a flat
|
|
window.
|
|
- **Games and toys.** WebXR games and experiments made with
|
|
[three.js](https://threejs.org/examples/?q=webxr),
|
|
[A-Frame](https://aframe.io/) or [Babylon.js](https://www.babylonjs.com/),
|
|
with nothing to install.
|
|
- **Learning.** Virtual museum tours, space and anatomy explorers, and other
|
|
educational experiences built for the web.
|
|
- **Art and music.** Painting, sculpting and music toys that run in a page.
|
|
- **Building WebXR sites.** Test your own WebXR app on real headset hardware
|
|
from a normal URL, with Chromium's DevTools.
|
|
|
|
## Status
|
|
|
|
Tested on a Steam Frame (SteamOS 0.3.0, build 20260922.6101926,
|
|
SteamVR 2.17.10) with Chromium **156.0.8071.0**, built for arm64:
|
|
|
|
| | |
|
|
|---|---|
|
|
| `isSessionSupported("immersive-vr")` | `true` |
|
|
| [WebXR Samples](https://immersive-web.github.io/webxr-samples/) Immersive VR Session | shows its scene in the headset |
|
|
| three.js [stereo 360 video](https://threejs.org/examples/webxr_vr_video.html) | plays in 3D |
|
|
| Launch from the Steam library | opens as its own panel, like any app; WebXR renders in the headset |
|
|
| Controller and hand input inside WebXR pages | not tested yet |
|
|
| Frame rate | not measured (looks smooth) |
|
|
|
|
This is an unofficial, experimental build. See [Limitations](#limitations)
|
|
before you use it for anything other than VR sites.
|
|
|
|
## Requirements
|
|
|
|
- A Steam Frame with SteamVR, and a way to run commands on it: the terminal
|
|
in Desktop Mode, or SSH.
|
|
- To build: an **x86-64 Linux machine** with about **90 GB free disk**, git,
|
|
Python 3, tmux (or another way to keep a long job running) and a few
|
|
hours. No root access is needed. The first build took about 9.5 hours on
|
|
a 6-core, 12-thread desktop CPU; rebuilds take minutes.
|
|
|
|
## Build
|
|
|
|
On the Linux build machine:
|
|
|
|
```sh
|
|
git clone https://github.com/saphid/chromium-webxr-steam-frame
|
|
cd chromium-webxr-steam-frame
|
|
mkdir -p ~/chromium-xr
|
|
tmux new -d -s chromium-xr 'build/build.sh > ~/chromium-xr/build.log 2>&1'
|
|
```
|
|
|
|
`build.sh` fetches Chromium with the Linux OpenXR changes, applies the patch
|
|
in [`patches/`](patches), cross-compiles for arm64 and packs the result into
|
|
`~/chromium-xr/chromium-xr-arm64.tar.xz` (about 145 MB).
|
|
|
|
- Follow progress with `tail -F ~/chromium-xr/stage` (milestones) or
|
|
`tail -F ~/chromium-xr/build.log` (everything).
|
|
- If it stops (reboot, full disk, network), run the same command again. It
|
|
picks up where it left off.
|
|
- To build on another disk, set `CHROMIUM_XR_DIR` and use that directory
|
|
in place of `~/chromium-xr` in the commands above, including the log path.
|
|
- It stops itself if free disk space drops below 12 GB.
|
|
|
|
## Install on the Frame
|
|
|
|
Copy the tarball and this repo to the Frame, then run the installer there.
|
|
For example, over SSH from the build machine (replace `steamframe` with your
|
|
Frame's hostname or IP address):
|
|
|
|
```sh
|
|
scp ~/chromium-xr/chromium-xr-arm64.tar.xz steamos@steamframe:
|
|
ssh steamos@steamframe
|
|
git clone https://github.com/saphid/chromium-webxr-steam-frame
|
|
chromium-webxr-steam-frame/frame/install.sh ~/chromium-xr-arm64.tar.xz
|
|
```
|
|
|
|
The installer:
|
|
|
|
- unpacks the build into `~/chromium-xr`, after checking the new binary runs;
|
|
- installs the `chromium-xr` launcher in `~/.local/bin`;
|
|
- adds **Chromium XR** to the Desktop Mode app menu;
|
|
- adds **Chromium XR** to your Steam library, without restarting Steam.
|
|
|
|
Run it again with a newer tarball to update. Your profile
|
|
(`~/.config/chromium-xr`) and the Steam shortcut are kept. You can delete
|
|
the repo clone afterwards; the installer keeps what it needs to uninstall.
|
|
|
|
If the Steam shortcut can't be added automatically, add it by hand: in
|
|
Desktop Mode, open Steam, choose **Games → Add a Non-Steam Game to My
|
|
Library**, and pick Chromium XR.
|
|
|
|
## Use it
|
|
|
|
1. Open **Chromium XR** from your Steam library. It appears as a panel in
|
|
the headset.
|
|
2. Go to a WebXR site, for example the
|
|
[WebXR Samples](https://immersive-web.github.io/webxr-samples/).
|
|
3. Press the site's **Enter VR** button.
|
|
4. Chromium asks **Allow VR?** in the browser panel. Choose *Allow this time*
|
|
or *Allow while visiting the site*.
|
|
5. To leave VR, use the site's exit button or the Steam button.
|
|
|
|
The first time you launch it, Steam may show an **External Controller
|
|
Translation** notice. It's only information about controller button icons;
|
|
choose OK.
|
|
|
|
From a terminal on the Frame, `chromium-xr https://example.com` opens a
|
|
page directly.
|
|
|
|
## Limitations
|
|
|
|
- **Part of the sandbox is off.** The launcher passes
|
|
`--disable-seccomp-filter-sandbox`, which turns off Chrome's system-call
|
|
filter for every process; the namespace sandbox stays on. Without it,
|
|
SteamVR refuses the session (details in
|
|
[docs/technical-notes.md](docs/technical-notes.md)). Use Chromium XR for VR
|
|
sites and keep another browser for everyday browsing.
|
|
- **Saved passwords aren't encrypted.** The launcher uses
|
|
`--password-store=basic` so startup doesn't stop at a keyring prompt, so
|
|
passwords you save are stored unencrypted in `~/.config/chromium-xr`.
|
|
- **No automatic updates.** It won't get Chromium security fixes until you
|
|
rebuild it.
|
|
- **No DRM video.** There's no Widevine, so paid streaming services that
|
|
need it won't play.
|
|
- **One window at a time per profile.** If Chromium XR is already open,
|
|
launching it again opens the page in the existing window.
|
|
- **Not a default browser.** It works as one (the desktop entry registers
|
|
for web links), but for the reasons above it's better kept for VR.
|
|
|
|
## Remove it
|
|
|
|
```sh
|
|
~/.local/share/chromium-xr/uninstall.sh # keeps your profile
|
|
~/.local/share/chromium-xr/uninstall.sh --remove-profile # also deletes settings and logins
|
|
```
|
|
|
|
This removes the build, the launcher, the menu entry and the Steam shortcut.
|
|
|
|
## Updating
|
|
|
|
The Chromium changes are still under review upstream, so this repo pins one
|
|
revision of them (`CL_REF` in [`build/build.sh`](build/build.sh), currently
|
|
patch set 44 of CL 8132979). To build a newer patch set, set `CL_REF` when
|
|
you run the build, for example
|
|
`CL_REF=refs/changes/79/8132979/45 build/build.sh`. The script fetches it,
|
|
syncs, re-applies the local patch and rebuilds. A newer patch set may need
|
|
the patch in [`patches/`](patches) updated. Then install the new tarball on
|
|
the Frame as above.
|
|
|
|
## How it works
|
|
|
|
- **Chromium changes.** [CL 8441736](https://chromium-review.googlesource.com/c/chromium/src/+/8441736)
|
|
(a sandboxed XR process on Linux) and
|
|
[CL 8132979](https://chromium-review.googlesource.com/c/chromium/src/+/8132979)
|
|
(the OpenXR device provider on Linux, patch set 44), tracked in Chromium
|
|
[issue 506004811](https://issues.chromium.org/issues/506004811). CL 8441736
|
|
has since merged; CL 8132979 is still in review. The OpenXR device is behind
|
|
`--enable-features=OpenXR`, which the launcher passes.
|
|
- **SteamVR fix.** SteamVR's OpenXR runtime asks the kernel who is on the
|
|
other end of its socket (`getsockopt(SO_PEERCRED)`). The XR sandbox policy
|
|
blocks all `getsockopt` calls, which crashed the XR process.
|
|
[`patches/0001-…`](patches/0001-xr-sandbox-allow-getsockopt-SO_PEERCRED.patch)
|
|
allows only that one option. It's reported upstream, with the seccomp
|
|
issue below, in
|
|
[utzcoz/chromium-webxr-linux#7](https://github.com/utzcoz/chromium-webxr-linux/issues/7).
|
|
- **Steam integration.** `frame/steam-shortcut.py` adds the shortcut through
|
|
the Steam client's local DevTools port, the same API the Steam UI uses.
|
|
Steam runs each app as its own panel, so Chromium gets one too.
|
|
|
|
More detail, including why the seccomp filter is off, is in
|
|
[docs/technical-notes.md](docs/technical-notes.md).
|
|
|
|
## Related work
|
|
|
|
- [utzcoz/chromium-webxr-linux](https://github.com/utzcoz/chromium-webxr-linux):
|
|
a fuller patch series for WebXR over OpenXR on Linux desktops, including
|
|
the in-headset permission UI and crash fixes, tested with
|
|
[Monado](https://monado.dev/). If you're on an x86-64 Linux PC rather than
|
|
the Steam Frame, start there.
|
|
- [Chromium issue 506004811](https://issues.chromium.org/issues/506004811):
|
|
upstream tracking for WebXR on Linux.
|
|
|
|
## License
|
|
|
|
The scripts in this repo are under the [BSD 3-Clause License](LICENSE). The
|
|
patch in [`patches/`](patches) modifies Chromium and is under
|
|
[Chromium's license](https://chromium.googlesource.com/chromium/src/+/main/LICENSE).
|
|
Chromium is a trademark of Google LLC; this project is not affiliated with
|
|
Google or Valve.
|