From c0afc5cf2ae617a56bf3db194ebbe6d65bf9d790 Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Fri, 27 May 2022 16:00:16 +0200 Subject: [PATCH] config: allow setting per-device scroll wheel speed --- jay-config/src/_private/client.rs | 4 ++++ jay-config/src/_private/ipc.rs | 4 ++++ jay-config/src/input.rs | 12 ++++++++++++ src/config/handler.rs | 9 +++++++++ src/ifs/wl_seat/event_handling.rs | 16 +++++++++++----- src/ifs/wl_seat/pointer_owner.rs | 5 +++-- src/ifs/wl_surface.rs | 10 ++++++++-- src/state.rs | 1 + src/tasks/input_device.rs | 6 ++++-- src/tree.rs | 9 ++++++++- src/tree/container.rs | 9 +++++++-- src/tree/output.rs | 9 +++++++-- 12 files changed, 78 insertions(+), 16 deletions(-) diff --git a/jay-config/src/_private/client.rs b/jay-config/src/_private/client.rs index b67a712a..59286e51 100644 --- a/jay-config/src/_private/client.rs +++ b/jay-config/src/_private/client.rs @@ -532,6 +532,10 @@ impl Client { self.send(&ClientMessage::SetTransformMatrix { device, matrix }) } + pub fn set_px_per_wheel_scroll(&self, device: InputDevice, px: f64) { + self.send(&ClientMessage::SetPxPerWheelScroll { device, px }) + } + pub fn device_name(&self, device: InputDevice) -> String { let res = self.send_with_response(&ClientMessage::GetDeviceName { device }); get_response!(res, String::new(), GetDeviceName { name }); diff --git a/jay-config/src/_private/ipc.rs b/jay-config/src/_private/ipc.rs index 5c86cd6e..67dc351b 100644 --- a/jay-config/src/_private/ipc.rs +++ b/jay-config/src/_private/ipc.rs @@ -270,6 +270,10 @@ pub enum ClientMessage<'a> { SetFont { font: &'a str, }, + SetPxPerWheelScroll { + device: InputDevice, + px: f64, + }, } #[derive(Encode, Decode, Debug)] diff --git a/jay-config/src/input.rs b/jay-config/src/input.rs index dfbdefdf..a3e21a7c 100644 --- a/jay-config/src/input.rs +++ b/jay-config/src/input.rs @@ -71,6 +71,18 @@ impl InputDevice { pub fn name(self) -> String { get!(String::new()).device_name(self) } + + /// Sets how many pixel to scroll per scroll wheel dedent. + /// + /// Default: `15.0` + /// + /// This setting has no effect on non-wheel input such as touchpads. + /// + /// Some mouse wheels support high-resolution scrolling without discrete steps. In + /// this case a value proportional to this setting will be used. + pub fn set_px_per_wheel_scroll(self, px: f64) { + get!().set_px_per_wheel_scroll(self, px); + } } /// A seat. diff --git a/src/config/handler.rs b/src/config/handler.rs index cf99ae48..2c76aebf 100644 --- a/src/config/handler.rs +++ b/src/config/handler.rs @@ -487,6 +487,12 @@ impl ConfigProxyHandler { Ok(()) } + fn handle_set_px_per_wheel_scroll(&self, device: InputDevice, px: f64) -> Result<(), CphError> { + let dev = self.get_device_handler_data(device)?; + dev.px_per_scroll_wheel.set(px); + Ok(()) + } + fn handle_set_transform_matrix( &self, device: InputDevice, @@ -1077,6 +1083,9 @@ impl ConfigProxyHandler { ClientMessage::ResetFont => self.handle_reset_font(), ClientMessage::GetFont => self.handle_get_font(), ClientMessage::SetFont { font } => self.handle_set_font(font), + ClientMessage::SetPxPerWheelScroll { device, px } => self + .handle_set_px_per_wheel_scroll(device, px) + .wrn("set_px_per_wheel_scroll")?, } Ok(()) } diff --git a/src/ifs/wl_seat/event_handling.rs b/src/ifs/wl_seat/event_handling.rs index 38447ecc..47c0077a 100644 --- a/src/ifs/wl_seat/event_handling.rs +++ b/src/ifs/wl_seat/event_handling.rs @@ -20,10 +20,11 @@ use { WHEEL_TILT_SINCE_VERSION, }, zwp_relative_pointer_v1::ZwpRelativePointerV1, - Dnd, SeatId, WlSeat, WlSeatGlobal, CHANGE_CURSOR_MOVED, PX_PER_SCROLL, + Dnd, SeatId, WlSeat, WlSeatGlobal, CHANGE_CURSOR_MOVED, }, wl_surface::{xdg_surface::xdg_popup::XdgPopup, WlSurface}, }, + state::DeviceHandlerData, tree::{Direction, FloatNode, Node, ToplevelNode}, utils::{bitflags::BitflagsExt, clonecell::CloneCell, smallmap::SmallMap}, wire::WlDataOfferId, @@ -166,7 +167,7 @@ impl NodeSeatState { } impl WlSeatGlobal { - pub fn event(self: &Rc, event: InputEvent) { + pub fn event(self: &Rc, dev: &DeviceHandlerData, event: InputEvent) { match event { InputEvent::Key { time_usec, @@ -196,7 +197,7 @@ impl WlSeatGlobal { InputEvent::Axis120 { dist, axis } => self.pointer_owner.axis_120(dist, axis), InputEvent::AxisSmooth { dist, axis } => self.pointer_owner.axis_smooth(dist, axis), InputEvent::AxisStop { axis } => self.pointer_owner.axis_stop(axis), - InputEvent::AxisFrame { time_usec } => self.pointer_owner.frame(self, time_usec), + InputEvent::AxisFrame { time_usec } => self.pointer_owner.frame(dev, self, time_usec), } } @@ -537,7 +538,12 @@ impl WlSeatGlobal { // Scroll callbacks impl WlSeatGlobal { - pub fn scroll_surface(&self, surface: &WlSurface, event: &PendingScroll) { + pub fn scroll_surface( + &self, + dev: &DeviceHandlerData, + surface: &WlSurface, + event: &PendingScroll, + ) { if let Some(source) = event.source.get() { let since = if source >= WHEEL_TILT { WHEEL_TILT_SINCE_VERSION @@ -556,7 +562,7 @@ impl WlSeatGlobal { } else if p.seat.version >= AXIS_DISCRETE_SINCE_VERSION { p.send_axis_discrete(axis, delta / AXIS_120); } - let px = (delta as f64 / AXIS_120 as f64) * PX_PER_SCROLL; + let px = (delta as f64 / AXIS_120 as f64) * dev.px_per_scroll_wheel.get(); p.send_axis(time, axis, Fixed::from_f64(px)); } else if let Some(delta) = event.smooth[i].get() { p.send_axis(time, axis, delta); diff --git a/src/ifs/wl_seat/pointer_owner.rs b/src/ifs/wl_seat/pointer_owner.rs index fad71137..fce723e3 100644 --- a/src/ifs/wl_seat/pointer_owner.rs +++ b/src/ifs/wl_seat/pointer_owner.rs @@ -8,6 +8,7 @@ use { wl_seat::{wl_pointer::PendingScroll, Dnd, DroppedDnd, WlSeatError, WlSeatGlobal}, wl_surface::WlSurface, }, + state::DeviceHandlerData, tree::{FoundNode, Node}, utils::{clonecell::CloneCell, smallmap::SmallMap}, }, @@ -51,11 +52,11 @@ impl PointerOwnerHolder { self.pending_scroll.stop[axis as usize].set(true); } - pub fn frame(&self, seat: &Rc, time_usec: u64) { + pub fn frame(&self, dev: &DeviceHandlerData, seat: &Rc, time_usec: u64) { self.pending_scroll.time_usec.set(time_usec); let pending = self.pending_scroll.take(); if let Some(node) = self.owner.get().axis_node(seat) { - node.node_on_axis_event(seat, &pending); + node.node_on_axis_event(dev, seat, &pending); } } diff --git a/src/ifs/wl_surface.rs b/src/ifs/wl_surface.rs index 8b884caf..47834de3 100644 --- a/src/ifs/wl_surface.rs +++ b/src/ifs/wl_surface.rs @@ -25,6 +25,7 @@ use { object::Object, rect::{Rect, Region}, render::Renderer, + state::DeviceHandlerData, tree::{FindTreeResult, FoundNode, Node, NodeId, NodeVisitor, ToplevelNode}, utils::{ buffd::{MsgParser, MsgParserError}, @@ -779,8 +780,13 @@ impl Node for WlSurface { seat.button_surface(&self, time_usec, button, state, serial); } - fn node_on_axis_event(self: Rc, seat: &Rc, event: &PendingScroll) { - seat.scroll_surface(&*self, event); + fn node_on_axis_event( + self: Rc, + dev: &DeviceHandlerData, + seat: &Rc, + event: &PendingScroll, + ) { + seat.scroll_surface(dev, &*self, event); } fn node_on_focus(self: Rc, seat: &Rc) { diff --git a/src/state.rs b/src/state.rs index 64ae1da8..1aa9a048 100644 --- a/src/state.rs +++ b/src/state.rs @@ -173,6 +173,7 @@ pub struct InputDeviceData { pub struct DeviceHandlerData { pub seat: CloneCell>>, + pub px_per_scroll_wheel: Cell, pub device: Rc, } diff --git a/src/tasks/input_device.rs b/src/tasks/input_device.rs index 1b304b2e..4901eb86 100644 --- a/src/tasks/input_device.rs +++ b/src/tasks/input_device.rs @@ -1,15 +1,17 @@ use { crate::{ backend::InputDevice, + ifs::wl_seat::PX_PER_SCROLL, state::{DeviceHandlerData, InputDeviceData, State}, utils::asyncevent::AsyncEvent, }, - std::rc::Rc, + std::{cell::Cell, rc::Rc}, }; pub fn handle(state: &Rc, dev: Rc) { let data = Rc::new(DeviceHandlerData { seat: Default::default(), + px_per_scroll_wheel: Cell::new(PX_PER_SCROLL), device: dev.clone(), }); let ae = Rc::new(AsyncEvent::default()); @@ -54,7 +56,7 @@ impl DeviceHandler { if let Some(seat) = self.data.seat.get() { let mut any_events = false; while let Some(event) = self.dev.event() { - seat.event(event); + seat.event(&self.data, event); any_events = true; } if any_events { diff --git a/src/tree.rs b/src/tree.rs index 6e31beb6..0162a603 100644 --- a/src/tree.rs +++ b/src/tree.rs @@ -9,6 +9,7 @@ use { }, rect::Rect, render::Renderer, + state::DeviceHandlerData, utils::numcell::NumCell, xkbcommon::ModifierState, }, @@ -184,7 +185,13 @@ pub trait Node: 'static { let _ = serial; } - fn node_on_axis_event(self: Rc, seat: &Rc, event: &PendingScroll) { + fn node_on_axis_event( + self: Rc, + dev: &DeviceHandlerData, + seat: &Rc, + event: &PendingScroll, + ) { + let _ = dev; let _ = seat; let _ = event; } diff --git a/src/tree/container.rs b/src/tree/container.rs index 957c067e..2601cbe9 100644 --- a/src/tree/container.rs +++ b/src/tree/container.rs @@ -9,7 +9,7 @@ use { }, rect::Rect, render::{Renderer, Texture}, - state::State, + state::{DeviceHandlerData, State}, text, tree::{ walker::NodeVisitor, ContainingNode, Direction, FindTreeResult, FoundNode, Node, @@ -1145,7 +1145,12 @@ impl Node for ContainerNode { } } - fn node_on_axis_event(self: Rc, seat: &Rc, event: &PendingScroll) { + fn node_on_axis_event( + self: Rc, + _dev: &DeviceHandlerData, + seat: &Rc, + event: &PendingScroll, + ) { let mut seat_datas = self.seats.borrow_mut(); let seat_data = match seat_datas.get_mut(&seat.id()) { Some(s) => s, diff --git a/src/tree/output.rs b/src/tree/output.rs index de93a59c..eb96fab2 100644 --- a/src/tree/output.rs +++ b/src/tree/output.rs @@ -17,7 +17,7 @@ use { }, rect::Rect, render::{Renderer, Texture}, - state::State, + state::{DeviceHandlerData, State}, text, tree::{ walker::NodeVisitor, Direction, FindTreeResult, FoundNode, Node, NodeId, WorkspaceNode, @@ -512,7 +512,12 @@ impl Node for OutputNode { self.state.tree_changed(); } - fn node_on_axis_event(self: Rc, seat: &Rc, event: &PendingScroll) { + fn node_on_axis_event( + self: Rc, + _dev: &DeviceHandlerData, + seat: &Rc, + event: &PendingScroll, + ) { let steps = match self.scroll.handle(event) { Some(e) => e, _ => return,