From 507c0677c8096cc85612df5ab3f60848b1a933ff Mon Sep 17 00:00:00 2001 From: galister <22305755+galister@users.noreply.github.com> Date: Wed, 6 Mar 2024 20:40:05 +0100 Subject: [PATCH] ShowUi & ShowMirror: no implicit show/hide --- src/backend/openvr/mod.rs | 51 ++++++++++++++++++++++----------------- src/backend/openxr/mod.rs | 13 +++++++--- src/backend/overlay.rs | 2 ++ src/gui/modular/button.rs | 21 ---------------- src/res/settings.yaml | 13 ++++++++-- src/res/watch.yaml | 7 ++++-- 6 files changed, 56 insertions(+), 51 deletions(-) diff --git a/src/backend/openvr/mod.rs b/src/backend/openvr/mod.rs index f2abe77..abb50c9 100644 --- a/src/backend/openvr/mod.rs +++ b/src/backend/openvr/mod.rs @@ -1,7 +1,7 @@ use std::{ collections::VecDeque, sync::{ - atomic::{AtomicBool, Ordering}, + atomic::{AtomicBool, AtomicUsize, Ordering}, Arc, }, time::{Duration, Instant}, @@ -46,6 +46,8 @@ pub mod manifest; pub mod overlay; pub mod playspace; +static FRAME_COUNTER: AtomicUsize = AtomicUsize::new(0); + pub fn openvr_uninstall() { let app_type = EVRApplicationType::VRApplication_Overlay; let Ok(context) = ovr_overlay::Context::init(app_type) else { @@ -67,15 +69,15 @@ pub fn openvr_run(running: Arc) -> Result<(), BackendError> { log::info!("Using OpenVR runtime"); let mut app_mgr = context.applications_mngr(); - let mut input_mngr = context.input_mngr(); - let mut system_mngr = context.system_mngr(); - let mut overlay_mngr = context.overlay_mngr(); - let mut settings_mngr = context.settings_mngr(); + let mut input_mgr = context.input_mngr(); + let mut system_mgr = context.system_mngr(); + let mut overlay_mgr = context.overlay_mngr(); + let mut settings_mgr = context.settings_mngr(); let mut chaperone_mgr = context.chaperone_setup_mngr(); - let mut compositor_mngr = context.compositor_mngr(); + let mut compositor_mgr = context.compositor_mngr(); let device_extensions_fn = |device: &PhysicalDevice| { - let names = compositor_mngr.get_vulkan_device_extensions_required(device.handle().as_raw()); + let names = compositor_mgr.get_vulkan_device_extensions_required(device.handle().as_raw()); let ext = DeviceExtensions::from_iter(names.iter().map(|s| s.as_str())); ext }; @@ -105,11 +107,11 @@ pub fn openvr_run(running: Arc) -> Result<(), BackendError> { state.hid_provider.set_desktop_extent(overlays.extent); - set_action_manifest(&mut input_mngr)?; + set_action_manifest(&mut input_mgr)?; - let mut input_source = OpenVrInputSource::new(&mut input_mngr)?; + let mut input_source = OpenVrInputSource::new(&mut input_mgr)?; - let Ok(refresh_rate) = system_mngr.get_tracked_device_property::( + let Ok(refresh_rate) = system_mgr.get_tracked_device_property::( TrackedDeviceIndex::HMD, ETrackedDeviceProperty::Prop_DisplayFrequency_Float, ) else { @@ -135,7 +137,9 @@ pub fn openvr_run(running: Arc) -> Result<(), BackendError> { break 'main_loop; } - while let Some(event) = system_mngr.poll_next_event() { + let cur_frame = FRAME_COUNTER.fetch_add(1, Ordering::Relaxed); + + while let Some(event) = system_mgr.poll_next_event() { match event.event_type { EVREventType::VREvent_Quit => { log::warn!("Received quit event, shutting down."); @@ -151,7 +155,7 @@ pub fn openvr_run(running: Arc) -> Result<(), BackendError> { } if next_device_update <= Instant::now() { - input_source.update_devices(&mut system_mngr, &mut state); + input_source.update_devices(&mut system_mgr, &mut state); next_device_update = Instant::now() + Duration::from_secs(30); } @@ -171,9 +175,10 @@ pub fn openvr_run(running: Arc) -> Result<(), BackendError> { continue; }; - let Some((state, backend)) = f(&mut state) else { + let Some((mut state, backend)) = f(&mut state) else { continue; }; + state.birthframe = cur_frame; overlays.add(OverlayData { state, @@ -183,13 +188,15 @@ pub fn openvr_run(running: Arc) -> Result<(), BackendError> { } TaskType::DropOverlay(sel) => { if let Some(o) = overlays.mut_by_selector(&sel) { - o.destroy(&mut overlay_mngr); - overlays.remove_by_selector(&sel); + if o.state.birthframe < cur_frame { + o.destroy(&mut overlay_mgr); + overlays.remove_by_selector(&sel); + } } } TaskType::System(task) => match task { SystemTask::ColorGain(channel, value) => { - let _ = adjust_gain(&mut settings_mngr, channel, value); + let _ = adjust_gain(&mut settings_mgr, channel, value); } SystemTask::FixFloor => { space_mover.fix_floor(&mut chaperone_mgr, &state.input_state); @@ -202,7 +209,7 @@ pub fn openvr_run(running: Arc) -> Result<(), BackendError> { } state.input_state.pre_update(); - input_source.update(&mut input_mngr, &mut system_mngr, &mut state); + input_source.update(&mut input_mgr, &mut system_mgr, &mut state); state.input_state.post_update(); if state @@ -231,14 +238,14 @@ pub fn openvr_run(running: Arc) -> Result<(), BackendError> { &state.input_state.hmd, ); if let Some(haptics) = haptics { - input_source.haptics(&mut input_mngr, idx, haptics) + input_source.haptics(&mut input_mgr, idx, haptics) } } - lines.update(&mut overlay_mngr, &mut state)?; + lines.update(&mut overlay_mgr, &mut state)?; for o in overlays.iter_mut() { - o.after_input(&mut overlay_mngr, &mut state)?; + o.after_input(&mut overlay_mgr, &mut state)?; } #[cfg(feature = "osc")] @@ -258,7 +265,7 @@ pub fn openvr_run(running: Arc) -> Result<(), BackendError> { overlays .iter_mut() - .for_each(|o| o.after_render(&mut overlay_mngr, &state.graphics)); + .for_each(|o| o.after_render(&mut overlay_mgr, &state.graphics)); // chaperone @@ -268,7 +275,7 @@ pub fn openvr_run(running: Arc) -> Result<(), BackendError> { let mut seconds_since_vsync = 0f32; std::thread::sleep(Duration::from_secs_f32( - if system_mngr.get_time_since_last_vsync(&mut seconds_since_vsync, &mut 0u64) { + if system_mgr.get_time_since_last_vsync(&mut seconds_since_vsync, &mut 0u64) { (frame_time - seconds_since_vsync).max(0.0) } else { frame_time diff --git a/src/backend/openxr/mod.rs b/src/backend/openxr/mod.rs index 6dcd02f..86b052a 100644 --- a/src/backend/openxr/mod.rs +++ b/src/backend/openxr/mod.rs @@ -315,9 +315,10 @@ pub fn openxr_run(running: Arc) -> Result<(), BackendError> { continue; }; - let Some((state, backend)) = f(&mut app_state) else { + let Some((mut state, backend)) = f(&mut app_state) else { continue; }; + state.birthframe = cur_frame; overlays.add(OverlayData { state, @@ -326,9 +327,13 @@ pub fn openxr_run(running: Arc) -> Result<(), BackendError> { }); } TaskType::DropOverlay(sel) => { - let o = overlays.remove_by_selector(&sel); - // set for deletion after all images are done showing - delete_queue.push((o, cur_frame + 5)); + if let Some(o) = overlays.mut_by_selector(&sel) { + if o.state.birthframe < cur_frame { + let o = overlays.remove_by_selector(&sel); + // set for deletion after all images are done showing + delete_queue.push((o, cur_frame + 5)); + } + } } TaskType::System(_task) => { // Not implemented diff --git a/src/backend/overlay.rs b/src/backend/overlay.rs index 2956d5d..7b4e47b 100644 --- a/src/backend/overlay.rs +++ b/src/backend/overlay.rs @@ -37,6 +37,7 @@ pub struct OverlayState { pub relative_to: RelativeTo, pub primary_pointer: Option, pub interaction_transform: Affine2, + pub birthframe: usize, } impl Default for OverlayState { @@ -60,6 +61,7 @@ impl Default for OverlayState { transform: Affine3A::IDENTITY, primary_pointer: None, interaction_transform: Affine2::IDENTITY, + birthframe: 0, } } } diff --git a/src/gui/modular/button.rs b/src/gui/modular/button.rs index 0fdf4ec..f9c0401 100644 --- a/src/gui/modular/button.rs +++ b/src/gui/modular/button.rs @@ -578,20 +578,9 @@ fn run_overlay(overlay: &OverlaySelector, action: &OverlayAction, app: &mut AppS fn run_window(window: &Arc, action: &WindowAction, app: &mut AppState) { use crate::overlays::custom; - let selector = OverlaySelector::Name(window.clone()); match action { WindowAction::ShowMirror => { - app.tasks.enqueue(TaskType::Overlay( - selector, - Box::new(|app, o| { - o.want_visible = !o.want_visible; - if o.recenter { - o.show_hide = o.want_visible; - o.reset(app, false); - } - }), - )); #[cfg(feature = "wayland")] app.tasks.enqueue(TaskType::CreateOverlay( OverlaySelector::Name(window.clone()), @@ -609,16 +598,6 @@ fn run_window(window: &Arc, action: &WindowAction, app: &mut AppState) { log::warn!("Mirror not available without Wayland feature."); } WindowAction::ShowUi => { - app.tasks.enqueue(TaskType::Overlay( - selector, - Box::new(|app, o| { - o.want_visible = !o.want_visible; - if o.recenter { - o.show_hide = o.want_visible; - o.reset(app, false); - } - }), - )); app.tasks.enqueue(TaskType::CreateOverlay( OverlaySelector::Name(window.clone()), Box::new({ diff --git a/src/res/settings.yaml b/src/res/settings.yaml index 1b8b677..9521aa1 100644 --- a/src/res/settings.yaml +++ b/src/res/settings.yaml @@ -270,10 +270,13 @@ elements: fg_color: "#ffffff" bg_color: "#707070" text: "Show/Hide" - click_down: + click_down: # ToggleVisible if exists, else create + - type: Overlay + target: M1 + action: ToggleVisible # only fires if overlay exists - type: Window target: M1 - action: ShowMirror + action: ShowMirror # only fires if not exists - type: Button rect: [185, 270, 60, 30] @@ -311,6 +314,9 @@ elements: bg_color: "#707070" text: "Show/Hide" click_down: + - type: Overlay + target: M2 + action: ToggleVisible - type: Window target: M2 action: ShowMirror @@ -351,6 +357,9 @@ elements: bg_color: "#707070" text: "Show/Hide" click_down: + - type: Overlay + target: M3 + action: ToggleVisible - type: Window target: M3 action: ShowMirror diff --git a/src/res/watch.yaml b/src/res/watch.yaml index 30f564b..2a9a645 100644 --- a/src/res/watch.yaml +++ b/src/res/watch.yaml @@ -18,10 +18,13 @@ elements: bg_color: "#808040" fg_color: "#ffffff" text: "C" - click_up: + click_up: # destroy if exists, otherwise create - type: Window target: settings - action: ShowUi + action: ShowUi # only triggers if not exists + - type: Window + target: settings + action: Destroy # only triggers if exists since before current frame # Keyboard button - type: Button