feat: add focus follows the mouse mode (#23)
This commit is contained in:
@@ -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)]
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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")?,
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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() {
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user