aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Molodetskikh <yalterz@gmail.com>2025-02-16 08:46:38 +0300
committerIvan Molodetskikh <yalterz@gmail.com>2025-02-16 10:18:00 +0300
commitf2b1fc66f21f720ba85a4c218546298e527ba8b9 (patch)
treeec7c6950c3a7007357f3ede823392982295c3e1b
parent22302bf224def0ba24ad73e10a987ee6ba33cb2d (diff)
downloadniri-f2b1fc66f21f720ba85a4c218546298e527ba8b9.tar.gz
niri-f2b1fc66f21f720ba85a4c218546298e527ba8b9.tar.bz2
niri-f2b1fc66f21f720ba85a4c218546298e527ba8b9.zip
Make DnD edge view scroll configurable
-rw-r--r--niri-config/src/lib.rs46
-rw-r--r--src/layout/mod.rs3
-rw-r--r--src/layout/scrolling.rs7
-rw-r--r--src/layout/workspace.rs22
4 files changed, 70 insertions, 8 deletions
diff --git a/niri-config/src/lib.rs b/niri-config/src/lib.rs
index 0c4f5680..54e2a3a9 100644
--- a/niri-config/src/lib.rs
+++ b/niri-config/src/lib.rs
@@ -59,6 +59,8 @@ pub struct Config {
#[knuffel(child, default)]
pub animations: Animations,
#[knuffel(child, default)]
+ pub gestures: Gestures,
+ #[knuffel(child, default)]
pub environment: Environment,
#[knuffel(children(name = "window-rule"))]
pub window_rules: Vec<WindowRule>,
@@ -1115,6 +1117,32 @@ pub struct SpringParams {
pub epsilon: f64,
}
+#[derive(knuffel::Decode, Debug, Default, Clone, Copy, PartialEq)]
+pub struct Gestures {
+ #[knuffel(child, default)]
+ pub dnd_edge_view_scroll: DndEdgeViewScroll,
+}
+
+#[derive(knuffel::Decode, 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 delay_ms: u16,
+ #[knuffel(child, unwrap(argument), default = Self::default().max_speed)]
+ pub max_speed: FloatOrInt<0, 1_000_000>,
+}
+
+impl Default for DndEdgeViewScroll {
+ fn default() -> Self {
+ Self {
+ trigger_width: FloatOrInt(30.), // Taken from GTK 4.
+ delay_ms: 50,
+ max_speed: FloatOrInt(1500.),
+ }
+ }
+}
+
#[derive(knuffel::Decode, Debug, Default, Clone, PartialEq, Eq)]
pub struct Environment(#[knuffel(children)] pub Vec<EnvironmentVariable>);
@@ -3679,6 +3707,13 @@ mod tests {
window-open { off; }
}
+ gestures {
+ dnd-edge-view-scroll {
+ trigger-width 10
+ max-speed 50
+ }
+ }
+
environment {
QT_QPA_PLATFORM "wayland"
DISPLAY null
@@ -4252,6 +4287,17 @@ mod tests {
},
),
},
+ gestures: Gestures {
+ dnd_edge_view_scroll: DndEdgeViewScroll {
+ trigger_width: FloatOrInt(
+ 10.0,
+ ),
+ delay_ms: 50,
+ max_speed: FloatOrInt(
+ 50.0,
+ ),
+ },
+ },
environment: Environment(
[
EnvironmentVariable {
diff --git a/src/layout/mod.rs b/src/layout/mod.rs
index 248a5c4f..1f99f9d1 100644
--- a/src/layout/mod.rs
+++ b/src/layout/mod.rs
@@ -328,6 +328,7 @@ pub struct Options {
/// Window height that `toggle_window_height()` switches between.
pub preset_window_heights: Vec<PresetSize>,
pub animations: niri_config::Animations,
+ pub gestures: niri_config::Gestures,
// Debug flags.
pub disable_resize_throttling: bool,
pub disable_transactions: bool,
@@ -354,6 +355,7 @@ impl Default for Options {
],
default_column_width: None,
animations: Default::default(),
+ gestures: Default::default(),
disable_resize_throttling: false,
disable_transactions: false,
preset_window_heights: vec![
@@ -582,6 +584,7 @@ impl Options {
preset_column_widths,
default_column_width,
animations: config.animations.clone(),
+ gestures: config.gestures,
disable_resize_throttling: config.debug.disable_resize_throttling,
disable_transactions: config.debug.disable_transactions,
preset_window_heights,
diff --git a/src/layout/scrolling.rs b/src/layout/scrolling.rs
index d559c281..926cfd76 100644
--- a/src/layout/scrolling.rs
+++ b/src/layout/scrolling.rs
@@ -2806,6 +2806,8 @@ impl<W: LayoutElement> ScrollingSpace<W> {
return;
};
+ let config = &self.options.gestures.dnd_edge_view_scroll;
+
let now = self.clock.now_unadjusted();
gesture.dnd_last_event_time = Some(now);
@@ -2819,13 +2821,14 @@ impl<W: LayoutElement> ScrollingSpace<W> {
// Delay starting the gesture a bit to avoid unwanted movement when dragging across
// monitors.
- if now.saturating_sub(nonzero_start) < Duration::from_millis(50) {
+ let delay = Duration::from_millis(u64::from(config.delay_ms));
+ if now.saturating_sub(nonzero_start) < delay {
return;
}
let time_delta = now.saturating_sub(last_time).as_secs_f64();
- let delta = delta * time_delta * 50.;
+ let delta = delta * time_delta * config.max_speed.0;
gesture.tracker.push(delta, now);
diff --git a/src/layout/workspace.rs b/src/layout/workspace.rs
index 37e6aa99..54926a1f 100644
--- a/src/layout/workspace.rs
+++ b/src/layout/workspace.rs
@@ -1614,22 +1614,32 @@ impl<W: LayoutElement> Workspace<W> {
}
pub fn dnd_scroll_gesture_scroll(&mut self, pos: Point<f64, Logical>) {
- // Taken from GTK 4.
- const SCROLL_EDGE_SIZE: f64 = 30.;
+ let config = &self.options.gestures.dnd_edge_view_scroll;
+ let trigger_width = config.trigger_width.0;
// This working area intentionally does not include extra struts from Options.
let x = pos.x - self.working_area.loc.x;
let width = self.working_area.size.w;
+
let x = x.clamp(0., width);
+ let trigger_width = trigger_width.clamp(0., width / 2.);
- let delta = if x < SCROLL_EDGE_SIZE {
- -(SCROLL_EDGE_SIZE - x)
- } else if width - x < SCROLL_EDGE_SIZE {
- SCROLL_EDGE_SIZE - (width - x)
+ let delta = if x < trigger_width {
+ -(trigger_width - x)
+ } else if width - x < trigger_width {
+ trigger_width - (width - x)
} else {
0.
};
+ let delta = if trigger_width < 0.01 {
+ // Sanity check for trigger-width 0 or small window sizes.
+ 0.
+ } else {
+ // Normalize to [0, 1].
+ delta / trigger_width
+ };
+
self.scrolling.dnd_scroll_gesture_scroll(delta);
}