The docked row has one height, and no way left to arrive at another

Fixkamo-internal
Shipped
September 7, 2026 at 4:34 AM UTC
Author
Kamo
Commit
e86b625

Resizing a docked window's top edge moves every window's top edge — the row sits on the bottom with its tops in a line, and a row of different heights is a ragged edge rather than a row. Members kept finding windows that arrived at the wrong height anyway, intermittently. Four separate ways in, one shared cause: the row's height was not derived from anything, it was carried on each window and hoped to stay equal. The everyday one needs no race and no gesture at all. `layoutDock` clamps a window to what the viewport can show and the relayout writes that clamped number back INTO the window, so a window opened on a 600px viewport became 584 tall — for ever. Grow the viewport and nothing gave it back, because with no member-chosen height the dock deliberately had "no opinion" and left every window as it found it. The next window opened at the registry default of 690, beside it. Nothing in the app knew the two were meant to match. So the row now always has a height: `dockRowHeight` answers the member's if they have set one and DOCK_DEFAULT_HEIGHT if they have not, re-derived against the current viewport every time. The clamp stops being lossy, and a viewport that shrinks and grows again gives the height back. `dockHeightNow` still answers null for the question it was really asking — has the member chosen? — which is not the question the layout needed. The other three: - A window was born at its tool's default and corrected a whole rAF later. That is a visible pop on a busy main thread and, below, sometimes never arrived at all. The row height is now spent at `windowOpened`, beside the remembered width, so a window is born the height of the row it is being born into. - The early-open buffer replayed its opens BEFORE the store's own listeners were registered a few lines further down, so an early open — a deep link, an auto-popup, any child whose mount effect runs before its parent's — missed its `windowOpened` (row height, remembered width), its `makeRoom` (no hexhead moved aside) and its `wrapAroundDock` (no re-pack at all), and stayed odd until something else happened to re-pack the row. The drain now runs last. - A floating window dragged back to the row previewed landing at `preFloat`'s height, which is the height the row was at when it left. And `tool:resize` / `onRequestResize` wrote a height and repacked nothing, leaving a window standing proud with nothing scheduled to pull it back. Also: a height dragged in one tab now reaches the others. `prefs` was read once at module load, so two tabs of the same member disagreed until a reload, with no gesture available that would explain the difference. Refused mid-drag, which is the only time adopting one would fight a hand already on the seam. `dockRowHeight.test.ts` is new and drives the REAL provider, store and layout strategy — every other file in that folder mocks `ToolWindowsContext`, and the raggedness was inside it — asking after each gesture whether the row is flush. A guard in the registry's own test fails if a tool stops declaring the row default, since a tool with a taller default would not get to be taller, only to make the row's starting height a coin toss.

All changes

Like what you see shipping?

Every one of these updates lands in your workspace automatically. Start free and watch it grow week after week.

Start Free ForeverView Pricing