mirror of
https://gitlab.com/gabmus/envision.git
synced 2025-07-30 04:38:44 +00:00
feat: try to connect to openxr service to verify it's running
This commit is contained in:
parent
33d906f50d
commit
adbeffaba1
7 changed files with 202 additions and 27 deletions
|
@ -23,7 +23,7 @@ cargo:clippy:
|
|||
RUSTFLAGS: "-Dwarnings"
|
||||
script:
|
||||
- apt-get update
|
||||
- apt-get install libgtk-4-dev libadwaita-1-dev libssl-dev libjxl-dev libvte-2.91-gtk4-dev meson ninja-build git desktop-file-utils gettext file libusb-dev libusb-1.0-0-dev curl -y
|
||||
- apt-get install libgtk-4-dev libadwaita-1-dev libssl-dev libjxl-dev libvte-2.91-gtk4-dev meson ninja-build git desktop-file-utils gettext file libusb-dev libusb-1.0-0-dev libopenxr-dev curl -y
|
||||
- curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs -o /tmp/rustup.sh
|
||||
- chmod +x /tmp/rustup.sh
|
||||
- /tmp/rustup.sh -y
|
||||
|
@ -38,7 +38,7 @@ cargo:test:
|
|||
stage: check
|
||||
script:
|
||||
- apt-get update
|
||||
- apt-get install libgtk-4-dev libadwaita-1-dev libssl-dev libjxl-dev libvte-2.91-gtk4-dev meson ninja-build git desktop-file-utils gettext file libusb-dev libusb-1.0-0-dev curl -y
|
||||
- apt-get install libgtk-4-dev libadwaita-1-dev libssl-dev libjxl-dev libvte-2.91-gtk4-dev meson ninja-build git desktop-file-utils gettext file libusb-dev libusb-1.0-0-dev libopenxr-dev curl -y
|
||||
- curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs -o /tmp/rustup.sh
|
||||
- chmod +x /tmp/rustup.sh
|
||||
- /tmp/rustup.sh -y
|
||||
|
@ -55,7 +55,7 @@ appimage:
|
|||
stage: deploy
|
||||
script:
|
||||
- apt-get update
|
||||
- apt-get install libgtk-4-dev libadwaita-1-dev libssl-dev libjxl-dev libvte-2.91-gtk4-dev meson ninja-build git desktop-file-utils gettext file libusb-dev libusb-1.0-0-dev curl -y
|
||||
- apt-get install libgtk-4-dev libadwaita-1-dev libssl-dev libjxl-dev libvte-2.91-gtk4-dev meson ninja-build git desktop-file-utils gettext file libusb-dev libusb-1.0-0-dev libopenxr-dev curl -y
|
||||
- curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs -o /tmp/rustup.sh
|
||||
- chmod +x /tmp/rustup.sh
|
||||
- /tmp/rustup.sh -y
|
||||
|
|
38
Cargo.lock
generated
38
Cargo.lock
generated
|
@ -191,7 +191,7 @@ checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f"
|
|||
dependencies = [
|
||||
"glob",
|
||||
"libc",
|
||||
"libloading",
|
||||
"libloading 0.7.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -278,6 +278,7 @@ dependencies = [
|
|||
"libadwaita",
|
||||
"libmonado-rs",
|
||||
"nix",
|
||||
"openxr",
|
||||
"phf",
|
||||
"phf_macros",
|
||||
"relm4",
|
||||
|
@ -1075,6 +1076,16 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"windows-targets 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libmonado-rs"
|
||||
version = "0.1.0"
|
||||
|
@ -1254,6 +1265,12 @@ dependencies = [
|
|||
"tempfile",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ndk-context"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b"
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.29.0"
|
||||
|
@ -1374,6 +1391,25 @@ dependencies = [
|
|||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openxr"
|
||||
version = "0.18.0"
|
||||
source = "git+https://github.com/galister/openxrs?rev=af4a55d#af4a55df60125491c80c61464c824219c6019b76"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"libloading 0.8.5",
|
||||
"ndk-context",
|
||||
"openxr-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openxr-sys"
|
||||
version = "0.10.0"
|
||||
source = "git+https://github.com/galister/openxrs?rev=af4a55d#af4a55df60125491c80c61464c824219c6019b76"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pango"
|
||||
version = "0.19.5"
|
||||
|
|
|
@ -26,3 +26,6 @@ tracker = "0.2.1"
|
|||
uuid = { version = "1.8.0", features = ["v4", "fast-rng"] }
|
||||
vte4 = { version = "0.7.1", features = ["v0_72"] }
|
||||
xdg = "2.5.2"
|
||||
openxr = { git = "https://github.com/galister/openxrs", rev = "af4a55d", features = [
|
||||
"linked",
|
||||
] }
|
||||
|
|
|
@ -34,6 +34,7 @@ pub mod linux_distro;
|
|||
pub mod log_level;
|
||||
pub mod log_parser;
|
||||
pub mod monado_utils;
|
||||
pub mod openxr_prober;
|
||||
pub mod paths;
|
||||
pub mod profile;
|
||||
pub mod profiles;
|
||||
|
|
39
src/openxr_prober.rs
Normal file
39
src/openxr_prober.rs
Normal file
|
@ -0,0 +1,39 @@
|
|||
// gracefully stolen from https://github.com/galister/wlx-overlay-s/blob/main/src/backend/openxr/helpers.rs#L9
|
||||
// original code licensed gpl 3
|
||||
use openxr as xr;
|
||||
|
||||
use crate::constants::CMD_NAME;
|
||||
|
||||
pub fn is_openxr_ready() -> bool {
|
||||
let entry = xr::Entry::linked();
|
||||
|
||||
if entry.enumerate_extensions().is_err() {
|
||||
return false;
|
||||
};
|
||||
|
||||
let enabled_extensions = xr::ExtensionSet::default();
|
||||
|
||||
let layers = [];
|
||||
|
||||
let Ok(xr_instance) = entry.create_instance(
|
||||
&xr::ApplicationInfo {
|
||||
application_name: &format!("{}-openxr-prober", CMD_NAME),
|
||||
application_version: 0,
|
||||
engine_name: CMD_NAME,
|
||||
engine_version: 0,
|
||||
},
|
||||
&enabled_extensions,
|
||||
&layers,
|
||||
) else {
|
||||
return false;
|
||||
};
|
||||
|
||||
if xr_instance
|
||||
.system(xr::FormFactor::HEAD_MOUNTED_DISPLAY)
|
||||
.is_err()
|
||||
{
|
||||
return false;
|
||||
};
|
||||
|
||||
true
|
||||
}
|
|
@ -4,7 +4,7 @@ use super::build_window::{BuildStatus, BuildWindow};
|
|||
use super::cmdline_opts::CmdLineOpts;
|
||||
use super::debug_view::{DebugView, DebugViewMsg};
|
||||
use super::job_worker::internal_worker::JobWorkerOut;
|
||||
use super::job_worker::job::WorkerJob;
|
||||
use super::job_worker::job::{FuncWorkerOut, WorkerJob};
|
||||
use super::job_worker::JobWorker;
|
||||
use super::libsurvive_setup_window::LibsurviveSetupWindow;
|
||||
use super::main_view::MainViewMsg;
|
||||
|
@ -35,6 +35,7 @@ use crate::file_builders::openvrpaths_vrpath::{
|
|||
use crate::file_utils::setcap_cap_sys_nice_eip;
|
||||
use crate::is_appimage::IS_APPIMAGE;
|
||||
use crate::linux_distro::LinuxDistro;
|
||||
use crate::openxr_prober::is_openxr_ready;
|
||||
use crate::paths::{get_data_dir, get_ipc_file_path};
|
||||
use crate::profile::{Profile, XRServiceType};
|
||||
use crate::stateless_action;
|
||||
|
@ -111,6 +112,9 @@ pub struct App {
|
|||
wivrn_appimage_warn_shown: bool,
|
||||
#[tracker::do_not_track]
|
||||
configure_wivrn_action: gtk::gio::SimpleAction,
|
||||
|
||||
#[tracker::do_not_track]
|
||||
openxr_prober_worker: Option<JobWorker>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -139,6 +143,9 @@ pub enum Msg {
|
|||
DebugCopyEnvVars,
|
||||
OpenWivrnConfig,
|
||||
HandleCommandLine(CmdLineOpts),
|
||||
StartProber,
|
||||
OnProberExit(bool),
|
||||
NoOp,
|
||||
}
|
||||
|
||||
impl App {
|
||||
|
@ -203,23 +210,6 @@ impl App {
|
|||
debug,
|
||||
);
|
||||
worker.start();
|
||||
if let Some(autostart_cmd) = &prof.autostart_command {
|
||||
let autostart_worker = JobWorker::new_with_timer(
|
||||
Duration::from_secs(5),
|
||||
WorkerJob::new_cmd(
|
||||
Some(prof.environment.clone()),
|
||||
"sh".into(),
|
||||
Some(vec!["-c".into(), autostart_cmd.clone()]),
|
||||
),
|
||||
sender.input_sender(),
|
||||
|msg| match msg {
|
||||
JobWorkerOut::Log(rows) => Msg::OnServiceLog(rows),
|
||||
JobWorkerOut::Exit(code) => Msg::OnAutostartExit(code),
|
||||
},
|
||||
);
|
||||
autostart_worker.start();
|
||||
self.autostart_worker = Some(autostart_worker)
|
||||
}
|
||||
self.xrservice_worker = Some(worker);
|
||||
self.main_view
|
||||
.sender()
|
||||
|
@ -233,6 +223,7 @@ impl App {
|
|||
.sender()
|
||||
.emit(DebugViewMsg::XRServiceActiveChanged(true));
|
||||
self.set_inhibit_session(true);
|
||||
sender.input(Msg::StartProber);
|
||||
} else {
|
||||
alert(
|
||||
"Failed to start profile",
|
||||
|
@ -245,6 +236,24 @@ impl App {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn run_autostart(&mut self, sender: ComponentSender<Self>) {
|
||||
let prof = self.get_selected_profile();
|
||||
if let Some(autostart_cmd) = &prof.autostart_command {
|
||||
let mut jobs = VecDeque::new();
|
||||
jobs.push_back(WorkerJob::new_cmd(
|
||||
Some(prof.environment.clone()),
|
||||
"sh".into(),
|
||||
Some(vec!["-c".into(), autostart_cmd.clone()]),
|
||||
));
|
||||
let autostart_worker = JobWorker::new(jobs, sender.input_sender(), |msg| match msg {
|
||||
JobWorkerOut::Log(rows) => Msg::OnServiceLog(rows),
|
||||
JobWorkerOut::Exit(code) => Msg::OnAutostartExit(code),
|
||||
});
|
||||
autostart_worker.start();
|
||||
self.autostart_worker = Some(autostart_worker);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn restore_openxr_openvr_files(&self) {
|
||||
restore_runtime_entrypoint();
|
||||
if let Err(e) = set_current_active_runtime_to_steam() {
|
||||
|
@ -264,6 +273,11 @@ impl App {
|
|||
}
|
||||
|
||||
pub fn shutdown_xrservice(&mut self) {
|
||||
if let Some(w) = self.openxr_prober_worker.as_ref() {
|
||||
w.stop();
|
||||
// this can cause threads to remain hanging...
|
||||
self.openxr_prober_worker = None;
|
||||
}
|
||||
self.set_inhibit_session(false);
|
||||
if let Some(worker) = self.xrservice_worker.as_ref() {
|
||||
worker.stop();
|
||||
|
@ -331,6 +345,7 @@ impl SimpleComponent for App {
|
|||
self.reset();
|
||||
|
||||
match message {
|
||||
Msg::NoOp => {}
|
||||
Msg::OnServiceLog(rows) => {
|
||||
if !rows.is_empty() {
|
||||
self.debug_view
|
||||
|
@ -727,6 +742,50 @@ impl SimpleComponent for App {
|
|||
self.skip_depcheck = true;
|
||||
}
|
||||
}
|
||||
Msg::StartProber => {
|
||||
if self
|
||||
.openxr_prober_worker
|
||||
.as_ref()
|
||||
.is_some_and(|w| w.exit_code().is_none())
|
||||
{
|
||||
eprintln!(">>>>>>>>>>>>>>> prober already running!");
|
||||
// prober already running
|
||||
return;
|
||||
}
|
||||
let worker = JobWorker::new_with_timer(
|
||||
Duration::from_millis(500),
|
||||
WorkerJob::new_func(Box::new(move || {
|
||||
println!(">>>>>>>>>>>>>>> probing now <<<<<<<<<<<<<<<<<<");
|
||||
let ready = is_openxr_ready();
|
||||
println!(">>>>>>>>>>>>>>> ready? {}", ready);
|
||||
FuncWorkerOut {
|
||||
success: ready,
|
||||
..Default::default()
|
||||
}
|
||||
})),
|
||||
sender.input_sender(),
|
||||
|msg| match msg {
|
||||
JobWorkerOut::Exit(code) => Self::Input::OnProberExit(code == 0),
|
||||
_ => Self::Input::NoOp,
|
||||
},
|
||||
);
|
||||
worker.start();
|
||||
self.openxr_prober_worker = Some(worker);
|
||||
}
|
||||
Msg::OnProberExit(success) => {
|
||||
self.main_view
|
||||
.sender()
|
||||
.emit(MainViewMsg::UpdateXrServiceReady(success));
|
||||
if success {
|
||||
self.run_autostart(sender.clone());
|
||||
} else if self
|
||||
.xrservice_worker
|
||||
.as_ref()
|
||||
.is_some_and(|w| w.exit_code().is_none())
|
||||
{
|
||||
sender.input(Msg::StartProber);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -875,6 +934,7 @@ impl SimpleComponent for App {
|
|||
skip_depcheck: false,
|
||||
wivrn_appimage_warn_shown: false,
|
||||
configure_wivrn_action,
|
||||
openxr_prober_worker: None,
|
||||
};
|
||||
let widgets = view_output!();
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ use crate::config::Config;
|
|||
use crate::dependencies::common::dep_pkexec;
|
||||
use crate::file_utils::mount_has_nosuid;
|
||||
use crate::gpu_profile::{get_amd_gpu_power_profile, GpuPowerProfile};
|
||||
use crate::profile::{LighthouseDriver, Profile};
|
||||
use crate::profile::{LighthouseDriver, Profile, XRServiceType};
|
||||
use crate::steamvr_utils::chaperone_info_exists;
|
||||
use crate::ui::app::{
|
||||
AboutAction, BuildProfileAction, BuildProfileCleanAction, ConfigureWivrnAction,
|
||||
|
@ -48,6 +48,7 @@ pub struct MainView {
|
|||
steamvr_calibration_box: Controller<SteamVrCalibrationBox>,
|
||||
#[tracker::do_not_track]
|
||||
root_win: gtk::Window,
|
||||
xrservice_ready: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -67,6 +68,7 @@ pub enum MainViewMsg {
|
|||
DuplicateProfile,
|
||||
SaveProfile(Profile),
|
||||
UpdateDevices(Vec<XRDevice>),
|
||||
UpdateXrServiceReady(bool),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -180,6 +182,32 @@ impl SimpleComponent for MainView {
|
|||
},
|
||||
},
|
||||
},
|
||||
adw::Bin {
|
||||
#[track = "model.changed(Self::xrservice_active())"]
|
||||
set_visible: model.xrservice_active,
|
||||
add_css_class: "card",
|
||||
gtk::Label {
|
||||
#[track = "model.changed(Self::xrservice_active()) || model.changed(Self::xrservice_ready())"]
|
||||
set_label: if model.xrservice_ready {
|
||||
"Service ready, you can launch XR apps"
|
||||
} else {
|
||||
match model.selected_profile.xrservice_type {
|
||||
XRServiceType::Monado =>
|
||||
"Starting…",
|
||||
XRServiceType::Wivrn =>
|
||||
"Starting, please connect your client device…",
|
||||
}
|
||||
},
|
||||
set_margin_all: 18,
|
||||
add_css_class: "heading",
|
||||
add_css_class: "success",
|
||||
add_css_class: "warning",
|
||||
#[track = "model.changed(Self::xrservice_active()) || model.changed(Self::xrservice_ready())"]
|
||||
set_class_active: ("warning", !model.xrservice_ready),
|
||||
set_wrap: true,
|
||||
set_justify: gtk::Justification::Center,
|
||||
},
|
||||
},
|
||||
model.devices_box.widget(),
|
||||
gtk::Box {
|
||||
set_orientation: gtk::Orientation::Vertical,
|
||||
|
@ -424,6 +452,9 @@ impl SimpleComponent for MainView {
|
|||
.expect("Sender output failed");
|
||||
}
|
||||
Self::Input::XRServiceActiveChanged(active, profile, show_launch_opts) => {
|
||||
if !active {
|
||||
self.set_xrservice_ready(false);
|
||||
}
|
||||
self.set_xrservice_active(active);
|
||||
self.steamvr_calibration_box
|
||||
.sender()
|
||||
|
@ -536,10 +567,14 @@ impl SimpleComponent for MainView {
|
|||
);
|
||||
}
|
||||
}
|
||||
Self::Input::UpdateDevices(devs) => self
|
||||
.devices_box
|
||||
.sender()
|
||||
.emit(DevicesBoxMsg::UpdateDevices(devs)),
|
||||
Self::Input::UpdateDevices(devs) => {
|
||||
self.devices_box
|
||||
.sender()
|
||||
.emit(DevicesBoxMsg::UpdateDevices(devs));
|
||||
}
|
||||
Self::Input::UpdateXrServiceReady(ready) => {
|
||||
self.set_xrservice_ready(ready);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -621,6 +656,7 @@ impl SimpleComponent for MainView {
|
|||
root_win: init.root_win.clone(),
|
||||
steamvr_calibration_box,
|
||||
profile_editor: None,
|
||||
xrservice_ready: false,
|
||||
tracker: 0,
|
||||
};
|
||||
let widgets = view_output!();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue