The drag learns the stepper's trick — past the screen's edge, lane growth re-divides instead of stopping
The right-edge drag's growth was capped at the screen's visible frame, because each snap tick grows the window; on a window near the screen edge that left a lane stuck at a tick or two of headroom. Settled 2026-08-08 (03-board-ui.md § Lane, superseding the pathfinder's hard stop): at the screen the window pins and each further tick re-divides the fixed strip width across one more unit — siblings compress, the stepper's mechanism arriving under the drag's fingers. The regimes meet with no pixel jump (the re-divided standard at the fit IS the frozen standard, by the exact-fill identity), shrinking mirrors the way back, the rubber band moves to the strip's own capacity, and a window with no headroom at all — full screen included — re-divides from the very first snap. New pure arithmetic in LaneLayoutMath (pinnedStripWidth, resizeStandard, resizeMaxUnits, resizeWindowDelta, snappedUnits over per-count slots); LaneResizeSession splits the tick across the regimes and derives its standard from the live count; the handle and BoardView hand the session the strip's whole divide. 2709 unit tests green (+11). Claude-Session: https://claude.ai/code/session_014PtZdPwqZuqEDLc6wZMtEy
This commit is contained in:
@@ -28,6 +28,13 @@ struct LaneResizeHandle: View {
|
||||
let standard: CGFloat
|
||||
let gap: CGFloat
|
||||
|
||||
/// The strip's whole unit total THIS render — every lane's units plus the shown trash's fixed
|
||||
/// one, the same divide the resting layout runs on (`BoardView.stripTotalUnits`). The session
|
||||
/// needs it because past the screen's fit the drag re-divides the strip rather than growing the
|
||||
/// window (03-board-ui.md § Lane, settled 2026-08-08), and a re-divide is a fact about the whole
|
||||
/// strip rather than about this lane.
|
||||
let totalUnits: Int
|
||||
|
||||
/// How the session reaches the host window it resizes. A closure rather than a stored
|
||||
/// `NSWindow?` because the window attaches asynchronously (`WindowAccessor`), and a value
|
||||
/// captured in an early body evaluation would be `nil` for the window's whole life.
|
||||
@@ -75,7 +82,8 @@ struct LaneResizeHandle: View {
|
||||
// not exist yet; when it does, this is where the `isDragging` guard goes.
|
||||
pushCursor()
|
||||
session.begin(laneID: laneID, units: committedUnits,
|
||||
standard: standard, gap: gap, window: window())
|
||||
standard: standard, gap: gap,
|
||||
totalUnits: totalUnits, window: window())
|
||||
}
|
||||
session.update(translation: value.translation.width)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user