add option to block poses when using keyboard (OpenXR only)
This commit is contained in:
@@ -36,6 +36,8 @@
|
|||||||
"BLOCK_GAME_INPUT_HELP": "Blocks all input when an overlay is hovered",
|
"BLOCK_GAME_INPUT_HELP": "Blocks all input when an overlay is hovered",
|
||||||
"BLOCK_GAME_INPUT_IGNORE_WATCH": "Ignore watch when blocking input",
|
"BLOCK_GAME_INPUT_IGNORE_WATCH": "Ignore watch when blocking input",
|
||||||
"BLOCK_GAME_INPUT_IGNORE_WATCH_HELP": "Do not block input when watch is hovered",
|
"BLOCK_GAME_INPUT_IGNORE_WATCH_HELP": "Do not block input when watch is hovered",
|
||||||
|
"BLOCK_POSES_ON_KBD_INTERACTION": "Block poses when interacting with keyboard",
|
||||||
|
"BLOCK_POSES_ON_KBD_INTERACTION_HELP": "Blocks the game from receiving poses when the keyboard is hovered and 'Block game input' is enabled",
|
||||||
"CAPTURE_METHOD": "Wayland screen capture",
|
"CAPTURE_METHOD": "Wayland screen capture",
|
||||||
"CAPTURE_METHOD_HELP": "Try changing this if you are\nexperiencing black or glitchy screens",
|
"CAPTURE_METHOD_HELP": "Try changing this if you are\nexperiencing black or glitchy screens",
|
||||||
"CLEAR_PIPEWIRE_TOKENS": "Clear PipeWire tokens",
|
"CLEAR_PIPEWIRE_TOKENS": "Clear PipeWire tokens",
|
||||||
|
|||||||
@@ -227,6 +227,7 @@ enum SettingType {
|
|||||||
LeftHandedMouse,
|
LeftHandedMouse,
|
||||||
BlockGameInput,
|
BlockGameInput,
|
||||||
BlockGameInputIgnoreWatch,
|
BlockGameInputIgnoreWatch,
|
||||||
|
BlockPosesOnKbdInteraction,
|
||||||
SpaceDragMultiplier,
|
SpaceDragMultiplier,
|
||||||
UseSkybox,
|
UseSkybox,
|
||||||
UsePassthrough,
|
UsePassthrough,
|
||||||
@@ -260,6 +261,7 @@ impl SettingType {
|
|||||||
Self::LeftHandedMouse => &mut config.left_handed_mouse,
|
Self::LeftHandedMouse => &mut config.left_handed_mouse,
|
||||||
Self::BlockGameInput => &mut config.block_game_input,
|
Self::BlockGameInput => &mut config.block_game_input,
|
||||||
Self::BlockGameInputIgnoreWatch => &mut config.block_game_input_ignore_watch,
|
Self::BlockGameInputIgnoreWatch => &mut config.block_game_input_ignore_watch,
|
||||||
|
Self::BlockPosesOnKbdInteraction => &mut config.block_poses_on_kbd_interaction,
|
||||||
Self::UseSkybox => &mut config.use_skybox,
|
Self::UseSkybox => &mut config.use_skybox,
|
||||||
Self::UsePassthrough => &mut config.use_passthrough,
|
Self::UsePassthrough => &mut config.use_passthrough,
|
||||||
Self::ScreenRenderDown => &mut config.screen_render_down,
|
Self::ScreenRenderDown => &mut config.screen_render_down,
|
||||||
@@ -363,6 +365,7 @@ impl SettingType {
|
|||||||
Self::LeftHandedMouse => Ok("APP_SETTINGS.LEFT_HANDED_MOUSE"),
|
Self::LeftHandedMouse => Ok("APP_SETTINGS.LEFT_HANDED_MOUSE"),
|
||||||
Self::BlockGameInput => Ok("APP_SETTINGS.BLOCK_GAME_INPUT"),
|
Self::BlockGameInput => Ok("APP_SETTINGS.BLOCK_GAME_INPUT"),
|
||||||
Self::BlockGameInputIgnoreWatch => Ok("APP_SETTINGS.BLOCK_GAME_INPUT_IGNORE_WATCH"),
|
Self::BlockGameInputIgnoreWatch => Ok("APP_SETTINGS.BLOCK_GAME_INPUT_IGNORE_WATCH"),
|
||||||
|
Self::BlockPosesOnKbdInteraction => Ok("APP_SETTINGS.BLOCK_POSES_ON_KBD_INTERACTION"),
|
||||||
Self::SpaceDragMultiplier => Ok("APP_SETTINGS.SPACE_DRAG_MULTIPLIER"),
|
Self::SpaceDragMultiplier => Ok("APP_SETTINGS.SPACE_DRAG_MULTIPLIER"),
|
||||||
Self::UseSkybox => Ok("APP_SETTINGS.USE_SKYBOX"),
|
Self::UseSkybox => Ok("APP_SETTINGS.USE_SKYBOX"),
|
||||||
Self::UsePassthrough => Ok("APP_SETTINGS.USE_PASSTHROUGH"),
|
Self::UsePassthrough => Ok("APP_SETTINGS.USE_PASSTHROUGH"),
|
||||||
@@ -390,6 +393,7 @@ impl SettingType {
|
|||||||
Self::LeftHandedMouse => Some("APP_SETTINGS.LEFT_HANDED_MOUSE_HELP"),
|
Self::LeftHandedMouse => Some("APP_SETTINGS.LEFT_HANDED_MOUSE_HELP"),
|
||||||
Self::BlockGameInput => Some("APP_SETTINGS.BLOCK_GAME_INPUT_HELP"),
|
Self::BlockGameInput => Some("APP_SETTINGS.BLOCK_GAME_INPUT_HELP"),
|
||||||
Self::BlockGameInputIgnoreWatch => Some("APP_SETTINGS.BLOCK_GAME_INPUT_IGNORE_WATCH_HELP"),
|
Self::BlockGameInputIgnoreWatch => Some("APP_SETTINGS.BLOCK_GAME_INPUT_IGNORE_WATCH_HELP"),
|
||||||
|
Self::BlockPosesOnKbdInteraction => Some("APP_SETTINGS.BLOCK_POSES_ON_KBD_INTERACTION_HELP"),
|
||||||
Self::UseSkybox => Some("APP_SETTINGS.USE_SKYBOX_HELP"),
|
Self::UseSkybox => Some("APP_SETTINGS.USE_SKYBOX_HELP"),
|
||||||
Self::UsePassthrough => Some("APP_SETTINGS.USE_PASSTHROUGH_HELP"),
|
Self::UsePassthrough => Some("APP_SETTINGS.USE_PASSTHROUGH_HELP"),
|
||||||
Self::ScreenRenderDown => Some("APP_SETTINGS.SCREEN_RENDER_DOWN_HELP"),
|
Self::ScreenRenderDown => Some("APP_SETTINGS.SCREEN_RENDER_DOWN_HELP"),
|
||||||
@@ -726,6 +730,7 @@ impl<T> TabSettings<T> {
|
|||||||
slider_f32!(mp, c, SettingType::SpaceDragMultiplier, -10.0, 10.0, 0.5);
|
slider_f32!(mp, c, SettingType::SpaceDragMultiplier, -10.0, 10.0, 0.5);
|
||||||
checkbox!(mp, c, SettingType::BlockGameInput);
|
checkbox!(mp, c, SettingType::BlockGameInput);
|
||||||
checkbox!(mp, c, SettingType::BlockGameInputIgnoreWatch);
|
checkbox!(mp, c, SettingType::BlockGameInputIgnoreWatch);
|
||||||
|
checkbox!(mp, c, SettingType::BlockPosesOnKbdInteraction);
|
||||||
}
|
}
|
||||||
TabNameEnum::Controls => {
|
TabNameEnum::Controls => {
|
||||||
let c = category!(mp, root, "APP_SETTINGS.CONTROLS", "dashboard/controller.svg")?;
|
let c = category!(mp, root, "APP_SETTINGS.CONTROLS", "dashboard/controller.svg")?;
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ use wlx_common::windowing::{OverlayWindowState, Positioning};
|
|||||||
|
|
||||||
use crate::backend::task::{InputTask, OverlayTask};
|
use crate::backend::task::{InputTask, OverlayTask};
|
||||||
use crate::overlays::anchor::{ANCHOR_NAME, GRAB_HELP_NAME};
|
use crate::overlays::anchor::{ANCHOR_NAME, GRAB_HELP_NAME};
|
||||||
|
use crate::overlays::keyboard::KEYBOARD_NAME;
|
||||||
use crate::overlays::watch::WATCH_NAME;
|
use crate::overlays::watch::WATCH_NAME;
|
||||||
use crate::state::{AppSession, AppState};
|
use crate::state::{AppSession, AppState};
|
||||||
use crate::subsystem::hid::WheelDelta;
|
use crate::subsystem::hid::WheelDelta;
|
||||||
@@ -210,6 +211,7 @@ pub struct InteractionState {
|
|||||||
pub next_push: Instant,
|
pub next_push: Instant,
|
||||||
pub haptics: Option<f32>,
|
pub haptics: Option<f32>,
|
||||||
pub should_block_input: bool,
|
pub should_block_input: bool,
|
||||||
|
pub should_block_poses: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for InteractionState {
|
impl Default for InteractionState {
|
||||||
@@ -222,6 +224,7 @@ impl Default for InteractionState {
|
|||||||
next_push: Instant::now(),
|
next_push: Instant::now(),
|
||||||
haptics: None,
|
haptics: None,
|
||||||
should_block_input: false,
|
should_block_input: false,
|
||||||
|
should_block_poses: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -473,13 +476,18 @@ where
|
|||||||
hit.primary = true;
|
hit.primary = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
pointer.interaction.should_block_input = hovered
|
if let Some(state) = hovered.config.active_state.as_ref() {
|
||||||
.config
|
pointer.interaction.should_block_input = state.block_input
|
||||||
.active_state
|
&& (hovered.config.name.as_ref() != WATCH_NAME
|
||||||
.as_ref()
|
|| !app.session.config.block_game_input_ignore_watch);
|
||||||
.map_or(false, |state| state.block_input)
|
|
||||||
&& (hovered.config.name.as_ref() != WATCH_NAME
|
pointer.interaction.should_block_poses = state.block_input
|
||||||
|| !app.session.config.block_game_input_ignore_watch);
|
&& app.session.config.block_poses_on_kbd_interaction
|
||||||
|
&& hovered.config.name.as_ref() == KEYBOARD_NAME;
|
||||||
|
} else {
|
||||||
|
pointer.interaction.should_block_input = false;
|
||||||
|
pointer.interaction.should_block_poses = false;
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
log::trace!("Hit: {} {:?}", hovered.config.name, hit);
|
log::trace!("Hit: {} {:?}", hovered.config.name, hit);
|
||||||
@@ -556,6 +564,7 @@ fn handle_no_hit<O>(
|
|||||||
|
|
||||||
let pointer = &mut app.input_state.pointers[pointer_idx];
|
let pointer = &mut app.input_state.pointers[pointer_idx];
|
||||||
pointer.interaction.should_block_input = false;
|
pointer.interaction.should_block_input = false;
|
||||||
|
pointer.interaction.should_block_poses = false;
|
||||||
|
|
||||||
// in case click released while not aiming at anything
|
// in case click released while not aiming at anything
|
||||||
// send release event to overlay that was originally clicked
|
// send release event to overlay that was originally clicked
|
||||||
|
|||||||
@@ -5,14 +5,16 @@ use crate::state::AppState;
|
|||||||
|
|
||||||
pub(super) struct InputBlocker {
|
pub(super) struct InputBlocker {
|
||||||
use_io_blocks: bool,
|
use_io_blocks: bool,
|
||||||
blocked_last_frame: bool,
|
inputs_blocked_last_frame: bool,
|
||||||
|
poses_blocked_last_frame: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InputBlocker {
|
impl InputBlocker {
|
||||||
pub fn new(monado: &Monado) -> Self {
|
pub fn new(monado: &Monado) -> Self {
|
||||||
Self {
|
Self {
|
||||||
use_io_blocks: monado.get_api_version() >= Version::new(1, 6, 0),
|
use_io_blocks: monado.get_api_version() >= Version::new(1, 6, 0),
|
||||||
blocked_last_frame: false,
|
inputs_blocked_last_frame: false,
|
||||||
|
poses_blocked_last_frame: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -21,29 +23,36 @@ impl InputBlocker {
|
|||||||
return; // monado not available
|
return; // monado not available
|
||||||
};
|
};
|
||||||
|
|
||||||
let should_block = app
|
let should_block_inputs = app
|
||||||
.input_state
|
.input_state
|
||||||
.pointers
|
.pointers
|
||||||
.iter()
|
.iter()
|
||||||
.any(|p| p.interaction.should_block_input)
|
.any(|p| p.interaction.should_block_input)
|
||||||
&& app.session.config.block_game_input;
|
&& app.session.config.block_game_input;
|
||||||
|
|
||||||
match (should_block, self.blocked_last_frame) {
|
let should_block_poses = app
|
||||||
(true, false) => {
|
.input_state
|
||||||
|
.pointers
|
||||||
|
.iter()
|
||||||
|
.any(|p| p.interaction.should_block_poses)
|
||||||
|
&& app.session.config.block_poses_on_kbd_interaction;
|
||||||
|
|
||||||
|
if should_block_inputs != self.inputs_blocked_last_frame
|
||||||
|
|| should_block_poses != self.poses_blocked_last_frame
|
||||||
|
{
|
||||||
|
if should_block_inputs {
|
||||||
trace!("Blocking input");
|
trace!("Blocking input");
|
||||||
self.block_inputs(monado, true);
|
} else {
|
||||||
}
|
|
||||||
(false, true) => {
|
|
||||||
trace!("Unblocking input");
|
trace!("Unblocking input");
|
||||||
self.block_inputs(monado, false);
|
|
||||||
}
|
}
|
||||||
_ => {}
|
self.block_inputs(monado, should_block_inputs, should_block_poses);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.blocked_last_frame = should_block;
|
self.inputs_blocked_last_frame = should_block_inputs;
|
||||||
|
self.poses_blocked_last_frame = should_block_poses;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn block_inputs(&self, monado: &mut Monado, block: bool) {
|
fn block_inputs(&self, monado: &mut Monado, block_inputs: bool, block_poses: bool) {
|
||||||
match monado.clients() {
|
match monado.clients() {
|
||||||
Ok(clients) => {
|
Ok(clients) => {
|
||||||
for mut client in clients {
|
for mut client in clients {
|
||||||
@@ -69,13 +78,14 @@ impl InputBlocker {
|
|||||||
|
|
||||||
if state.contains(ClientState::ClientSessionVisible) {
|
if state.contains(ClientState::ClientSessionVisible) {
|
||||||
let r = if self.use_io_blocks {
|
let r = if self.use_io_blocks {
|
||||||
client.set_io_blocks(if block {
|
let flags = match (block_inputs, block_poses) {
|
||||||
BlockFlags::BlockInputs.into()
|
(true, true) => BlockFlags::BlockPoses | BlockFlags::BlockInputs,
|
||||||
} else {
|
(true, false) => BlockFlags::BlockInputs.into(),
|
||||||
BlockFlags::None.into()
|
(false, _) => BlockFlags::None.into(),
|
||||||
})
|
};
|
||||||
|
client.set_io_blocks(flags)
|
||||||
} else {
|
} else {
|
||||||
client.set_io_active(!block)
|
client.set_io_active(!block_inputs)
|
||||||
};
|
};
|
||||||
if let Err(e) = r {
|
if let Err(e) = r {
|
||||||
warn!("Failed to set io active for client: {e}");
|
warn!("Failed to set io active for client: {e}");
|
||||||
|
|||||||
@@ -126,6 +126,7 @@ pub struct AutoSettings {
|
|||||||
pub left_handed_mouse: bool,
|
pub left_handed_mouse: bool,
|
||||||
pub block_game_input: bool,
|
pub block_game_input: bool,
|
||||||
pub block_game_input_ignore_watch: bool,
|
pub block_game_input_ignore_watch: bool,
|
||||||
|
pub block_poses_on_kbd_interaction: bool,
|
||||||
pub space_drag_multiplier: f32,
|
pub space_drag_multiplier: f32,
|
||||||
pub use_skybox: bool,
|
pub use_skybox: bool,
|
||||||
pub use_passthrough: bool,
|
pub use_passthrough: bool,
|
||||||
@@ -174,6 +175,7 @@ pub fn save_settings(config: &GeneralConfig) -> anyhow::Result<()> {
|
|||||||
left_handed_mouse: config.left_handed_mouse,
|
left_handed_mouse: config.left_handed_mouse,
|
||||||
block_game_input: config.block_game_input,
|
block_game_input: config.block_game_input,
|
||||||
block_game_input_ignore_watch: config.block_game_input_ignore_watch,
|
block_game_input_ignore_watch: config.block_game_input_ignore_watch,
|
||||||
|
block_poses_on_kbd_interaction: config.block_poses_on_kbd_interaction,
|
||||||
space_drag_multiplier: config.space_drag_multiplier,
|
space_drag_multiplier: config.space_drag_multiplier,
|
||||||
use_skybox: config.use_skybox,
|
use_skybox: config.use_skybox,
|
||||||
use_passthrough: config.use_passthrough,
|
use_passthrough: config.use_passthrough,
|
||||||
|
|||||||
@@ -102,6 +102,10 @@
|
|||||||
## Do not block input when the watch is hovered.
|
## Do not block input when the watch is hovered.
|
||||||
#block_game_input_ignore_watch: true
|
#block_game_input_ignore_watch: true
|
||||||
|
|
||||||
|
## Monado/WiVRn only. Do not send hand poses when interacting with the
|
||||||
|
## keyboard.
|
||||||
|
#block_poses_on_kbd_interaction: true
|
||||||
|
|
||||||
## How fast to drag when the space drag feature is activated
|
## How fast to drag when the space drag feature is activated
|
||||||
#space_drag_multiplier: 1.0
|
#space_drag_multiplier: 1.0
|
||||||
|
|
||||||
|
|||||||
@@ -251,6 +251,9 @@ pub struct GeneralConfig {
|
|||||||
#[serde(default = "def_true")]
|
#[serde(default = "def_true")]
|
||||||
pub block_game_input_ignore_watch: bool,
|
pub block_game_input_ignore_watch: bool,
|
||||||
|
|
||||||
|
#[serde(default = "def_true")]
|
||||||
|
pub block_poses_on_kbd_interaction: bool,
|
||||||
|
|
||||||
#[serde(default = "def_one")]
|
#[serde(default = "def_one")]
|
||||||
pub space_drag_multiplier: f32,
|
pub space_drag_multiplier: f32,
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user