···11<!-- SPDX-License-Identifier: CC-BY-SA-4.0 -->
22<!-- Copyright (c) 2025 Shiloh Fen <shiloh@shilohfen.com> -->
3344-AtomicXR (axr)
55-==============
44+# AtomicXR #
55+XR for Universal Blue and Fedora Atomic Desktops.
6677-Install and manage XR applications on Fedora Atomic Desktops.
77+This repo contains the AtomicXR core libraries and CLI. Other AtomicXR repos can be found below:
88+- [AtomicXR Homebrew Tap](https://codeberg.org/shiloh/homebrew-atomicxr): XR packaging for Fedora Atomic.
8999-Developed and tested on [Bluefin](https://projectbluefin.io/), but should work with:
1010+AtomicXR is developed and tested on [Bluefin](https://projectbluefin.io/), but should work with:
1011- [Bazzite](https://bazzite.gg/)
1112- [Fedora Silverblue](https://fedoraproject.org/atomic-desktops/silverblue/)
1213- Other Fedora Atomic-based distros
13141414-## Installing
1515+## Install ##
1616+Homebrew (reccomeneded): `brew tap shiloh/atomicxr https://codeberg.org/shiloh/homebrew-atomicxr.git; brew install atomic-xr`
15171618> NOTE: Developed with Nushell version `0.106.0`. Lower versions are not guaranteed to work.
17191818-Using the install script:
1919-- bash: `bash <(curl -s https://codeberg.org/shiloh/atomic-xr/raw/branch/main/install.sh)`
2020-- nu: `nu -c (http get https://codeberg.org/shiloh/atomic-xr/raw/branch/main/install.nu)`
2121-2222-From this repo:
2323-1. Install Nushell (for example with Homebrew: `brew install nushell`)
2424-2. `nu -c "use src/atomic-xr ; atomic-xr self install --local"`
2525-2626-## Usage
2020+From this repo: `./install.sh`
27212222+## Usage ##
2823> NOTE: If you plan to use the SteamVR Lighthouse driver with:
2924> - Flatpak Steam
3025> - WiVRn without a lighthouse-tracked headset (for example if you want to use lighthouse body trackers, but don't own a lighthouse headset)
3126>
3232-> ..you'll have to calibrate using AtomicXR instead of Envision: `axr calibrate steamvr-lh`
2727+> ..you can calibrate using AtomicXR instead of Envision: `axr steamvr-lh calibrate`
33283429CLI:
3535-- Configure: `axr icfg`
3636-- Apply configuration & update applications: `axr apply`
3737-- Update AtomicXR: `axr self update`
3030+- Install Envision: `axr envision install`
3131+- Update Envision: `axr envision upgrade`
3232+- Set up Steam Flatpak XR: `axr flatpak steam enable-xr`
3333+- Launch [OSC Avatar Manager](https://github.com/galister/oscavmgr): `axr oscavmgr start [babble | openxr | alvr]` (use `openxr` for WiVRn)
3834- List avaliable CLI functions: `axr -l`
39354036Building Envision profiles:
···4455if ! nu -v $>/dev/null; then
66 brew install nushell \
77- || echo -e "\e[35mFailed to install Nushell using Homebrew. Please install Nushell or Homebrew and re-run this script.\e[0m"
77+ || echo -e "\e[35mFailed to install Nushell using Homebrew. Please install Nushell or Homebrew, then re-run this script.\e[0m"
88fi
991010if nu -v $>/dev/null; then
1111- nu -c "$(curl -s https://codeberg.org/shiloh/atomic-xr/raw/branch/main/install.nu)"
1111+ nu ./install.nu
1212fi
···11-# SPDX-License-Identifier: AGPL-3.0-only
22-# Copyright (c) 2025 Shiloh Fen <shiloh@shilohfen.com>
33-44-use std log
55-use common.nu *
66-use applications.nu *
77-use sysconfig.nu
88-99-const self: path = $data_path | path join "self"
1010-const meta_path = $data_path | path join "metadata.nuon"
1111-1212-# Install or update AtomicXR
1313-#
1414-# This command can only be safely used if the same module version that's loaded is the one being installed, which is never the case with `axr`
1515-export def "self install" [
1616- --local (-l) # Install from local repo (make sure you cd to root of the repo you want to install from)
1717- --update (-u)
1818-] {
1919- migrate
2020-2121- mkdir $data_path
2222-2323- if not $local {
2424- if not ($self | path exists) {
2525- git clone https://codeberg.org/shiloh/atomic-xr.git ($data_path | path join self)
2626- }
2727- cd $self
2828- git pull
2929- }
3030-3131- log debug $"Installing from `(pwd)`"
3232-3333- if not $update {
3434- try {toolbox create atomic-xr --distro fedora --release 42}
3535- toolbox run --container atomic-xr sudo dnf install -y nu
3636- }
3737-3838- log debug $"AXR_MODULE_PATH: ($env.AXR_MODULE_PATH)"
3939-4040- mkdir ~/.local/bin
4141- mkdir ($env.AXR_MODULE_PATH | path dirname)
4242-4343- try {brew tap shiloh/atomicxr https://codeberg.org/shiloh/homebrew-atomicxr.git}
4444- try {rm -r $env.AXR_MODULE_PATH o+e> /dev/null}
4545- cp -r src/atomic-xr $env.AXR_MODULE_PATH
4646- cp -f src/axr.nu ~/.local/bin/axr
4747- chmod 744 ~/.local/bin/axr
4848- cp -f src/oscavmgr-launch.sh ~/.local/bin/oscavmgr-launch
4949- chmod 744 ~/.local/bin/oscavmgr-launch
5050-5151- write-version $version
5252-}
5353-5454-# Update AtomicXR
5555-export def "self update" [
5656- --local (-l) # Install from local repo (make sure you cd to root of the repo you want to install from)
5757-] {
5858- mkdir $data_path
5959-6060- if not $local {
6161- if not ($self | path exists) {
6262- git clone https://codeberg.org/shiloh/atomic-xr.git ($data_path | path join self)
6363- }
6464- cd $self
6565- git pull
6666- }
6767-6868- # This is nessesary to install any new files and do migrations from the new version
6969- # It runs the new version's `self install` instead of this version's
7070- # It always uses --local, so the repo is not pulled an extra time.
7171- nu -c $"use src/atomic-xr ; atomic-xr self install --update --local"
7272-}
7373-7474-# Uninstall AtomicXR
7575-export def "self uninstall" [] {
7676- log info "Removing manually installed applicaions"
7777- uninstall envision
7878-7979- log info "Disabling system configurations"
8080- sysconfig disable envision-plugins
8181- sysconfig disable steam-flaptak-symlink
8282- sysconfig disable steam-flatpak-permissions
8383-8484- log info "Removing AtomicXR container"
8585- toolbox rm -f atomic-xr
8686-8787- log info "Uninstalling AtomicXR"
8888- rm -r $env.AXR_MODULE_PATH
8989- rm ~/.local/bin/oscavmgr-launch
9090- rm ~/.local/bin/axr
9191- rm -r ~/.local/share/atomic-xr
9292-}
9393-9494-# Migrate version 1 to 2
9595-def "migrate 1" [] {
9696- # Application exporting and installation was overhauled in this version
9797- log info "Removing outdated container"
9898- toolbox rm -f atomic-xr
9999- log info "Uninstalling previously installed applications (don't worry, you can reinstall them later)"
100100- rm -f ~/.local/bin/motoc ~/.local/bin/oscavmgr ~/.local/bin/wayvr-dashboard ~/.local/bin/wlx-overlay-s ~/.local/bin/envision ~/.local/share/applications/org.gabmus.envision.Devel.desktop ~/.local/share/applications/org.gabmus.envision.Devel.desktop ~/.local/share/bin/envision
101101-}
102102-103103-def "migrate 2" [] {
104104- # steam-flatpak-envision and steam-flatpak-wivrn were merged into steam-flatpak-permissions
105105- if not ($config_path | path exists) {
106106- log warning "Config file not found, migration not attempted"
107107- return
108108- }
109109-110110- let config = open $config_path
111111-112112- let sysconfigs = if "steam-flaptak-envision" in $config.sysconfigs or "steam-flatpak-wivrn" in $config.sysconfigs {
113113- $config.sysconfigs
114114- | where $it != "steam-flaptak-envision" and $it != "steam-flatpak-wivrn"
115115- | prepend "steam-flaptak-permissions"
116116- } else {
117117- $config.sysconfigs
118118- }
119119-120120- $config
121121- | merge {sysconfigs: $sysconfigs}
122122- | save -f $config_path
123123-}
124124-125125-def "migrate 3" [] {
126126- # there was a bug in `icfg` that still set these values. after that was fixed, this migration had to be run again for some people that used it
127127- migrate 2
128128-}
129129-130130-def "migrate 4" [] {
131131- # Switched to Homebrew for wlx-overlay-s, wayvr-dashboard, oscavmgr, vrcadvert, motoc, and openxr loader
132132- log info "Removing manually installed applications: wlx-overlay-s, wayvr-dashboard, oscavmgr, vrcadvert, and motoc"
133133- rm -f ~/.local/bin/wlx-overlay-s ~/.local/bin/wayvr-dashboard ~/.local/bin/motoc ~/.local/bin/oscavmgr ~/.local/bin/VrcAdvert
134134- [
135135- "wlx-overlay-s"
136136- "wayvr-dashboard"
137137- "motoc"
138138- "oscavmgr"
139139- "vrcadvert"
140140- ]
141141- | par-each {|e|
142142- let repo = $data_path | path join repos $e
143143- rm -rf $repo
144144- }
145145-146146- log warning "Please run `axr apply` to apply the new configuration!"
147147-}
148148-149149-# Migrate from installed version to current version
150150-def migrate [] {
151151- log info "Checking for migrations"
152152-153153- if not ($data_path | path exists) {
154154- log info "AtomicXR is not installed, no migrations neessesary."
155155- return
156156- }
157157-158158- let installed_version = if ($meta_path | path exists) {
159159- open $meta_path | get version
160160- } else {
161161- log warning "No metadata file found, assuming fresh install. No migrations attempted."
162162- return
163163- }
164164-165165- if $installed_version == $version {
166166- log info "No migrations neessesary."
167167- return
168168- }
169169-170170- $installed_version..($version - 1) | each {|e|
171171- log info $"Starting migration: ($e) -> ($e + 1)"
172172- match $e {
173173- 1 => (migrate 1)
174174- 2 => (migrate 2)
175175- 3 => (migrate 3)
176176- 4 => (migrate 4)
177177- _ => (error make {
178178- msg: $"Attempted to migrate from an unknown version: ($e)."
179179- help: "Please report this issue at: https://codeberg.org/shiloh/atomic-xr/issues"
180180- })
181181- }
182182- write-version ($e + 1)
183183- log info $"Finished migration: ($e) -> ($e + 1)"
184184- }
185185-}
186186-187187-def write-version [version: int] {
188188- if ($meta_path | path exists) {
189189- open $meta_path
190190- | merge {version: $version}
191191- | collect
192192- | save -f $meta_path
193193- } else {
194194- {version: $version}
195195- | save $meta_path
196196- }
197197-}
+74
src/atomic-xr/steamvr-lh.nu
···11+# SPDX-License-Identifier: AGPL-3.0-only
22+# Copyright (c) 2025 Shiloh Fen <shiloh@shilohfen.com>
33+44+use std log
55+66+def "ask yn" [prompt: string] {
77+ loop {
88+ match (input -n 1 $"($prompt) [y/n]: " | str downcase) {
99+ "y" => (return true)
1010+ "n" => (return false)
1111+ _ => (log error "Invalid option, please choose `y` or `n`.")
1212+ }
1313+ }
1414+}
1515+1616+# SteamVR Quick Calibration
1717+export def calibrate [] {
1818+ # TODO: Support using native steam installation
1919+ log warning "This is intended for Flatpak Steam, if you're using native Steam, please use Envision instead."
2020+ log warning "If you'd like to see native Steam functionality in AtomicXR, please open an issue on Codeberg."
2121+2222+ if (ask yn "Do you own a lighthouse-tracked HMD? (e.g. Index, Vive Pro)") {
2323+ input -sn 1 "Please connect your headset and place it on the floor, then press any key to start the calibration."
2424+2525+ log info "Starting SteamVR Lighthouse calibration"
2626+2727+ let vrcmd_bin: path = $"($env.HOME)/.steam/root/steamapps/common/SteamVR/bin/linux64/vrcmd"
2828+ let environment = $"LD_LIBRARY_PATH=('~/.var/app/com.valvesoftware.Steam/.steam/root/steamapps/common/SteamVR/bin/linux64' | path expand)"
2929+3030+ let server = job spawn {flatpak run --command=$"($vrcmd_bin)" --env=$"($environment)" com.valvesoftware.Steam --pollposes}
3131+ sleep 2sec # TODO: detect when the server is ready
3232+ try {
3333+ flatpak run --command=$"($vrcmd_bin)" --env=$"($environment)" com.valvesoftware.Steam --resetroomsetup
3434+ } catch {|err|
3535+ job kill $server
3636+ error make $err
3737+ }
3838+3939+ job kill $server
4040+ log info "Calibration finished"
4141+ } else {
4242+ log info "Creating default Lighthouse Database"
4343+4444+ if not ("~/.steam/root/config/lighthouse/" | path exists) {
4545+ error make {
4646+ msg: "Could not find lighthouse configuration directory."
4747+ help: "Make sure you have SteamVR installed, and .steam points to the correct location. You may need to select \"Symlink .steam directory\" in `axr icfg` if you're using the Steam Flatpak."
4848+ }
4949+ }
5050+5151+ {
5252+ base_stations: []
5353+ known_objects: []
5454+ known_universes: []
5555+ revision: 1
5656+ }
5757+ | save -f ~/.steam/root/config/lighthouse/lighthousedb.json
5858+5959+ log info "Created default Lighthouse Database"
6060+ }
6161+}
6262+6363+# Open SteamVR's lighthouse_console
6464+#
6565+# Useful for pairing, dumping device configs, etc.
6666+export def console [
6767+ ...args # Arguments to pass to lighthouse_console
6868+] {
6969+ # TODO: Support using native steam installation
7070+ log warning "This is intended for Flatpak Steam, if you're using native Steam, please use Envision instead."
7171+ log warning "If you'd like to see this functionality in AtomicXR, please open an issue on Codeberg."
7272+7373+ flatpak run --command=$"($env.HOME)/.steam/root/steamapps/common/SteamVR/tools/lighthouse/bin/linux64/lighthouse_console" com.valvesoftware.Steam ...$args
7474+}