1 parent
9f039d6440
commit
836c222f0c
1 file changed
+27
-58
@@ -5,54 +5,25 @@ Not a decisions log; delete it when the extraction is done.
|
||||
|
||||
## Where things stand
|
||||
|
||||
Canonical `main` is **`43ce8c7`** (#12, pointer routing). Fourteen slices are
|
||||
in.
|
||||
Canonical `main` is **`ca2b4b2`** (#17, the headless rig). Sixteen slices are
|
||||
in, and #16's size work and #17's rig both merged on 2026-09-14.
|
||||
|
||||
- **#16** `split/16-draw-size`, worktree `/home/bob/repos/iris-pr16`, head
|
||||
`4654756`. A widget sizes itself while drawing; `SizeCtx`, the `desired_*`
|
||||
methods and the size cache are gone, and `on_resize(axis)` drives the
|
||||
retained path. Two review rounds answered: `Widget::draw` returns the `Size`
|
||||
(no `Painter::set_size`), both `place` methods are folded back into
|
||||
`widget_within`/`draw_inner`, `Painter::size_hint` records the size
|
||||
dependency `place` used to, `()` sizes itself rest so it is a gap, and a
|
||||
resize now moves the drawing instead of wiping the tree. `tabs` (all five
|
||||
tabs, and a replay that adds two images), `view` and `minimal` render
|
||||
byte-identical to `upstream/main`.
|
||||
- **#17** `split/17-headless-rig`, worktree `/home/bob/repos/iris-pr17`, head
|
||||
`deb9c1b`. The compositor script, `rig-input`'s `replay-touch` and the
|
||||
`.touch` parser, so a rendering claim no longer has to be checked from
|
||||
ai-app's checkout. One review round answered: machine-specific prose out of
|
||||
the comments, and `sway`/`swaymsg`/`grim` detected up front. Small, and
|
||||
disjoint from #16.
|
||||
- **#18** `split/18-position-chain`, worktree `/home/bob/repos/iris-pr18`, head
|
||||
`8223a55`. LAYOUT.md §2's O(1) subtree movement: every active widget owns a
|
||||
slot in `UiRenderState::moves`, `prelude.wgsl` walks the chain, and
|
||||
`try_reuse`'s translation case writes one slot instead of remapping a
|
||||
subtree's primitives. Measured at 100 primitive region writes to 0 on a span
|
||||
of 20 rows five primitives deep. `Vec2` is `repr(align(8))` so a GPU struct
|
||||
holding one matches WGSL without saying so itself.
|
||||
|
||||
**Waiting on the owner:** whether size dependencies should be recorded per
|
||||
axis. They could be, but `mark_readers`' only trigger is `needs_redraw`, which
|
||||
carries no axis, so the precision would be unusable until the trigger changes:
|
||||
redraw a child first, compare its new size to the old, and propagate only to
|
||||
readers of the axes that moved. Offered on #16 as its own slice, ahead of the
|
||||
position chain.
|
||||
Not in it, both wanting the above first: `Painter::set_child_offset` for a
|
||||
container that moves its children as a group (the scrolling case), and
|
||||
`LazySpan`. Built-in alignment is after those -- the owner reordered it
|
||||
behind the chain on 2026-09-14 as the more important of the two.
|
||||
|
||||
**What the resize change taught, and why the chain moved up.** `mov` cannot
|
||||
stretch a drawing out of a box with no relative extent. `UiScalar::within` maps
|
||||
a part's `(rel, abs)` through a matrix whose determinant is the box's own rel
|
||||
extent, so at zero extent it is singular: every fraction of that box collapses
|
||||
onto one stored value, and nothing recovers which one. `lerp_inv` used to return
|
||||
a plausible number there instead of saying so; it and `outside` now return
|
||||
`Option`, and `Remap` is the checked region-level operation, so a drawing that
|
||||
cannot be taken out of its box is redrawn rather than left at its old size.
|
||||
|
||||
`Remap` is explicitly a holding pattern: the owner accepted it on 2026-09-14
|
||||
with *"I don't like remap much but I'll let it in for now until we get proper
|
||||
region chaining"*. Delete it in the chaining slice rather than build on it --
|
||||
holding each part's own region against its box means there is no composition to
|
||||
invert and nothing for `Remap` to check.
|
||||
|
||||
Counted draws on a resize, against the old wipe-everything: 101 widgets of
|
||||
padded rows went 101 -> 0, `tabs` 73 -> 0, and the `text` example 49 -> 48. The
|
||||
last is the shape that does not benefit -- both paragraphs rewrap to a different
|
||||
height and the relayout runs to the root. Holding each part's own region against
|
||||
its box and resolving late is what removes those, so the position chain now sits
|
||||
directly after built-in alignment.
|
||||
The invariant the chain rests on: `resolved = region + resolve(slot)`, so
|
||||
anything that rewrites a region owes that slot a zero. `mov` does it for the
|
||||
subtree it rewrites and `draw_inner` for the widget it draws.
|
||||
|
||||
Check for a review before starting anything, and read the newest
|
||||
`submitted_at` rather than the first result:
|
||||
@@ -127,8 +98,8 @@ Other standing instructions from the owner:
|
||||
|
||||
## The next slice
|
||||
|
||||
**Built-in alignment** — see the first entry below. #16 and #17 are both
|
||||
waiting on review, and the alignment slice is disjoint from either.
|
||||
**`set_child_offset` and `LazySpan`**, finishing LAYOUT.md §2 on top of #18,
|
||||
then built-in alignment.
|
||||
|
||||
The archive is not a patch here: it writes `Widget::draw` against
|
||||
`painter.set_size`, which #16 replaced with a returned `Size`, and it writes
|
||||
@@ -137,11 +108,14 @@ Recreate on today's `Len` and let the dp slice follow.
|
||||
|
||||
Still in the target, roughly in dependency order:
|
||||
|
||||
- **Built-in alignment, and probably size**, directly after #16 and before the
|
||||
position chain: the chain is an optimisation, this is behaviour. A child of a
|
||||
span is handed the full extent on the ortho axis, so `.width(rel(0.5))`
|
||||
inside a `Dir::DOWN` span changes what the child reports and not the box it
|
||||
gets. **Do not "fix" that by reading the child's ortho `size_hint`**: a `Pad`
|
||||
- **The rest of the position chain** (LAYOUT.md §2), on top of #18:
|
||||
`set_child_offset` for a container that moves its children as a group, and
|
||||
`LazySpan`.
|
||||
- **Built-in alignment, and probably size**, after the chain rather than
|
||||
before it: the owner reordered the two on 2026-09-14. Reproduced in the
|
||||
harness -- a child of a span is handed the full extent on the ortho axis, so
|
||||
`.width(rel(0.5))` inside a `Dir::DOWN` span changes what the child reports
|
||||
and not the box it gets. **Do not "fix" that by reading the child's ortho `size_hint`**: a `Pad`
|
||||
between the `SetSize` and the span has no hint of its own, so the declared
|
||||
width silently goes back to filling. It works only when nothing is in the
|
||||
way. Alignment has to belong to the widget rather than be discovered through
|
||||
@@ -156,12 +130,7 @@ Still in the target, roughly in dependency order:
|
||||
|
||||
Size is the harder half: a declared size beside the one `draw` returns is two
|
||||
sources of truth for one thing, so settle what each means before building it.
|
||||
- **The position chain** (LAYOUT.md §2): `UiData::move_offsets`, per-primitive
|
||||
slot ids and a bounded chain walk in WGSL, so moving a subtree writes one
|
||||
slot instead of every descendant's primitives.
|
||||
|
||||
It also has to make `OnResize::Translate` possible, which is the reason that
|
||||
variant does nothing today. `ActiveData::region` is both the box a widget was
|
||||
- **`OnResize::Translate`**, which still does nothing. `ActiveData::region` is both the box a widget was
|
||||
given and the box its primitives occupy, and `mov` remaps out of it; keeping
|
||||
a drawing at its old size while the box grows leaves the two disagreeing and
|
||||
the next move stretches it. Found by rendering `tabs` against `main`, not by
|
||||
|
||||
Reference in new issue
Block a user