Expand description
A Surface = one A2UI surface: its catalog, its normalized tree, its
data model, its theme and settings, the local UI state the core owns,
and one layout engine (main root + one root per open layer) kept across
passes.
Round 1 (renderer hardening):
- nodes live in STABLE SLOTS keyed by id: a rebuild (a data write, a tab
switch, an opened overlay, a scrolled window) reconciles by id, keeps
every unchanged node’s style, visual and measurement, and reports the
difference as a
NodeDelta(added/removed/changed); - restyle is PER NODE: a state change restyles that node, a viewport change only the nodes with conditions, a theme/mode/settings change every node;
- settings: locale + strings, mode
light|dark|system, density, contrast, font scale, safe-area insets, pointer hover, reduced motion (SurfaceSettings).
The API is COARSE by design (the FFI facade mirrors it one to one):
messages in (apply), viewport/state setters, layout(measure) out —
never a call per node or per keystroke.
Re-exports§
pub use crate::layout_tree::ToastSpec as Toast;
Structs§
- Apply
Outcome - Frame
- Absolute frame in surface coordinates (points/dp; fractional unless rounding is on).
- Insets
- Safe-area insets (status bar, notch, home indicator) layers keep clear of.
- Layer
- One overlay layer in paint order, frames in SURFACE coordinates.
- Layout
Output - Leaf
Data - A measured leaf, OWNED: what the step API hands a host across a lock.
- List
Output - Node
Delta - What changed in
nodes()since the previouslayout():addedandchangedslots to fetch again (nodes_at),removedslots to drop.renumbered= every index moved (compaction, a new surface): fetch all. - Placed
Frame - Placed
Node - The static description of one layout node (
Surface::nodes): fetched once, then patched withNodeDelta. Indices are STABLE slots; paint order = accessibility order = the order ofLayoutOutput.frames. - Scroll
Output - One scroll container (any
overflow: scroll|autonode, windowed lists, a Dialog body): its offset (clamped), its viewport (the node’s frame) and its scrollable content size. Frames are reported UNSCROLLED: a painter translates every descendant by-offsetand clips to the frame. - Sticky
Output - Round 2 (§2, §5): a node pinned by
position: sticky(or a List’s pinned section header): paint it (and its subtree) translated by(dx, dy)on top of its frame, inside the same scroll translation as its siblings. Only nodes that move are listed. - Surface
- Surface
Options - Surface
Settings - What a host sets per surface (docs/round-1-contract.md §4–6).
Enums§
- Contrast
Setting normal | high | system(system = the platform’s high-contrast flag).- Layout
Step - One step of a resumable layout pass (
Surface::layout_begin). - OutEvent
- What the host must do after an interaction (
non_exhaustive: match with a wildcard arm; new kinds are additive). The wire form is camelCase throughout, kinds AND fields ({kind: "action", componentId, …},{kind: "hoverTimer", owner, delayMs}), as the host API’s. - Surface
Command - What a host may ask of a live surface (
catalog/a11y.jsoncommands).
Constants§
- HOVER_
CLOSE_ MS - How long a hover overlay (Tooltip,
openOn: hoverPopover) waits after the pointer left its trigger and content before it closes (the reference’sHOVER_CLOSE_MS): time to cross the gap into the content.