iris: mark() -- a drawn disclosure triangle, instead of a codepoint the phone lacks
The tool cards' open/closed marks were U+25B8/25BE/25B4 in whatever face resolved. That worked while iris bundled its own fonts; since the move to the platform collection on 2026-09-07 Iris's phone draws an empty box and this machine draws a dot -- UI_RULES' 'don't rely on characters the platform might not have'. iris::widget::mark rasterises one oversampled, antialiased triangle into the ordinary texture path and scales it into the box the caller asks for, so it needs no new primitive and is correct at any density. Its two tests check the shape points where it was asked to and leaves its corners clear, which is the half nobody would look at on a device that renders it wrong. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
af1b0c5ab2
commit
e5a90c6135
4 files changed
+261
-9
No files matched your search
@@ -8,6 +8,63 @@ capability that moved. Small and trivial changes do not go here.
|
||||
An entry gives the date, what changed, why, and a short before/after where
|
||||
it helps judge the change without the session that made it. Newest first.
|
||||
|
||||
## 2026-09-08: a gesture can be cancelled, and the pointer belongs to the input handler
|
||||
|
||||
Two changes to how a drag ends, from defects on Iris's phone (a code
|
||||
fence panned sideways made the transcript jump on the next tap, and made
|
||||
the fence itself snap back).
|
||||
|
||||
**`CursorSense::Cancel`, and `GestureOutcome::Cancelled`.** Taking
|
||||
pointer capture cuts every other widget off from the press completely --
|
||||
no `PressEnd`, no `Drop` -- so anything else tracking that press was left
|
||||
with a gesture open at an origin belonging to a finger long gone, and the
|
||||
next touch anywhere was measured from it. A widget that loses a capture
|
||||
race is now told, exactly once. It is a separate sense from `Drop`
|
||||
deliberately: `Drop` means "your gesture finished" and callers act on it
|
||||
(a fling, a tap, a link followed), which is precisely wrong here.
|
||||
|
||||
**`CursorSense::drag_senses()`** is what a widget driving a `DragGesture`
|
||||
registers -- the frames plus `unclick`, `Drop` and `Cancel`. Both ways a
|
||||
gesture can end, stated once rather than remembered per call site;
|
||||
forgetting `Drop` is what left a `Scroll` panning from a stale position.
|
||||
|
||||
**The pointer's state left `UiRenderState`.** `capture_pointer`,
|
||||
`release_pointer` and `captured_pointer` are gone from it. Capture and
|
||||
the pressed set are `PointerInput` -- the cursor senses' `Event::Global`,
|
||||
a new associated type for state an event owns that belongs to no single
|
||||
widget -- held by the event manager that runs the dispatch and reached
|
||||
by `&mut`, with no lock anywhere. A handler asks through
|
||||
`ctx.data.pointer` (`PointerRequests`: `capture(id)`, `release()`,
|
||||
`holder()`).
|
||||
|
||||
// before -- interior mutability on whatever structure was reachable
|
||||
ctx.data.render.capture_pointer(id);
|
||||
// after
|
||||
ctx.data.pointer.capture(id);
|
||||
|
||||
`DragGesture::handle` and `Scroll::drag` take `&PointerRequests` where
|
||||
they took `&UiRenderState`. `task_on` also lost a `Data: Send` bound it
|
||||
never needed -- the future it spawns never sees the event's data, and
|
||||
that bound was the whole reason the pointer state had been behind a
|
||||
`Mutex`.
|
||||
|
||||
## 2026-09-08: `mark(dir, dp, colour)` -- a drawn triangle, and a scroll area's opening edge
|
||||
|
||||
**`iris::widget::mark`** draws a filled, antialiased triangle pointing
|
||||
along a `Dir`, at a size in dp. It replaces the disclosure codepoints
|
||||
U+25B8/25BE/25B4, which were a bet that the platform's fonts have them --
|
||||
once iris stopped bundling its own faces, Iris's phone drew an empty box.
|
||||
It rasterises one oversampled bitmap into the ordinary texture path and
|
||||
scales it into the box asked for, so no new primitive was needed and it
|
||||
is correct at any density.
|
||||
|
||||
**`scrollable_on` now opens at the beginning of its content, and
|
||||
`scrollable_to_end(axis)` is the other one** -- pinned to the end and
|
||||
staying there while the content grows, which is what a composer wants and
|
||||
what everything did before. A code fence was opening at the end of its
|
||||
longest line, in the middle of a word. `Scroll::new` takes the edge as a
|
||||
third argument rather than deciding for its caller.
|
||||
|
||||
## 2026-09-08: masks have a shape -- `.masked_by(shape)`, and clipping applies to touch
|
||||
|
||||
A mask no longer carries a rectangle. It carries **the slot of a
|
||||
|
||||
Reference in new issue
Block a user