Switch to WheelHiRes. Add horizontal scrolling (#171)
* Switch to HiResScroll. Add horizontal scrolling * Fix OpenVR compilation for horizontal scrolling * fix OpenXR scroll using x axis for both scroll axes
This commit is contained in:
@@ -217,7 +217,8 @@ impl Pointer {
|
||||
|
||||
#[derive(Clone, Copy, Default)]
|
||||
pub struct PointerState {
|
||||
pub scroll: f32,
|
||||
pub scroll_x: f32,
|
||||
pub scroll_y: f32,
|
||||
pub click: bool,
|
||||
pub grab: bool,
|
||||
pub alt_click: bool,
|
||||
@@ -252,7 +253,7 @@ pub trait InteractionHandler {
|
||||
fn on_hover(&mut self, app: &mut AppState, hit: &PointerHit) -> Option<Haptics>;
|
||||
fn on_left(&mut self, app: &mut AppState, pointer: usize);
|
||||
fn on_pointer(&mut self, app: &mut AppState, hit: &PointerHit, pressed: bool);
|
||||
fn on_scroll(&mut self, app: &mut AppState, hit: &PointerHit, delta: f32);
|
||||
fn on_scroll(&mut self, app: &mut AppState, hit: &PointerHit, delta_y: f32, delta_x: f32);
|
||||
}
|
||||
|
||||
pub struct DummyInteractionHandler;
|
||||
@@ -263,7 +264,7 @@ impl InteractionHandler for DummyInteractionHandler {
|
||||
None
|
||||
}
|
||||
fn on_pointer(&mut self, _app: &mut AppState, _hit: &PointerHit, _pressed: bool) {}
|
||||
fn on_scroll(&mut self, _app: &mut AppState, _hit: &PointerHit, _delta: f32) {}
|
||||
fn on_scroll(&mut self, _app: &mut AppState, _hit: &PointerHit, _delta_y: f32, _delta_x: f32) {}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Default)]
|
||||
@@ -419,8 +420,9 @@ where
|
||||
|
||||
pointer = &mut app.input_state.pointers[idx];
|
||||
|
||||
if pointer.now.scroll.abs() > 0.1 {
|
||||
let scroll = pointer.now.scroll;
|
||||
if pointer.now.scroll_x.abs() > 0.1 || pointer.now.scroll_y.abs() > 0.1 {
|
||||
let scroll_x = pointer.now.scroll_x;
|
||||
let scroll_y = pointer.now.scroll_y;
|
||||
if app.input_state.pointers[1 - idx]
|
||||
.interaction
|
||||
.grabbed
|
||||
@@ -432,7 +434,7 @@ where
|
||||
|
||||
if can_curve {
|
||||
let cur = hovered.state.curvature.unwrap_or(0.0);
|
||||
let new = (cur - scroll * 0.01).min(0.5);
|
||||
let new = (cur - scroll_y * 0.01).min(0.5);
|
||||
if new <= f32::EPSILON {
|
||||
hovered.state.curvature = None;
|
||||
} else {
|
||||
@@ -442,7 +444,7 @@ where
|
||||
hovered.state.curvature = None;
|
||||
}
|
||||
} else {
|
||||
hovered.backend.on_scroll(app, &hit, scroll);
|
||||
hovered.backend.on_scroll(app, &hit, scroll_y, scroll_x);
|
||||
}
|
||||
pointer = &mut app.input_state.pointers[idx];
|
||||
}
|
||||
@@ -560,10 +562,10 @@ impl Pointer {
|
||||
if self.now.click {
|
||||
self.interaction.mode = PointerMode::Special;
|
||||
let cur_scale = overlay.state.transform.x_axis.length();
|
||||
if cur_scale < 0.1 && self.now.scroll > 0.0 {
|
||||
if cur_scale < 0.1 && self.now.scroll_y > 0.0 {
|
||||
return;
|
||||
}
|
||||
if cur_scale > 20. && self.now.scroll < 0.0 {
|
||||
if cur_scale > 20. && self.now.scroll_y < 0.0 {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -571,9 +573,9 @@ impl Pointer {
|
||||
.state
|
||||
.transform
|
||||
.matrix3
|
||||
.mul_scalar(1.0 - 0.025 * self.now.scroll);
|
||||
} else if config.allow_sliding && self.now.scroll.is_finite() {
|
||||
grab_data.offset.z -= self.now.scroll * 0.05;
|
||||
.mul_scalar(1.0 - 0.025 * self.now.scroll_y);
|
||||
} else if config.allow_sliding && self.now.scroll_y.is_finite() {
|
||||
grab_data.offset.z -= self.now.scroll_y * 0.05;
|
||||
}
|
||||
overlay.state.transform.translation = self.pose.transform_point3a(grab_data.offset);
|
||||
overlay.state.realign(hmd);
|
||||
|
||||
@@ -230,10 +230,12 @@ impl OpenVrInputSource {
|
||||
.map(|x| x.0.bState)
|
||||
.unwrap_or(false);
|
||||
|
||||
app_hand.now.scroll = input
|
||||
let scroll = input
|
||||
.get_analog_action_data(self.scroll_hnd, hand.input_hnd)
|
||||
.map(|x| x.0.y)
|
||||
.unwrap_or(0.0);
|
||||
.map(|x| (x.0.x, x.0.y))
|
||||
.unwrap_or((0.0, 0.0));
|
||||
app_hand.now.scroll_x = scroll.0;
|
||||
app_hand.now.scroll_y = scroll.1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ use std::{
|
||||
|
||||
use glam::{bool, Affine3A, Quat, Vec3};
|
||||
use libmonado as mnd;
|
||||
use openxr::{self as xr, Quaternionf, Vector3f};
|
||||
use openxr::{self as xr, Quaternionf, Vector2f, Vector3f};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
@@ -161,7 +161,7 @@ pub(super) struct OpenXrHandSource {
|
||||
action_modifier_right: CustomClickAction,
|
||||
action_modifier_middle: CustomClickAction,
|
||||
action_move_mouse: CustomClickAction,
|
||||
action_scroll: xr::Action<f32>,
|
||||
action_scroll: xr::Action<Vector2f>,
|
||||
action_haptics: xr::Action<xr::Haptic>,
|
||||
}
|
||||
|
||||
@@ -350,12 +350,15 @@ impl OpenXrHand {
|
||||
.action_grab
|
||||
.state(pointer.before.grab, xr, session)?;
|
||||
|
||||
pointer.now.scroll = self
|
||||
let scroll = self
|
||||
.source
|
||||
.action_scroll
|
||||
.state(&xr.session, xr::Path::NULL)?
|
||||
.current_state;
|
||||
|
||||
pointer.now.scroll_x = scroll.x;
|
||||
pointer.now.scroll_y = scroll.y;
|
||||
|
||||
pointer.now.alt_click =
|
||||
self.source
|
||||
.action_alt_click
|
||||
@@ -417,7 +420,7 @@ impl OpenXrHandSource {
|
||||
&[],
|
||||
)?;
|
||||
|
||||
let action_scroll = action_set.create_action::<f32>(
|
||||
let action_scroll = action_set.create_action::<Vector2f>(
|
||||
&format!("{}_scroll", side),
|
||||
&format!("{} hand scroll", side),
|
||||
&[],
|
||||
|
||||
@@ -81,6 +81,10 @@
|
||||
left: "/user/hand/left/input/thumbstick/y",
|
||||
right: "/user/hand/right/input/thumbstick/y"
|
||||
},
|
||||
scroll_horizontal: {
|
||||
left: "/user/hand/left/input/thumbstick/x",
|
||||
right: "/user/hand/right/input/thumbstick/x"
|
||||
},
|
||||
show_hide: {
|
||||
double_click: true,
|
||||
left: "/user/hand/left/input/y/click",
|
||||
@@ -129,6 +133,10 @@
|
||||
scroll: {
|
||||
left: "/user/hand/left/input/thumbstick/y",
|
||||
right: "/user/hand/right/input/thumbstick/y"
|
||||
},
|
||||
scroll_horizontal: {
|
||||
left: "/user/hand/left/input/thumbstick/x",
|
||||
right: "/user/hand/right/input/thumbstick/x"
|
||||
},
|
||||
toggle_dashboard: {
|
||||
double_click: false,
|
||||
@@ -180,6 +188,10 @@
|
||||
left: "/user/hand/left/input/trackpad/y",
|
||||
right: "/user/hand/right/input/trackpad/y"
|
||||
},
|
||||
scroll_horizontal: {
|
||||
left: "/user/hand/left/input/trackpad/x",
|
||||
right: "/user/hand/right/input/trackpad/x"
|
||||
},
|
||||
show_hide: {
|
||||
left: "/user/hand/left/input/menu/click",
|
||||
},
|
||||
@@ -215,6 +227,10 @@
|
||||
left: "/user/hand/left/input/thumbstick/y",
|
||||
right: "/user/hand/right/input/thumbstick/y"
|
||||
},
|
||||
scroll_horizontal: {
|
||||
left: "/user/hand/left/input/thumbstick/x",
|
||||
right: "/user/hand/right/input/thumbstick/x"
|
||||
},
|
||||
show_hide: {
|
||||
left: "/user/hand/left/input/menu/click",
|
||||
},
|
||||
@@ -246,6 +262,10 @@
|
||||
left: "/user/hand/left/input/thumbstick/y",
|
||||
right: "/user/hand/right/input/thumbstick/y"
|
||||
},
|
||||
scroll_horizontal: {
|
||||
left: "/user/hand/left/input/thumbstick/x",
|
||||
right: "/user/hand/right/input/thumbstick/x"
|
||||
},
|
||||
show_hide: {
|
||||
left: "/user/hand/left/input/menu/click",
|
||||
},
|
||||
|
||||
@@ -365,8 +365,8 @@ impl InteractionHandler for SplitOverlayBackend {
|
||||
fn on_hover(&mut self, app: &mut AppState, hit: &PointerHit) -> Option<Haptics> {
|
||||
self.interaction.on_hover(app, hit)
|
||||
}
|
||||
fn on_scroll(&mut self, app: &mut AppState, hit: &PointerHit, delta: f32) {
|
||||
self.interaction.on_scroll(app, hit, delta);
|
||||
fn on_scroll(&mut self, app: &mut AppState, hit: &PointerHit, delta_y: f32, delta_x: f32) {
|
||||
self.interaction.on_scroll(app, hit, delta_y, delta_x);
|
||||
}
|
||||
fn on_pointer(&mut self, app: &mut AppState, hit: &PointerHit, pressed: bool) {
|
||||
self.interaction.on_pointer(app, hit, pressed);
|
||||
|
||||
@@ -479,7 +479,7 @@ impl Display {
|
||||
manager.seat_pointer.frame(&mut manager.state);
|
||||
}
|
||||
|
||||
pub fn send_mouse_scroll(&self, manager: &mut WayVRCompositor, delta: f32) {
|
||||
pub fn send_mouse_scroll(&self, manager: &mut WayVRCompositor, delta_y: f32, delta_x: f32) {
|
||||
manager.seat_pointer.axis(
|
||||
&mut manager.state,
|
||||
input::pointer::AxisFrame {
|
||||
@@ -489,8 +489,8 @@ impl Display {
|
||||
smithay::backend::input::AxisRelativeDirection::Identical,
|
||||
),
|
||||
time: 0,
|
||||
axis: (0.0, -delta as f64),
|
||||
v120: Some((0, (delta * -120.0) as i32)),
|
||||
axis: (delta_x as f64, -delta_y as f64),
|
||||
v120: Some((0, (delta_y * -120.0) as i32)),
|
||||
stop: (false, false),
|
||||
},
|
||||
);
|
||||
|
||||
@@ -463,9 +463,9 @@ impl WayVRState {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn send_mouse_scroll(&mut self, display: display::DisplayHandle, delta: f32) {
|
||||
pub fn send_mouse_scroll(&mut self, display: display::DisplayHandle, delta_y: f32, delta_x: f32) {
|
||||
if let Some(display) = self.displays.get(&display) {
|
||||
display.send_mouse_scroll(&mut self.manager, delta);
|
||||
display.send_mouse_scroll(&mut self.manager, delta_y, delta_x);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ pub(crate) struct Control<D, S> {
|
||||
pub on_update: Option<fn(&mut Self, &mut D, &mut AppState)>,
|
||||
pub on_press: Option<fn(&mut Self, &mut D, &mut AppState, PointerMode)>,
|
||||
pub on_release: Option<fn(&mut Self, &mut D, &mut AppState)>,
|
||||
pub on_scroll: Option<fn(&mut Self, &mut D, &mut AppState, f32)>,
|
||||
pub on_scroll: Option<fn(&mut Self, &mut D, &mut AppState, f32, f32)>,
|
||||
pub test_highlight: Option<fn(&Self, &mut D, &mut AppState) -> Option<Vec4>>,
|
||||
|
||||
pub(super) on_render_bg: Option<ControlRenderer<D, S>>,
|
||||
|
||||
@@ -267,13 +267,13 @@ impl<D, S> InteractionHandler for Canvas<D, S> {
|
||||
}
|
||||
}
|
||||
}
|
||||
fn on_scroll(&mut self, app: &mut AppState, hit: &PointerHit, delta: f32) {
|
||||
fn on_scroll(&mut self, app: &mut AppState, hit: &PointerHit, delta_y: f32, delta_x: f32) {
|
||||
let idx = self.hover_controls[hit.pointer];
|
||||
|
||||
if let Some(idx) = idx {
|
||||
let c = &mut self.controls[idx];
|
||||
if let Some(ref mut f) = c.on_scroll {
|
||||
f(c, &mut self.canvas.data, app, delta);
|
||||
f(c, &mut self.canvas.data, app, delta_y, delta_x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -326,13 +326,13 @@ fn modular_button_up(button: &mut ModularControl, _: &mut (), app: &mut AppState
|
||||
}
|
||||
}
|
||||
|
||||
fn modular_button_scroll(button: &mut ModularControl, _: &mut (), app: &mut AppState, delta: f32) {
|
||||
fn modular_button_scroll(button: &mut ModularControl, _: &mut (), app: &mut AppState, delta_y: f32, delta_x: f32) {
|
||||
// want panic
|
||||
let ModularData::Button(data) = button.state.as_mut().unwrap() else {
|
||||
panic!("modular_button_scroll: button state is not Button");
|
||||
};
|
||||
|
||||
let actions = if delta < 0.0 {
|
||||
let actions = if delta_y < 0.0 {
|
||||
data.scroll_down.as_ref()
|
||||
} else {
|
||||
data.scroll_up.as_ref()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use glam::Vec2;
|
||||
use glam::{IVec2, Vec2};
|
||||
use idmap::{idmap, IdMap};
|
||||
use idmap_derive::IntegerId;
|
||||
use input_linux::{
|
||||
@@ -46,7 +46,7 @@ pub fn initialize() -> Box<dyn HidProvider> {
|
||||
pub trait HidProvider {
|
||||
fn mouse_move(&mut self, pos: Vec2);
|
||||
fn send_button(&mut self, button: u16, down: bool);
|
||||
fn wheel(&mut self, delta: i32);
|
||||
fn wheel(&mut self, delta_y: i32, delta_x: i32);
|
||||
fn set_modifiers(&mut self, mods: u8);
|
||||
fn send_key(&self, key: VirtualKey, down: bool);
|
||||
fn set_desktop_extent(&mut self, extent: Vec2);
|
||||
@@ -64,7 +64,7 @@ struct MouseAction {
|
||||
last_requested_pos: Option<Vec2>,
|
||||
pos: Option<Vec2>,
|
||||
button: Option<MouseButtonAction>,
|
||||
scroll: Option<i32>,
|
||||
scroll: Option<IVec2>,
|
||||
}
|
||||
|
||||
pub struct UInputProvider {
|
||||
@@ -149,7 +149,8 @@ impl UInputProvider {
|
||||
mouse_handle.set_evbit(EventKind::Relative).ok()?;
|
||||
mouse_handle.set_absbit(AbsoluteAxis::X).ok()?;
|
||||
mouse_handle.set_absbit(AbsoluteAxis::Y).ok()?;
|
||||
mouse_handle.set_relbit(RelativeAxis::Wheel).ok()?;
|
||||
mouse_handle.set_relbit(RelativeAxis::WheelHiRes).ok()?;
|
||||
mouse_handle.set_relbit(RelativeAxis::HorizontalWheelHiRes).ok()?;
|
||||
mouse_handle.set_evbit(EventKind::Key).ok()?;
|
||||
|
||||
for btn in MOUSE_LEFT..=MOUSE_MIDDLE {
|
||||
@@ -193,10 +194,11 @@ impl UInputProvider {
|
||||
log::error!("{}", res.to_string());
|
||||
}
|
||||
}
|
||||
fn wheel_internal(&self, delta: i32) {
|
||||
fn wheel_internal(&self, delta_y: i32, delta_x: i32) {
|
||||
let time = get_time();
|
||||
let events = [
|
||||
new_event(time, EV_REL, RelativeAxis::Wheel as _, delta),
|
||||
new_event(time, EV_REL, RelativeAxis::WheelHiRes as _, delta_y),
|
||||
new_event(time, EV_REL, RelativeAxis::HorizontalWheelHiRes as _, delta_x),
|
||||
new_event(time, EV_SYN, 0, 0),
|
||||
];
|
||||
if let Err(res) = self.mouse_handle.write(&events) {
|
||||
@@ -247,9 +249,9 @@ impl HidProvider for UInputProvider {
|
||||
self.current_action.pos = self.current_action.last_requested_pos;
|
||||
}
|
||||
}
|
||||
fn wheel(&mut self, delta: i32) {
|
||||
fn wheel(&mut self, delta_y: i32, delta_x: i32) {
|
||||
if self.current_action.scroll.is_none() {
|
||||
self.current_action.scroll = Some(delta);
|
||||
self.current_action.scroll = Some(IVec2::new(delta_x, delta_y));
|
||||
// Pass mouse motion events only if not scrolling
|
||||
// (allows scrolling on all Chromium-based applications)
|
||||
self.current_action.pos = None;
|
||||
@@ -263,7 +265,7 @@ impl HidProvider for UInputProvider {
|
||||
self.send_button_internal(button.button, button.down);
|
||||
}
|
||||
if let Some(scroll) = self.current_action.scroll.take() {
|
||||
self.wheel_internal(scroll);
|
||||
self.wheel_internal(scroll.y, scroll.x);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -271,7 +273,7 @@ impl HidProvider for UInputProvider {
|
||||
impl HidProvider for DummyProvider {
|
||||
fn mouse_move(&mut self, _pos: Vec2) {}
|
||||
fn send_button(&mut self, _button: u16, _down: bool) {}
|
||||
fn wheel(&mut self, _delta: i32) {}
|
||||
fn wheel(&mut self, _delta_y: i32, _delta_x: i32) {}
|
||||
fn set_modifiers(&mut self, _modifiers: u8) {}
|
||||
fn send_key(&self, _key: VirtualKey, _down: bool) {}
|
||||
fn set_desktop_extent(&mut self, _extent: Vec2) {}
|
||||
|
||||
@@ -516,9 +516,10 @@ impl InteractionHandler for KeyboardBackend {
|
||||
&mut self,
|
||||
app: &mut AppState,
|
||||
hit: &crate::backend::input::PointerHit,
|
||||
delta: f32,
|
||||
delta_y: f32,
|
||||
delta_x: f32,
|
||||
) {
|
||||
self.canvas.on_scroll(app, hit, delta)
|
||||
self.canvas.on_scroll(app, hit, delta_y, delta_x)
|
||||
}
|
||||
fn on_left(&mut self, app: &mut AppState, pointer: usize) {
|
||||
self.canvas.on_left(app, pointer)
|
||||
|
||||
@@ -88,7 +88,6 @@ fn set_next_move(millis_from_now: u64) {
|
||||
}
|
||||
|
||||
pub struct ScreenInteractionHandler {
|
||||
next_scroll: Instant,
|
||||
mouse_transform: Affine2,
|
||||
}
|
||||
impl ScreenInteractionHandler {
|
||||
@@ -113,7 +112,6 @@ impl ScreenInteractionHandler {
|
||||
};
|
||||
|
||||
ScreenInteractionHandler {
|
||||
next_scroll: Instant::now(),
|
||||
mouse_transform: transform,
|
||||
}
|
||||
}
|
||||
@@ -152,19 +150,8 @@ impl InteractionHandler for ScreenInteractionHandler {
|
||||
let pos = self.mouse_transform.transform_point2(hit.uv);
|
||||
app.hid_provider.mouse_move(pos);
|
||||
}
|
||||
fn on_scroll(&mut self, app: &mut AppState, hit: &PointerHit, delta: f32) {
|
||||
if self.next_scroll > Instant::now() {
|
||||
return;
|
||||
}
|
||||
let max_millis = if matches!(hit.mode, PointerMode::Left) {
|
||||
200.0
|
||||
} else {
|
||||
100.0
|
||||
};
|
||||
|
||||
let millis = (1. - delta.abs()) * max_millis;
|
||||
self.next_scroll = Instant::now().add(Duration::from_millis(millis as _));
|
||||
app.hid_provider.wheel(if delta < 0. { -1 } else { 1 })
|
||||
fn on_scroll(&mut self, app: &mut AppState, _hit: &PointerHit, delta_y: f32, delta_x: f32) {
|
||||
app.hid_provider.wheel((delta_y*64.) as i32, (delta_x*64.) as i32)
|
||||
}
|
||||
fn on_left(&mut self, _app: &mut AppState, _hand: usize) {}
|
||||
}
|
||||
|
||||
@@ -153,13 +153,13 @@ impl InteractionHandler for WayVRInteractionHandler {
|
||||
}
|
||||
}
|
||||
|
||||
fn on_scroll(&mut self, _app: &mut state::AppState, _hit: &input::PointerHit, delta: f32) {
|
||||
fn on_scroll(&mut self, _app: &mut state::AppState, _hit: &input::PointerHit, delta_y: f32, delta_x: f32) {
|
||||
let ctx = self.context.borrow();
|
||||
ctx.wayvr
|
||||
.borrow_mut()
|
||||
.data
|
||||
.state
|
||||
.send_mouse_scroll(ctx.display, delta);
|
||||
.send_mouse_scroll(ctx.display, delta_y, delta_x);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user