1
0
Fork 0
forked from wry/wry

config: allow setting per-device scroll wheel speed

This commit is contained in:
Julian Orth 2022-05-27 16:00:16 +02:00
parent 50c87d6da7
commit c0afc5cf2a
12 changed files with 78 additions and 16 deletions

View file

@ -532,6 +532,10 @@ impl Client {
self.send(&ClientMessage::SetTransformMatrix { device, matrix }) 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 { pub fn device_name(&self, device: InputDevice) -> String {
let res = self.send_with_response(&ClientMessage::GetDeviceName { device }); let res = self.send_with_response(&ClientMessage::GetDeviceName { device });
get_response!(res, String::new(), GetDeviceName { name }); get_response!(res, String::new(), GetDeviceName { name });

View file

@ -270,6 +270,10 @@ pub enum ClientMessage<'a> {
SetFont { SetFont {
font: &'a str, font: &'a str,
}, },
SetPxPerWheelScroll {
device: InputDevice,
px: f64,
},
} }
#[derive(Encode, Decode, Debug)] #[derive(Encode, Decode, Debug)]

View file

@ -71,6 +71,18 @@ impl InputDevice {
pub fn name(self) -> String { pub fn name(self) -> String {
get!(String::new()).device_name(self) 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. /// A seat.

View file

@ -487,6 +487,12 @@ impl ConfigProxyHandler {
Ok(()) 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( fn handle_set_transform_matrix(
&self, &self,
device: InputDevice, device: InputDevice,
@ -1077,6 +1083,9 @@ impl ConfigProxyHandler {
ClientMessage::ResetFont => self.handle_reset_font(), ClientMessage::ResetFont => self.handle_reset_font(),
ClientMessage::GetFont => self.handle_get_font(), ClientMessage::GetFont => self.handle_get_font(),
ClientMessage::SetFont { font } => self.handle_set_font(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(()) Ok(())
} }

View file

@ -20,10 +20,11 @@ use {
WHEEL_TILT_SINCE_VERSION, WHEEL_TILT_SINCE_VERSION,
}, },
zwp_relative_pointer_v1::ZwpRelativePointerV1, 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}, wl_surface::{xdg_surface::xdg_popup::XdgPopup, WlSurface},
}, },
state::DeviceHandlerData,
tree::{Direction, FloatNode, Node, ToplevelNode}, tree::{Direction, FloatNode, Node, ToplevelNode},
utils::{bitflags::BitflagsExt, clonecell::CloneCell, smallmap::SmallMap}, utils::{bitflags::BitflagsExt, clonecell::CloneCell, smallmap::SmallMap},
wire::WlDataOfferId, wire::WlDataOfferId,
@ -166,7 +167,7 @@ impl NodeSeatState {
} }
impl WlSeatGlobal { impl WlSeatGlobal {
pub fn event(self: &Rc<Self>, event: InputEvent) { pub fn event(self: &Rc<Self>, dev: &DeviceHandlerData, event: InputEvent) {
match event { match event {
InputEvent::Key { InputEvent::Key {
time_usec, time_usec,
@ -196,7 +197,7 @@ impl WlSeatGlobal {
InputEvent::Axis120 { dist, axis } => self.pointer_owner.axis_120(dist, axis), InputEvent::Axis120 { dist, axis } => self.pointer_owner.axis_120(dist, axis),
InputEvent::AxisSmooth { dist, axis } => self.pointer_owner.axis_smooth(dist, axis), InputEvent::AxisSmooth { dist, axis } => self.pointer_owner.axis_smooth(dist, axis),
InputEvent::AxisStop { axis } => self.pointer_owner.axis_stop(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 // Scroll callbacks
impl WlSeatGlobal { 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() { if let Some(source) = event.source.get() {
let since = if source >= WHEEL_TILT { let since = if source >= WHEEL_TILT {
WHEEL_TILT_SINCE_VERSION WHEEL_TILT_SINCE_VERSION
@ -556,7 +562,7 @@ impl WlSeatGlobal {
} else if p.seat.version >= AXIS_DISCRETE_SINCE_VERSION { } else if p.seat.version >= AXIS_DISCRETE_SINCE_VERSION {
p.send_axis_discrete(axis, delta / AXIS_120); 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)); p.send_axis(time, axis, Fixed::from_f64(px));
} else if let Some(delta) = event.smooth[i].get() { } else if let Some(delta) = event.smooth[i].get() {
p.send_axis(time, axis, delta); p.send_axis(time, axis, delta);

View file

@ -8,6 +8,7 @@ use {
wl_seat::{wl_pointer::PendingScroll, Dnd, DroppedDnd, WlSeatError, WlSeatGlobal}, wl_seat::{wl_pointer::PendingScroll, Dnd, DroppedDnd, WlSeatError, WlSeatGlobal},
wl_surface::WlSurface, wl_surface::WlSurface,
}, },
state::DeviceHandlerData,
tree::{FoundNode, Node}, tree::{FoundNode, Node},
utils::{clonecell::CloneCell, smallmap::SmallMap}, utils::{clonecell::CloneCell, smallmap::SmallMap},
}, },
@ -51,11 +52,11 @@ impl PointerOwnerHolder {
self.pending_scroll.stop[axis as usize].set(true); self.pending_scroll.stop[axis as usize].set(true);
} }
pub fn frame(&self, seat: &Rc<WlSeatGlobal>, time_usec: u64) { pub fn frame(&self, dev: &DeviceHandlerData, seat: &Rc<WlSeatGlobal>, time_usec: u64) {
self.pending_scroll.time_usec.set(time_usec); self.pending_scroll.time_usec.set(time_usec);
let pending = self.pending_scroll.take(); let pending = self.pending_scroll.take();
if let Some(node) = self.owner.get().axis_node(seat) { 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);
} }
} }

View file

@ -25,6 +25,7 @@ use {
object::Object, object::Object,
rect::{Rect, Region}, rect::{Rect, Region},
render::Renderer, render::Renderer,
state::DeviceHandlerData,
tree::{FindTreeResult, FoundNode, Node, NodeId, NodeVisitor, ToplevelNode}, tree::{FindTreeResult, FoundNode, Node, NodeId, NodeVisitor, ToplevelNode},
utils::{ utils::{
buffd::{MsgParser, MsgParserError}, buffd::{MsgParser, MsgParserError},
@ -779,8 +780,13 @@ impl Node for WlSurface {
seat.button_surface(&self, time_usec, button, state, serial); seat.button_surface(&self, time_usec, button, state, serial);
} }
fn node_on_axis_event(self: Rc<Self>, seat: &Rc<WlSeatGlobal>, event: &PendingScroll) { fn node_on_axis_event(
seat.scroll_surface(&*self, event); self: Rc<Self>,
dev: &DeviceHandlerData,
seat: &Rc<WlSeatGlobal>,
event: &PendingScroll,
) {
seat.scroll_surface(dev, &*self, event);
} }
fn node_on_focus(self: Rc<Self>, seat: &Rc<WlSeatGlobal>) { fn node_on_focus(self: Rc<Self>, seat: &Rc<WlSeatGlobal>) {

View file

@ -173,6 +173,7 @@ pub struct InputDeviceData {
pub struct DeviceHandlerData { pub struct DeviceHandlerData {
pub seat: CloneCell<Option<Rc<WlSeatGlobal>>>, pub seat: CloneCell<Option<Rc<WlSeatGlobal>>>,
pub px_per_scroll_wheel: Cell<f64>,
pub device: Rc<dyn InputDevice>, pub device: Rc<dyn InputDevice>,
} }

View file

@ -1,15 +1,17 @@
use { use {
crate::{ crate::{
backend::InputDevice, backend::InputDevice,
ifs::wl_seat::PX_PER_SCROLL,
state::{DeviceHandlerData, InputDeviceData, State}, state::{DeviceHandlerData, InputDeviceData, State},
utils::asyncevent::AsyncEvent, utils::asyncevent::AsyncEvent,
}, },
std::rc::Rc, std::{cell::Cell, rc::Rc},
}; };
pub fn handle(state: &Rc<State>, dev: Rc<dyn InputDevice>) { pub fn handle(state: &Rc<State>, dev: Rc<dyn InputDevice>) {
let data = Rc::new(DeviceHandlerData { let data = Rc::new(DeviceHandlerData {
seat: Default::default(), seat: Default::default(),
px_per_scroll_wheel: Cell::new(PX_PER_SCROLL),
device: dev.clone(), device: dev.clone(),
}); });
let ae = Rc::new(AsyncEvent::default()); let ae = Rc::new(AsyncEvent::default());
@ -54,7 +56,7 @@ impl DeviceHandler {
if let Some(seat) = self.data.seat.get() { if let Some(seat) = self.data.seat.get() {
let mut any_events = false; let mut any_events = false;
while let Some(event) = self.dev.event() { while let Some(event) = self.dev.event() {
seat.event(event); seat.event(&self.data, event);
any_events = true; any_events = true;
} }
if any_events { if any_events {

View file

@ -9,6 +9,7 @@ use {
}, },
rect::Rect, rect::Rect,
render::Renderer, render::Renderer,
state::DeviceHandlerData,
utils::numcell::NumCell, utils::numcell::NumCell,
xkbcommon::ModifierState, xkbcommon::ModifierState,
}, },
@ -184,7 +185,13 @@ pub trait Node: 'static {
let _ = serial; let _ = serial;
} }
fn node_on_axis_event(self: Rc<Self>, seat: &Rc<WlSeatGlobal>, event: &PendingScroll) { fn node_on_axis_event(
self: Rc<Self>,
dev: &DeviceHandlerData,
seat: &Rc<WlSeatGlobal>,
event: &PendingScroll,
) {
let _ = dev;
let _ = seat; let _ = seat;
let _ = event; let _ = event;
} }

View file

@ -9,7 +9,7 @@ use {
}, },
rect::Rect, rect::Rect,
render::{Renderer, Texture}, render::{Renderer, Texture},
state::State, state::{DeviceHandlerData, State},
text, text,
tree::{ tree::{
walker::NodeVisitor, ContainingNode, Direction, FindTreeResult, FoundNode, Node, walker::NodeVisitor, ContainingNode, Direction, FindTreeResult, FoundNode, Node,
@ -1145,7 +1145,12 @@ impl Node for ContainerNode {
} }
} }
fn node_on_axis_event(self: Rc<Self>, seat: &Rc<WlSeatGlobal>, event: &PendingScroll) { fn node_on_axis_event(
self: Rc<Self>,
_dev: &DeviceHandlerData,
seat: &Rc<WlSeatGlobal>,
event: &PendingScroll,
) {
let mut seat_datas = self.seats.borrow_mut(); let mut seat_datas = self.seats.borrow_mut();
let seat_data = match seat_datas.get_mut(&seat.id()) { let seat_data = match seat_datas.get_mut(&seat.id()) {
Some(s) => s, Some(s) => s,

View file

@ -17,7 +17,7 @@ use {
}, },
rect::Rect, rect::Rect,
render::{Renderer, Texture}, render::{Renderer, Texture},
state::State, state::{DeviceHandlerData, State},
text, text,
tree::{ tree::{
walker::NodeVisitor, Direction, FindTreeResult, FoundNode, Node, NodeId, WorkspaceNode, walker::NodeVisitor, Direction, FindTreeResult, FoundNode, Node, NodeId, WorkspaceNode,
@ -512,7 +512,12 @@ impl Node for OutputNode {
self.state.tree_changed(); self.state.tree_changed();
} }
fn node_on_axis_event(self: Rc<Self>, seat: &Rc<WlSeatGlobal>, event: &PendingScroll) { fn node_on_axis_event(
self: Rc<Self>,
_dev: &DeviceHandlerData,
seat: &Rc<WlSeatGlobal>,
event: &PendingScroll,
) {
let steps = match self.scroll.handle(event) { let steps = match self.scroll.handle(event) {
Some(e) => e, Some(e) => e,
_ => return, _ => return,