Keyboard focus: which widget receives key events. A base primitive with no styling of its own — a
focusable widget (e.g. crate::Input) requests focus on tap and consults it in on_event/view.
Window-management calls for UI code. A custom title bar’s buttons call these directly — including from
.rsxon_press handlers (on_press(|| telar::window::close())). Each enqueues a
platform_core::WindowCommand that the runner applies to the OS window right after the current event is
dispatched. On backends without a movable top-level window (layer-shell, headless) they are inert no-ops.
Transpile every .rsx file under src/ and declare the module tree — what app! does, minus the winit
runner. Use this in a crate that drives rsx through a customPlatform (e.g. a Wayland layer-shell
backend) instead of the built-in desktop runner: invoke telar::rsx_modules!() at the crate root, then build
your own App from the transpiled components and run it via telar::run_with_platform /
telar::run_multi_with_platform. Pass a theme type — rsx_modules!(MyTheme) — if your .rsx calls
use_theme; otherwise rsx_modules!().
What the CPU renderer’s caches are holding, and a way to make them let go. Exposed so an app can answer “is the
memory in the renderer?” from outside the renderer, which nothing short of a heap profiler could do before.
What one cache is holding, for a census something outside the renderer can read.
Wraps a child so its rendered output is clipped to the child’s own layout rect. When the child
collapses to a zero rect (e.g. a section hidden via display:none), the clip is empty, so nothing
inside draws — even a widget left with a stale rect or one that paints at fixed coordinates. Layout
is unchanged: layout_node passes through to the wrapped child.
Flat draw state tracking clips and transforms. Note: PushLayer and PopLayer commands are intentionally not tracked here; layers are managed outside this struct by the caller.
A live subscription. Dropping it deregisters the effect, so the closure runs once and never again — which
looks exactly like a working binding until the value it derives is expected to move. Bind it to something
that lives as long as the work should: a struct field, a returned value, or a let the reader captures.
The worker’s handle to a spawn_stream, for posting items back to the UI thread. Send and cloneable,
so the work can hand it to nested helpers or a callback-driven library.
Shared font configuration for both software and hardware renderers. Lets callers supply extra fonts, raw font bytes, a system fonts directory, and preferred sans-serif families without duplicating these fields across renderer-specific config structs.
A single-line editable text field bound to a RwSignal<String>. A base primitive: unstyled (no
border or background — wrap it in a box for the look) and keyboard-driven. It requests focus on
tap and, while focused, edits the bound signal from key events, drawing a caret at the insertion
point. Selection (Shift+arrows/Home/End, Ctrl+A) with copy, cut and paste; IME composition is not yet
supported. Drag-to-select waits on click-to-position, which this field does not have either.
Line is designed for use inside Canvas closures where you control absolute coordinates. It does not implement LayoutItem because its p1/p2 points are absolute, not relative to a layout rect. To use Line in a layout context, embed it in a Canvas widget.
A line-number gutter for a code editor: the column “1\n2\n3…” drawn top-aligned with the same line height a
TextArea uses, so line n here sits exactly on line n of the editor. Place it beside
the editor inside the same scroll (so they scroll together) and give both the same font_size. It measures
its own width from the widest number and its height from the line count, re-measuring reactively as the
count changes. Toggle it by collapsing its node (set_display) inside a ClippedItem
so a hidden gutter both takes no width and draws nothing.
A portal layer: its content is laid out out-of-flow, filling the viewport, and hoisted to the top at
compose time — drawn above everything and free of any ancestor clip/transform. A base primitive:
unstyled; wrap content in a box for a scrim/panel, and position it with normal flex (align/justify).
Path is designed for use inside Canvas closures where you control absolute coordinates. It does not implement LayoutItem because its path data uses absolute points, not relative to a layout rect. To use Path in a layout context, embed it in a Canvas widget.
A reactive list: for item in $items key id (or, keyless, for item in $items) in .rsx. Re-runs its
source reactively and reconciles the item widgets — reused keys/positions keep their node/widget, new
ones are built, gone ones are disposed, and the layout children are reordered — instead of rebuilding the
whole block on every change. new/with_gap reconcile by key (identity-stable); positional/
positional_with_gap reconcile by index (no key clause needed, cheap append/truncate).
A paragraph of mixed-style text: a sequence of TextRuns (bold, italic, coloured links) shaped and
wrapped as one, the multi-style counterpart of Text. The shared paragraph metrics — font
size, line height, wrapping, max_lines — come from a base TextStyle; each run overrides only weight,
slant, and colour.
A handle to the enclosing scroll area’s live viewport, handed to the content builder by
LayoutScrollArea::new_with. Because a scroll area lays its content out as its OWN layout root,
every descendant’s tracked rect is already in the same content-local space the scroll offset
indexes into — so visible is a plain rect overlap, no scroll-transform math.
A node emitted by Segment::walk: one mounted component, with its pre-order id, widget name,
nesting depth, and the bounding rect of its own draw commands unioned with all descendants’.
The children a component receives from its call site, grouped by slot. A bare child lands in the
default slot (None); a child written with slot:"name" lands in that named slot. Inside the
component, the children placeholder drains the default slot and children name:"x" drains the
"x" slot — each in call-site order. Draining is one-shot: a slot placeholder consumes its
children, so referencing the same slot twice yields an empty list the second time.
Stroke style for drawing primitives. Includes join to control how corners are rendered in paths and rects; for line segments join is unused and defaults to Miter.
Identifies one surface within a MultiSurfacePlatform run. Assigned by the platform (e.g. one per
monitor for a desktop shell). Opaque and cheap to copy.
A full-viewport scaffold that positions a panel against a screen edge, optionally dims the area behind
it, and dismisses on a press outside the panel. It is the reusable body of a drawer/modal: a shell
mounts it as the root of a full-screen layer-shell surface, and a windowed app can mount it in-tree as
an in-window portal — both get the same positioning and dismiss behaviour.
The one progress value a surface’s arrival and departure share: 0 is off its edge and transparent, 1 is
settled. Opening runs it to 1; leave runs it back to 0, so the exit is the entrance
reversed rather than a second animation that has to be kept in step with the first.
A spawned task or stream. Dropping it detaches — the work keeps running and its callback keeps firing.
Keep it to cancel when whatever the callback would write is going away.
A multi-line editable text area bound to a RwSignal<String> — the multi-line sibling of Input.
A base primitive: unstyled (wrap it in a box for a border/background), keyboard-driven, no soft-wrap (only
\n breaks lines, so long lines overflow horizontally). It requests focus on tap, positions the caret at
the click, edits the bound signal from key events (typing, Enter for a newline, Backspace/Delete joining
lines, arrows in all four directions, Home/End, Tab), and draws a caret. Its measured height grows with the
line count, so wrapping it in a LayoutScrollArea gives a scrolling editor.
Selection (Shift+arrows, Ctrl+A, shift-click) with copy, cut and paste, newlines and all. IME is not
yet supported.
One inline run of a rich-text paragraph: a slice of text with its own weight, slant, and colour. Paragraph
metrics (font size, line height, wrapping, alignment) live on the DrawCommand::RichTextbase style,
so a run overrides only what varies inline (bold, italic, a link’s colour).
A 2D affine transform stored as a 2×3 matrix [a, b, c, d, e, f], mapping a
point (x, y) to (a*x + c*y + e, b*x + d*y + f). This is the same [f32; 6]
layout consumed by RenderNode::transform_with, so to_array() plugs in
directly. Compose with Transform::then instead of multiplying matrices by
hand.
One child position in a container: a fixed widget, or a reactive fragment (built lazily once the host
node exists). Produced by ChildSlot::stat / fragment / fragment_positional.
How large the controls in this part of the tree are, in the sense SwiftUI’s controlSize means: a
preference the container expresses and each control interprets, not a size any one of them is given.
The pointer shape over a window. In a modeller the cursor is the mode indicator — whether the next
press orbits, resizes a panel or places a point — so the set covers the gestures a desktop app arms
rather than the platform’s full catalogue.
A window-management action requested by UI code (a custom title bar’s buttons) and applied by the runner
to the OS window after event dispatch. Enqueued via push_window_command and drained via
take_window_commands; kept as data (rather than direct Window calls) because widget closures run
deep in the tree walk with no access to the platform window.
The default scrim wash: ~35 % black over the content behind a drawer/modal. Rendered as a fill (not an
opacity layer) so the panel above it stays fully opaque. Kept as the value a caller reaches for rather
than being folded into the scaffold, because SurfaceScaffold now takes the colour itself.
Imperative-state components re-render only when on_event returns EventResult::Handled; reactive-state components re-render automatically on signal change.
A platform that drives N independent surfaces from a single run, each with its own
EventHandler — the seam a multi-window app or a desktop shell (a bar/OSD/notification per monitor)
needs. It is separate from Platform so the single-surface contract and every existing single-window
entry point stay exactly as they are.
Opt-in semantic-token contract the built-in component catalogue reads through, so a component can resolve a
token without knowing the concrete theme type.
A surface a Telar app runs on, from the loop’s point of view: how big it is, how to ask it to redraw, and the
window-management verbs a custom title bar needs.
Moves the item at from into slot to, where to counts positions in itemsas it is now — the
frame of reference insertion_index answers in. Returns whether anything moved.
Builds the affine matrix for a box’s declarative rotate/scale/translate attributes, pivoting
rotation and scale on the box centre. Returns None when every component is identity, so an untransformed
box skips the extra transform node entirely.
What the CPU renderer’s caches are holding, and a way to make them let go. Exposed so an app can answer “is the
memory in the renderer?” from outside the renderer, which nothing short of a heap profiler could do before.
Every rendering thread’s caches, summed by name.
Closes the overlay named id. Note this is not the same as a dismissal: it closes exactly this overlay,
where dismiss_top closes whichever is frontmost.
Lays out root against the given space and reflects the result into each node’s rect signal.
Collects the (signal, rect) updates while holding the runtime borrow, then applies them in a batch
after releasing it — a rect .set() can flush effects, and one of those may itself touch the
layout runtime (a reactive list), which would re-enter the borrow.
This surface’s context of type T, as the latest build left it. None before anything set one — a widget
built outside a surface, which is every unit test.
The language subtag of the OS locale, from $LC_ALL / $LC_MESSAGES / $LANG (in POSIX precedence),
lowercased and stripped of any territory/encoding suffix — e.g. es_ES.UTF-8 → "es". None when unset
or the C/POSIX locale. An app can seed the initial language by passing this to set_locale at startup.
The cargo telar dev-loop entry, for an app that wires its own runner instead of expanding crate::app! —
a multi-surface host, or one on an out-of-tree backend, which reaches crate::run_with_platform or
crate::run_multi_with_platform directly. app! generates a call to this; anything using rsx_modules!
has to make it by hand, and until it does, cargo telar preview/test silently start the real application.
Makes the writing direction follow the active locale, so switching to Arabic or Hebrew mirrors the layout
and switching back restores it — no rebuild, the existing nodes are re-resolved on the next layout pass.
Drives the active mode from the OS light/dark preference — light → light, dark → dark — updating live
as the OS scheme changes. Installs a reactive effect (kept alive internally) and designates the pair so
[is_dark] stays consistent. Re-calling replaces the effect (hot reload re-runs setup). A manual
set_mode still wins until the next OS change re-drives it.
Iterates cmds calling f(cmd, cumulative_matrix) for every command. PushMatrix/PopMatrix update the matrix before the callback; all other commands see the matrix that was active when they were emitted.
A keyed reactive region — for item in $items key <expr> (identity-stable reconciliation). gap is laid
out as a main-axis leading margin between consecutive items (see [reconcile_slot]), so the region still
flows transparently in the host’s direction (horizontal in a row) instead of becoming a boxed list; pass
0.0 for none.
Without dev there is no dylib swap to survive, so the key is inert and this degrades to a plain signal.
The bounds match the dev build’s so a type that compiles here cannot fail once hot-reload is on — letting
hand-written app state (a navigation stack, an active locale) be declared once instead of behind a cfg.
Installs the glyph-shaping text measurer, for code that lays out text with no runner behind it — a layout test,
or a tool that composes a tree only to measure it.
The current laid-out rects of every interactive widget on the active surface, dropping any not yet laid
out (zero-sized). Read without subscribing (peek), so the platform’s frame loop can call it outside a
reactive scope without accidentally tracking the layout signals.
Where a move lands in a grid columns tiles wide. A single column is a list, which is why key_nav_apply is this
with columns = 1 rather than a second implementation.
Whether key went down during this frame. False for a key the OS is repeating, which is what makes it
the one to drive a once-per-press action while key_held drives a continuous one.
Records what event says about the buttons. The runner calls this for every event before dispatch, so a
handler running on this very event already sees the state it establishes.
Enqueue a window-management command from UI code (e.g. a title-bar button’s on_press). The runner drains
the queue after event dispatch and applies each command to the OS window. Lives in a thread-local so it
works from any widget closure without threading a window handle through the tree; each surface owns its
own queue (activated via WindowCommandContext), so commands never cross windows.
Registers a named mode. apply installs the concrete theme when the mode is selected. Re-registering an
id replaces its closure, which is expected: hot reload re-runs the app’s setup and re-registers every mode.
Re-lays out every root that has been computed at least once, picking up any nodes a reactive change
dirtied since the last frame. Each compute_layout early-returns when its root is clean and the space
is unchanged, so this is cheap on a still frame. The runtime calls it once per redraw (after flushing
reactive effects, before rendering) so a data change deep in the tree — e.g. a reactive list adding an
item — is reflected in layout without the app shell knowing about it. Node dirtiness propagates up to
the root through taffy, so a dirtied list container makes its root recompute.
Detaches and frees node (a former list item) from the runtime: removes it from the layout tree and
drops its rect signal and bookkeeping. The caller must have removed it from its parent’s child list
(via set_children) first.
Stops the worker pool and drops every pending callback. Called before a hot-reload dylib is closed: its
threads are parked in, and its callbacks are made of, code that is about to be unmapped.
Replaces parent’s children with children, in order, marking parent dirty. Operates on the
thread-local runtime; parent must be a container already registered in the runtime.
Installs the backend the app’s clipboard goes through. The desktop runner calls this at startup; a shell
that speaks the protocol itself installs its own, and a test can install a stub. The first call wins.
Sets this surface’s context of type T — what its content wants every widget under it to be able to read
without being handed it: which page a panel shows, which screen a chip is on.
Sets the ambient control size. Reactive: everything that read it re-runs, so a switch re-spaces the
controls already on screen rather than waiting for whatever rebuilds them.
Shows or hides a node in layout flow. A hidden node takes no space (and lays out none of its subtree); mark an ancestor dirty and recompute for the change to take effect. Used for responsive layouts (e.g. collapsing a sidebar on narrow windows).
Sets the active locale (a BCP-47 tag such as "en" or "es"), re-rendering every translated string that
reads it. The tag should be one of the baked catalog’s locales; an unknown tag simply falls back to the
catalog’s default locale at lookup time.
Sets node’s minimum height to px after the initial layout (dirtying it, which propagates up), so a
content-measured leaf grows to at least px even when its content is shorter. A scrolling editor uses it
to fill its viewport so a click anywhere in the empty area — not just over the text — lands on the leaf.
Selects a mode: runs its registered apply closure (if one is registered) and publishes the id to the
reactive active-mode signal. Setting an unregistered id still updates the signal, so an app may drive the
theme from its own effect on [use_mode] instead of registering closures.
Reports the OS light/dark preference into the reactive graph. Called by the runner at window creation and
whenever the OS scheme changes; drives follow_system.
Runs work on a background thread, handing it an Emitter, and runs on_itemon this thread for
every item it emits — in order, during the frames that follow. on_end runs once the worker returns.
What the CPU renderer’s caches are holding, and a way to make them let go. Exposed so an app can answer “is the
memory in the renderer?” from outside the renderer, which nothing short of a heap profiler could do before.
Drops everything no frame has asked for within each cache’s idle horizon.
Maps clip rect r (in the currently-active transform’s local space) to window space — the axis-aligned bounds of its four mapped corners. Widgets emit clip rects in their own local space, but the renderer clips in window space, so a clip must be mapped through the active cumulative matrix (scroll/layout translations) to compose correctly.
Applies the full affine inverse of matrix to all pointer-coordinate events. Returns None for
non-pointer events or when matrix is degenerate (det ≈ 0), so callers fall back to the original.
Renders every preview component headlessly (build → layout → flatten) and exits with a non-zero code if any panics or returns a layout error. Backs cargo telar test, entered via the TELAR_TEST env var set on the app binary.
Reactive read of the active direction — subscribes the caller, for the rare widget that has to mirror
something layout cannot flip on its own (a chevron glyph, a directional icon).
Reactive read of the active locale — subscribes the caller so translated text re-renders on switch. None
before any locale is set (callers fall back to the catalog’s default locale).
Sets the distribution of space between and around content items.
For Flexbox it controls alignment in the main axis.
For Grid it controls alignment in the inline axis.