-38
install.nu
-38
install.nu
···
1
-
#!/usr/bin/env nu
2
-
# SPDX-License-Identifier: AGPL-3.0-only
3
-
# Copyright (c) 2025 Shiloh Fen <shiloh@shilohfen.com>
4
-
5
-
use std log
6
-
7
-
const self: path = path self .
8
-
9
-
def main [
10
-
prefix: string = "~/.local"
11
-
--install-library (-l)
12
-
--force (-f) # Overwrite existing files
13
-
] {
14
-
let prefix = $prefix | path expand
15
-
log debug $"Install prefix: ($prefix)"
16
-
let lib_dir = $prefix | path join "share" "atomic-xr" "lib"
17
-
let axr = open ($self | path join 'src' 'axr.nu.in') --raw
18
-
| str replace -a "/@AXR_LIB@/" $"use ($lib_dir)/atomic-xr"
19
-
let bin = $prefix | path join "bin" "axr"
20
-
21
-
if $force {
22
-
rm -rf ($lib_dir | path join "atomic-xr")
23
-
rm -f $bin
24
-
}
25
-
26
-
mkdir $lib_dir
27
-
cp -r ($self | path join 'src' 'atomic-xr') $lib_dir
28
-
if $install_library {
29
-
if $force {rm -f ($NU_LIB_DIRS | first | path join "atomic-xr")}
30
-
ln -s ($lib_dir | path join "atomic-xr") ($NU_LIB_DIRS | first)
31
-
}
32
-
33
-
mkdir ($bin | path dirname)
34
-
$axr | save $bin
35
-
chmod +x $bin
36
-
37
-
log info "AtomicXR CLI has been installed, use `axr -l` for a list of commands."
38
-
}
-12
install.sh
-12
install.sh
···
1
-
#!/usr/bin/bash
2
-
# SPDX-License-Identifier: AGPL-3.0-only
3
-
# Copyright (c) 2025 Shiloh Fen <shiloh@shilohfen.com>
4
-
5
-
if ! nu -v $>/dev/null; then
6
-
brew install nushell \
7
-
|| echo -e "\e[35mFailed to install Nushell using Homebrew. Please install Nushell or Homebrew, then re-run this script.\e[0m"
8
-
fi
9
-
10
-
if nu -v $>/dev/null; then
11
-
nu ./install.nu
12
-
fi
-119
src/atomic-xr/_debug.nu
-119
src/atomic-xr/_debug.nu
···
1
-
# SPDX-License-Identifier: AGPL-3.0-only
2
-
# Copyright (c) 2025 Shiloh Fen <shiloh@shilohfen.com>
3
-
4
-
use std log
5
-
6
-
export def main [
7
-
output?: path
8
-
--base64 # Output base64 instead of creating a file
9
-
--full (-f) # Include extra debug information
10
-
] {
11
-
let output = $output | default (mktemp -t --suffix .msgpackz) | path expand
12
-
13
-
log info "Gathering debug information"
14
-
15
-
let flatpak_installed = flatpak list --columns application | lines
16
-
let sys = if $full {
17
-
{
18
-
host: (sys host | reject hostname)
19
-
cpu: (sys cpu)
20
-
mem: (sys mem)
21
-
temp: (sys temp)
22
-
disks: (sys disks)
23
-
}
24
-
} else {
25
-
{
26
-
host: (sys host | reject hostname)
27
-
}
28
-
}
29
-
30
-
{
31
-
debug_version: "1.0.0"
32
-
sys: $sys
33
-
brew: {
34
-
installed: (which brew | is-not-empty)
35
-
doctor: (try {brew doctor o+e>| $in})
36
-
atomicxr_installed: (try {
37
-
brew list --full-name
38
-
| find -n matrixfurry.com/atomicxr/
39
-
| each {|| brew info --json $in | from json}
40
-
| flatten
41
-
})
42
-
}
43
-
distrobox: {
44
-
installed: (which distrobox | is-not-empty)
45
-
}
46
-
envision: {
47
-
container: (try {
48
-
distrobox ls --no-color
49
-
| parse -r '(?P<id>.*)\s\|\s(?P<name>.*)\s\|\s(?P<status>.*)\s\|\s(?P<image>.*)'
50
-
| str trim
51
-
| skip 1
52
-
| where name == envision
53
-
})
54
-
paths_exist: {
55
-
bin: ("~/.local/bin/envision" | path exists)
56
-
devel_desktop: ("~/.local/share/applications/org.gabmus.envision.Devel.desktop" | path exists)
57
-
desktop: ("~/.local/share/applications/org.gabmus.envision.desktop" | path exists)
58
-
localshare_bin: ("~/.local/share/bin/envision" | path exists)
59
-
config: ("~/.config/envision/envision.json" | path exists)
60
-
}
61
-
config: (try {open ~/.config/envision/envision.json})
62
-
}
63
-
paths_exist: {
64
-
local: {
65
-
_self: ("~/.local" | path exists)
66
-
share: {
67
-
_self: ("~/.local/share" | path exists)
68
-
applications: ("~/.local/share/applications" | path exists)
69
-
}
70
-
bin: ("~/.local/bin" | path exists)
71
-
}
72
-
}
73
-
steam: {
74
-
paths: {
75
-
dotsteam: (try {ls -lD ~/.steam})
76
-
localshare: (try {ls -lD ~/.local/share/Steam})
77
-
flatpak: ("~/.var/app/com.valvesoftware.Steam" | path exists)
78
-
}
79
-
}
80
-
rpm-ostree: {
81
-
requested: (rpm-ostree status --json | from json | get deployments | first | get requested-packages)
82
-
}
83
-
flatpak: {
84
-
installed: {
85
-
steam: ($flatpak_installed has "com.valvesoftware.Steam")
86
-
gaiasky: ($flatpak_installed has "space.gaiasky.GaiaSky")
87
-
}
88
-
}
89
-
}
90
-
| to msgpackz
91
-
| if $base64 {
92
-
print (ansi cyan)
93
-
$in | encode base64 | print
94
-
print (ansi reset)
95
-
} else {
96
-
save -f $output
97
-
log info $"Successfully created debug file. It has been saved to ($output)"
98
-
}
99
-
100
-
if $base64 {
101
-
log info $"If you'd like to check what info that contains, use `axr '_debug decode --base64 {base64}'`"
102
-
} else {
103
-
log info $"If you'd like to check what info it contains, use `axr _debug decode ($output)`"
104
-
}
105
-
}
106
-
107
-
export def decode [
108
-
input # Base64 or file to decode
109
-
--base64
110
-
--explore (-e) # Explore output
111
-
] {
112
-
if $base64 {
113
-
$input | decode base64
114
-
} else {
115
-
open $input
116
-
}
117
-
| from msgpackz
118
-
| if $explore {explore} else {$in}
119
-
}
-35
src/atomic-xr/_migrate.nu
-35
src/atomic-xr/_migrate.nu
···
1
-
# SPDX-License-Identifier: AGPL-3.0-only
2
-
# Copyright (c) 2025 Shiloh Fen <shiloh@shilohfen.com>
3
-
4
-
use std log
5
-
use envision.nu
6
-
7
-
# Migrate from version 1.x.x to 2.x.x
8
-
export def "v1" [] {
9
-
log info "Starting migration: 1.x.x -> 2.x.x"
10
-
11
-
log info "Updating Envision config"
12
-
do {
13
-
const envision_config_path = "~/.config/envision/envision.json" | path expand
14
-
15
-
let envision_config = try {open $envision_config_path} catch {
16
-
log info "Envision config not found, no config migration nessesary"
17
-
return
18
-
}
19
-
let plugins = $envision_config.plugins
20
-
| reject -o ...("cc.dwagon.atomic-xr.{wlx-overlay-s,motoc,oscavmgr.project-babble,oscavmgr.wivrn}" | str expand)
21
-
22
-
$envision_config
23
-
| merge {plugins: $plugins}
24
-
| save -f $envision_config_path
25
-
log info "Envision plugins unregistered successfully"
26
-
}
27
-
28
-
if ("~/.local/bin/envision" | path exists) {
29
-
envision upgrade
30
-
} else {
31
-
log info "Envision is not installed, no upgrade nessesary"
32
-
}
33
-
34
-
log info "Migration completed: 1.x.x -> 2.x.x"
35
-
}
-12
src/atomic-xr/bin/oscavmgr-launch.sh
-12
src/atomic-xr/bin/oscavmgr-launch.sh
···
1
-
#!/usr/bin/env bash
2
-
# SPDX-License-Identifier: AGPL-3.0-only
3
-
# Copyright (c) 2025 Shiloh Fen <shiloh@shilohfen.com>
4
-
#
5
-
# Portions of this file are derived from OscAvMgr, which is licensed under the MIT License
6
-
# Copyright (c) 2023 galister
7
-
8
-
trap 'jobs -p | xargs kill' EXIT
9
-
10
-
VrcAdvert OscAvMgr 9402 9002 --tracking &
11
-
12
-
oscavmgr "${@}"
-118
src/atomic-xr/envision.nu
-118
src/atomic-xr/envision.nu
···
1
-
# SPDX-License-Identifier: AGPL-3.0-only
2
-
# Copyright (c) 2025 Shiloh Fen <shiloh@shilohfen.com>
3
-
4
-
const repo = "~/.local/share/atomic-xr/envision" | path expand
5
-
const envision_config_path = "~/.config/envision/envision.json" | path expand
6
-
7
-
const self = path self .
8
-
9
-
use std log
10
-
use runtime.nu
11
-
12
-
export def install [
13
-
--no-monado (-m) # Don't install runtime deps for Monado
14
-
] {
15
-
runtime install xr (if not $no_monado {"monado"})
16
-
17
-
distrobox create envision --no-entry -Y -i registry.fedoraproject.org/fedora-toolbox:42
18
-
distrobox enter envision -- sudo dnf install -y nu
19
-
upgrade
20
-
log info "Successfully installed Envision"
21
-
}
22
-
23
-
export def uninstall [] {
24
-
try {distrobox rm -f envision}
25
-
log info "Removing files"
26
-
rm -f ~/.local/bin/envision ~/.local/share/applications/org.gabmus.envision.Devel.desktop ~/.local/share/applications/org.gabmus.envision.desktop ~/.local/share/bin/envision
27
-
log info "Successfully uninstalled Envision"
28
-
}
29
-
30
-
export def upgrade [] {
31
-
distrobox upgrade envision
32
-
33
-
mkdir ($repo | path dirname)
34
-
if ($repo | path exists) {
35
-
cd $repo
36
-
git reset --hard # Reset patches
37
-
git switch main
38
-
git pull
39
-
} else {
40
-
git clone "https://gitlab.com/gabmus/envision.git" $repo
41
-
cd $repo
42
-
}
43
-
git switch --detach (git tag -l --sort=v:refname | lines | last)
44
-
45
-
let patches = $self | path join patches envision
46
-
47
-
ls $patches
48
-
| get name
49
-
| each {|patch|
50
-
git apply $patch
51
-
}
52
-
53
-
{
54
-
if (rpm -q rpmfusion-free-release | complete | get exit_code) != 0 {
55
-
sudo dnf install -y https://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-(rpm -E %fedora).noarch.rpm
56
-
sudo dnf swap -y ffmpeg-free ffmpeg --allowerasing
57
-
}
58
-
59
-
sudo dnf builddep -y envision
60
-
61
-
# TODO: Only install dependencies required for the requested profiles
62
-
[
63
-
# WiVRn
64
-
envision-wivrn
65
-
avahi-devel
66
-
avahi-glib-devel
67
-
cli11-devel
68
-
glslang-devel
69
-
glslc
70
-
gstreamer1-plugins-base-devel
71
-
gstreamer1-devel
72
-
ffmpeg-devel
73
-
libnotify-devel
74
-
libva-devel
75
-
json-devel
76
-
x264-devel
77
-
pipewire-devel
78
-
cmake
79
-
gcc-c++
80
-
clang19-devel
81
-
openxr-devel
82
-
android-tools
83
-
librsvg2-devel
84
-
libarchive-devel
85
-
86
-
# Monado
87
-
envision-monado
88
-
cmake
89
-
gcc-c++
90
-
glslang-devel
91
-
glslc
92
-
libbsd-devel
93
-
libusb1
94
-
libusb1-devel
95
-
SDL2-devel
96
-
wayland-protocols-devel
97
-
openxr-devel
98
-
99
-
# WMR
100
-
fmt-devel
101
-
fmt-devel
102
-
git-lfs
103
-
glew-devel
104
-
glew-devel
105
-
gtest-devel
106
-
jq
107
-
lz4-devel
108
-
tbb-devel
109
-
] | sudo dnf install -y ...$in
110
-
111
-
meson setup build -Dprefix=($env.HOME)/.local --reconfigure
112
-
ninja -C build
113
-
ninja -C build install
114
-
}
115
-
| distrobox enter envision -- nu -c $"do (view source $in)"
116
-
117
-
log info "Successfully upgraded Envision"
118
-
}
-91
src/atomic-xr/flatpak.nu
-91
src/atomic-xr/flatpak.nu
···
1
-
# SPDX-License-Identifier: AGPL-3.0-only
2
-
# Copyright (c) 2025 Shiloh Fen <shiloh@shilohfen.com>
3
-
4
-
use std log
5
-
6
-
const xr_permissions = {
7
-
filesystem: [
8
-
"xdg-data/envision:ro"
9
-
"xdg-run/monado_comp_ipc"
10
-
"/var/lib/flatpak/app/io.github.wivrn.wivrn:ro"
11
-
"~/.var/app/io.github.wivrn.wivrn:ro"
12
-
"xdg-run/wivrn"
13
-
"xdg-config/openxr:ro"
14
-
"xdg-config/openvr:ro"
15
-
]
16
-
}
17
-
18
-
def "permissions allow" [appid: string] {
19
-
flatpak override --user ...(
20
-
$"--filesystem={($xr_permissions.filesystem | str join ',')}" | str expand
21
-
) $appid
22
-
}
23
-
24
-
def "permissions revoke" [appid: string] {
25
-
flatpak override --user ...(
26
-
$"--nofilesystem={($xr_permissions.filesystem | str replace -r ':.*' '' | str join ',')}" | str expand
27
-
) $appid
28
-
}
29
-
30
-
export module steam {
31
-
# Enable XR support for Steam Flatpak
32
-
export def enable-xr [] {
33
-
permissions allow com.valvesoftware.Steam
34
-
35
-
if not ("~/.steam" | path exists) {
36
-
ln -s ~/.var/app/com.valvesoftware.Steam/.steam ~/
37
-
log debug "Symlinked Steam Flatpak's .steam directory to ~/.steam."
38
-
} else if (ls -lD ~/.steam).0.target != ("~/.var/app/com.valvesoftware.Steam/.steam/" | path expand) {
39
-
error make {
40
-
msg: "Could not link Steam Flatpak's .steam directory to ~/.steam."
41
-
help: "Back up or remove your existing ~/.steam directory, then run this command again."
42
-
}
43
-
}
44
-
45
-
log info "Successfully set up Steam Flatpak XR."
46
-
}
47
-
48
-
# Disable XR support for Steam Flatpak
49
-
export def disable-xr [] {
50
-
permissions revoke com.valvesoftware.Steam
51
-
52
-
if not ("~/.steam" | path exists) {
53
-
log debug "~/.steam does not exist."
54
-
} else if (ls -lD ~/.steam).0.target == ("~/.var/app/com.valvesoftware.Steam/.steam/" | path expand) {
55
-
rm ~/.steam
56
-
if ("~/.steam.bak-axr" | path exists) {
57
-
mv ~/.steam.bak-axr ~/.steam
58
-
}
59
-
}
60
-
61
-
log info "Successfully reset Steam Flatpak XR."
62
-
}
63
-
}
64
-
65
-
export module gaiasky {
66
-
# Enable VR mode for Gaia Sky
67
-
export def enable-vr [] {
68
-
permissions allow space.gaiasky.GaiaSky
69
-
[
70
-
(open /var/lib/flatpak/app/space.gaiasky.GaiaSky/current/active/export/share/applications/space.gaiasky.GaiaSky.desktop
71
-
| str replace "Exec=/usr/bin/flatpak run --branch=stable --arch=x86_64 --command=gaiasky space.gaiasky.GaiaSky" "Exec=/usr/bin/flatpak run --branch=stable --arch=x86_64 --command=gaiasky space.gaiasky.GaiaSky -vr")
72
-
"Actions=DesktopMode;"
73
-
""
74
-
"[Desktop Action DesktopMode]"
75
-
"Exec=/usr/bin/flatpak run --branch=stable --arch=x86_64 --command=gaiasky space.gaiasky.GaiaSky"
76
-
"Name=Launch in Desktop Mode"
77
-
]
78
-
| str join "\n"
79
-
| save -f ~/.local/share/applications/space.gaiasky.GaiaSky.desktop
80
-
81
-
log info "Successfully enabled Gaia Sky's VR mode."
82
-
}
83
-
84
-
# Disable VR mode for Gaia Sky
85
-
export def disable-vr [] {
86
-
permissions revoke space.gaiasky.GaiaSky
87
-
rm -f ~/.local/share/applications/space.gaiasky.GaiaSky.desktop
88
-
89
-
log info "Successfully disabled Gaia Sky's VR mode."
90
-
}
91
-
}
-12
src/atomic-xr/homebrew.nu
-12
src/atomic-xr/homebrew.nu
···
1
-
# SPDX-License-Identifier: AGPL-3.0-only
2
-
# Copyright (c) 2025 Shiloh Fen <shiloh@shilohfen.com>
3
-
4
-
# Tap AtomicXR Homebrew
5
-
export def tap [] {
6
-
brew tap matrixfurry.com/atomicxr https://tangled.sh/@matrixfurry.com/homebrew-atomicxr
7
-
}
8
-
9
-
# Untap AtomicXR Homebrew
10
-
export def untap [] {
11
-
brew untap shiloh/atomicxr
12
-
}
-12
src/atomic-xr/mod.nu
-12
src/atomic-xr/mod.nu
···
1
-
# SPDX-License-Identifier: AGPL-3.0-only
2
-
# Copyright (c) 2025 Shiloh Fen <shiloh@shilohfen.com>
3
-
4
-
export use _debug.nu
5
-
export use _migrate.nu
6
-
export use envision.nu
7
-
export use flatpak.nu
8
-
export use homebrew.nu
9
-
export use oscavmgr.nu
10
-
export use runtime.nu
11
-
export use steamvr-lh.nu
12
-
export use wayvr.nu
-18
src/atomic-xr/oscavmgr.nu
-18
src/atomic-xr/oscavmgr.nu
···
1
-
# SPDX-License-Identifier: AGPL-3.0-only
2
-
# Copyright (c) 2025 Shiloh Fen <shiloh@shilohfen.com>
3
-
4
-
const self = path self .
5
-
6
-
# Start OSC Avatar Manager and advertise it using VrcAdvert
7
-
export def start [
8
-
module: string # babble, openxr (WiVRn), alvr
9
-
] {
10
-
if (which oscavmgr | length) == 0 or (which VrcAdvert | length) == 0 {
11
-
error make -u {
12
-
msg: "OscAvMgr and VrcAdvert are not installed"
13
-
help: "Use `brew install oscavmgr vrc-advert` to install them"
14
-
}
15
-
}
16
-
17
-
exec ($self | path join 'bin' 'oscavmgr-launch.sh') $module
18
-
}
-25
src/atomic-xr/patches/envision/0001-Add-build-mode-to-desktop-entry.patch
-25
src/atomic-xr/patches/envision/0001-Add-build-mode-to-desktop-entry.patch
···
1
-
From d2359c7ad267214a1bc63775c5d95a5a09cd19cb Mon Sep 17 00:00:00 2001
2
-
From: "@matrixfurry.com" <did:plc:zmjoeu3stwcn44647rhxa44o>
3
-
Date: Fri, 5 Sep 2025 13:38:33 -0500
4
-
Subject: [PATCH 1/4] Add build mode to desktop entry
5
-
6
-
---
7
-
data/org.gabmus.envision.desktop.in.in | 5 +++++
8
-
1 file changed, 5 insertions(+)
9
-
10
-
diff --git a/data/org.gabmus.envision.desktop.in.in b/data/org.gabmus.envision.desktop.in.in
11
-
index 31ac287..394ff19 100644
12
-
--- a/data/org.gabmus.envision.desktop.in.in
13
-
+++ b/data/org.gabmus.envision.desktop.in.in
14
-
@@ -12,3 +12,8 @@ Keywords=vr;virtual;reality;monado;
15
-
Icon=@APP_ID@
16
-
StartupNotify=true
17
-
X-GNOME-UsesNotifications=true
18
-
+Actions=BuildMode;
19
-
+
20
-
+[Desktop Action BuildMode]
21
-
+Exec=distrobox enter envision -- @CMD_NAME@
22
-
+Name=Launch in Build Mode
23
-
--
24
-
2.51.0
25
-
-35
src/atomic-xr/patches/envision/0002-Replace-plugin-manifests.patch
-35
src/atomic-xr/patches/envision/0002-Replace-plugin-manifests.patch
···
1
-
From 7e56cd4c602069392be88e2ecd87dff6bf993f60 Mon Sep 17 00:00:00 2001
2
-
From: "@matrixfurry.com" <did:plc:zmjoeu3stwcn44647rhxa44o>
3
-
Date: Fri, 5 Sep 2025 13:45:50 -0500
4
-
Subject: [PATCH 2/4] Replace plugin manifests
5
-
6
-
---
7
-
src/ui/plugins/mod.rs | 12 ++++++++----
8
-
1 file changed, 8 insertions(+), 4 deletions(-)
9
-
10
-
diff --git a/src/ui/plugins/mod.rs b/src/ui/plugins/mod.rs
11
-
index cb18440..c4902fe 100644
12
-
--- a/src/ui/plugins/mod.rs
13
-
+++ b/src/ui/plugins/mod.rs
14
-
@@ -163,10 +163,14 @@ impl Plugin {
15
-
16
-
/// urls to manifest json files representing plugins.
17
-
/// each manifest should be json and the link should always point to the latest version
18
-
-const MANIFESTS: [&str;3] = [
19
-
- "https://github.com/galister/wlx-overlay-s/raw/refs/heads/meta/com.github.galister.wlx-overlay-s.json",
20
-
- "https://github.com/StardustXR/telescope/raw/refs/heads/main/envision/org.stardustxr.telescope.json",
21
-
- "https://github.com/olekolek1000/wayvr-dashboard/raw/refs/heads/meta/dev.oo8.wayvr_dashboard.json",
22
-
+const MANIFESTS: [&str;7] = [
23
-
+ "https://tangled.org/matrixfurry.com/atomic-xr/raw/main/data/envision-plugins/manifest/wlx-overlay-s.json",
24
-
+ "https://tangled.org/matrixfurry.com/atomic-xr/raw/main/data/envision-plugins/manifest/wayvr-dashboard.json",
25
-
+ "https://tangled.org/matrixfurry.com/atomic-xr/raw/main/data/envision-plugins/manifest/lovr-playspace.json",
26
-
+ "https://tangled.org/matrixfurry.com/atomic-xr/raw/main/data/envision-plugins/manifest/motoc.json",
27
-
+ "https://tangled.org/matrixfurry.com/atomic-xr/raw/main/data/envision-plugins/manifest/oscavmgr.openxr.json",
28
-
+ "https://tangled.org/matrixfurry.com/atomic-xr/raw/main/data/envision-plugins/manifest/oscavmgr.babble.json",
29
-
+ "https://tangled.org/matrixfurry.com/atomic-xr/raw/main/data/envision-plugins/manifest/index-camera-passthrough.json",
30
-
];
31
-
32
-
pub async fn refresh_plugins() -> anyhow::Result<Vec<anyhow::Result<Plugin>>> {
33
-
--
34
-
2.51.0
35
-
-31
src/atomic-xr/patches/envision/0003-Modify-plugin-download-error-message.patch
-31
src/atomic-xr/patches/envision/0003-Modify-plugin-download-error-message.patch
···
1
-
From e8f9266d41e4e9275b5031c63a017255749fefb1 Mon Sep 17 00:00:00 2001
2
-
From: "@matrixfurry.com" <did:plc:zmjoeu3stwcn44647rhxa44o>
3
-
Date: Fri, 5 Sep 2025 23:07:27 -0500
4
-
Subject: [PATCH 3/4] Modify plugin download error message
5
-
6
-
---
7
-
src/ui/plugins/store.rs | 8 ++------
8
-
1 file changed, 2 insertions(+), 6 deletions(-)
9
-
10
-
diff --git a/src/ui/plugins/store.rs b/src/ui/plugins/store.rs
11
-
index 0faf99a..17d1534 100644
12
-
--- a/src/ui/plugins/store.rs
13
-
+++ b/src/ui/plugins/store.rs
14
-
@@ -357,12 +357,8 @@ impl AsyncComponent for PluginStore {
15
-
None => {
16
-
alert(
17
-
"Download failed",
18
-
- Some(&format!(
19
-
- "Downloading {} {} failed:\n\nNo executable url provided for this plugin, this is likely a bug!",
20
-
- plugin.name,
21
-
- plugin.version.as_ref().unwrap_or(&"(no version)".to_string()))
22
-
- ),
23
-
- Some(&self.win.as_ref().unwrap().clone().upcast::<gtk::Window>())
24
-
+ Some("Please use Homebrew to install plugins."),
25
-
+ Some(&self.win.as_ref().unwrap().clone().upcast::<gtk::Window>()),
26
-
);
27
-
}
28
-
};
29
-
--
30
-
2.51.0
31
-
-27
src/atomic-xr/patches/envision/0004-Add-plugin-to-config-when-enabled.patch
-27
src/atomic-xr/patches/envision/0004-Add-plugin-to-config-when-enabled.patch
···
1
-
From 39e8a8787ef0b0bb69c8754a880bb6bc4b2fe707 Mon Sep 17 00:00:00 2001
2
-
From: "@matrixfurry.com" <did:plc:zmjoeu3stwcn44647rhxa44o>
3
-
Date: Sat, 6 Sep 2025 01:13:52 -0500
4
-
Subject: [PATCH 4/4] Add plugin to config when enabled
5
-
6
-
---
7
-
src/ui/plugins/store.rs | 4 ++++
8
-
1 file changed, 4 insertions(+)
9
-
10
-
diff --git a/src/ui/plugins/store.rs b/src/ui/plugins/store.rs
11
-
index 17d1534..c8f989d 100644
12
-
--- a/src/ui/plugins/store.rs
13
-
+++ b/src/ui/plugins/store.rs
14
-
@@ -413,6 +413,10 @@ impl AsyncComponent for PluginStore {
15
-
self.set_locked(false);
16
-
}
17
-
Self::Input::SetEnabled(signal_sender, plugin, enabled) => {
18
-
+ // HACK: I'm sure there's a much better way to do this, but I'm not a Rust
19
-
+ // HACK: ...developer, and this seems to work fine.
20
-
+ self.add_plugin_to_config(&sender, plugin.clone());
21
-
+
22
-
if let Some(cp) = self.config_plugins.get_mut(&plugin.appid) {
23
-
if let Err(e) = plugin.set_enabled(enabled) {
24
-
error!(
25
-
--
26
-
2.51.0
27
-
-113
src/atomic-xr/runtime.nu
-113
src/atomic-xr/runtime.nu
···
1
-
# SPDX-License-Identifier: AGPL-3.0-only
2
-
# Copyright (c) 2025 Shiloh Fen <shiloh@shilohfen.com>
3
-
4
-
use std log
5
-
6
-
const runtime_deps = {
7
-
xr: [openxr-libs openvr-api]
8
-
monado: [
9
-
libuvc
10
-
openhmd
11
-
opencv
12
-
onnxruntime
13
-
librealsense
14
-
opencv-video
15
-
]
16
-
}
17
-
18
-
# Install runtime dependencies
19
-
export def install [
20
-
...groups: string # Package groups to install
21
-
] {
22
-
ensure-installed (get-packages $groups)
23
-
}
24
-
25
-
# Uninstall runtime dependencies
26
-
export def uninstall [
27
-
...groups: string # Package groups to install
28
-
] {
29
-
ensure-not-installed (get-packages $groups)
30
-
}
31
-
32
-
def get-packages [
33
-
groups: list<string>
34
-
] {
35
-
if ($groups | is-empty) {
36
-
$runtime_deps
37
-
| transpose group packages
38
-
} else {
39
-
validate $groups
40
-
41
-
$runtime_deps
42
-
| transpose group packages
43
-
| where group in $groups
44
-
}
45
-
| get packages
46
-
| flatten
47
-
}
48
-
49
-
def validate [
50
-
groups: list<string>
51
-
] {
52
-
let avaliable_groups = $runtime_deps
53
-
| transpose group packages
54
-
| get group
55
-
56
-
$groups
57
-
| each {|group|
58
-
if $group not-in $avaliable_groups {
59
-
error make {
60
-
msg: "Unknown package group"
61
-
label: {
62
-
span: (metadata $group).span
63
-
text: $"Unknown package group: ($group)"
64
-
}
65
-
help: $"Avaliable groups: ($avaliable_groups | str join ', ')"
66
-
}
67
-
}
68
-
}
69
-
}
70
-
71
-
def ensure-installed [
72
-
packages: list<string>
73
-
] {
74
-
let missing_packages = $packages
75
-
| each {|package|
76
-
if (rpm -q $package | complete | get exit_code) != 0 {
77
-
$package
78
-
}
79
-
}
80
-
81
-
if ($missing_packages | is-not-empty) {
82
-
rpm-ostree install ...$missing_packages
83
-
job spawn {
84
-
match (notify-send -u critical "Package(s) installed" "Please reboot or use `rpm-ostree ex apply-live` to apply changes." -A reboot="Reboot" -A live="Apply Changes Live") {
85
-
"reboot" => (systemctl reboot)
86
-
"live" => (pkexec rpm-ostree ex apply-live)
87
-
}
88
-
}
89
-
null
90
-
}
91
-
}
92
-
93
-
def ensure-not-installed [
94
-
packages: list<string>
95
-
] {
96
-
let installed_packages = $packages
97
-
| each {|package|
98
-
if (rpm -q $package | complete | get exit_code) == 0 {
99
-
$package
100
-
}
101
-
}
102
-
103
-
if ($installed_packages | is-not-empty) {
104
-
rpm-ostree remove ...$installed_packages
105
-
job spawn {
106
-
match (notify-send -u critical "Package(s) removed" "Please reboot or use `rpm-ostree ex apply-live` to apply changes." -A reboot="Reboot" -A live="Apply Changes Live") {
107
-
"reboot" => (systemctl reboot)
108
-
"live" => (pkexec rpm-ostree ex apply-live --allow-replacement)
109
-
}
110
-
}
111
-
null
112
-
}
113
-
}
-92
src/atomic-xr/steamvr-lh.nu
-92
src/atomic-xr/steamvr-lh.nu
···
1
-
# SPDX-License-Identifier: AGPL-3.0-only
2
-
# Copyright (c) 2025 Shiloh Fen <shiloh@shilohfen.com>
3
-
4
-
use std log
5
-
6
-
def "ask yn" [prompt: string] {
7
-
loop {
8
-
match (input -n 1 $"($prompt) [y/n]: " | str downcase) {
9
-
"y" => (return true)
10
-
"n" => (return false)
11
-
_ => (log error "Invalid option, please choose `y` or `n`.")
12
-
}
13
-
}
14
-
}
15
-
16
-
# SteamVR Quick Calibration
17
-
export def calibrate [] {
18
-
# TODO: Support using native steam installation
19
-
log warning "This is intended for Flatpak Steam, if you're using native Steam, please use Envision instead."
20
-
log warning "If you'd like to use this feature with native Steam, please open an issue on Tangled."
21
-
22
-
if (ask yn "Do you own a lighthouse-tracked HMD? (e.g. Index, Vive Pro)") {
23
-
input -sn 1 "Please connect your headset and place it on the floor, then press any key to start the calibration."
24
-
25
-
log info "Starting SteamVR Lighthouse calibration"
26
-
27
-
let vrcmd_bin: path = $"($env.HOME)/.steam/root/steamapps/common/SteamVR/bin/linux64/vrcmd"
28
-
let environment = $"LD_LIBRARY_PATH=('~/.var/app/com.valvesoftware.Steam/.steam/root/steamapps/common/SteamVR/bin/linux64' | path expand)"
29
-
30
-
let server = job spawn {flatpak run --command=$"($vrcmd_bin)" --env=$"($environment)" com.valvesoftware.Steam --pollposes}
31
-
sleep 2sec # TODO: detect when the server is ready
32
-
try {
33
-
flatpak run --command=$"($vrcmd_bin)" --env=$"($environment)" com.valvesoftware.Steam --resetroomsetup
34
-
} catch {|err|
35
-
job kill $server
36
-
error make $err
37
-
}
38
-
39
-
job kill $server
40
-
log info "Calibration finished"
41
-
} else {
42
-
log info "Creating default Lighthouse Database"
43
-
44
-
if not ("~/.steam/root/config/lighthouse/" | path exists) {
45
-
error make {
46
-
msg: "Could not find lighthouse configuration directory."
47
-
help: "Make sure you have SteamVR installed, and .steam points to the correct location. You may need to run `axr flatpak steam enable-xr` if you're using the Steam Flatpak."
48
-
}
49
-
}
50
-
51
-
{
52
-
base_stations: []
53
-
known_objects: []
54
-
known_universes: []
55
-
revision: 1
56
-
}
57
-
| save -f ~/.steam/root/config/lighthouse/lighthousedb.json
58
-
59
-
log info "Created default Lighthouse Database"
60
-
}
61
-
}
62
-
63
-
# Run lighthouse console natively or via flatpak depending on which is installed
64
-
def lh-console [...args]: any -> any {
65
-
if (which lighthouse_console | length) > 0 {
66
-
log debug "Running lighthouse_console from PATH"
67
-
run-external lighthouse_console
68
-
} else if not ("~/.steam" | path exists) and (
69
-
"~/.var/app/com.valvesoftware.Steam/.steam/root/steamapps/common/SteamVR/tools/lighthouse/bin/linux64/lighthouse_console"
70
-
| path exists
71
-
) or (ls -lD ~/.steam).0.target == ("~/.var/app/com.valvesoftware.Steam/.steam/" | path expand) {
72
-
log debug "Running lighthouse_console from steam flatpak"
73
-
flatpak run --command=$"($env.HOME)/.var/app/com.valvesoftware.Steam/.steam/root/steamapps/common/SteamVR/tools/lighthouse/bin/linux64/lighthouse_console" com.valvesoftware.Steam ...$args
74
-
} else if ("~/.steam" | path exists) {
75
-
log debug "Running lighthouse_console from steam native"
76
-
run-external $"($env.HOME)/.steam/root/steamapps/common/SteamVR/tools/lighthouse/bin/linux64/lighthouse_console" ...$args
77
-
} else {
78
-
error make {
79
-
msg: "Could not find lighthouse_console"
80
-
help: "Please make sure SteamVR is installed"
81
-
}
82
-
}
83
-
}
84
-
85
-
# Open SteamVR's lighthouse_console
86
-
#
87
-
# Useful for pairing, dumping device configs, etc.
88
-
export def console [
89
-
...args # Arguments to pass to lighthouse_console
90
-
] {
91
-
lh-console ...$args
92
-
}
-20
src/atomic-xr/wayvr.nu
-20
src/atomic-xr/wayvr.nu
···
1
-
# SPDX-License-Identifier: AGPL-3.0-only
2
-
# Copyright (c) 2025 Shiloh Fen <shiloh@shilohfen.com>
3
-
4
-
# Enable WayVR Dashboard
5
-
export def "dashboard enable" [] {
6
-
mkdir ~/.config/wlxoverlay/wayvr.conf.d
7
-
8
-
{dashboard: {
9
-
exec: /home/linuxbrew/.linuxbrew/bin/wayvr-dashboard
10
-
args: ''
11
-
env: []
12
-
}}
13
-
| to yaml
14
-
| save ~/.config/wlxoverlay/wayvr.conf.d/dashboard.yaml
15
-
}
16
-
17
-
# Disable WayVR Dashboard
18
-
export def "dashboard disable" [] {
19
-
rm ~/.config/wlxoverlay/wayvr.conf.d/dashboard.yaml
20
-
}
-63
src/axr.nu.in
-63
src/axr.nu.in
···
1
-
#!/usr/bin/env nu
2
-
# SPDX-License-Identifier: AGPL-3.0-only
3
-
# Copyright (c) 2025 Shiloh Fen <shiloh@shilohfen.com>
4
-
5
-
use std log
6
-
/@AXR_LIB@/
7
-
8
-
def main [
9
-
# TODO: --choose (-c) # Interactively choose a function
10
-
--list (-l) # List avaliable commands
11
-
--interactive (-i) # Enter interactive shell with the module loaded
12
-
...function
13
-
] {
14
-
let function = $function | str join ' '
15
-
if $interactive {
16
-
exec nu -e "/@AXR_LIB@/; print $'(ansi yellow)AtomicXR module loaded.(ansi reset)'"
17
-
} else if $list or ($function | is-empty) {
18
-
print-functions
19
-
} else {
20
-
# Make sure the function is valid to avoid unhelpful error messages
21
-
# This regex checks if $function starts with anything in get-functions
22
-
if $function like $"^\(?:(get-functions | str join '|')\)" {
23
-
nu -c $"/@AXR_LIB@/; atomic-xr ($function)"
24
-
} else {
25
-
log error $"Invalid function: `($function)`"
26
-
print-functions
27
-
}
28
-
}
29
-
}
30
-
31
-
def get-functions [] {
32
-
scope modules
33
-
| where name == atomic-xr
34
-
| get 0.commands.name
35
-
}
36
-
37
-
def print-functions [] {
38
-
get-functions
39
-
| where not ($it starts-with "_")
40
-
| each {|function|
41
-
let help = help atomic-xr $function | lines
42
-
43
-
let short_description = $help
44
-
| first
45
-
| if $in == $"(ansi green)Usage(ansi reset):" {
46
-
null
47
-
} else {
48
-
$in
49
-
}
50
-
51
-
# let usage = $help
52
-
# | get (
53
-
# ($help | enumerate | where item == $"(ansi green)Usage(ansi reset):").0.index + 1
54
-
# )
55
-
# | str trim
56
-
57
-
{
58
-
command: $"(ansi cyan)($function)(ansi reset)"
59
-
description: $"(ansi lp)($short_description)(ansi reset)"
60
-
}
61
-
}
62
-
| table --index false --theme rounded
63
-
}