diff --git a/wayvr/src/assets/gui/edit.xml b/wayvr/src/assets/gui/edit.xml index 022ae8a..0abe10a 100644 --- a/wayvr/src/assets/gui/edit.xml +++ b/wayvr/src/assets/gui/edit.xml @@ -72,8 +72,9 @@
-
+
+
diff --git a/wayvr/src/assets/lang/de.json b/wayvr/src/assets/lang/de.json index 3567e6b..ee24515 100644 --- a/wayvr/src/assets/lang/de.json +++ b/wayvr/src/assets/lang/de.json @@ -39,6 +39,7 @@ "MOVE_PRESS_AND_DRAG": "Verschieben (drücken & ziehen)", "OPACITY": "Undurchsichtigkeit", "POSITIONING": "Positionierung", + "BLOCK_GAME_INPUT": "Spieleingabe blockieren", "RESIZE_PRESS_AND_DRAG": "Größe ändern (gedrückt halten & ziehen)", "POS_STATIC": "Statisch: Bleibt an Ort und Stelle und wird niemals neu zentriert.", "POS_ANCHORED": "Verankert: Bewegt sich zusammen mit dem Rest des Sets. Standard.", diff --git a/wayvr/src/assets/lang/en.json b/wayvr/src/assets/lang/en.json index 701f307..a09a5a5 100644 --- a/wayvr/src/assets/lang/en.json +++ b/wayvr/src/assets/lang/en.json @@ -45,6 +45,7 @@ "POS_STATIC": "Static: Not part of any set, no recenter.", "POSITIONING": "Positioning", "GLOBAL": "Always visible", + "BLOCK_INPUT": "Block game input", "RESIZE_PRESS_AND_DRAG": "Resize (press & drag)", "STEREO_3D_MODE": { "ADJUST_MOUSE": "Adjust mouse", diff --git a/wayvr/src/assets/lang/es.json b/wayvr/src/assets/lang/es.json index 0fbf10b..afbd185 100644 --- a/wayvr/src/assets/lang/es.json +++ b/wayvr/src/assets/lang/es.json @@ -39,6 +39,7 @@ "MOVE_PRESS_AND_DRAG": "Mover (presionar y arrastrar)", "OPACITY": "Opacidad", "POSITIONING": "Posicionamiento", + "BLOCK_GAME_INPUT": "Bloquear entrada del juego", "RESIZE_PRESS_AND_DRAG": "Redimensionar (presionar y arrastrar)", "POS_STATIC": "Estático: Permanece en su lugar y nunca se recentra.", "POS_ANCHORED": "Anclado: Se mueve junto con el resto del conjunto. Predeterminado.", diff --git a/wayvr/src/assets/lang/it.json b/wayvr/src/assets/lang/it.json index 297d254..f2b2af0 100644 --- a/wayvr/src/assets/lang/it.json +++ b/wayvr/src/assets/lang/it.json @@ -38,6 +38,7 @@ "POS_HMD": "Segui l'HMD.", "POS_STATIC": "Statico: non fa parte di alcun set, senza recentratura.", "POSITIONING": "Posizionamento", + "BLOCK_GAME_INPUT": "Blocca l'input di gioco", "RESIZE_PRESS_AND_DRAG": "Ridimensiona (premi e trascina)", "STEREO_3D_MODE": { "SPLIT_BOTTOM_TOP": "DAL BASSO→IN ALTO", diff --git a/wayvr/src/assets/lang/ja.json b/wayvr/src/assets/lang/ja.json index 88bf424..63cf155 100644 --- a/wayvr/src/assets/lang/ja.json +++ b/wayvr/src/assets/lang/ja.json @@ -39,6 +39,7 @@ "MOVE_PRESS_AND_DRAG": "移動(押してドラッグ)", "OPACITY": "不透明度", "POSITIONING": "位置付け", + "BLOCK_GAME_INPUT": "ゲームの入力をブロック", "RESIZE_PRESS_AND_DRAG": "サイズ変更(押してドラッグ)", "POS_STATIC": "固定:置かれた場所に留まり、再センタリングされません。", "POS_ANCHORED": "アンカー:セット内の他のウィンドウと共に移動します。デフォルト。", diff --git a/wayvr/src/assets/lang/pl.json b/wayvr/src/assets/lang/pl.json index 254c584..b682b89 100644 --- a/wayvr/src/assets/lang/pl.json +++ b/wayvr/src/assets/lang/pl.json @@ -39,6 +39,7 @@ "MOVE_PRESS_AND_DRAG": "Przesuń (naciśnij i przeciągnij)", "OPACITY": "Przezroczystość", "POSITIONING": "Pozycjonowanie", + "BLOCK_INPUT": "Blokuj input z gry", "RESIZE_PRESS_AND_DRAG": "Zmień rozmiar (naciśnij i przeciągnij)", "POS_STATIC": "Statyczne: Pozostaje w miejscu i nigdy nie jest ponownie wyśrodkowywane.", "POS_ANCHORED": "Zakotwiczone: Porusza się razem z resztą zestawu. Domyślne.", diff --git a/wayvr/src/assets/lang/zh_CN.json b/wayvr/src/assets/lang/zh_CN.json index 0b7dc07..c479f48 100644 --- a/wayvr/src/assets/lang/zh_CN.json +++ b/wayvr/src/assets/lang/zh_CN.json @@ -38,6 +38,7 @@ "POS_HMD": "跟随头显 (HMD)。", "POS_STATIC": "静态:不属于任何集合,不重新居中。", "POSITIONING": "定位", + "BLOCK_GAME_INPUT": "屏蔽游戏输入", "RESIZE_PRESS_AND_DRAG": "调整大小 (按住并拖拽)", "STEREO_3D_MODE": { "SPLIT_BOTTOM_TOP": "下→上", diff --git a/wayvr/src/backend/input.rs b/wayvr/src/backend/input.rs index 8349167..ad64efc 100644 --- a/wayvr/src/backend/input.rs +++ b/wayvr/src/backend/input.rs @@ -3,7 +3,7 @@ use std::process::{Child, Command}; use std::sync::Arc; use std::time::Instant; -use glam::{Affine3A, Mat3A, Vec2, Vec3, Vec3A, Vec3Swizzles}; +use glam::{Affine3A, Vec2, Vec3A, Vec3Swizzles}; use idmap_derive::IntegerId; use smallvec::{SmallVec, smallvec}; @@ -209,6 +209,7 @@ pub struct InteractionState { pub hovered_id: Option, pub next_push: Instant, pub haptics: Option, + pub should_block_input: bool, } impl Default for InteractionState { @@ -220,6 +221,7 @@ impl Default for InteractionState { hovered_id: None, next_push: Instant::now(), haptics: None, + should_block_input: false, } } } @@ -393,7 +395,7 @@ where for (idx, hit) in hits.iter().enumerate() { populate_lines( lines, - &mut app.input_state.pointers[idx], + &app.input_state.pointers[idx], hit.0, &app.input_state.hmd, ); @@ -471,6 +473,14 @@ where hit.primary = true; } + pointer.interaction.should_block_input = hovered + .config + .active_state + .as_ref() + .map_or(false, |state| state.block_input) + && (hovered.config.name.as_ref() != WATCH_NAME + || !app.session.config.block_game_input_ignore_watch); + #[cfg(debug_assertions)] log::trace!("Hit: {} {:?}", hovered.config.name, hit); @@ -544,9 +554,11 @@ fn handle_no_hit( } } + let pointer = &mut app.input_state.pointers[pointer_idx]; + pointer.interaction.should_block_input = false; + // in case click released while not aiming at anything // send release event to overlay that was originally clicked - let pointer = &mut app.input_state.pointers[pointer_idx]; if !pointer.now.click && pointer.before.click && let Some(clicked_id) = pointer.interaction.clicked_id.take() diff --git a/wayvr/src/backend/openvr/input.rs b/wayvr/src/backend/openvr/input.rs index a22925d..671268a 100644 --- a/wayvr/src/backend/openvr/input.rs +++ b/wayvr/src/backend/openvr/input.rs @@ -15,7 +15,6 @@ use wlx_common::config_io; use crate::{ backend::input::{Haptics, TrackedDevice, TrackedDeviceRole}, state::AppState, - windowing::OverlayID, }; use super::helpers::{Affine3AConvert, OVRError}; @@ -143,26 +142,41 @@ impl OpenVrInputSource { input: &mut InputManager, system: &mut SystemManager, app: &mut AppState, - watch_id: OverlayID, ) { - let should_block_input = app.input_state.pointers.iter().any(|p| { - p.interaction.hovered_id.is_some_and(|id| { - id != watch_id || !app.session.config.block_game_input_ignore_watch - }) - }) && app.session.config.block_game_input; + let should_block_input_left = app.input_state.pointers[0].interaction.should_block_input + && app.session.config.block_game_input; - let aas = ActiveActionSet(ovr_overlay::sys::VRActiveActionSet_t { + let should_block_input_right = app.input_state.pointers[1].interaction.should_block_input + && app.session.config.block_game_input; + + let aas_left = ActiveActionSet(ovr_overlay::sys::VRActiveActionSet_t { ulActionSet: self.set_hnd.0, - ulRestrictedToDevice: 0, + ulRestrictedToDevice: self.hands[0].input_hnd.0, ulSecondaryActionSet: 0, unPadding: 0, // the range between 0x01000000 and 0x01FFFFFF overrides game action sets as long as // global input from overlays is enabled in SteamVR developer settings // (taken from https://github.com/ValveSoftware/openvr/issues/1236) - nPriority: if should_block_input { 0x01000000 } else { 0x0 }, + nPriority: if should_block_input_left { + 0x01000000 + } else { + 0x0 + }, }); - let _ = input.update_actions(&mut [aas]); + let aas_right = ActiveActionSet(ovr_overlay::sys::VRActiveActionSet_t { + ulActionSet: self.set_hnd.0, + ulRestrictedToDevice: self.hands[1].input_hnd.0, + ulSecondaryActionSet: 0, + unPadding: 0, + nPriority: if should_block_input_right { + 0x01000000 + } else { + 0x0 + }, + }); + + let _ = input.update_actions(&mut [aas_left, aas_right]); let devices = system.get_device_to_absolute_tracking_pose(universe.clone(), 0.005); app.input_state.hmd = devices[0].mDeviceToAbsoluteTracking.to_affine(); diff --git a/wayvr/src/backend/openvr/mod.rs b/wayvr/src/backend/openvr/mod.rs index 00ffe08..e07cec7 100644 --- a/wayvr/src/backend/openvr/mod.rs +++ b/wayvr/src/backend/openvr/mod.rs @@ -241,13 +241,7 @@ pub fn openvr_run(show_by_default: bool, headless: bool) -> Result<(), BackendEr let universe = playspace.get_universe(); app.input_state.pre_update(); - input_source.update( - universe.clone(), - &mut input_mgr, - &mut system_mgr, - &mut app, - watch_id, - ); + input_source.update(universe.clone(), &mut input_mgr, &mut system_mgr, &mut app); app.input_state.post_update(&app.session); if app diff --git a/wayvr/src/backend/openxr/blocker.rs b/wayvr/src/backend/openxr/blocker.rs index 6544aaf..645c935 100644 --- a/wayvr/src/backend/openxr/blocker.rs +++ b/wayvr/src/backend/openxr/blocker.rs @@ -1,7 +1,7 @@ use libmonado::{ClientState, Monado}; use log::{trace, warn}; -use crate::{state::AppState, windowing::OverlayID}; +use crate::state::AppState; pub(super) struct InputBlocker { blocked_last_frame: bool, @@ -14,16 +14,17 @@ impl InputBlocker { } } - pub fn update(&mut self, app: &mut AppState, watch_id: OverlayID) { + pub fn update(&mut self, app: &mut AppState) { let Some(monado) = &mut app.monado else { return; // monado not available }; - let should_block = app.input_state.pointers.iter().any(|p| { - p.interaction.hovered_id.is_some_and(|id| { - id != watch_id || !app.session.config.block_game_input_ignore_watch - }) - }) && app.session.config.block_game_input; + let should_block = app + .input_state + .pointers + .iter() + .any(|p| p.interaction.should_block_input) + && app.session.config.block_game_input; match (should_block, self.blocked_last_frame) { (true, false) => { diff --git a/wayvr/src/backend/openxr/mod.rs b/wayvr/src/backend/openxr/mod.rs index fb86dd1..bb7b4ff 100644 --- a/wayvr/src/backend/openxr/mod.rs +++ b/wayvr/src/backend/openxr/mod.rs @@ -274,7 +274,7 @@ pub fn openxr_run(show_by_default: bool, headless: bool) -> Result<(), BackendEr app.input_state.post_update(&app.session); if let Some(ref mut blocker) = blocker { - blocker.update(&mut app, watch_id); + blocker.update(&mut app); } if app diff --git a/wayvr/src/overlays/edit/mod.rs b/wayvr/src/overlays/edit/mod.rs index e1349fa..597ef1f 100644 --- a/wayvr/src/overlays/edit/mod.rs +++ b/wayvr/src/overlays/edit/mod.rs @@ -432,6 +432,7 @@ fn make_edit_panel(app: &mut AppState) -> anyhow::Result { set_up_checkbox(&mut panel, "additive_box", cb_assign_additive)?; set_up_checkbox(&mut panel, "align_box", cb_assign_align)?; set_up_checkbox(&mut panel, "global_box", cb_assign_global)?; + set_up_checkbox(&mut panel, "block_input_box", cb_assign_block_input)?; set_up_checkbox( &mut panel, "stereo_full_frame_box", @@ -498,6 +499,11 @@ fn reset_panel( .fetch_component_as::("global_box")?; c.set_checked(&mut common, owc.global); + let c = panel + .parser_state + .fetch_component_as::("block_input_box")?; + c.set_checked(&mut common, state.block_input); + panel .state .pos @@ -601,6 +607,14 @@ const fn cb_assign_global(_app: &mut AppState, owc: &mut OverlayWindowConfig, gl owc.global = global; } +const fn cb_assign_block_input( + _app: &mut AppState, + owc: &mut OverlayWindowConfig, + block_input: bool, +) { + owc.active_state.as_mut().unwrap().block_input = block_input; +} + fn cb_assign_stereo_full_frame( _app: &mut AppState, owc: &mut OverlayWindowConfig, diff --git a/wlx-common/src/windowing.rs b/wlx-common/src/windowing.rs index 23101e9..f921ed0 100644 --- a/wlx-common/src/windowing.rs +++ b/wlx-common/src/windowing.rs @@ -76,6 +76,7 @@ pub struct OverlayWindowState { pub curvature: Option, pub additive: bool, pub saved_transform: Option, + pub block_input: bool, } impl Default for OverlayWindowState { @@ -89,6 +90,7 @@ impl Default for OverlayWindowState { transform: Affine3A::IDENTITY, additive: false, saved_transform: None, + block_input: true, } } }