From 4746a0da7dffde6befcb3c80609fa3d31bffc29c Mon Sep 17 00:00:00 2001 From: Yuya Nishihara Date: Sun, 26 May 2024 14:41:00 +0900 Subject: Add scroll-method property to pointer devices My use case is to enable middle-button scroll on my keyboard with pointing stick. The device is recognized as USB mouse. --- niri-config/src/lib.rs | 47 ++++++++++++++++++++++++++++++++++++++++++++ resources/default-config.kdl | 2 ++ src/input/mod.rs | 18 +++++++++++++++++ wiki/Configuration:-Input.md | 5 +++++ 4 files changed, 72 insertions(+) diff --git a/niri-config/src/lib.rs b/niri-config/src/lib.rs index b3a00e79..e966031a 100644 --- a/niri-config/src/lib.rs +++ b/niri-config/src/lib.rs @@ -170,6 +170,8 @@ pub struct Touchpad { #[knuffel(child, unwrap(argument, str))] pub accel_profile: Option, #[knuffel(child, unwrap(argument, str))] + pub scroll_method: Option, + #[knuffel(child, unwrap(argument, str))] pub tap_button_map: Option, #[knuffel(child)] pub left_handed: bool, @@ -183,6 +185,8 @@ pub struct Mouse { pub accel_speed: f64, #[knuffel(child, unwrap(argument, str))] pub accel_profile: Option, + #[knuffel(child, unwrap(argument, str))] + pub scroll_method: Option, #[knuffel(child)] pub left_handed: bool, } @@ -195,6 +199,8 @@ pub struct Trackpoint { pub accel_speed: f64, #[knuffel(child, unwrap(argument, str))] pub accel_profile: Option, + #[knuffel(child, unwrap(argument, str))] + pub scroll_method: Option, } #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -227,6 +233,25 @@ impl From for input::AccelProfile { } } +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum ScrollMethod { + NoScroll, + TwoFinger, + Edge, + OnButtonDown, +} + +impl From for input::ScrollMethod { + fn from(value: ScrollMethod) -> Self { + match value { + ScrollMethod::NoScroll => Self::NoScroll, + ScrollMethod::TwoFinger => Self::TwoFinger, + ScrollMethod::Edge => Self::Edge, + ScrollMethod::OnButtonDown => Self::OnButtonDown, + } + } +} + #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum TapButtonMap { LeftRightMiddle, @@ -2245,6 +2270,22 @@ impl FromStr for AccelProfile { } } +impl FromStr for ScrollMethod { + type Err = miette::Error; + + fn from_str(s: &str) -> Result { + match s { + "no-scroll" => Ok(Self::NoScroll), + "two-finger" => Ok(Self::TwoFinger), + "edge" => Ok(Self::Edge), + "on-button-down" => Ok(Self::OnButtonDown), + _ => Err(miette!( + r#"invalid scroll method, can be "no-scroll" or "two-finger", "edge", or "on-button-down""# + )), + } + } +} + impl FromStr for TapButtonMap { type Err = miette::Error; @@ -2299,6 +2340,7 @@ mod tests { click-method "clickfinger" accel-speed 0.2 accel-profile "flat" + scroll-method "two-finger" tap-button-map "left-middle-right" } @@ -2306,12 +2348,14 @@ mod tests { natural-scroll accel-speed 0.4 accel-profile "flat" + scroll-method "no-scroll" } trackpoint { natural-scroll accel-speed 0.0 accel-profile "flat" + scroll-method "on-button-down" } tablet { @@ -2467,6 +2511,7 @@ mod tests { natural_scroll: false, accel_speed: 0.2, accel_profile: Some(AccelProfile::Flat), + scroll_method: Some(ScrollMethod::TwoFinger), tap_button_map: Some(TapButtonMap::LeftMiddleRight), left_handed: false, }, @@ -2474,12 +2519,14 @@ mod tests { natural_scroll: true, accel_speed: 0.4, accel_profile: Some(AccelProfile::Flat), + scroll_method: Some(ScrollMethod::NoScroll), left_handed: false, }, trackpoint: Trackpoint { natural_scroll: true, accel_speed: 0.0, accel_profile: Some(AccelProfile::Flat), + scroll_method: Some(ScrollMethod::OnButtonDown), }, tablet: Tablet { map_to_output: Some("eDP-1".to_owned()), diff --git a/resources/default-config.kdl b/resources/default-config.kdl index 4b283466..d417b05d 100644 --- a/resources/default-config.kdl +++ b/resources/default-config.kdl @@ -27,12 +27,14 @@ input { natural-scroll // accel-speed 0.2 // accel-profile "flat" + // scroll-method "two-finger" } mouse { // natural-scroll // accel-speed 0.2 // accel-profile "flat" + // scroll-method "no-scroll" } // Uncomment this to make the mouse warp to the center of newly focused windows. diff --git a/src/input/mod.rs b/src/input/mod.rs index 8bf94d15..a36ea62b 100644 --- a/src/input/mod.rs +++ b/src/input/mod.rs @@ -2232,6 +2232,12 @@ pub fn apply_libinput_settings(config: &niri_config::Input, device: &mut input:: let _ = device.config_accel_set_profile(default); } + if let Some(method) = c.scroll_method { + let _ = device.config_scroll_set_method(method.into()); + } else if let Some(default) = device.config_scroll_default_method() { + let _ = device.config_scroll_set_method(default); + } + if let Some(tap_button_map) = c.tap_button_map { let _ = device.config_tap_set_button_map(tap_button_map.into()); } else if let Some(default) = device.config_tap_default_button_map() { @@ -2275,6 +2281,12 @@ pub fn apply_libinput_settings(config: &niri_config::Input, device: &mut input:: } else if let Some(default) = device.config_accel_default_profile() { let _ = device.config_accel_set_profile(default); } + + if let Some(method) = c.scroll_method { + let _ = device.config_scroll_set_method(method.into()); + } else if let Some(default) = device.config_scroll_default_method() { + let _ = device.config_scroll_set_method(default); + } } if is_trackpoint { @@ -2287,6 +2299,12 @@ pub fn apply_libinput_settings(config: &niri_config::Input, device: &mut input:: } else if let Some(default) = device.config_accel_default_profile() { let _ = device.config_accel_set_profile(default); } + + if let Some(method) = c.scroll_method { + let _ = device.config_scroll_set_method(method.into()); + } else if let Some(default) = device.config_scroll_default_method() { + let _ = device.config_scroll_set_method(default); + } } let is_tablet = device.has_capability(input::DeviceCapability::TabletTool); diff --git a/wiki/Configuration:-Input.md b/wiki/Configuration:-Input.md index 988514b4..baa43acb 100644 --- a/wiki/Configuration:-Input.md +++ b/wiki/Configuration:-Input.md @@ -31,6 +31,7 @@ input { natural-scroll // accel-speed 0.2 // accel-profile "flat" + // scroll-method "two-finger" // tap-button-map "left-middle-right" // click-method "clickfinger" // left-handed @@ -40,6 +41,7 @@ input { // natural-scroll // accel-speed 0.2 // accel-profile "flat" + // scroll-method "no-scroll" // left-handed } @@ -47,6 +49,7 @@ input { // natural-scroll // accel-speed 0.2 // accel-profile "flat" + // scroll-method "on-button-down" } tablet { @@ -124,6 +127,8 @@ A few settings are common between `touchpad`, `mouse` and `trackpoint`: - `natural-scroll`: if set, inverts the scrolling direction. - `accel-speed`: pointer acceleration speed, valid values are from `-1.0` to `1.0` where the default is `0.0`. - `accel-profile`: can be `adaptive` (the default) or `flat` (disables pointer acceleration). +- `scroll-method`: when to generate scroll events instead of pointer motion events, can be `no-scroll`, `two-finger`, `edge`, or `on-button-down`. + The default and supported methods vary depending on the device type. Settings specific to `touchpad`s: -- cgit