diff --git a/niri-config/src/gestures.rs b/niri-config/src/gestures.rs index 8c4b1363..dcf296ac 100644 --- a/niri-config/src/gestures.rs +++ b/niri-config/src/gestures.rs @@ -1,55 +1,102 @@ +use crate::utils::MergeWith; use crate::FloatOrInt; -#[derive(knuffel::Decode, Debug, Default, Clone, Copy, PartialEq)] +#[derive(Debug, Default, Clone, Copy, PartialEq)] pub struct Gestures { - #[knuffel(child, default)] pub dnd_edge_view_scroll: DndEdgeViewScroll, - #[knuffel(child, default)] pub dnd_edge_workspace_switch: DndEdgeWorkspaceSwitch, - #[knuffel(child, default)] pub hot_corners: HotCorners, } -#[derive(knuffel::Decode, Debug, Clone, Copy, PartialEq)] +#[derive(knuffel::Decode, Debug, Default, Clone, Copy, PartialEq)] +pub struct GesturesPart { + #[knuffel(child)] + pub dnd_edge_view_scroll: Option, + #[knuffel(child)] + pub dnd_edge_workspace_switch: Option, + #[knuffel(child)] + pub hot_corners: Option, +} + +impl MergeWith for Gestures { + fn merge_with(&mut self, part: &GesturesPart) { + merge!( + (self, part), + dnd_edge_view_scroll, + dnd_edge_workspace_switch, + ); + merge_clone!((self, part), hot_corners); + } +} + +#[derive(Debug, Clone, Copy, PartialEq)] pub struct DndEdgeViewScroll { - #[knuffel(child, unwrap(argument), default = Self::default().trigger_width)] - pub trigger_width: FloatOrInt<0, 65535>, - #[knuffel(child, unwrap(argument), default = Self::default().delay_ms)] + pub trigger_width: f64, pub delay_ms: u16, - #[knuffel(child, unwrap(argument), default = Self::default().max_speed)] - pub max_speed: FloatOrInt<0, 1_000_000>, + pub max_speed: f64, } impl Default for DndEdgeViewScroll { fn default() -> Self { Self { - trigger_width: FloatOrInt(30.), // Taken from GTK 4. + trigger_width: 30., // Taken from GTK 4. delay_ms: 100, - max_speed: FloatOrInt(1500.), + max_speed: 1500., } } } #[derive(knuffel::Decode, Debug, Clone, Copy, PartialEq)] +pub struct DndEdgeViewScrollPart { + #[knuffel(child, unwrap(argument))] + pub trigger_width: Option>, + #[knuffel(child, unwrap(argument))] + pub delay_ms: Option, + #[knuffel(child, unwrap(argument))] + pub max_speed: Option>, +} + +impl MergeWith for DndEdgeViewScroll { + fn merge_with(&mut self, part: &DndEdgeViewScrollPart) { + merge!((self, part), trigger_width, max_speed); + merge_clone!((self, part), delay_ms); + } +} + +#[derive(Debug, Clone, Copy, PartialEq)] pub struct DndEdgeWorkspaceSwitch { - #[knuffel(child, unwrap(argument), default = Self::default().trigger_height)] - pub trigger_height: FloatOrInt<0, 65535>, - #[knuffel(child, unwrap(argument), default = Self::default().delay_ms)] + pub trigger_height: f64, pub delay_ms: u16, - #[knuffel(child, unwrap(argument), default = Self::default().max_speed)] - pub max_speed: FloatOrInt<0, 1_000_000>, + pub max_speed: f64, } impl Default for DndEdgeWorkspaceSwitch { fn default() -> Self { Self { - trigger_height: FloatOrInt(50.), + trigger_height: 50., delay_ms: 100, - max_speed: FloatOrInt(1500.), + max_speed: 1500., } } } +#[derive(knuffel::Decode, Debug, Clone, Copy, PartialEq)] +pub struct DndEdgeWorkspaceSwitchPart { + #[knuffel(child, unwrap(argument))] + pub trigger_height: Option>, + #[knuffel(child, unwrap(argument))] + pub delay_ms: Option, + #[knuffel(child, unwrap(argument))] + pub max_speed: Option>, +} + +impl MergeWith for DndEdgeWorkspaceSwitch { + fn merge_with(&mut self, part: &DndEdgeWorkspaceSwitchPart) { + merge!((self, part), trigger_height, max_speed); + merge_clone!((self, part), delay_ms); + } +} + #[derive(knuffel::Decode, Debug, Default, Clone, Copy, PartialEq)] pub struct HotCorners { #[knuffel(child)] diff --git a/niri-config/src/lib.rs b/niri-config/src/lib.rs index 7a07b71b..ab63361d 100644 --- a/niri-config/src/lib.rs +++ b/niri-config/src/lib.rs @@ -192,7 +192,7 @@ where "hotkey-overlay" => m_merge!(hotkey_overlay), "config-notification" => m_merge!(config_notification), "animations" => m_replace!(animations), - "gestures" => m_replace!(gestures), + "gestures" => m_merge!(gestures), "overview" => m_merge!(overview), "xwayland-satellite" => m_merge!(xwayland_satellite), "switch-events" => m_merge!(switch_events), @@ -1433,22 +1433,14 @@ mod tests { }, gestures: Gestures { dnd_edge_view_scroll: DndEdgeViewScroll { - trigger_width: FloatOrInt( - 10.0, - ), + trigger_width: 10.0, delay_ms: 100, - max_speed: FloatOrInt( - 50.0, - ), + max_speed: 50.0, }, dnd_edge_workspace_switch: DndEdgeWorkspaceSwitch { - trigger_height: FloatOrInt( - 50.0, - ), + trigger_height: 50.0, delay_ms: 100, - max_speed: FloatOrInt( - 1500.0, - ), + max_speed: 1500.0, }, hot_corners: HotCorners { off: false, diff --git a/src/layout/monitor.rs b/src/layout/monitor.rs index 5e463a7e..8f322e9e 100644 --- a/src/layout/monitor.rs +++ b/src/layout/monitor.rs @@ -1904,7 +1904,7 @@ impl Monitor { }; let config = &self.options.gestures.dnd_edge_workspace_switch; - let trigger_height = config.trigger_height.0; + let trigger_height = config.trigger_height; // Restrict the scrolling horizontally to the strip of workspaces to avoid unwanted trigger // after using the hot corner or during horizontal scroll. @@ -1958,7 +1958,7 @@ impl Monitor { let time_delta = now.saturating_sub(last_time).as_secs_f64(); - let delta = delta * time_delta * config.max_speed.0; + let delta = delta * time_delta * config.max_speed; gesture.tracker.push(delta, now); diff --git a/src/layout/scrolling.rs b/src/layout/scrolling.rs index 9c483e72..02541d1b 100644 --- a/src/layout/scrolling.rs +++ b/src/layout/scrolling.rs @@ -3045,7 +3045,7 @@ impl ScrollingSpace { let time_delta = now.saturating_sub(last_time).as_secs_f64(); - let delta = delta * time_delta * config.max_speed.0; + let delta = delta * time_delta * config.max_speed; gesture.tracker.push(delta, now); diff --git a/src/layout/workspace.rs b/src/layout/workspace.rs index 5bdd2624..32ce3c9e 100644 --- a/src/layout/workspace.rs +++ b/src/layout/workspace.rs @@ -1766,7 +1766,7 @@ impl Workspace { pub fn dnd_scroll_gesture_scroll(&mut self, pos: Point, speed: f64) -> bool { let config = &self.options.gestures.dnd_edge_view_scroll; - let trigger_width = config.trigger_width.0; + let trigger_width = config.trigger_width; // This working area intentionally does not include extra struts from Options. let x = pos.x - self.working_area.loc.x;