Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git
fix(input): the swipe lean follows the dominant axis only
A hand swiping left drifts a little up or down as well, and with
focus_up/focus_down bound that drift leaned the camera vertically too,
then eased it back when the bind fired — a wobble on top of the real
move, plainly visible at a 120 px peek. The lean now follows whichever
axis the swipe has travelled further along, and nothing on the other.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
CLAUDE.md | 4 +++-
src/server/cursor.rs | 16 +++++++++++-----
2 files changed, 14 insertions(+), 6 deletions(-)
diff --git a/CLAUDE.md b/CLAUDE.md
index 701fb5b..eff0e61 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -525,7 +525,9 @@ directional focus or pan (`focus_left (gesture)"swipe3_left"` in input.kdl)
fires once the accumulated travel passes `window_manager { swipe_threshold }`
(libinput units, default 50; `WindowManager::swipe_threshold`). Short of
that the camera *leans* toward the bind the
-swipe is heading for, 1:1 with the fingers and proportional to the travel —
+swipe is heading for, 1:1 with the fingers along the swipe's dominant axis
+only (a hand's sideways drift must not lean the camera vertically, or the
+fire eases a wobble back) and proportional to the travel —
`window_manager { swipe_peek }` screen px at the threshold (default 60, 0
disables; `WindowManager::swipe_peek_px` — not under `input`, whose
config.kdl block input.kdl's replaces wholesale), clamped there — and eases
diff --git a/src/server/cursor.rs b/src/server/cursor.rs
index 250c422..ef87647 100644
--- a/src/server/cursor.rs
+++ b/src/server/cursor.rs
@@ -3784,14 +3784,20 @@ unsafe extern "C" fn handle_swipe_update(listener: *mut ffi::wl_listener, data:
// Short of the threshold: lean the camera toward the bind the swipe
// is heading for, 1:1 with the fingers like a two-finger pan (queued
// for the frame, no easing), recomputed from the total travel so a
- // reversal leans back through zero.
+ // reversal leans back through zero. Along the DOMINANT axis only: a
+ // hand swiping left drifts a little up or down as well, and with
+ // up/down binds present that drift leaned the camera vertically too,
+ // then eased it back when the bind fired — a wobble on top of the
+ // real move.
{
let wm = &mut (*seat.server).wm;
let peek_px = wm.swipe_peek_px;
- let want = [
- swipe_peek_for(cursor.gesture_dx, navigates[0], navigates[1], threshold, peek_px, wm.desk_zoom),
- swipe_peek_for(cursor.gesture_dy, navigates[2], navigates[3], threshold, peek_px, wm.desk_zoom),
- ];
+ let (dx, dy) = (cursor.gesture_dx, cursor.gesture_dy);
+ let want = if dx.abs() >= dy.abs() {
+ [swipe_peek_for(dx, navigates[0], navigates[1], threshold, peek_px, wm.desk_zoom), 0.0]
+ } else {
+ [0.0, swipe_peek_for(dy, navigates[2], navigates[3], threshold, peek_px, wm.desk_zoom)]
+ };
let delta = [want[0] - cursor.swipe_peek[0], want[1] - cursor.swipe_peek[1]];
if delta != [0.0, 0.0] {
wm.stop_panning_animation();