aboutsummaryrefslogtreecommitdiff
path: root/niri-config/src
diff options
context:
space:
mode:
Diffstat (limited to 'niri-config/src')
-rw-r--r--niri-config/src/lib.rs282
1 files changed, 272 insertions, 10 deletions
diff --git a/niri-config/src/lib.rs b/niri-config/src/lib.rs
index 16ec6dca..dbd6b5ea 100644
--- a/niri-config/src/lib.rs
+++ b/niri-config/src/lib.rs
@@ -191,6 +191,25 @@ pub enum TrackLayout {
Window,
}
+#[derive(knuffel::Decode, Debug, Default, Clone, Copy, PartialEq)]
+pub struct ScrollFactor {
+ #[knuffel(argument)]
+ pub base: Option<FloatOrInt<0, 100>>,
+ #[knuffel(property)]
+ pub horizontal: Option<FloatOrInt<-100, 100>>,
+ #[knuffel(property)]
+ pub vertical: Option<FloatOrInt<-100, 100>>,
+}
+
+impl ScrollFactor {
+ pub fn h_v_factors(&self) -> (f64, f64) {
+ let base_value = self.base.map(|f| f.0).unwrap_or(1.0);
+ let h = self.horizontal.map(|f| f.0).unwrap_or(base_value);
+ let v = self.vertical.map(|f| f.0).unwrap_or(base_value);
+ (h, v)
+ }
+}
+
#[derive(knuffel::Decode, Debug, Default, PartialEq)]
pub struct Touchpad {
#[knuffel(child)]
@@ -227,8 +246,8 @@ pub struct Touchpad {
pub disabled_on_external_mouse: bool,
#[knuffel(child)]
pub middle_emulation: bool,
- #[knuffel(child, unwrap(argument))]
- pub scroll_factor: Option<FloatOrInt<0, 100>>,
+ #[knuffel(child)]
+ pub scroll_factor: Option<ScrollFactor>,
}
#[derive(knuffel::Decode, Debug, Default, PartialEq)]
@@ -251,8 +270,8 @@ pub struct Mouse {
pub left_handed: bool,
#[knuffel(child)]
pub middle_emulation: bool,
- #[knuffel(child, unwrap(argument))]
- pub scroll_factor: Option<FloatOrInt<0, 100>>,
+ #[knuffel(child)]
+ pub scroll_factor: Option<ScrollFactor>,
}
#[derive(knuffel::Decode, Debug, Default, PartialEq)]
@@ -4055,6 +4074,237 @@ mod tests {
}
#[test]
+ fn parse_scroll_factor_combined() {
+ // Test combined scroll-factor syntax
+ let parsed = do_parse(
+ r#"
+ input {
+ mouse {
+ scroll-factor 2.0
+ }
+ touchpad {
+ scroll-factor 1.5
+ }
+ }
+ "#,
+ );
+
+ assert_debug_snapshot!(parsed.input.mouse.scroll_factor, @r#"
+ Some(
+ ScrollFactor {
+ base: Some(
+ FloatOrInt(
+ 2.0,
+ ),
+ ),
+ horizontal: None,
+ vertical: None,
+ },
+ )
+ "#);
+ assert_debug_snapshot!(parsed.input.touchpad.scroll_factor, @r#"
+ Some(
+ ScrollFactor {
+ base: Some(
+ FloatOrInt(
+ 1.5,
+ ),
+ ),
+ horizontal: None,
+ vertical: None,
+ },
+ )
+ "#);
+ }
+
+ #[test]
+ fn parse_scroll_factor_split() {
+ // Test split horizontal/vertical syntax
+ let parsed = do_parse(
+ r#"
+ input {
+ mouse {
+ scroll-factor horizontal=2.0 vertical=-1.0
+ }
+ touchpad {
+ scroll-factor horizontal=-1.5 vertical=0.5
+ }
+ }
+ "#,
+ );
+
+ assert_debug_snapshot!(parsed.input.mouse.scroll_factor, @r#"
+ Some(
+ ScrollFactor {
+ base: None,
+ horizontal: Some(
+ FloatOrInt(
+ 2.0,
+ ),
+ ),
+ vertical: Some(
+ FloatOrInt(
+ -1.0,
+ ),
+ ),
+ },
+ )
+ "#);
+ assert_debug_snapshot!(parsed.input.touchpad.scroll_factor, @r#"
+ Some(
+ ScrollFactor {
+ base: None,
+ horizontal: Some(
+ FloatOrInt(
+ -1.5,
+ ),
+ ),
+ vertical: Some(
+ FloatOrInt(
+ 0.5,
+ ),
+ ),
+ },
+ )
+ "#);
+ }
+
+ #[test]
+ fn parse_scroll_factor_partial() {
+ // Test partial specification (only one axis)
+ let parsed = do_parse(
+ r#"
+ input {
+ mouse {
+ scroll-factor horizontal=2.0
+ }
+ touchpad {
+ scroll-factor vertical=-1.5
+ }
+ }
+ "#,
+ );
+
+ assert_debug_snapshot!(parsed.input.mouse.scroll_factor, @r#"
+ Some(
+ ScrollFactor {
+ base: None,
+ horizontal: Some(
+ FloatOrInt(
+ 2.0,
+ ),
+ ),
+ vertical: None,
+ },
+ )
+ "#);
+ assert_debug_snapshot!(parsed.input.touchpad.scroll_factor, @r#"
+ Some(
+ ScrollFactor {
+ base: None,
+ horizontal: None,
+ vertical: Some(
+ FloatOrInt(
+ -1.5,
+ ),
+ ),
+ },
+ )
+ "#);
+ }
+
+ #[test]
+ fn parse_scroll_factor_mixed() {
+ // Test mixed base + override syntax
+ let parsed = do_parse(
+ r#"
+ input {
+ mouse {
+ scroll-factor 2 vertical=-1
+ }
+ touchpad {
+ scroll-factor 1.5 horizontal=3
+ }
+ }
+ "#,
+ );
+
+ assert_debug_snapshot!(parsed.input.mouse.scroll_factor, @r#"
+ Some(
+ ScrollFactor {
+ base: Some(
+ FloatOrInt(
+ 2.0,
+ ),
+ ),
+ horizontal: None,
+ vertical: Some(
+ FloatOrInt(
+ -1.0,
+ ),
+ ),
+ },
+ )
+ "#);
+ assert_debug_snapshot!(parsed.input.touchpad.scroll_factor, @r#"
+ Some(
+ ScrollFactor {
+ base: Some(
+ FloatOrInt(
+ 1.5,
+ ),
+ ),
+ horizontal: Some(
+ FloatOrInt(
+ 3.0,
+ ),
+ ),
+ vertical: None,
+ },
+ )
+ "#);
+ }
+
+ #[test]
+ fn scroll_factor_h_v_factors() {
+ let sf = ScrollFactor {
+ base: Some(FloatOrInt(2.0)),
+ horizontal: None,
+ vertical: None,
+ };
+ assert_debug_snapshot!(sf.h_v_factors(), @r#"
+ (
+ 2.0,
+ 2.0,
+ )
+ "#);
+
+ let sf = ScrollFactor {
+ base: None,
+ horizontal: Some(FloatOrInt(3.0)),
+ vertical: Some(FloatOrInt(-1.0)),
+ };
+ assert_debug_snapshot!(sf.h_v_factors(), @r#"
+ (
+ 3.0,
+ -1.0,
+ )
+ "#);
+
+ let sf = ScrollFactor {
+ base: Some(FloatOrInt(2.0)),
+ horizontal: Some(FloatOrInt(1.0)),
+ vertical: None,
+ };
+ assert_debug_snapshot!(sf.h_v_factors(), @r"
+ (
+ 1.0,
+ 2.0,
+ )
+ ");
+ }
+
+ #[test]
fn parse() {
let parsed = do_parse(
r##"
@@ -4370,9 +4620,15 @@ mod tests {
disabled_on_external_mouse: true,
middle_emulation: false,
scroll_factor: Some(
- FloatOrInt(
- 0.9,
- ),
+ ScrollFactor {
+ base: Some(
+ FloatOrInt(
+ 0.9,
+ ),
+ ),
+ horizontal: None,
+ vertical: None,
+ },
),
},
mouse: Mouse {
@@ -4394,9 +4650,15 @@ mod tests {
left_handed: false,
middle_emulation: true,
scroll_factor: Some(
- FloatOrInt(
- 0.2,
- ),
+ ScrollFactor {
+ base: Some(
+ FloatOrInt(
+ 0.2,
+ ),
+ ),
+ horizontal: None,
+ vertical: None,
+ },
),
},
trackpoint: Trackpoint {