Record what making the frame a window length corrected

Step 2 of the layout plan is done in the experiment checkout, at 1512d84
and 23523ee. The handoff carries the commits and what is left; LAYOUT.md
carries the settled rule, which is now one coordinate unit with the frame
a length of it and both pins beside each other; the log carries what
implementing the plan corrected in it, including the four that would have
shipped as wrong layout and the two rig gaps that hid them.
This commit is contained in:
iris-ai committed 2026-09-19 00:21:44 -04:00
1 parent da1807664a
commit 36ce66554b
3 files changed
+196 -146

No files matched your search

+35 -15
View File
@@ -333,11 +333,30 @@ that box by re-expressing the drawing, and nothing is drawn again in a box an
answer chose. `Holds` is a contract about the ask box alone, read only to
decide whether a re-ask can be skipped. A container that puts an answer
somewhere other than where it asked says so with `Painter::place_at`, which
never runs the body. A frame is narrowed by a length of the parent's frame,
never by a region, and is put back into the part by the child's alignment on
every placement. This is `wip/one-ask` in the experiment checkout. The
padding rule above needs the frame to be a length and the box a region in
the region node's coordinates, which is the next step in `docs/HANDOFF.md`.
never runs the body. This is `wip/one-ask` in the experiment checkout.
**There is one coordinate unit, the window** (`1512d84`, `23523ee`). Every box in the
tree is a region in window units; a widget's frame is a *length* in the same
units and is only what fractions resolve against, so a widget's box need not
be its frame and padding can take from both. A region node's entry is a
translation -- a `rel 1` region anchored where its box starts -- so nothing
composes a frame back up a chain.
A frame decided for a child is therefore a length of the window too: a row's
slot, padding's frame less its pixels, or the box a stack's sizing child
decided (which arrives as `Part::Sized`). It is never a fraction of the
parent's frame, because a slot of a row is not a fraction of anything the row
can name -- a division of two lengths, which a `rel + px` length cannot hold.
A widget's own declaration *is* a fraction, of whichever of those reached it,
and it is the only one of them that also places the box inside the part.
Validity has a pin for each: `LayoutHolds::extent_len` for the box's symbolic
length and `frame_len` for the frame's. A range of window pixels cannot say
which frame an answer is a fraction of, since two frames are different
lengths at the same window size. Resolving any of these lengths in pixels is
a read of the window, and `Painter::to_px` is where that read is taken --
pinning the window where the length has a fraction in it, and nothing where
it is only pixels.
## Layout decisions and invariants (2026-09-15 to 2026-09-17)
@@ -389,14 +408,15 @@ floats.
so a boundary derived with a division guards a drawing made with a
multiply (`53b00c6`).
### A box in pixels is one multiply from its parent's
### A box in pixels is one multiply from the window
A draw threads pixel lengths down: the box a parent gave a widget, then the
part of that box its own answer placed its drawing in. `Painter::px_size`
and `px_len` read that value, and a local redraw takes the same steps back
up the parent chain (`asked_px`). Neither chain has a coordinate frame in it,
so a region node cannot break either, and warm and cold reach every length
by the same expression.
Every length in the tree is a length of the window, so it becomes pixels in
one multiply wherever it is read: `Painter::px_size` and `px_len` for the
box, `frame_len` for the frame. There is no chain to walk and no coordinate
frame in the way, so a region node cannot break it and warm and cold reach
every length by the same expression. (Before `1512d84` a frame was a length
of its parent's frame and a local redraw walked back up the parent chain in
`asked_px`; both are gone.)
- **`Holds::through` is the exact preimage of `px + floor(rel * box)`**:
`floor(rel * B) >= lo - px` is `rel * B >= (lo - px) << REL` and
@@ -412,9 +432,9 @@ by the same expression.
Nothing layout decides is composed back up the move chain.
- **`px` is not stored on `ActiveData`, deliberately.** A resize every
widget's `Holds` admits redraws nothing, so a stored pixel length would
be stale on every widget in the tree with nothing to say so. `asked_px`
walks up only where a widget is already being redrawn; the mean chain is
2.8 levels.
be stale on every widget in the tree with nothing to say so. What is
stored is the symbolic frame, which a redraw resolves against the window
it has.
- **The window is not a move entry** (`5b78002`). A chain bottoms out in
`MoveIdx::NONE`; the window is applied where a fraction becomes pixels,
`to_px(output_size)` on the CPU and the uniform in the shader. A resize