Merge remote-tracking branch 'origin/main' into frame-sideload-features

This commit is contained in:
saphid committed 2026-09-26 22:01:46 +10:00
commit 84ac687399
3 files changed
+93 -16

No files matched your search

+20 -1
View File
@@ -70,6 +70,7 @@ seccomp off (below), so the patch only matters once that's fixed too.
```sh ```sh
BUILD_HOST=my-linux-box scripts/chromium-xr.sh install # your build host; scp, unpack to ~/chromium-xr BUILD_HOST=my-linux-box scripts/chromium-xr.sh install # your build host; scp, unpack to ~/chromium-xr
scripts/chromium-xr.sh launch [URL] # its own VR panel, --enable-features=OpenXR scripts/chromium-xr.sh launch [URL] # its own VR panel, --enable-features=OpenXR
scripts/chromium-xr.sh steam # adds "Chromium XR" to the Steam library
scripts/chromium-xr.sh check # prints isSessionSupported('immersive-vr') scripts/chromium-xr.sh check # prints isSessionSupported('immersive-vr')
``` ```
@@ -81,7 +82,25 @@ collide with the Flatpak's 9222. When a page enters VR, Chrome asks
**Allow VR?** in the browser panel; choose *Allow this time* or *Allow while **Allow VR?** in the browser panel; choose *Allow this time* or *Allow while
visiting the site*. visiting the site*.
**Seccomp is off.** `launch` passes `--disable-seccomp-filter-sandbox`. With Both ways of starting it run
[`frame/chromium-xr/launch.sh`](../frame/chromium-xr/launch.sh), copied to
`~/Applications/ChromiumXR/launch.sh` on the Frame, which holds Chrome's flags.
It sits outside `~/chromium-xr` so `install` doesn't delete it.
**From the Steam library (verified 2026-09-26).** `steam` adds a non-Steam
shortcut called "Chromium XR" (with the Flathub Chromium icon, if that's
installed) through the Steam client's DevTools port, the same way as T3 Code
([apks.md](apks.md)), without restarting Steam. It saves the app id in
`~/Applications/ChromiumXR/shortcut-appid`, so rerunning it, even after you
rename the shortcut in the library, doesn't add a second one. On this Frame
the shortcut app id is 2240749789. Launching it from the library gives
Chromium its own panel, `valve.steam.desktopgame.2240749789`, like any other
app. A Steam launch doesn't open a DevTools port, so `check` needs `launch`.
Chromium runs one browser per profile: while the Steam-launched one is open,
`launch` opens its URL in that window, without DevTools, then prints
`failed: ... exited` because no new window appeared. Close it first.
**Seccomp is off.** The wrapper passes `--disable-seccomp-filter-sandbox`. With
the XR seccomp policy on, SteamVR's client reads `/proc/self/status` through the XR seccomp policy on, SteamVR's client reads `/proc/self/status` through
Chrome's file broker and gets the broker's pid. SteamVR then binds the app to Chrome's file broker and gets the broker's pid. SteamVR then binds the app to
the wrong process ("Unable to init path manager: VRInitError_Init_Internal") the wrong process ("Unable to init path manager: VRInitError_Init_Internal")
+27
View File
@@ -0,0 +1,27 @@
#!/bin/bash
# Frame-side: start the WebXR Chromium build (~/chromium-xr). The Steam
# library shortcut "Chromium XR" runs this, and so does
# `scripts/chromium-xr.sh launch` (which adds a DevTools port). Extra
# arguments go to Chrome, so a URL opens that page.
#
# Lives in ~/Applications/ChromiumXR, outside ~/chromium-xr, so reinstalling
# the build doesn't delete it.
set -euo pipefail
CHROME="$HOME/chromium-xr/chrome"
[[ -x "$CHROME" ]] || { echo "launch.sh: no build at $CHROME (run chromium-xr.sh install)" >&2; exit 1; }
# Without --no-first-run and --password-store=basic, startup can stop at a
# first-run or keyring prompt.
# --disable-seccomp-filter-sandbox: under the XR seccomp policy, SteamVR's
# client reads /proc/self/status through the file broker, gets the broker's
# pid, and SteamVR binds the app to the wrong process, so xrCreateInstance
# fails. The namespace sandbox stays on, but seccomp is off for every
# process, so keep this profile for VR sites.
exec "$CHROME" \
--user-data-dir="$HOME/.config/chromium-xr" \
--enable-features=OpenXR \
--ozone-platform=x11 \
--no-first-run --no-default-browser-check --password-store=basic \
--disable-seccomp-filter-sandbox \
"$@"
+46 -15
View File
@@ -10,6 +10,7 @@
# Usage: # Usage:
# scripts/chromium-xr.sh install [TARBALL] # default: scp from $BUILD_HOST # scripts/chromium-xr.sh install [TARBALL] # default: scp from $BUILD_HOST
# scripts/chromium-xr.sh launch [URL] # opens as its own panel in the headset # scripts/chromium-xr.sh launch [URL] # opens as its own panel in the headset
# scripts/chromium-xr.sh steam # adds "Chromium XR" to the Steam library
# scripts/chromium-xr.sh check # isSessionSupported via DevTools # scripts/chromium-xr.sh check # isSessionSupported via DevTools
set -euo pipefail set -euo pipefail
@@ -17,7 +18,16 @@ FRAME_ALIAS=${FRAME_ALIAS:-frame}
BUILD_HOST=${BUILD_HOST:-} BUILD_HOST=${BUILD_HOST:-}
BUILD_TARBALL=${BUILD_TARBALL:-chromium-xr/chromium-xr-arm64.tar.xz} BUILD_TARBALL=${BUILD_TARBALL:-chromium-xr/chromium-xr-arm64.tar.xz}
DEVTOOLS_PORT=${DEVTOOLS_PORT:-9223} DEVTOOLS_PORT=${DEVTOOLS_PORT:-9223}
STEAM_NAME=${STEAM_NAME:-Chromium XR}
here=${0:A:h} here=${0:A:h}
wrapper='~/Applications/ChromiumXR/launch.sh'
# frame/chromium-xr/launch.sh holds Chrome's flags; both launch paths run it.
push_wrapper() {
# Write then rename, so a dropped connection can't leave a torn script.
ssh "$FRAME_ALIAS" 'mkdir -p ~/Applications/ChromiumXR && cd ~/Applications/ChromiumXR && cat > launch.sh.new && chmod +x launch.sh.new && mv launch.sh.new launch.sh' \
< "$here/../frame/chromium-xr/launch.sh"
}
case "${1:-}" in case "${1:-}" in
install) install)
@@ -36,23 +46,44 @@ case "${1:-}" in
;; ;;
launch) launch)
# Its own VR panel on gamescope's X display, so the Plasma desktop doesn't # Its own VR panel on gamescope's X display, so the Plasma desktop doesn't
# need to be open. The app starts in $HOME, so the profile path is relative. # need to be open. DevTools is only on for this path (for `check`).
# Without --no-first-run and --password-store=basic, startup can stop at a push_wrapper
# first-run or keyring prompt before DevTools comes up. exec "$here/panel-on-frame.sh" --name chromium-xr -- "$wrapper" \
# --disable-seccomp-filter-sandbox: under the XR seccomp policy, SteamVR's
# client reads /proc/self/status through the file broker, gets the
# broker's pid, and SteamVR binds the app to the wrong process, so
# xrCreateInstance fails. The namespace sandbox stays on, but seccomp is
# off for every process, so keep this profile for VR sites.
exec "$here/panel-on-frame.sh" --name chromium-xr -- '~/chromium-xr/chrome' \
--user-data-dir=.config/chromium-xr \
--enable-features=OpenXR \
--ozone-platform=x11 \
--no-first-run --no-default-browser-check --password-store=basic \
--disable-seccomp-filter-sandbox \
--remote-debugging-port="$DEVTOOLS_PORT" \ --remote-debugging-port="$DEVTOOLS_PORT" \
"${2:-https://immersive-web.github.io/webxr-samples/}" "${2:-https://immersive-web.github.io/webxr-samples/}"
;; ;;
steam)
# A non-Steam shortcut, added through the Steam client's DevTools port
# without restarting Steam (see docs/apks.md). Launching it from the
# library gives Chromium its own panel like any game. Safe to rerun: it
# refreshes the wrapper and only adds the shortcut if it's missing.
ssh "$FRAME_ALIAS" 'test -x ~/chromium-xr/chrome' ||
{ print -u2 "No build in ~/chromium-xr on the Frame: run 'chromium-xr.sh install' first"; exit 1; }
push_wrapper
# The app id is kept next to the wrapper, so renaming the shortcut in the
# library doesn't make a rerun add a second one.
shortcuts=$here/../frame/android/steam_shortcuts.py
home=$(ssh "$FRAME_ALIAS" 'printf %s "$HOME"')
saved=$(ssh "$FRAME_ALIAS" 'cat ~/Applications/ChromiumXR/shortcut-appid 2>/dev/null || true')
existing=$(ssh "$FRAME_ALIAS" python3 - list < "$shortcuts" |
python3 -c 'import json,sys
apps = json.load(sys.stdin)
ids = [a["appid"] for a in apps if str(a["appid"]) == sys.argv[2]] or [a["appid"] for a in apps if a["name"] == sys.argv[1]]
print(ids[0] if ids else "")' "$STEAM_NAME" "$saved")
if [[ -n "$existing" ]]; then
print -r -- "The shortcut is already in the Steam library (app id $existing)"
else
icon=''
for dir in /var/lib/flatpak '~/.local/share/flatpak'; do
candidate=$dir/exports/share/icons/hicolor/256x256/apps/org.chromium.Chromium.png
if ssh "$FRAME_ALIAS" "test -f $candidate"; then icon=${candidate/#\~/$home}; break; fi
done
existing=$(ssh "$FRAME_ALIAS" python3 - add ${(q)STEAM_NAME} ${(q)home}/Applications/ChromiumXR/launch.sh ${(q)home} ${(q)icon} < "$shortcuts")
[[ "$existing" == <-> ]] || { print -u2 -r -- "Steam didn't return a shortcut app id: $existing"; exit 1; }
print -r -- "Added $STEAM_NAME to the Steam library (shortcut app id $existing)"
fi
ssh "$FRAME_ALIAS" "printf '%s\n' $existing > ~/Applications/ChromiumXR/shortcut-appid"
;;
check) check)
# DevTools listens on the Frame's loopback only; evaluate there. # DevTools listens on the Frame's loopback only; evaluate there.
ssh "$FRAME_ALIAS" python3 - "$DEVTOOLS_PORT" <<'EOF' ssh "$FRAME_ALIAS" python3 - "$DEVTOOLS_PORT" <<'EOF'
@@ -105,5 +136,5 @@ while reply is None:
print("immersive-vr supported:", reply["result"]["result"].get("value")) print("immersive-vr supported:", reply["result"]["result"].get("value"))
EOF EOF
;; ;;
*) sed -n '2,13p' "$0"; exit 2 ;; *) sed -n '2,14p' "$0"; exit 2 ;;
esac esac