diff --git a/wayvr/src/backend/openvr/mod.rs b/wayvr/src/backend/openvr/mod.rs index bd33cf62..20e3004e 100644 --- a/wayvr/src/backend/openvr/mod.rs +++ b/wayvr/src/backend/openvr/mod.rs @@ -15,7 +15,7 @@ use vulkano::{Handle, VulkanObject, device::physical::PhysicalDevice}; use wlx_common::overlays::ToastTopic; use crate::{ - FRAME_COUNTER, RUNNING, + Args, FRAME_COUNTER, RUNNING, backend::{ BackendError, XrBackend, input::interact, @@ -57,14 +57,12 @@ pub fn openvr_uninstall() { } #[allow(clippy::too_many_lines, clippy::cognitive_complexity)] -pub fn openvr_run( - show_by_default: bool, - headless: bool, - no_autostart: bool, -) -> Result<(), BackendError> { +pub fn openvr_run(args: &Args) -> Result<(), BackendError> { let app_type = EVRApplicationType::VRApplication_Overlay; let Ok(context) = ovr_overlay::Context::init(app_type) else { - log::warn!("Will not use OpenVR: Context init failed"); + if !args.wait { + log::warn!("Will not use OpenVR: Context init failed"); + } return Err(BackendError::NotSupported); }; @@ -94,9 +92,9 @@ pub fn openvr_run( AppState::from_graphics(gfx, gfx_extras, XrBackend::OpenVR)? }; - app.session.no_autostart = no_autostart; + app.session.no_autostart = args.no_autostart; - if show_by_default { + if args.show { app.session.config.tutorial_graduated = true; app.tasks.enqueue_at( TaskType::Overlay(OverlayTask::ShowHide), @@ -116,7 +114,7 @@ pub fn openvr_run( let _ = install_manifest(&mut app_mgr); - let mut overlays = OverlayWindowManager::::new(&mut app, headless)?; + let mut overlays = OverlayWindowManager::::new(&mut app, args.headless)?; let mut playspace = playspace::PlayspaceMover::new(); playspace.playspace_changed(&mut compositor_mgr, &mut chaperone_mgr); diff --git a/wayvr/src/backend/openxr/mod.rs b/wayvr/src/backend/openxr/mod.rs index a41f1530..af703abc 100644 --- a/wayvr/src/backend/openxr/mod.rs +++ b/wayvr/src/backend/openxr/mod.rs @@ -13,7 +13,7 @@ use vulkano::{Handle, VulkanObject}; use wlx_common::overlays::{StereoMode, ToastTopic}; use crate::{ - FRAME_COUNTER, RUNNING, + Args, FRAME_COUNTER, RUNNING, backend::{ BackendError, XrBackend, input::interact, @@ -52,15 +52,13 @@ struct XrState { } #[allow(clippy::too_many_lines, clippy::cognitive_complexity)] -pub fn openxr_run( - show_by_default: bool, - headless: bool, - no_autostart: bool, -) -> Result<(), BackendError> { +pub fn openxr_run(args: &Args) -> Result<(), BackendError> { let (xr_instance, system) = match helpers::init_xr() { Ok((xr_instance, system)) => (xr_instance, system), Err(e) => { - log::warn!("Will not use OpenXR: {e}"); + if !args.wait { + log::warn!("Will not use OpenXR: {e}"); + } return Err(BackendError::NotSupported); } }; @@ -70,11 +68,11 @@ pub fn openxr_run( AppState::from_graphics(gfx, gfx_extras, XrBackend::OpenXR)? }; - app.session.no_autostart = no_autostart; + app.session.no_autostart = args.no_autostart; let modes = xr_instance.enumerate_environment_blend_modes(system, VIEW_TYPE)?; - if show_by_default { + if args.show { app.session.config.tutorial_graduated = true; app.tasks.enqueue_at( TaskType::Overlay(OverlayTask::ShowHide), @@ -82,7 +80,7 @@ pub fn openxr_run( ); } - let mut overlays = OverlayWindowManager::::new(&mut app, headless)?; + let mut overlays = OverlayWindowManager::::new(&mut app, args.headless)?; let mut lines = LinePool::new(&app)?; let mut current_lines = Vec::with_capacity(2); diff --git a/wayvr/src/main.rs b/wayvr/src/main.rs index eb2f7670..853b127b 100644 --- a/wayvr/src/main.rs +++ b/wayvr/src/main.rs @@ -34,6 +34,7 @@ use std::{ path::PathBuf, process::Command, sync::atomic::{AtomicBool, AtomicUsize, Ordering}, + time::{Duration, Instant}, }; use clap::Parser; @@ -68,6 +69,10 @@ struct Args { #[arg(long)] show: bool, + /// Wait for a runtime to be available instead of exiting + #[arg(long)] + wait: bool, + /// Uninstall OpenVR manifest and exit #[arg(long)] uninstall: bool, @@ -150,39 +155,54 @@ fn auto_run(args: Args, used_backend: &mut Option) { let mut tried_xr = false; let mut tried_vr = false; - #[cfg(feature = "openxr")] - if !args_get_openvr(&args) { - use crate::backend::{BackendError, openxr::openxr_run}; - tried_xr = true; - match openxr_run(args.show, args.headless, args.no_autostart) { - Ok(()) => { - used_backend.replace(XrBackend::OpenXR); - return; - } - Err(BackendError::NotSupported) => (), - Err(e) => { - used_backend.replace(XrBackend::OpenXR); - log::error!("{e:?}"); - return; + loop { + #[cfg(feature = "openxr")] + if !args_get_openvr(&args) { + use crate::backend::{BackendError, openxr::openxr_run}; + tried_xr = true; + match openxr_run(&args) { + Ok(()) => { + used_backend.replace(XrBackend::OpenXR); + return; + } + Err(BackendError::NotSupported) => (), + Err(e) => { + used_backend.replace(XrBackend::OpenXR); + log::error!("{e:?}"); + return; + } } } - } - #[cfg(feature = "openvr")] - if !args_get_openxr(&args) { - use crate::backend::{BackendError, openvr::openvr_run}; - tried_vr = true; - match openvr_run(args.show, args.headless, args.no_autostart) { - Ok(()) => { - used_backend.replace(XrBackend::OpenVR); - return; + #[cfg(feature = "openvr")] + if !args_get_openxr(&args) { + use crate::backend::{BackendError, openvr::openvr_run}; + tried_vr = true; + match openvr_run(&args) { + Ok(()) => { + used_backend.replace(XrBackend::OpenVR); + return; + } + Err(BackendError::NotSupported) => (), + Err(e) => { + used_backend.replace(XrBackend::OpenVR); + log::error!("{e:?}"); + return; + } } - Err(BackendError::NotSupported) => (), - Err(e) => { - used_backend.replace(XrBackend::OpenVR); - log::error!("{e:?}"); - return; + } + + if args.wait { + // wait 5s unless we get signaled + let deadline = Instant::now() + Duration::from_secs(5); + while Instant::now() < deadline { + if !RUNNING.load(Ordering::Relaxed) { + return; + } + std::thread::sleep(Duration::from_millis(100)); } + } else { + break; } }