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

commit6d8edada0d8f25cc7b55a4768927c966b52db0d7
parentc03a722c90
authorLucas Galante <[email protected]>
date2026-08-04 21:51
fix: border taps pan to mostly-hidden windows; drags still don't

A border press focuses the window and kills any focus-follow pan so a
drag never fights the camera — but a TAP (press+release with <4px of
motion) is a click, not a drag. Aiming at a thin content sliver at the
screen edge it is easy to land on the border band instead: the window
focused and nothing else happened (the data-editor menubar case, part
two). op_end now runs focus_follow_pan for motionless ops; any real
drag keeps the camera still.

Co-Authored-By: Claude Fable 5 <[email protected]>

 src/server/seat.rs | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/src/server/seat.rs b/src/server/seat.rs
index c51f08e..d467e0f 100644
--- a/src/server/seat.rs
+++ b/src/server/seat.rs
@@ -1353,6 +1353,19 @@ impl Seat {
                         (*self.server).wm.dirty_windowing();
                     }
                 }
+                // A border TAP — press+release without meaningful motion —
+                // is a click, not a drag. The press focused the window and
+                // killed any focus-follow pan (drag protection), which left
+                // a mostly-hidden window stranded: aiming at a thin content
+                // sliver at the screen edge, it is easy to land on the
+                // border band instead, focus the window, and see nothing
+                // happen. Restore the pan for taps; real drags (any actual
+                // motion) keep the camera still.
+                let dx = (op.x - op.start_x).abs();
+                let dy = (op.y - op.start_y).abs();
+                if dx < 4 && dy < 4 {
+                    self.focus_follow_pan(win);
+                }
             }
             match op.input {
                 SeatOpInput::Pointer => {