diff --git a/cosmic-comp-config/src/input.rs b/cosmic-comp-config/src/input.rs index d085a278..3f14df8b 100644 --- a/cosmic-comp-config/src/input.rs +++ b/cosmic-comp-config/src/input.rs @@ -42,6 +42,7 @@ pub struct ScrollConfig { pub method: Option, pub natural_scroll: Option, pub scroll_button: Option, + pub scroll_factor: Option, } #[derive(Copy, Clone, Debug, Serialize, Deserialize)] diff --git a/src/config/input_config.rs b/src/config/input_config.rs index 463d678d..063e80cf 100644 --- a/src/config/input_config.rs +++ b/src/config/input_config.rs @@ -64,6 +64,7 @@ pub fn for_device(device: &InputDevice) -> InputConfig { } else { None }, + scroll_factor: None, }) } else { None @@ -83,7 +84,7 @@ pub fn for_device(device: &InputDevice) -> InputConfig { // Get setting from `device_config` if present, then `default_config` // Returns `is_default` to indicate this is a default value. -fn get_config<'a, T: 'a, F: Fn(&'a InputConfig) -> Option>( +pub fn get_config<'a, T: 'a, F: Fn(&'a InputConfig) -> Option>( device_config: Option<&'a InputConfig>, default_config: &'a InputConfig, f: F, diff --git a/src/config/mod.rs b/src/config/mod.rs index 826bf220..98b56c9d 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -412,13 +412,26 @@ impl Config { } pub fn read_device(&self, device: &mut InputDevice) { + let (device_config, default_config) = self.get_device_config(device); + input_config::update_device(device, device_config, default_config); + } + + pub fn scroll_factor(&self, device: &InputDevice) -> f64 { + let (device_config, default_config) = self.get_device_config(device); + input_config::get_config(device_config, default_config, |x| { + x.scroll_config.as_ref()?.scroll_factor + }) + .map_or(1.0, |x| x.0) + } + + fn get_device_config(&self, device: &InputDevice) -> (Option<&InputConfig>, &InputConfig) { let default_config = if device.config_tap_finger_count() > 0 { &self.input_touchpad } else { &self.input_default }; let device_config = self.input_devices.get(device.name()); - input_config::update_device(device, device_config, default_config); + (device_config, default_config) } } diff --git a/src/input/mod.rs b/src/input/mod.rs index 27ec163f..a0b85780 100644 --- a/src/input/mod.rs +++ b/src/input/mod.rs @@ -15,6 +15,7 @@ use crate::{ }; use calloop::{timer::Timer, RegistrationToken}; use cosmic_protocols::screencopy::v1::server::zcosmic_screencopy_session_v1::InputType; +#[allow(deprecated)] use smithay::{ backend::input::{ Axis, AxisSource, Device, DeviceCapability, InputBackend, InputEvent, KeyState, @@ -27,7 +28,10 @@ use smithay::{ Seat, SeatState, }, output::Output, - reexports::wayland_server::DisplayHandle, + reexports::{ + input::event::pointer::PointerAxisEvent as LibinputPointerAxisEvent, + wayland_server::DisplayHandle, + }, utils::{Logical, Point, Rectangle, Serial, SERIAL_COUNTER}, wayland::{ keyboard_shortcuts_inhibit::KeyboardShortcutsInhibitorSeat, seat::WaylandFocus, @@ -40,6 +44,7 @@ use tracing::info; use tracing::{error, trace, warn}; use std::{ + any::Any, cell::RefCell, collections::HashMap, time::{Duration, Instant}, @@ -171,7 +176,9 @@ impl State { &mut self, event: InputEvent, needs_key_repetition: bool, - ) { + ) where + ::PointerAxisEvent: 'static, + { use smithay::backend::input::Event; match event { @@ -737,6 +744,15 @@ impl State { } } InputEvent::PointerAxis { event, .. } => { + #[allow(deprecated)] + let scroll_factor = if let Some(event) = + ::downcast_ref::(&event) + { + self.common.config.scroll_factor(&event.device()) + } else { + 1.0 + }; + let device = event.device(); for seat in self.common.seats().cloned().collect::>().iter() { #[cfg(feature = "debug")] @@ -775,7 +791,8 @@ impl State { let mut frame = AxisFrame::new(event.time_msec()).source(event.source()); if horizontal_amount != 0.0 { - frame = frame.value(Axis::Horizontal, horizontal_amount); + frame = frame + .value(Axis::Horizontal, scroll_factor * horizontal_amount); if let Some(discrete) = horizontal_amount_discrete { frame = frame.discrete(Axis::Horizontal, discrete as i32); } @@ -783,7 +800,8 @@ impl State { frame = frame.stop(Axis::Horizontal); } if vertical_amount != 0.0 { - frame = frame.value(Axis::Vertical, vertical_amount); + frame = + frame.value(Axis::Vertical, scroll_factor * vertical_amount); if let Some(discrete) = vertical_amount_discrete { frame = frame.discrete(Axis::Vertical, discrete as i32); }