Repository navigation
fix(input): allow unconstrained selection translation on pannable boards and sync drag anchor - #425
Merged
devmobasa merged 2 commits intoOct 26, 2026
Conversation
gsmith-alvarez
marked this pull request as draft
October 25, 2026 15:48
Contributor
Author
|
Give it more time since issues keep arrive. Will keep running for longer to confirm stability |
…rds and sync drag anchor - Pannable boards (solid boards) have unbounded canvases; do not clamp selection translation against the viewport rectangle. - Retain clamping on transparent overlay boards where the canvas is bound to the output. - Always advance MovingSelection last_x/last_y on pointer motion so dragging against a boundary does not leave a stale reference anchor that causes jumping.
gsmith-alvarez
force-pushed
the
fix/unconstrained-panned-selection-move
branch
from
October 25, 2026 16:00
c7b9d17 to
f9b8622
Compare
devmobasa
marked this pull request as ready for review
October 25, 2026 16:45
Keep the press as the drag anchor until the pointer leaves the click radius, so the first drag motion is not lost. After that the anchor follows the pointer on every motion, including blocked ones, so reversing at an edge moves the selection at once. Apply coordinate limits on every board. Pannable boards still move freely, but each translated coordinate and the painted bounds now stay in the i32 range. Before, a nudge near i32::MAX wrapped in release builds: the line jumped to span the whole coordinate range and was saved that way. Debug builds panicked instead. On a fixed canvas (the transparent overlay, or a board with panning disabled), a selection that already crosses an edge, or lies outside the canvas, can no longer move further out, and it is never pulled back. Before, any nudge snapped it inside, up to thousands of pixels. Align the move-to-edge actions with the visible canvas, including pan and zoom, instead of the screen origin. A target further away than i32::MAX is reached in several steps that record one undo entry. Combine selection bounds in i64. Shape bounds are clamped to the i32 range, so a shape at the coordinate limit is measured on a copy moved toward the origin; the limits and edge actions then see its full stroke padding. A selection whose painted bounds end past i32::MAX gets no selection Rect, because handle hit-testing and other selection code compute x + width in i32. Its chrome then marks full damage, so the halos of its other members are still repainted. The Properties panel uses the same bounds, the text resize handle is omitted when it would end past i32::MAX, and handle hit-testing compares pointer distances in i64. Test changes: - nudge_selection_clamps_right_and_bottom_edges starts at (87, 87). At (90, 90) the stroke padding already crossed the canvas edge, and the test passed only because the old clamp pulled the shape back. - moving_a_selection_on_transparent_board_clamps_to_screen checks the exact landing edge. It also passed when nothing moved. The coordinate guard and the view-relative edge targets are adapted from devmobasa#424.
Owner
|
Thanks for the fix and the clear report. I pushed one commit on top of yours (da68d15) rather than asking you for another round. What it adds:
Could you try it on your niri setup before we merge? From this branch: On a panned (and zoomed) blackboard:
On the transparent overlay, drag a shape against a screen edge, keep pushing, then drag back. It should stop at the edge and come back as soon as you reverse. If anything looks off, a short clip like the one in #422 helps a lot. |
Contributor
Author
|
Yeah I'll test it now. |
Contributor
Author
|
Works just fine to me |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #423.
PR #423 addressed the coordinate unit mismatch by clamping against
visible_canvas_rect. However, on solid boards where panning is enabled, the canvas is unbounded. Constraining selection translation to the visible viewport created an artificial "invisible wall" around the monitor edges. Furthermore, when motion was clamped to zero delta,last_x/last_ystopped advancing, causing a stale reference anchor that made selections jump when the pointer moved in an unblocked direction.This change:
pan_enabled && !board_is_transparent), allowing free selection movement across the canvas.last_x/last_yon pointer motion so the drag anchor never becomes stale or jumps.Validation:
src/input/state/tests/transform.rs:moving_a_selection_on_a_panned_board_follows_the_pointermoving_a_selection_on_a_panned_board_can_move_freely_across_canvasmoving_a_selection_on_transparent_board_clamps_to_screencargo test --lib moving_a_selection(3 passed, 0 failed).cargo fmt --checkclean.git diff --checkclean.(Note: Prepared with AI assistance.)