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_IGNORE_WATCH": "Ignore watch when blocking input",
|
||||
"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_HELP": "Try changing this if you are\nexperiencing black or glitchy screens",
|
||||
"CLEAR_PIPEWIRE_TOKENS": "Clear PipeWire tokens",
|
||||
|
||||
@@ -227,6 +227,7 @@ enum SettingType {
|
||||
LeftHandedMouse,
|
||||
BlockGameInput,
|
||||
BlockGameInputIgnoreWatch,
|
||||
BlockPosesOnKbdInteraction,
|
||||
SpaceDragMultiplier,
|
||||
UseSkybox,
|
||||
UsePassthrough,
|
||||
@@ -260,6 +261,7 @@ impl SettingType {
|
||||
Self::LeftHandedMouse => &mut config.left_handed_mouse,
|
||||
Self::BlockGameInput => &mut config.block_game_input,
|
||||
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::UsePassthrough => &mut config.use_passthrough,
|
||||
Self::ScreenRenderDown => &mut config.screen_render_down,
|
||||
@@ -363,6 +365,7 @@ impl SettingType {
|
||||
Self::LeftHandedMouse => Ok("APP_SETTINGS.LEFT_HANDED_MOUSE"),
|
||||
Self::BlockGameInput => Ok("APP_SETTINGS.BLOCK_GAME_INPUT"),
|
||||
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::UseSkybox => Ok("APP_SETTINGS.USE_SKYBOX"),
|
||||
Self::UsePassthrough => Ok("APP_SETTINGS.USE_PASSTHROUGH"),
|
||||
@@ -390,6 +393,7 @@ impl SettingType {
|
||||
Self::LeftHandedMouse => Some("APP_SETTINGS.LEFT_HANDED_MOUSE_HELP"),
|
||||
Self::BlockGameInput => Some("APP_SETTINGS.BLOCK_GAME_INPUT_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::UsePassthrough => Some("APP_SETTINGS.USE_PASSTHROUGH_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);
|
||||
checkbox!(mp, c, SettingType::BlockGameInput);
|
||||
checkbox!(mp, c, SettingType::BlockGameInputIgnoreWatch);
|
||||
checkbox!(mp, c, SettingType::BlockPosesOnKbdInteraction);
|
||||
}
|
||||
TabNameEnum::Controls => {
|
||||
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::overlays::anchor::{ANCHOR_NAME, GRAB_HELP_NAME};
|
||||
use crate::overlays::keyboard::KEYBOARD_NAME;
|
||||
use crate::overlays::watch::WATCH_NAME;
|
||||
use crate::state::{AppSession, AppState};
|
||||
use crate::subsystem::hid::WheelDelta;
|
||||
@@ -210,6 +211,7 @@ pub struct InteractionState {
|
||||
pub next_push: Instant,
|
||||
pub haptics: Option<f32>,
|
||||
pub should_block_input: bool,
|
||||
pub should_block_poses: bool,
|
||||
}
|
||||
|
||||
impl Default for InteractionState {
|
||||
@@ -222,6 +224,7 @@ impl Default for InteractionState {
|
||||
next_push: Instant::now(),
|
||||
haptics: None,
|
||||
should_block_input: false,
|
||||
should_block_poses: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -473,13 +476,18 @@ 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);
|
||||
if let Some(state) = hovered.config.active_state.as_ref() {
|
||||
pointer.interaction.should_block_input = state.block_input
|
||||
&& (hovered.config.name.as_ref() != WATCH_NAME
|
||||
|| !app.session.config.block_game_input_ignore_watch);
|
||||
|
||||
pointer.interaction.should_block_poses = state.block_input
|
||||
&& 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)]
|
||||
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];
|
||||
pointer.interaction.should_block_input = false;
|
||||
pointer.interaction.should_block_poses = false;
|
||||
|
||||
// in case click released while not aiming at anything
|
||||
// send release event to overlay that was originally clicked
|
||||
|
||||
@@ -5,14 +5,16 @@ use crate::state::AppState;
|
||||
|
||||
pub(super) struct InputBlocker {
|
||||
use_io_blocks: bool,
|
||||
blocked_last_frame: bool,
|
||||
inputs_blocked_last_frame: bool,
|
||||
poses_blocked_last_frame: bool,
|
||||
}
|
||||
|
||||
impl InputBlocker {
|
||||
pub fn new(monado: &Monado) -> Self {
|
||||
Self {
|
||||
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
|
||||
};
|
||||
|
||||
let should_block = app
|
||||
let should_block_inputs = 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) => {
|
||||
let should_block_poses = app
|
||||
.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");
|
||||
self.block_inputs(monado, true);
|
||||
}
|
||||
(false, true) => {
|
||||
} else {
|
||||
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() {
|
||||
Ok(clients) => {
|
||||
for mut client in clients {
|
||||
@@ -69,13 +78,14 @@ impl InputBlocker {
|
||||
|
||||
if state.contains(ClientState::ClientSessionVisible) {
|
||||
let r = if self.use_io_blocks {
|
||||
client.set_io_blocks(if block {
|
||||
BlockFlags::BlockInputs.into()
|
||||
} else {
|
||||
BlockFlags::None.into()
|
||||
})
|
||||
let flags = match (block_inputs, block_poses) {
|
||||
(true, true) => BlockFlags::BlockPoses | BlockFlags::BlockInputs,
|
||||
(true, false) => BlockFlags::BlockInputs.into(),
|
||||
(false, _) => BlockFlags::None.into(),
|
||||
};
|
||||
client.set_io_blocks(flags)
|
||||
} else {
|
||||
client.set_io_active(!block)
|
||||
client.set_io_active(!block_inputs)
|
||||
};
|
||||
if let Err(e) = r {
|
||||
warn!("Failed to set io active for client: {e}");
|
||||
|
||||
@@ -126,6 +126,7 @@ pub struct AutoSettings {
|
||||
pub left_handed_mouse: bool,
|
||||
pub block_game_input: bool,
|
||||
pub block_game_input_ignore_watch: bool,
|
||||
pub block_poses_on_kbd_interaction: bool,
|
||||
pub space_drag_multiplier: f32,
|
||||
pub use_skybox: bool,
|
||||
pub use_passthrough: bool,
|
||||
@@ -174,6 +175,7 @@ pub fn save_settings(config: &GeneralConfig) -> anyhow::Result<()> {
|
||||
left_handed_mouse: config.left_handed_mouse,
|
||||
block_game_input: config.block_game_input,
|
||||
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,
|
||||
use_skybox: config.use_skybox,
|
||||
use_passthrough: config.use_passthrough,
|
||||
|
||||
@@ -102,6 +102,10 @@
|
||||
## Do not block input when the watch is hovered.
|
||||
#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
|
||||
#space_drag_multiplier: 1.0
|
||||
|
||||
|
||||
@@ -251,6 +251,9 @@ pub struct GeneralConfig {
|
||||
#[serde(default = "def_true")]
|
||||
pub block_game_input_ignore_watch: bool,
|
||||
|
||||
#[serde(default = "def_true")]
|
||||
pub block_poses_on_kbd_interaction: bool,
|
||||
|
||||
#[serde(default = "def_one")]
|
||||
pub space_drag_multiplier: f32,
|
||||
|
||||
|
||||
Reference in New Issue
Block a user