summaryrefslogtreecommitdiff
path: root/src/config.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/config.zig')
-rw-r--r--src/config.zig56
1 files changed, 56 insertions, 0 deletions
diff --git a/src/config.zig b/src/config.zig
index 35be4b9f..7f83155a 100644
--- a/src/config.zig
+++ b/src/config.zig
@@ -303,6 +303,62 @@ pub const search_submit: []const Chord = &.{.{ .cp = Key.enter }};
pub const wheel_rows: i32 = 1;
pub const wheel_cols: i32 = 4;
+/// Touchpad drift guard, in ticks. A two-finger swipe that is MEANT to be
+/// vertical carries a little sideways drift, and the pad faithfully turns that
+/// drift into wheel_left/wheel_right — so a plain scroll slides the view
+/// sideways under you. Every vertical tick re-arms the guard to this many
+/// ticks and every horizontal tick spends one instead of scrolling, which
+/// makes horizontal EARN its way back: it has to land this many ticks in a row
+/// with no vertical among them. 3, because drift arrives in ones and twos —
+/// at 1 or 2 a doubled drift tick mid-swipe still gets through, and much
+/// higher starts eating deliberate swipes. Set 0 to disable the heuristic.
+///
+/// It costs nothing at rest: the guard is only armed by vertical scrolling, so
+/// a horizontal swipe that starts from a still view moves on its FIRST tick.
+/// Note this applies to a tilt wheel too, where "recent vertical" is a much
+/// weaker signal of accident — a mouse would rather not have it. Living with
+/// that is deliberate: the only honest fix is a per-device flag out of the
+/// shell (libinput/SDL know which is which, vaxis does not), and paying for a
+/// device-detection layer to spare a tilt wheel three clicks after a scroll is
+/// a worse trade than the three clicks.
+pub const wheel_guard_ticks: u8 = 3;
+
+/// The whole guard, as one state machine, so it can be tested as one thing:
+/// fold a wheel tick into `guard` and answer whether it scrolls. The core owns
+/// the counter (Pardes.wheel_guard) because the gesture belongs to the DEVICE,
+/// not to whichever pane the pointer happens to sit over.
+pub fn wheelTick(guard: *u8, vertical: bool) bool {
+ if (vertical) {
+ guard.* = wheel_guard_ticks;
+ return true;
+ }
+ if (guard.* == 0) return true;
+ guard.* -= 1;
+ return false;
+}
+
+// written to hold for ANY tuning of wheel_guard_ticks, since tuning it by hand
+// is what this file is for — a test that pinned the number 3 would just be a
+// second place to edit it
+test "wheel drift guard" {
+ var g: u8 = 0;
+ // from rest, horizontal moves on the first tick — nothing to prove
+ try std.testing.expect(wheelTick(&g, false));
+ try std.testing.expect(wheelTick(&g, false));
+ if (wheel_guard_ticks == 0) return; // guard disabled: nothing left to check
+ // a vertical swipe with drift mixed in: every sideways tick is swallowed,
+ // because each vertical tick re-arms the guard in full
+ for (0..4) |_| try std.testing.expect(wheelTick(&g, true));
+ try std.testing.expect(!wheelTick(&g, false));
+ try std.testing.expect(wheelTick(&g, true));
+ try std.testing.expect(!wheelTick(&g, false));
+ // the deliberate horizontal swipe that follows pays off the rest of the
+ // guard tick by tick, then runs free
+ for (1..wheel_guard_ticks) |_| try std.testing.expect(!wheelTick(&g, false));
+ try std.testing.expect(wheelTick(&g, false));
+ try std.testing.expect(wheelTick(&g, false));
+}
+
// ---- layout numbers that are taste ----
/// the file pane's line-number gutter, in columns