diff --git a/uidev/src/main.rs b/uidev/src/main.rs index d627240..6292c82 100644 --- a/uidev/src/main.rs +++ b/uidev/src/main.rs @@ -134,7 +134,7 @@ fn main() -> Result<(), Box> { .borrow_mut() .push_event( &wgui::event::Event::MouseWheel(MouseWheelEvent { - shift: Vec2::new(x, y), + delta: Vec2::new(x, y), pos: mouse / scale, device: 0, }), @@ -149,7 +149,7 @@ fn main() -> Result<(), Box> { .borrow_mut() .push_event( &wgui::event::Event::MouseWheel(MouseWheelEvent { - shift: Vec2::new(pos.x as f32 / 5.0, pos.y as f32 / 5.0), + delta: Vec2::new(pos.x as f32 / 5.0, pos.y as f32 / 5.0), pos: mouse / scale, device: 0, }), diff --git a/wgui/src/event.rs b/wgui/src/event.rs index 0b80ffa..4088f91 100644 --- a/wgui/src/event.rs +++ b/wgui/src/event.rs @@ -55,8 +55,8 @@ pub struct MouseUpEvent { } pub struct MouseWheelEvent { - pub pos: Vec2, - pub shift: Vec2, + pub pos: Vec2, /* mouse position */ + pub delta: Vec2, /* wheel delta */ pub device: usize, } diff --git a/wgui/src/widget/mod.rs b/wgui/src/widget/mod.rs index 0b4b7c3..6169af9 100644 --- a/wgui/src/widget/mod.rs +++ b/wgui/src/widget/mod.rs @@ -395,7 +395,7 @@ impl WidgetState { if info.handle_size.x < 1.0 && wheel.pos.x != 0.0 { // Horizontal scrolling let mult = (1.0 / (l.content_box_width() - info.content_size.x)) * step_pixels; - let new_scroll = (self.data.scrolling_target.x + wheel.shift.x * mult).clamp(0.0, 1.0); + let new_scroll = (self.data.scrolling_target.x + wheel.delta.x * mult).clamp(0.0, 1.0); if self.data.scrolling_target.x != new_scroll { self.data.scrolling_target.x = new_scroll; params.alterables.mark_tick(self.obj.get_id()); @@ -405,7 +405,7 @@ impl WidgetState { if info.handle_size.y < 1.0 && wheel.pos.y != 0.0 { // Vertical scrolling let mult = (1.0 / (l.content_box_height() - info.content_size.y)) * step_pixels; - let new_scroll = (self.data.scrolling_target.y + wheel.shift.y * mult).clamp(0.0, 1.0); + let new_scroll = (self.data.scrolling_target.y + wheel.delta.y * mult).clamp(0.0, 1.0); if self.data.scrolling_target.y != new_scroll { self.data.scrolling_target.y = new_scroll; params.alterables.mark_tick(self.obj.get_id()); diff --git a/wlx-overlay-s/src/backend/input.rs b/wlx-overlay-s/src/backend/input.rs index 64c19cd..dfccfdd 100644 --- a/wlx-overlay-s/src/backend/input.rs +++ b/wlx-overlay-s/src/backend/input.rs @@ -4,10 +4,11 @@ use std::{collections::VecDeque, time::Instant}; use glam::{Affine3A, Vec2, Vec3, Vec3A, Vec3Swizzles}; -use smallvec::{smallvec, SmallVec}; +use smallvec::{SmallVec, smallvec}; use crate::overlays::anchor::ANCHOR_NAME; use crate::state::{AppSession, AppState}; +use crate::subsystem::hid::WheelDelta; use crate::subsystem::input::KeyboardFocus; use crate::windowing::manager::OverlayWindowManager; use crate::windowing::window::{OverlayWindowData, OverlayWindowState, Positioning}; @@ -450,37 +451,58 @@ fn handle_no_hit( fn handle_scroll(hit: &PointerHit, hovered: &mut OverlayWindowData, app: &mut AppState) { let pointer = &mut app.input_state.pointers[hit.pointer]; - 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 - hit.pointer] - .interaction - .grabbed - .is_some_and(|x| x.grabbed_id == hit.overlay) - { - let can_curve = hovered - .frame_meta() - .is_some_and(|e| e.extent[0] >= e.extent[1]); + if pointer.now.scroll_x.abs() <= 0.1 && pointer.now.scroll_x.abs() <= 0.1 { + return; + } - // re-borrow - let hovered_state = hovered.config.active_state.as_mut().unwrap(); - if can_curve { - let cur = hovered_state.curvature.unwrap_or(0.0); - let new = scroll_y.mul_add(-0.01, cur).min(0.5); - if new <= f32::EPSILON { - hovered_state.curvature = None; - } else { - hovered_state.curvature = Some(new); - } - } else { + let config = &app.session.config; + + let scroll_x = pointer.now.scroll_x + * config.scroll_speed + * if config.invert_scroll_direction_x { + -1.0 + } else { + 1.0 + }; + let scroll_y = pointer.now.scroll_y + * config.scroll_speed + * if config.invert_scroll_direction_x { + -1.0 + } else { + 1.0 + }; + + if app.input_state.pointers[1 - hit.pointer] + .interaction + .grabbed + .is_some_and(|x| x.grabbed_id == hit.overlay) + { + let can_curve = hovered + .frame_meta() + .is_some_and(|e| e.extent[0] >= e.extent[1]); + + // re-borrow + let hovered_state = hovered.config.active_state.as_mut().unwrap(); + if can_curve { + let cur = hovered_state.curvature.unwrap_or(0.0); + let new = scroll_y.mul_add(-0.01, cur).min(0.5); + if new <= f32::EPSILON { hovered_state.curvature = None; + } else { + hovered_state.curvature = Some(new); } } else { - hovered - .config - .backend - .on_scroll(app, hit, scroll_y, scroll_x); + hovered_state.curvature = None; } + } else { + hovered.config.backend.on_scroll( + app, + hit, + WheelDelta { + x: scroll_x, + y: scroll_y, + }, + ); } } diff --git a/wlx-overlay-s/src/backend/openvr/lines.rs b/wlx-overlay-s/src/backend/openvr/lines.rs index 73f0d55..a381b6e 100644 --- a/wlx-overlay-s/src/backend/openvr/lines.rs +++ b/wlx-overlay-s/src/backend/openvr/lines.rs @@ -1,6 +1,6 @@ use std::f32::consts::PI; -use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::Arc; +use std::sync::atomic::{AtomicUsize, Ordering}; use ash::vk::SubmitInfo; use glam::{Affine3A, Vec3, Vec3A, Vec4}; @@ -8,6 +8,7 @@ use idmap::IdMap; use ovr_overlay::overlay::OverlayManager; use ovr_overlay::sys::ETrackingUniverseOrigin; use vulkano::{ + VulkanObject, command_buffer::{ CommandBufferBeginInfo, CommandBufferLevel, CommandBufferUsage, RecordingCommandBuffer, }, @@ -15,19 +16,19 @@ use vulkano::{ image::view::ImageView, image::{Image, ImageLayout}, sync::{ - fence::{Fence, FenceCreateInfo}, AccessFlags, DependencyInfo, ImageMemoryBarrier, PipelineStages, + fence::{Fence, FenceCreateInfo}, }, - VulkanObject, }; use wgui::gfx::WGfx; use crate::backend::input::{HoverResult, PointerHit}; use crate::graphics::CommandBuffers; use crate::state::AppState; +use crate::subsystem::hid::WheelDelta; +use crate::windowing::Z_ORDER_LINES; use crate::windowing::backend::{FrameMeta, OverlayBackend, ShouldRender}; use crate::windowing::window::{OverlayWindowConfig, OverlayWindowData}; -use crate::windowing::Z_ORDER_LINES; use super::overlay::OpenVrOverlayData; @@ -209,7 +210,7 @@ impl OverlayBackend for LineBackend { } fn on_left(&mut self, _: &mut AppState, _: usize) {} fn on_pointer(&mut self, _: &mut AppState, _: &PointerHit, _: bool) {} - fn on_scroll(&mut self, _: &mut AppState, _: &PointerHit, _: f32, _: f32) {} + fn on_scroll(&mut self, _: &mut AppState, _: &PointerHit, _delta: WheelDelta) {} fn get_interaction_transform(&mut self) -> Option { None } diff --git a/wlx-overlay-s/src/backend/wayvr/display.rs b/wlx-overlay-s/src/backend/wayvr/display.rs index 14d9fe5..f5c8909 100644 --- a/wlx-overlay-s/src/backend/wayvr/display.rs +++ b/wlx-overlay-s/src/backend/wayvr/display.rs @@ -2,13 +2,13 @@ use std::{cell::RefCell, rc::Rc, sync::Arc}; use smithay::{ backend::renderer::{ - element::{ - surface::{render_elements_from_surface_tree, WaylandSurfaceRenderElement}, - Kind, - }, - gles::{ffi, GlesRenderer, GlesTexture}, - utils::draw_render_elements, Bind, Color32F, Frame, Renderer, + element::{ + Kind, + surface::{WaylandSurfaceRenderElement, render_elements_from_surface_tree}, + }, + gles::{GlesRenderer, GlesTexture, ffi}, + utils::draw_render_elements, }, input, utils::{Logical, Point, Rectangle, Size, Transform}, @@ -16,11 +16,13 @@ use smithay::{ }; use wayvr_ipc::packet_server; -use crate::{backend::wayvr::time::get_millis, gen_id, windowing::OverlayID}; +use crate::{ + backend::wayvr::time::get_millis, gen_id, subsystem::hid::WheelDelta, windowing::OverlayID, +}; use super::{ - client::WayVRCompositor, comp::send_frames_surface_tree, egl_data, event_queue::SyncEventQueue, - process, smithay_wrapper, time, window, BlitMethod, WayVRSignal, + BlitMethod, WayVRSignal, client::WayVRCompositor, comp::send_frames_surface_tree, egl_data, + event_queue::SyncEventQueue, process, smithay_wrapper, time, window, }; fn generate_auth_key() -> String { @@ -527,7 +529,7 @@ impl Display { manager.seat_pointer.frame(&mut manager.state); } - pub fn send_mouse_scroll(manager: &mut WayVRCompositor, delta_y: f32, delta_x: f32) { + pub fn send_mouse_scroll(manager: &mut WayVRCompositor, delta: WheelDelta) { manager.seat_pointer.axis( &mut manager.state, input::pointer::AxisFrame { @@ -537,8 +539,8 @@ impl Display { smithay::backend::input::AxisRelativeDirection::Identical, ), time: 0, - axis: (f64::from(delta_x), f64::from(-delta_y)), - v120: Some((0, (delta_y * -120.0) as i32)), + axis: (f64::from(delta.x), f64::from(-delta.y)), + v120: Some((0, (delta.y * -64.0) as i32)), stop: (false, false), }, ); diff --git a/wlx-overlay-s/src/backend/wayvr/mod.rs b/wlx-overlay-s/src/backend/wayvr/mod.rs index 6709472..1d9282c 100644 --- a/wlx-overlay-s/src/backend/wayvr/mod.rs +++ b/wlx-overlay-s/src/backend/wayvr/mod.rs @@ -42,7 +42,10 @@ use std::{ use time::get_millis; use wayvr_ipc::{packet_client, packet_server}; -use crate::{state::AppState, subsystem::hid::MODS_TO_KEYS}; +use crate::{ + state::AppState, + subsystem::hid::{MODS_TO_KEYS, WheelDelta}, +}; const STR_INVALID_HANDLE_DISP: &str = "Invalid display handle"; @@ -507,8 +510,8 @@ impl WayVRState { Display::send_mouse_up(&mut self.manager, index); } - pub fn send_mouse_scroll(&mut self, delta_y: f32, delta_x: f32) { - Display::send_mouse_scroll(&mut self.manager, delta_y, delta_x); + pub fn send_mouse_scroll(&mut self, delta: WheelDelta) { + Display::send_mouse_scroll(&mut self.manager, delta); } pub fn send_key(&mut self, virtual_key: u32, down: bool) { diff --git a/wlx-overlay-s/src/config.rs b/wlx-overlay-s/src/config.rs index 2b792cf..c9129dd 100644 --- a/wlx-overlay-s/src/config.rs +++ b/wlx-overlay-s/src/config.rs @@ -7,7 +7,7 @@ use crate::state::LeftRight; use crate::windowing::set::SerializedWindowSet; use chrono::Offset; use config::{Config, File}; -use glam::{vec3, Affine3A, Quat, Vec3}; +use glam::{Affine3A, Quat, Vec3, vec3}; use idmap::IdMap; use log::error; use serde::{Deserialize, Serialize}; @@ -193,6 +193,15 @@ pub struct GeneralConfig { #[serde(default = "def_click_freeze_time_ms")] pub click_freeze_time_ms: u32, + #[serde(default = "def_false")] + pub invert_scroll_direction_x: bool, + + #[serde(default = "def_false")] + pub invert_scroll_direction_y: bool, + + #[serde(default = "def_one")] + pub scroll_speed: f32, + #[serde(default = "def_mouse_move_interval_ms")] pub mouse_move_interval_ms: u32, @@ -343,6 +352,7 @@ impl GeneralConfig { fn post_load(&self) { Self::sanitize_range("keyboard_scale", self.keyboard_scale, 0.05, 5.0); Self::sanitize_range("desktop_view_scale", self.desktop_view_scale, 0.05, 5.0); + Self::sanitize_range("scroll_speed", self.scroll_speed, 0.01, 10.0); } } diff --git a/wlx-overlay-s/src/gui/panel/mod.rs b/wlx-overlay-s/src/gui/panel/mod.rs index 04fd1fc..e2c938d 100644 --- a/wlx-overlay-s/src/gui/panel/mod.rs +++ b/wlx-overlay-s/src/gui/panel/mod.rs @@ -1,7 +1,7 @@ use std::{cell::RefCell, rc::Rc, sync::Arc}; use button::setup_custom_button; -use glam::{vec2, Affine2, Vec2}; +use glam::{Affine2, Vec2, vec2}; use label::setup_custom_label; use vulkano::{command_buffer::CommandBufferUsage, image::view::ImageView}; use wgui::{ @@ -15,14 +15,15 @@ use wgui::{ layout::{Layout, LayoutParams, WidgetID}, parser::ParserState, renderer_vk::context::Context as WguiContext, - widget::{label::WidgetLabel, rectangle::WidgetRectangle, EventResult}, + widget::{EventResult, label::WidgetLabel, rectangle::WidgetRectangle}, }; use crate::{ backend::input::{Haptics, HoverResult, PointerHit, PointerMode}, graphics::{CommandBuffers, ExtentExt}, state::AppState, - windowing::backend::{ui_transform, FrameMeta, OverlayBackend, ShouldRender}, + subsystem::hid::WheelDelta, + windowing::backend::{FrameMeta, OverlayBackend, ShouldRender, ui_transform}, }; use super::{timer::GuiTimer, timestep::Timestep}; @@ -270,9 +271,9 @@ impl OverlayBackend for GuiPanel { }) } - fn on_scroll(&mut self, app: &mut AppState, hit: &PointerHit, delta_y: f32, delta_x: f32) { + fn on_scroll(&mut self, app: &mut AppState, hit: &PointerHit, delta: WheelDelta) { let e = WguiEvent::MouseWheel(MouseWheelEvent { - shift: vec2(delta_x, delta_y), + delta: vec2(delta.x, delta.y), pos: hit.uv * self.layout.content_size, device: hit.pointer, }); diff --git a/wlx-overlay-s/src/overlays/keyboard/mod.rs b/wlx-overlay-s/src/overlays/keyboard/mod.rs index 180c37d..9bd50e2 100644 --- a/wlx-overlay-s/src/overlays/keyboard/mod.rs +++ b/wlx-overlay-s/src/overlays/keyboard/mod.rs @@ -15,7 +15,7 @@ use crate::{ graphics::CommandBuffers, gui::panel::GuiPanel, state::AppState, - subsystem::hid::{KeyModifier, VirtualKey, ALT, CTRL, META, SHIFT, SUPER}, + subsystem::hid::{ALT, CTRL, KeyModifier, META, SHIFT, SUPER, VirtualKey, WheelDelta}, windowing::backend::{FrameMeta, OverlayBackend, ShouldRender}, }; @@ -69,8 +69,8 @@ impl OverlayBackend for KeyboardBackend { &wgui::event::Event::InternalStateChange(InternalStateChangeEvent { metadata: 0 }), ); } - fn on_scroll(&mut self, app: &mut AppState, hit: &PointerHit, delta_y: f32, delta_x: f32) { - self.panel.on_scroll(app, hit, delta_y, delta_x); + fn on_scroll(&mut self, app: &mut AppState, hit: &PointerHit, delta: WheelDelta) { + self.panel.on_scroll(app, hit, delta); } fn on_left(&mut self, app: &mut AppState, pointer: usize) { self.panel.on_left(app, pointer); diff --git a/wlx-overlay-s/src/overlays/mirror.rs b/wlx-overlay-s/src/overlays/mirror.rs index 428cd05..2e4ec07 100644 --- a/wlx-overlay-s/src/overlays/mirror.rs +++ b/wlx-overlay-s/src/overlays/mirror.rs @@ -6,7 +6,7 @@ use std::{ use futures::{Future, FutureExt}; use glam::{Affine2, Affine3A, Vec3}; use vulkano::image::view::ImageView; -use wlx_capture::pipewire::{pipewire_select_screen, PipewireCapture, PipewireSelectScreenResult}; +use wlx_capture::pipewire::{PipewireCapture, PipewireSelectScreenResult, pipewire_select_screen}; use crate::{ backend::{ @@ -15,10 +15,11 @@ use crate::{ }, graphics::CommandBuffers, state::{AppSession, AppState}, + subsystem::hid::WheelDelta, windowing::{ - backend::{ui_transform, FrameMeta, OverlayBackend, ShouldRender}, - window::{OverlayWindowConfig, OverlayWindowState}, OverlaySelector, + backend::{FrameMeta, OverlayBackend, ShouldRender, ui_transform}, + window::{OverlayWindowConfig, OverlayWindowState}, }, }; @@ -138,7 +139,7 @@ impl OverlayBackend for MirrorBackend { } fn on_left(&mut self, _: &mut AppState, _: usize) {} fn on_pointer(&mut self, _: &mut AppState, _: &PointerHit, _: bool) {} - fn on_scroll(&mut self, _: &mut AppState, _: &PointerHit, _: f32, _: f32) {} + fn on_scroll(&mut self, _: &mut AppState, _: &PointerHit, _delta: WheelDelta) {} fn get_interaction_transform(&mut self) -> Option { self.interaction_transform } diff --git a/wlx-overlay-s/src/overlays/screen/backend.rs b/wlx-overlay-s/src/overlays/screen/backend.rs index fef4fdd..dbcc21c 100644 --- a/wlx-overlay-s/src/overlays/screen/backend.rs +++ b/wlx-overlay-s/src/overlays/screen/backend.rs @@ -1,21 +1,21 @@ use std::{ - sync::{atomic::AtomicU64, Arc, LazyLock}, + sync::{Arc, LazyLock, atomic::AtomicU64}, time::Instant, }; -use glam::{vec2, Affine2, Vec2}; +use glam::{Affine2, Vec2, vec2}; use vulkano::image::view::ImageView; -use wlx_capture::{frame::Transform, WlxCapture}; +use wlx_capture::{WlxCapture, frame::Transform}; use crate::{ backend::input::{HoverResult, PointerHit, PointerMode}, graphics::{CommandBuffers, ExtentExt}, state::AppState, - subsystem::hid::{MOUSE_LEFT, MOUSE_MIDDLE, MOUSE_RIGHT}, + subsystem::hid::{MOUSE_LEFT, MOUSE_MIDDLE, MOUSE_RIGHT, WheelDelta}, windowing::backend::{FrameMeta, OverlayBackend, ShouldRender}, }; -use super::capture::{receive_callback, ScreenPipeline, WlxCaptureIn, WlxCaptureOut}; +use super::capture::{ScreenPipeline, WlxCaptureIn, WlxCaptureOut, receive_callback}; const CURSOR_SIZE: f32 = 16. / 1440.; @@ -246,11 +246,11 @@ impl OverlayBackend for ScreenBackend { let pos = self.mouse_transform.transform_point2(hit.uv); app.hid_provider.inner.mouse_move(pos); } - fn on_scroll(&mut self, app: &mut AppState, _hit: &PointerHit, delta_y: f32, delta_x: f32) { - app.hid_provider - .inner - .wheel((delta_y * 64.) as i32, (delta_x * 64.) as i32); + + fn on_scroll(&mut self, app: &mut AppState, _hit: &PointerHit, delta: WheelDelta) { + app.hid_provider.inner.wheel(delta); } + fn on_left(&mut self, _app: &mut AppState, _hand: usize) {} fn get_interaction_transform(&mut self) -> Option { diff --git a/wlx-overlay-s/src/overlays/wayvr.rs b/wlx-overlay-s/src/overlays/wayvr.rs index 8cb032e..622db07 100644 --- a/wlx-overlay-s/src/overlays/wayvr.rs +++ b/wlx-overlay-s/src/overlays/wayvr.rs @@ -1,17 +1,17 @@ -use glam::{vec3, Affine2, Affine3A, Quat, Vec3}; +use glam::{Affine2, Affine3A, Quat, Vec3, vec3}; use smallvec::smallvec; use std::{cell::RefCell, collections::HashMap, rc::Rc, sync::Arc}; use vulkano::{ buffer::{BufferUsage, Subbuffer}, command_buffer::CommandBufferUsage, format::Format, - image::{view::ImageView, Image, ImageTiling, SubresourceLayout}, + image::{Image, ImageTiling, SubresourceLayout, view::ImageView}, }; use wayvr_ipc::packet_server::{self, PacketServer, WvrStateChanged}; use wgui::gfx::{ + WGfx, pass::WGfxPass, pipeline::{WGfxPipeline, WPipelineCreateInfo}, - WGfx, }; use wlx_capture::frame::{DmabufFrame, FourCC, FrameFormat, FramePlane}; @@ -20,20 +20,19 @@ use crate::{ input::{self, HoverResult}, task::TaskType, wayvr::{ - self, display, + self, WayVR, WayVRAction, WayVRDisplayClickAction, display, server_ipc::{gen_args_vec, gen_env_vec}, - WayVR, WayVRAction, WayVRDisplayClickAction, }, }, config_wayvr, - graphics::{dmabuf::WGfxDmabuf, CommandBuffers, Vert2Uv}, + graphics::{CommandBuffers, Vert2Uv, dmabuf::WGfxDmabuf}, state::{self, AppState}, - subsystem::input::KeyboardFocus, + subsystem::{hid::WheelDelta, input::KeyboardFocus}, windowing::{ - backend::{ui_transform, FrameMeta, OverlayBackend, ShouldRender}, + OverlayID, OverlaySelector, Z_ORDER_DASHBOARD, + backend::{FrameMeta, OverlayBackend, ShouldRender, ui_transform}, manager::OverlayWindowManager, window::{OverlayWindowConfig, OverlayWindowData, OverlayWindowState}, - OverlayID, OverlaySelector, Z_ORDER_DASHBOARD, }, }; @@ -770,15 +769,10 @@ impl OverlayBackend for WayVRBackend { &mut self, _app: &mut state::AppState, _hit: &input::PointerHit, - delta_y: f32, - delta_x: f32, + delta: WheelDelta, ) { let ctx = self.context.borrow(); - ctx.wayvr - .borrow_mut() - .data - .state - .send_mouse_scroll(delta_y, delta_x); + ctx.wayvr.borrow_mut().data.state.send_mouse_scroll(delta); } fn get_interaction_transform(&mut self) -> Option { diff --git a/wlx-overlay-s/src/res/config.yaml b/wlx-overlay-s/src/res/config.yaml index 4d5f544..fee9dcb 100644 --- a/wlx-overlay-s/src/res/config.yaml +++ b/wlx-overlay-s/src/res/config.yaml @@ -3,6 +3,17 @@ # Default: 300 click_freeze_time_ms: 300 +# Make scroll events inverted in X/Y axis +# Default: false +invert_scroll_direction_x: false +invert_scroll_direction_y: false + +# Change speed of scrolling +# Default: 1.0 +# 0.5: half the speed +# 2.0: twice the speed +scroll_speed: 1.0 + # Default: true keyboard_sound_enabled: true diff --git a/wlx-overlay-s/src/subsystem/hid/mod.rs b/wlx-overlay-s/src/subsystem/hid/mod.rs index f7f2906..8e4ff6b 100644 --- a/wlx-overlay-s/src/subsystem/hid/mod.rs +++ b/wlx-overlay-s/src/subsystem/hid/mod.rs @@ -1,5 +1,5 @@ -use glam::{IVec2, Vec2}; -use idmap::{idmap, IdMap}; +use glam::Vec2; +use idmap::{IdMap, idmap}; use idmap_derive::IntegerId; use input_linux::{ AbsoluteAxis, AbsoluteInfo, AbsoluteInfoSetup, EventKind, InputId, Key, RelativeAxis, @@ -40,10 +40,15 @@ pub(super) fn initialize() -> Box { Box::new(DummyProvider {}) } +pub struct WheelDelta { + pub x: f32, + pub y: f32, +} + pub trait HidProvider: Sync + Send { fn mouse_move(&mut self, pos: Vec2); fn send_button(&mut self, button: u16, down: bool); - fn wheel(&mut self, delta_y: i32, delta_x: i32); + fn wheel(&mut self, delta: WheelDelta); fn set_modifiers(&mut self, mods: u8); fn send_key(&self, key: VirtualKey, down: bool); fn set_desktop_extent(&mut self, extent: Vec2); @@ -61,7 +66,7 @@ struct MouseAction { last_requested_pos: Option, pos: Option, button: Option, - scroll: Option, + scroll: Option, } pub struct UInputProvider { @@ -195,7 +200,12 @@ impl UInputProvider { log::error!("{res}"); } } - fn wheel_internal(&self, delta_y: i32, delta_x: i32) { + + fn wheel_internal(&self, delta: WheelDelta) { + let multiplier = 64.0; /* cherry-picked value, overall scrolling speed can be altered via `scroll_speed` in the config */ + let delta_x = (delta.x * multiplier) as i32; + let delta_y = (delta.y * multiplier) as i32; + let time = get_time(); let events = [ new_event(time, EV_REL, RelativeAxis::WheelHiRes as _, delta_y), @@ -257,14 +267,16 @@ impl HidProvider for UInputProvider { self.current_action.pos = self.current_action.last_requested_pos; } } - fn wheel(&mut self, delta_y: i32, delta_x: i32) { + + fn wheel(&mut self, delta: WheelDelta) { if self.current_action.scroll.is_none() { - self.current_action.scroll = Some(IVec2::new(delta_x, delta_y)); + self.current_action.scroll = Some(delta); // Pass mouse motion events only if not scrolling // (allows scrolling on all Chromium-based applications) self.current_action.pos = None; } } + fn commit(&mut self) { if let Some(pos) = self.current_action.pos.take() { self.mouse_move_internal(pos); @@ -273,7 +285,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.y, scroll.x); + self.wheel_internal(scroll); } } } @@ -281,7 +293,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_y: i32, _delta_x: i32) {} + fn wheel(&mut self, _delta: WheelDelta) {} fn set_modifiers(&mut self, _modifiers: u8) {} fn send_key(&self, _key: VirtualKey, _down: bool) {} fn set_desktop_extent(&mut self, _extent: Vec2) {} diff --git a/wlx-overlay-s/src/windowing/backend.rs b/wlx-overlay-s/src/windowing/backend.rs index ef2848f..a7e5bc1 100644 --- a/wlx-overlay-s/src/windowing/backend.rs +++ b/wlx-overlay-s/src/windowing/backend.rs @@ -6,6 +6,7 @@ use crate::{ backend::input::{HoverResult, PointerHit}, graphics::CommandBuffers, state::AppState, + subsystem::hid::WheelDelta, }; #[derive(Default, Clone, Copy)] @@ -51,7 +52,7 @@ pub trait OverlayBackend { fn on_hover(&mut self, app: &mut AppState, hit: &PointerHit) -> HoverResult; 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_y: f32, delta_x: f32); + fn on_scroll(&mut self, app: &mut AppState, hit: &PointerHit, delta: WheelDelta); fn get_interaction_transform(&mut self) -> Option; }