mouse-motion-only handsfree modes

This commit is contained in:
galister
2026-01-25 11:43:44 +09:00
parent 157c88127f
commit 3ec1dd7f4e
7 changed files with 23 additions and 10 deletions

View File

@@ -74,6 +74,8 @@
"AUTO_HELP": "ScreenCopy GPU if supported,\notherwise PipeWire GPU.", "AUTO_HELP": "ScreenCopy GPU if supported,\notherwise PipeWire GPU.",
"EYE_PINCH": "Eye + pinch", "EYE_PINCH": "Eye + pinch",
"HMD_PINCH": "HMD + pinch", "HMD_PINCH": "HMD + pinch",
"EYE_ONLY": "Eye only",
"HMD_ONLY": "HMD only",
"NONE": "None", "NONE": "None",
"PIPEWIRE_HELP": "Fast GPU capture,\nstandard on all desktops.", "PIPEWIRE_HELP": "Fast GPU capture,\nstandard on all desktops.",
"PW_FALLBACK_HELP": "Slow method with high CPU usage.\nTry in case PipeWire GPU doesn't work", "PW_FALLBACK_HELP": "Slow method with high CPU usage.\nTry in case PipeWire GPU doesn't work",

View File

@@ -167,7 +167,9 @@
<context_menu > <context_menu >
<cell translation="BAR.HANDSFREE.NONE" _press="::HandsfreeMode None" /> <cell translation="BAR.HANDSFREE.NONE" _press="::HandsfreeMode None" />
<cell translation="BAR.HANDSFREE.HMD" _press="::HandsfreeMode Hmd" /> <cell translation="BAR.HANDSFREE.HMD" _press="::HandsfreeMode Hmd" />
<cell translation="BAR.HANDSFREE.HMD_ONLY" _press="::HandsfreeMode HmdOnly" />
<cell translation="BAR.HANDSFREE.EYE_TRACKING" _press="::HandsfreeMode EyeTracking" /> <cell translation="BAR.HANDSFREE.EYE_TRACKING" _press="::HandsfreeMode EyeTracking" />
<cell translation="BAR.HANDSFREE.EYE_ONLY" _press="::HandsfreeMode EyeTrackingOnly" />
</context_menu> </context_menu>
</blueprint> </blueprint>

View File

@@ -17,7 +17,9 @@
"TITLE": "Handsfree mode", "TITLE": "Handsfree mode",
"NONE": "Off", "NONE": "Off",
"HMD": "HMD + pinch", "HMD": "HMD + pinch",
"EYE_TRACKING": "Eye + pinch" "EYE_TRACKING": "Eye + pinch",
"HMD_ONLY": "HMD only",
"EYE_ONLY": "Eye only"
} }
}, },
"DEFAULT": "Default", "DEFAULT": "Default",

View File

@@ -348,7 +348,7 @@ impl OpenXrPointer {
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
match session.config.handsfree_pointer { match session.config.handsfree_pointer {
HandsfreePointer::None => return Ok(()), HandsfreePointer::None => return Ok(()),
HandsfreePointer::Hmd => { HandsfreePointer::Hmd | HandsfreePointer::HmdOnly => {
pointer.tracked = hmd_tracked; pointer.tracked = hmd_tracked;
pointer.raw_pose = hmd; pointer.raw_pose = hmd;
pointer.pose = hmd; pointer.pose = hmd;
@@ -364,13 +364,21 @@ impl OpenXrPointer {
cur_pos.lerp(new_pos.into(), lerp_factor).into(), cur_pos.lerp(new_pos.into(), lerp_factor).into(),
); );
} }
HandsfreePointer::EyeTracking => { HandsfreePointer::EyeTracking | HandsfreePointer::EyeTrackingOnly => {
// more aggressive smoothing for eye // more aggressive smoothing for eye
self.pointer_load_pose(pointer, xr, session.config.pointer_lerp_factor * 0.5)?; self.pointer_load_pose(pointer, xr, session.config.pointer_lerp_factor * 0.5)?;
} }
} }
pointer.handsfree = pointer.tracked; pointer.handsfree = pointer.tracked;
if matches!(
session.config.handsfree_pointer,
HandsfreePointer::HmdOnly | HandsfreePointer::EyeTrackingOnly
) {
// skip actions
return Ok(());
}
self.pointer_load_actions(pointer, xr, session)?; self.pointer_load_actions(pointer, xr, session)?;
Ok(()) Ok(())

View File

@@ -1,6 +1,6 @@
use std::{rc::Rc, time::Duration}; use std::{rc::Rc, time::Duration};
use glam::{Affine3A, Quat, Vec3, Vec3A, vec3}; use glam::{Affine3A, Quat, Vec3, vec3};
use wgui::{ use wgui::{
assets::AssetPath, assets::AssetPath,
components::button::ComponentButton, components::button::ComponentButton,
@@ -23,11 +23,7 @@ use crate::{
timer::GuiTimer, timer::GuiTimer,
}, },
state::AppState, state::AppState,
windowing::{ windowing::{Z_ORDER_WATCH, backend::OverlayEventData, window::OverlayWindowConfig},
Z_ORDER_WATCH,
backend::OverlayEventData,
window::{OverlayWindowConfig, OverlayWindowData},
},
}; };
pub const WATCH_NAME: &str = "watch"; pub const WATCH_NAME: &str = "watch";

View File

@@ -12,7 +12,6 @@ use wlx_common::{
astr_containers::{AStrMap, AStrMapExt}, astr_containers::{AStrMap, AStrMapExt},
config::SerializedWindowSet, config::SerializedWindowSet,
overlays::{BackendAttrib, BackendAttribValue, ToastTopic}, overlays::{BackendAttrib, BackendAttribValue, ToastTopic},
windowing::Positioning,
}; };
use crate::{ use crate::{

View File

@@ -57,8 +57,12 @@ pub enum HandsfreePointer {
#[strum(props(Translation = "APP_SETTINGS.OPTION.HMD_PINCH"))] #[strum(props(Translation = "APP_SETTINGS.OPTION.HMD_PINCH"))]
#[default] #[default]
Hmd, Hmd,
#[strum(props(Translation = "APP_SETTINGS.OPTION.HMD_ONLY"))]
HmdOnly,
#[strum(props(Translation = "APP_SETTINGS.OPTION.EYE_PINCH"))] #[strum(props(Translation = "APP_SETTINGS.OPTION.EYE_PINCH"))]
EyeTracking, EyeTracking,
#[strum(props(Translation = "APP_SETTINGS.OPTION.EYE_ONLY"))]
EyeTrackingOnly,
} }
#[derive(Clone, Serialize, Deserialize)] #[derive(Clone, Serialize, Deserialize)]