git.lucas.co / cce-compositor
Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git

commitd9ee51e8085bc7128d65ca3ba3d8082871e4ccaf
parent359b99984c
authorLucas Galante <lsgalante12@gmail.com>
date2026-10-01 20:18
Don't lean the camera on a swipe when animations are off

With cce_ui::motion disabled, a three-finger focus/pan swipe no longer
peeks toward its bind short of the threshold: the camera holds still
until the bind fires, and the step's pan is already instant then.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

 CLAUDE.md            |  4 +++-
 src/server/cursor.rs | 14 ++++++++++++--
 2 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/CLAUDE.md b/CLAUDE.md
index bd3c9eb4..b6b10397 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -705,7 +705,9 @@ is smooth past that band. The size is proportional to the travel —
 disables; `WindowManager::swipe_peek_px` — not under `input`, whose
 config.kdl block input.kdl's replaces wholesale), clamped there — and eases
 back to where it started if the fingers lift first (`handle_swipe_end`), so
-a hesitant swipe shows where it would go without going. **A fire does
+a hesitant swipe shows where it would go without going. With animations
+off (`cce_ui::motion`) nothing leans: the camera holds still until the
+bind fires and the step's pan lands at once. **A fire does
 not end the swipe** (since 2026-09-24): the accumulated travel restarts
 from zero at the fire, and a further `window_manager {
 swipe_repeat_threshold }` of travel (libinput units, default four times
diff --git a/src/server/cursor.rs b/src/server/cursor.rs
index 5475f79d..81ad5bc3 100644
--- a/src/server/cursor.rs
+++ b/src/server/cursor.rs
@@ -4097,8 +4097,18 @@ unsafe extern "C" fn handle_swipe_update(listener: *mut ffi::wl_listener, data:
         // After a step the lean is slower as well as longer to fill: it
         // reaches `swipe_repeat_peek` (default half of `swipe_peek`) at the
         // repeat threshold, so a swipe that has just switched focus does
-        // not tug the camera toward the next window as eagerly.
-        let peek_px = if cursor.gesture_triggered { wm.swipe_repeat_peek_px } else { wm.swipe_peek_px };
+        // not tug the camera toward the next window as eagerly. With
+        // animations off (`cce_ui::motion`) there is no lean at all: the
+        // camera stays put until the bind fires, then jumps (the step's
+        // ease is instant then, `advance_camera_animation`). A lean
+        // already showing when they were turned off goes back the same way.
+        let peek_px = if !cce_ui::motion::enabled() {
+            0.0
+        } else if cursor.gesture_triggered {
+            wm.swipe_repeat_peek_px
+        } else {
+            wm.swipe_peek_px
+        };
         let (dx, dy) = (cursor.gesture_dx, cursor.gesture_dy);
         let want = swipe_lean(dx, dy, navigates, threshold, peek_px, wm.desk_zoom);
         let delta = [want[0] - cursor.swipe_peek[0], want[1] - cursor.swipe_peek[1]];