add basic input blocking through libmonado (#190)
This commit is contained in:
73
src/backend/openxr/blocker.rs
Normal file
73
src/backend/openxr/blocker.rs
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
use libmonado::{ClientState, Monado};
|
||||||
|
use log::{info, warn};
|
||||||
|
|
||||||
|
use crate::{backend::overlay::OverlayID, state::AppState};
|
||||||
|
|
||||||
|
pub(super) struct InputBlocker {
|
||||||
|
hovered_last_frame: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl InputBlocker {
|
||||||
|
pub const fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
hovered_last_frame: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update(&mut self, state: &AppState, watch_id: OverlayID, monado: &mut Monado) {
|
||||||
|
if !state.session.config.block_game_input {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let any_hovered = state.input_state.pointers.iter().any(|p| {
|
||||||
|
p.interaction.hovered_id.is_some_and(|id| {
|
||||||
|
id != watch_id || !state.session.config.block_game_input_ignore_watch
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
match (any_hovered, self.hovered_last_frame) {
|
||||||
|
(true, false) => {
|
||||||
|
info!("Blocking input");
|
||||||
|
set_clients_io_active(monado, false);
|
||||||
|
}
|
||||||
|
(false, true) => {
|
||||||
|
info!("Unblocking input");
|
||||||
|
set_clients_io_active(monado, true);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.hovered_last_frame = any_hovered;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_clients_io_active(monado: &mut Monado, active: bool) {
|
||||||
|
match monado.clients() {
|
||||||
|
Ok(clients) => {
|
||||||
|
for mut client in clients {
|
||||||
|
let name = match client.name() {
|
||||||
|
Ok(n) => n,
|
||||||
|
Err(e) => {
|
||||||
|
warn!("Failed to get client name: {e}");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let state = match client.state() {
|
||||||
|
Ok(s) => s,
|
||||||
|
Err(e) => {
|
||||||
|
warn!("Failed to get client state: {e}");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if name != "wlx-overlay-s" && state.contains(ClientState::ClientSessionVisible) {
|
||||||
|
if let Err(e) = client.set_io_active(active) {
|
||||||
|
warn!("Failed to set io active for client: {e}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => warn!("Failed to get clients from Monado: {e}"),
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -35,6 +35,7 @@ use crate::{
|
|||||||
#[cfg(feature = "wayvr")]
|
#[cfg(feature = "wayvr")]
|
||||||
use crate::{gui::modular::button::WayVRAction, overlays::wayvr::wayvr_action};
|
use crate::{gui::modular::button::WayVRAction, overlays::wayvr::wayvr_action};
|
||||||
|
|
||||||
|
mod blocker;
|
||||||
mod helpers;
|
mod helpers;
|
||||||
mod input;
|
mod input;
|
||||||
mod lines;
|
mod lines;
|
||||||
@@ -108,6 +109,8 @@ pub fn openxr_run(running: Arc<AtomicBool>, show_by_default: bool) -> Result<(),
|
|||||||
.ok()
|
.ok()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let mut blocker = monado.is_some().then(blocker::InputBlocker::new);
|
||||||
|
|
||||||
let (session, mut frame_wait, mut frame_stream) = unsafe {
|
let (session, mut frame_wait, mut frame_stream) = unsafe {
|
||||||
let raw_session = helpers::create_overlay_session(
|
let raw_session = helpers::create_overlay_session(
|
||||||
&xr_instance,
|
&xr_instance,
|
||||||
@@ -268,6 +271,14 @@ pub fn openxr_run(running: Arc<AtomicBool>, show_by_default: bool) -> Result<(),
|
|||||||
input_source.update(&xr_state, &mut app)?;
|
input_source.update(&xr_state, &mut app)?;
|
||||||
app.input_state.post_update(&app.session);
|
app.input_state.post_update(&app.session);
|
||||||
|
|
||||||
|
if let Some(ref mut blocker) = blocker {
|
||||||
|
blocker.update(
|
||||||
|
&app,
|
||||||
|
watch_id,
|
||||||
|
monado.as_mut().unwrap(), // safe
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if app
|
if app
|
||||||
.input_state
|
.input_state
|
||||||
.pointers
|
.pointers
|
||||||
|
|||||||
@@ -273,6 +273,12 @@ pub struct GeneralConfig {
|
|||||||
#[serde(default = "def_false")]
|
#[serde(default = "def_false")]
|
||||||
pub focus_follows_mouse_mode: bool,
|
pub focus_follows_mouse_mode: bool,
|
||||||
|
|
||||||
|
#[serde(default = "def_false")]
|
||||||
|
pub block_game_input: bool,
|
||||||
|
|
||||||
|
#[serde(default = "def_true")]
|
||||||
|
pub block_game_input_ignore_watch: bool,
|
||||||
|
|
||||||
#[serde(default = "def_font")]
|
#[serde(default = "def_font")]
|
||||||
pub primary_font: Arc<str>,
|
pub primary_font: Arc<str>,
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user