Skip to content

fix(explorer): the sweep box marks only rows it touches (#326) - #328

Merged
Maxaubert merged 3 commits into
mainfrom
fix/326-sweep-box-x
Oct 8, 2026
Merged

Maxaubert merged 3 commits into
mainfrom
fix/326-sweep-box-x

Conversation

@Maxaubert

@Maxaubert Maxaubert commented Oct 7, 2026 •

Copy link
Copy Markdown
Owner

The owner, 2026-10-07, with a screenshot of a sweep box drawn in the empty space right of the Explorer's columns that had marked the rows beside it:

i can select files without having the highlight box be over the files, that should not happen. only the ones that are inside it, even if that's a px should get marked but this is not inside at all

Cause

The sweep's hit test (rowsInBand, called from useSweep) compared only the box's vertical span with the rows'. Any rectangle at a row's height marked it, wherever it was across, so a box drawn in the blank space beside the rows, or up the empty right side from under them, marked every row it passed level with.

Fix

  • lib/marquee: rowsInBox takes the whole box and the row's drawn extent across. One pixel of overlap counts; a box starting at the row's right edge does not. Rows are still found by index, so rows scrolled out of view still count.
  • useSweep hands the hit test the whole box. The row's extent (rowAcross) is measured once per sweep, not on every tick (review: a forced layout read each frame), and asked again only while no row is drawn.
  • BrowseList measures the drawn row (the list's left to the end of its last column, Dragging: the whole row picks an item up, the cursor stays an arrow, and the box select starts only from empty space #320's gutter short of the edge) off any row in view, plus scrollLeft. The tree measures its own rows, which run its full width, so it behaves as before.
  • Version 0.96.1.

Tests

  • Unit: marquee.test.ts covers rowsInBox: a box right or left of the rows, below the last row, ending on the left edge, starting one pixel past, one pixel in, and rows far out of view.
  • e2e marqueeEdge (new): a box beside the rows, and one up the empty right side from under them, mark nothing, live and after release; a box ending a pixel past the rows marks nothing; a box two pixels in marks the rows it spans. It failed 5 checks on the old code.
  • marquee and marqueeQuiet: the sweeps that stayed beside the rows now reach into them.
  • typecheck, lint, the unit suite and the three marquee e2e scenarios pass locally.

Closes #326

🤖 Generated with Claude Code

https://claude.ai/code/session_01FHHaWKR4M5QtW7Wecyuk4t

Maxaubert and others added 3 commits October 7, 2026 20:51
The owner, 2026-10-07: "i can select files without having the highlight
box be over the files ... only the ones that are inside it, even if that's
a px should get marked but this is not inside at all". A rectangle drawn in
the empty space right of Date modified marked every row at its height,
because rowsInBand and the sweep's hit test only compared the vertical span.

- lib/marquee: rowsInBox takes the whole box and the row's drawn extent
  across; one pixel of overlap counts, the first column past the row does
  not. Rows are still found by index, so the lists stay virtual-safe.
- useSweep hands the hit test the whole box (hitsIn).
- BrowseList measures the drawn row (the list's left to its last column,
  #320's gutter short of the edge) off any row in view; the tree measures
  its own rows, which run its full width.
- e2e marqueeEdge: a box beside the rows, and one up the empty right side
  from under them, mark nothing; a box one pixel short marks nothing; a box
  two pixels in marks the rows it spans. It failed 5 checks before the fix.
  marquee and marqueeQuiet sweeps that stayed beside the rows now reach in.
- Version 0.96.1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FHHaWKR4M5QtW7Wecyuk4t
Review of #326: hitsIn ran a querySelector and two getBoundingClientRect
calls on every sweep tick, a forced layout read each frame. A row cannot
change width under a held button, so useSweep now asks the list for the
drawn row's extent (rowAcross) once, when the sweep's first update runs,
and hands it to hitsIn. It asks again only while no row is drawn (null),
when hitsIn falls back to the list's whole width as before.

typecheck, lint, unit and the marquee, marqueeQuiet and marqueeEdge e2e
pass.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FHHaWKR4M5QtW7Wecyuk4t
@Maxaubert
Maxaubert merged commit 69d3109 into main Oct 8, 2026
3 checks passed
@Maxaubert
Maxaubert deleted the fix/326-sweep-box-x branch October 8, 2026 09:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(explorer): the sweep box marks only rows it touches

1 participant