Add retained paints and shared text selection

This commit is contained in:
iris committed 2026-09-10 18:35:24 -04:00
1 parent 25370731d0
commit de92fccba5
60 files changed
+2848 -1297

No files matched your search

+11 -25
View File
@@ -22,8 +22,7 @@ the command and measured value when evidence matters.
next session should start. Its box below has the state.
- The port is one crate under `app-rust/`; `iris/` is only the UI framework.
- **Open across the rest of the docs**: `docs/IRIS_TODO.md` is iris's own
list (colour-space correctness is the live one), `docs/TODO.md` is the
Compose app's.
list; `docs/TODO.md` is the Compose app's.
## Desktop and phone share the code
@@ -81,7 +80,7 @@ runs inside `cargo test`.
pan, and (e) the composer clears a simulated 1000px IME inset
(`Composer::set_bottom_inset`). Each was confirmed to fail without
its subject rather than assumed: dropping `animate(id)` from
`Selection::drag` -- the phone's own "fling does nothing" defect --
`SelectionController::drag` -- the phone's own "fling does nothing" defect --
and starting the fling curve at the wall clock each fail only the
flick test; flinging on `Tapped` fails only the tap test; a 5s
`LONG_PRESS` fails only the selection test; a `set_bottom_inset` that
@@ -269,11 +268,14 @@ already got right (v2 signing, `uses-feature`, ABI splits).
Reading the Compose code for what a replacement must be able to express,
rather than what it happens to look like:
1. **The transcript is one selectable body of text.** One
`SelectionContainer` around the whole lazy list, so a selection runs from
a reply into the tool output beneath it. The framework needs selectable
read-only rich text across many rows, with the platform's selection
handles and clipboard on the phone.
1. **The transcript is one selectable body of text.** A
`SelectionController` is registered directly on the lazy list, with no
selection widget in the layout tree, so a selection runs from a reply into
the tool output beneath it. Each parent supplies either draw order or one
visual axis for its immediate children; ordering is resolved only when
selection queries it. Iris owns the selection handles because its text is
drawn into one surface, while the platform supplies the clipboard and
related system services.
2. **Rich inline text**: markdown with links (one tap detector per text,
not a node per link), inline code chips drawn behind the text, tables
with wrapping cells and a sideways scroll, syntax-highlighted fences,
@@ -442,7 +444,7 @@ buffer on **every keystroke**. So there is nothing to adopt, and adding
it would be upstream work in parley.
**And the app already does the thing incremental layout would buy.**
`RowBlocks::apply_delta` keeps one `TextEdit` per top-level markdown
`RowBlocks::apply_delta` keeps one `Text` per top-level markdown
block and re-shapes only the block a delta landed in; re-splitting the
markdown to find that block is 18µs at 18,000 characters and comparing
the blocks is 470ns. Neither is the cost.
@@ -664,12 +666,6 @@ pane is neither masked nor scrollable despite its construction comment saying
it is both. This is an `app-rust` defect, not an iris framework item.
- [ ] **P1 — session screen parity.** Continue in this order:
- [ ] **Before the next parity slice — make iris's colour pipeline
correct.** Both backends currently prefer an sRGB surface while
the shader returns palette/image bytes as
linear values; `IRIS_TODO.md` has the measured mismatch and
pass condition. Do this before judging or centralising the
app's styling. It is correctness, not cosmetic polish.
- [ ] **P1c — history paging and jump-to-latest.** Wire
`client::transcript_source` into `src/ui`:
the opening page, paging back on scroll with the cushion
@@ -725,16 +721,6 @@ it is both. This is an `app-rust` defect, not an iris framework item.
names are app content applied through iris's existing `.label()` API,
not a missing framework widget.
**`app-rust` UI defect still open**: tool-card text is not selectable.
A `TranscriptRow::Tools` has no markdown blocks, so cards can number
their own texts from zero without colliding with the row selection
keys. The risk is lifecycle: every card rebuild path must unregister
the old `TextEdit` handles before registering replacements, or the next
long press can find a freed handle. Cover result arrival, group toggle,
a call joining a run and the per-card widget swap with stale-handle
tests. This uses iris's existing selection API; it is not a framework
widget gap.
**Pass condition**: `app/ui-sandbox.sh`'s fixtures driven by
`ui-trace record --do "tap '<label>'"` — a session with the big
transcript (`AI_SANDBOX_BIG_MB`), a paused/slow-spawning one