feat: add focus follows the mouse mode (#23)

This commit is contained in:
alexdenerqal
2024-04-07 17:12:47 +02:00
committed by GitHub
parent 7e2f172b74
commit 1d1a4f01ae
9 changed files with 69 additions and 1 deletions

View File

@@ -198,6 +198,7 @@ pub struct PointerState {
pub space_rotate: bool, pub space_rotate: bool,
pub click_modifier_right: bool, pub click_modifier_right: bool,
pub click_modifier_middle: bool, pub click_modifier_middle: bool,
pub move_mouse: bool,
} }
#[derive(Debug, Clone, Copy, Default)] #[derive(Debug, Clone, Copy, Default)]

View File

@@ -39,6 +39,7 @@ const PATH_SPACE_DRAG: &str = "/actions/default/in/SpaceDrag";
const PATH_SPACE_ROTATE: &str = "/actions/default/in/SpaceRotate"; const PATH_SPACE_ROTATE: &str = "/actions/default/in/SpaceRotate";
const PATH_CLICK_MODIFIER_RIGHT: &str = "/actions/default/in/ClickModifierRight"; const PATH_CLICK_MODIFIER_RIGHT: &str = "/actions/default/in/ClickModifierRight";
const PATH_CLICK_MODIFIER_MIDDLE: &str = "/actions/default/in/ClickModifierMiddle"; const PATH_CLICK_MODIFIER_MIDDLE: &str = "/actions/default/in/ClickModifierMiddle";
const PATH_MOVE_MOUSE: &str = "/actions/default/in/MoveMouse";
const INPUT_ANY: InputValueHandle = InputValueHandle(ovr_overlay::sys::k_ulInvalidInputValueHandle); const INPUT_ANY: InputValueHandle = InputValueHandle(ovr_overlay::sys::k_ulInvalidInputValueHandle);
@@ -54,6 +55,7 @@ pub(super) struct OpenVrInputSource {
space_rotate_hnd: ActionHandle, space_rotate_hnd: ActionHandle,
click_modifier_right_hnd: ActionHandle, click_modifier_right_hnd: ActionHandle,
click_modifier_middle_hnd: ActionHandle, click_modifier_middle_hnd: ActionHandle,
move_mouse_hnd: ActionHandle,
} }
pub(super) struct OpenVrHandSource { pub(super) struct OpenVrHandSource {
@@ -77,6 +79,7 @@ impl OpenVrInputSource {
let space_rotate_hnd = input.get_action_handle(PATH_SPACE_ROTATE)?; let space_rotate_hnd = input.get_action_handle(PATH_SPACE_ROTATE)?;
let click_modifier_right_hnd = input.get_action_handle(PATH_CLICK_MODIFIER_RIGHT)?; let click_modifier_right_hnd = input.get_action_handle(PATH_CLICK_MODIFIER_RIGHT)?;
let click_modifier_middle_hnd = input.get_action_handle(PATH_CLICK_MODIFIER_MIDDLE)?; let click_modifier_middle_hnd = input.get_action_handle(PATH_CLICK_MODIFIER_MIDDLE)?;
let move_mouse_hnd = input.get_action_handle(PATH_MOVE_MOUSE)?;
let input_hnd: Vec<InputValueHandle> = INPUT_SOURCES let input_hnd: Vec<InputValueHandle> = INPUT_SOURCES
.iter() .iter()
@@ -112,6 +115,7 @@ impl OpenVrInputSource {
space_rotate_hnd, space_rotate_hnd,
click_modifier_right_hnd, click_modifier_right_hnd,
click_modifier_middle_hnd, click_modifier_middle_hnd,
move_mouse_hnd,
hands, hands,
}) })
} }
@@ -212,6 +216,11 @@ impl OpenVrInputSource {
.map(|x| x.0.bState) .map(|x| x.0.bState)
.unwrap_or(false); .unwrap_or(false);
app_hand.now.move_mouse = input
.get_digital_action_data(self.move_mouse_hnd, hand.input_hnd)
.map(|x| x.0.bState)
.unwrap_or(false);
app_hand.now.scroll = input app_hand.now.scroll = input
.get_analog_action_data(self.scroll_hnd, hand.input_hnd) .get_analog_action_data(self.scroll_hnd, hand.input_hnd)
.map(|x| x.0.y) .map(|x| x.0.y)

View File

@@ -53,6 +53,7 @@ pub(super) struct OpenXrHandSource {
action_show_hide: xr::Action<bool>, action_show_hide: xr::Action<bool>,
action_click_modifier_right: xr::Action<bool>, action_click_modifier_right: xr::Action<bool>,
action_click_modifier_middle: xr::Action<bool>, action_click_modifier_middle: xr::Action<bool>,
action_move_mouse: xr::Action<bool>,
action_haptics: xr::Action<xr::Haptic>, action_haptics: xr::Action<xr::Haptic>,
} }
@@ -194,6 +195,12 @@ impl OpenXrHand {
.state(&xr.session, xr::Path::NULL)? .state(&xr.session, xr::Path::NULL)?
.current_state; .current_state;
pointer.now.move_mouse = self
.source
.action_move_mouse
.state(&xr.session, xr::Path::NULL)?
.current_state;
Ok(()) Ok(())
} }
} }
@@ -242,6 +249,11 @@ impl OpenXrHandSource {
&format!("{} hand middle click modifier", side), &format!("{} hand middle click modifier", side),
&[], &[],
)?; )?;
let action_move_mouse = action_set.create_action::<bool>(
&format!("{}_move_mouse", side),
&format!("{} hand mouse move", side),
&[],
)?;
let action_haptics = action_set.create_action::<xr::Haptic>( let action_haptics = action_set.create_action::<xr::Haptic>(
&format!("{}_haptics", side), &format!("{}_haptics", side),
&format!("{} hand haptics", side), &format!("{} hand haptics", side),
@@ -257,6 +269,7 @@ impl OpenXrHandSource {
action_show_hide, action_show_hide,
action_click_modifier_right, action_click_modifier_right,
action_click_modifier_middle, action_click_modifier_middle,
action_move_mouse,
action_haptics, action_haptics,
}) })
} }
@@ -359,6 +372,14 @@ fn suggest_bindings(
&hands[1].action_click_modifier_middle, &hands[1].action_click_modifier_middle,
instance.string_to_path("/user/hand/right/input/a/touch")?, instance.string_to_path("/user/hand/right/input/a/touch")?,
), ),
xr::Binding::new(
&hands[0].action_move_mouse,
instance.string_to_path("/user/hand/left/input/trigger/touch")?,
),
xr::Binding::new(
&hands[1].action_move_mouse,
instance.string_to_path("/user/hand/right/input/trigger/touch")?,
),
xr::Binding::new( xr::Binding::new(
&hands[0].action_haptics, &hands[0].action_haptics,
instance.string_to_path("/user/hand/left/output/haptic")?, instance.string_to_path("/user/hand/left/output/haptic")?,
@@ -434,6 +455,14 @@ fn suggest_bindings(
&hands[1].action_click_modifier_middle, &hands[1].action_click_modifier_middle,
instance.string_to_path("/user/hand/right/input/a/touch")?, instance.string_to_path("/user/hand/right/input/a/touch")?,
), ),
xr::Binding::new(
&hands[0].action_move_mouse,
instance.string_to_path("/user/hand/left/input/trigger/touch")?,
),
xr::Binding::new(
&hands[1].action_move_mouse,
instance.string_to_path("/user/hand/right/input/trigger/touch")?,
),
xr::Binding::new( xr::Binding::new(
&hands[0].action_haptics, &hands[0].action_haptics,
instance.string_to_path("/user/hand/left/output/haptic")?, instance.string_to_path("/user/hand/left/output/haptic")?,

View File

@@ -223,6 +223,9 @@ pub struct GeneralConfig {
#[serde(default = "def_true")] #[serde(default = "def_true")]
pub realign_on_showhide: bool, pub realign_on_showhide: bool,
#[serde(default = "def_false")]
pub focus_follows_mouse_mode: bool,
} }
impl GeneralConfig { impl GeneralConfig {

View File

@@ -90,7 +90,9 @@ impl InteractionHandler for ScreenInteractionHandler {
fn on_hover(&mut self, app: &mut AppState, hit: &PointerHit) -> Option<Haptics> { fn on_hover(&mut self, app: &mut AppState, hit: &PointerHit) -> Option<Haptics> {
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
log::trace!("Hover: {:?}", hit.uv); log::trace!("Hover: {:?}", hit.uv);
if self.next_move < Instant::now() { if self.next_move < Instant::now() &&
(!app.session.config.focus_follows_mouse_mode
|| app.input_state.pointers[hit.pointer].now.move_mouse) {
let pos = self.mouse_transform.transform_point2(hit.uv); let pos = self.mouse_transform.transform_point2(hit.uv);
app.hid_provider.mouse_move(pos); app.hid_provider.mouse_move(pos);
} }
@@ -112,6 +114,7 @@ impl InteractionHandler for ScreenInteractionHandler {
let pos = self.mouse_transform.transform_point2(hit.uv); let pos = self.mouse_transform.transform_point2(hit.uv);
app.hid_provider.mouse_move(pos); app.hid_provider.mouse_move(pos);
} }
fn on_scroll(&mut self, app: &mut AppState, hit: &PointerHit, delta: f32) { fn on_scroll(&mut self, app: &mut AppState, hit: &PointerHit, delta: f32) {
if self.next_scroll > Instant::now() { if self.next_scroll > Instant::now() {

View File

@@ -35,6 +35,11 @@
"type": "boolean", "type": "boolean",
"requirement": "optional" "requirement": "optional"
}, },
{
"name": "/actions/default/in/MoveMouse",
"type": "boolean",
"requirement": "optional"
},
{ {
"name": "/actions/default/in/SpaceDrag", "name": "/actions/default/in/SpaceDrag",
"type": "boolean", "type": "boolean",

View File

@@ -67,6 +67,9 @@
"inputs" : { "inputs" : {
"click" : { "click" : {
"output" : "/actions/default/in/click" "output" : "/actions/default/in/click"
},
"touch": {
"output": "/actions/default/in/movemouse"
} }
}, },
"mode" : "button", "mode" : "button",
@@ -80,6 +83,9 @@
"inputs" : { "inputs" : {
"click" : { "click" : {
"output" : "/actions/default/in/click" "output" : "/actions/default/in/click"
},
"touch": {
"output": "/actions/default/in/movemouse"
} }
}, },
"mode" : "button", "mode" : "button",

View File

@@ -67,6 +67,9 @@
"inputs" : { "inputs" : {
"click" : { "click" : {
"output" : "/actions/default/in/click" "output" : "/actions/default/in/click"
},
"touch": {
"output": "/actions/default/in/movemouse"
} }
}, },
"mode": "button", "mode": "button",
@@ -76,6 +79,9 @@
"inputs" : { "inputs" : {
"click" : { "click" : {
"output" : "/actions/default/in/click" "output" : "/actions/default/in/click"
},
"touch": {
"output": "/actions/default/in/movemouse"
} }
}, },
"mode": "button", "mode": "button",

View File

@@ -19,3 +19,9 @@ allow_sliding: true
# Enable / disable realigning the working set windows when they are shown/hidden # Enable / disable realigning the working set windows when they are shown/hidden
# Default: true # Default: true
realign_on_showhide: true realign_on_showhide: true
# When enabled, the mouse pointer will not be moved on the screen, unless the trigger is touched
# allowing for moving both pointers off the screens to the keyboard, while keeping the cursor position
# unchanged, for when the desktop is configured to move the focus with the mouse cursor
# Default: false
focus_follows_mouse_mode: false