- Shipped
- September 6, 2026 at 5:46 AM UTC
- Author
- Kamo
- Commit
- 586ced0
Three things about the row of docked tool windows. **It stops covering scrollbars.** The dock reserves the viewport's right edge so it does not park a window on the page's bar, but it only ever looked for `.kamo-page-scroll`. This app paints its own 32px bar over every marked scroller — `.kamo-scroll` alone is used at 382 call sites, plus the grids, tables and panels the layer adopts by library class — and any of those flush against the right edge puts a bar exactly where the first window goes. The marker list now lives in `scrollbarModel` and both readers share it. The subtler half was wrong for longer: the gutter the browser reserves was both the test for "is there a bar" and the answer to "how wide", and it is reliably neither. Under overlay scrollbars — the macOS default — a scrolling element reserves no gutter at all, so the dock read zero and parked a window straight over a bar that was plainly painted. Measured in a real browser: scrollHeight 4000 over clientHeight 900, our bar drawn 32px wide, gutter 0, window right edge 1435 against a bar starting at 1408. It now asks whether the element is scrolling and reserves the width actually drawn; the same probe reports the edge at 1403, clear of the bar. Firefox failed the other way, reserving ~15px under the same 32px bar, and is covered by the same change. **Width by dragging a window's left edge.** An 11px band straddling the seam, so a press slightly over the target or over the neighbour to its left both land on it. The row packs right-to-left, so the window's right edge is anchored and pulling left widens it — every window further left shifts along, which is `layoutDock` doing what it already did. Held inside the tool's own `minSize.w`, and remembered per tool: widen a chat window and the next one opens wide. **Height by dragging the top edge — for the whole row at once.** Docked windows sit on the bottom edge with their tops in a line, and a row of different heights is a ragged edge rather than a row. The height lives in `dockSizeStore` and is imposed by `relayoutWindows`, the one choke point every path already runs through: opening, restoring a hexhead, un-maximizing, un-floating, a viewport resize, a snapshot restore. So a hexhead comes back at the height the dock is now, on its first frame, with no code of its own. Persisted to localStorage and read synchronously at module load, so the first window of a session already opens at the member's height rather than resizing a moment after it appears. Both seams light `--color-primary` while they are pulled; a height drag lights every window's top edge, because every window is moving. Both are `separator` roles with arrow keys, and the docked corner grip is gone — one control per property. Verified with headless Chrome against the real layout engine, since jsdom reports no scrollbars at all: the reserve, the overlap it prevents, and both drags (width 460 -> 580 with the right edge held at 1403; height 690 -> 840 with the bottom held).