Expand description
Everything needed to author a custom View/Widget pair.
frust alone is sufficient: an app that implements its own
layout/paint/event widget should need no framework dependency but this
crate. If something is reachable through neither this module nor the flat
facade, that is a bug — file it rather than reaching for frust-core
directly.
use frust::authoring::*; covers the widget-authoring vocabulary proper.
Two neighbouring surfaces are deliberately not duplicated here because
they are already reachable flat, and a real widget usually wants them too:
frust::input— gesture constants such asTOUCH_SLOP.- The animation vocabulary —
AnimationController,Curve,FrameTimeand friends.
For anything the by-name lists below omit, reach for the whole-crate valves:
frust::kurbo, frust::peniko,
frust::accesskit.
Not feature-gated (unlike the design-system re-exports above): an app that
disables every catalog (--no-default-features) still needs this seam to
build its own design system, so it always resolves.
§The EditingState split
frust_core::event::EditingState (flat, right here in authoring) and
frust_text::editor::EditingState (nested in text)
are two genuinely distinct types — the first is the retained
IME-surface payload an event-routing widget publishes/receives
(ImeState/ImeEvent), the second is TextEditor’s own byte-indexed
editing snapshot. A glob importing both into one scope will not compile
(use frust::authoring::*; use frust::authoring::text::*; collides on the
name); reach for the flat one for event/IME plumbing and
authoring::text::EditingState only alongside a TextEditor you’re
driving yourself.
§Example: a one-child container widget
A container that offsets its single child, wired through the full
lifecycle — build, rebuild, teardown, layout, paint, event routing,
semantics forwarding — with only frust named. Ported from
frust_widgets::authoring’s own worked example (the toolkit this module
re-exports), which an app cannot reach directly without depending on
frust-widgets itself.
use frust::authoring::*;
/// The declarative half: a child plus the offset to apply to it.
struct OffsetView<State: 'static> {
offset: Point,
child: AnyView<State>,
}
/// The view-fn app code calls; `any` erases the concrete child view.
fn offset<State: 'static, V: View<State>>(offset: Point, child: V) -> OffsetView<State> {
OffsetView { offset, child: any(child) }
}
/// The retained half: the live child pod plus the applied offset.
struct OffsetWidget {
offset: Point,
child: ChildPod,
}
impl<State: 'static> View<State> for OffsetView<State> {
type Element = OffsetWidget;
fn build(&self, ctx: &mut BuildCtx<'_>) -> OffsetWidget {
OffsetWidget { offset: self.offset, child: build_child(&self.child, ctx) }
}
fn rebuild(
&self,
prev: &Self,
element: &mut OffsetWidget,
ctx: &mut BuildCtx<'_>,
) -> ChangeFlags {
let mut flags = ChangeFlags::NONE;
if prev.offset != self.offset {
element.offset = self.offset;
flags |= ChangeFlags::LAYOUT;
}
flags | rebuild_child(&prev.child, &self.child, &mut element.child, ctx)
}
fn teardown(&self, element: &mut OffsetWidget, ctx: &mut BuildCtx<'_>) {
teardown_child(&self.child, &mut element.child, ctx);
}
}
impl Widget for OffsetWidget {
fn layout(&mut self, ctx: &mut LayoutCtx, bc: &BoxConstraints) -> Size {
let size = self.child.layout_child(ctx, bc);
self.child.set_origin(self.offset);
bc.constrain(size)
}
fn paint(&mut self, ctx: &mut PaintCtx, scene: &mut dyn PaintScene) {
self.child.paint_child(ctx, scene);
}
fn event(&mut self, ctx: &mut EventCtx, event: &InputEvent) -> EventResult {
// Never re-hit-test a captured child by hand — this helper owns the
// capture/focus fast paths and the blur-on-outside-tap rule.
route_event_single(&mut self.child, ctx, event)
}
fn semantics(&self, ctx: &mut SemanticsCtx) {
// A transparent wrapper still MUST forward, or the child's whole
// subtree drops out of the accessibility tree.
self.child.semantics_child(ctx);
}
}Modules§
- scene
- The renderer-agnostic display list, for widgets painting below
PaintScene. - text
- Text shaping/measurement for widgets laying out their own glyph runs.
Macros§
- visit_
children - Implement
Widget::visit_childrenfor the container whoseimpl Widgetblock this is written in, forwarding the named fields in the order given.
Structs§
- Affine
- A 2D affine transform.
- AnyView
- A type-erased
View: lets a piece of UI change its concrete view type between frames (e.g. a conditionalif cond { text(..) } else { button(..) }) while still fitting the statically-typed rebuild machinery. - BezPath
- A Bézier path.
- BoxConstraints
- Immutable min/max size bounds passed down during layout.
- Build
Ctx - Context threaded through
View::build/View::rebuild. - Change
Flags - Bitflags describing what work a
View::rebuildpass invalidated. - Child
Pod - A container’s owned child: a boxed widget plus the layout geometry and capture bookkeeping the container maintains for it.
- Corner
Inset - The inset vocabulary
LayoutCtx::window_insets/PaintCtx::window_insetsreturn — lifted because a widget that lays itself out around the status bar, notch, or on-screen keyboard cannot otherwise name the value those accessors hand it. A bar laying out around the iPadOS window control names the corner value,CornerInsets. The footprint of a system window control at one corner, in logical pixels. - Corner
Insets - The inset vocabulary
LayoutCtx::window_insets/PaintCtx::window_insetsreturn — lifted because a widget that lays itself out around the status bar, notch, or on-screen keyboard cannot otherwise name the value those accessors hand it. A bar laying out around the iPadOS window control names the corner value,CornerInsets. Window-control footprints at the four window corners, in logical pixels. - Corner
Radii - The paint vocabulary
PaintScene’s per-corner and dashed methods name —fill_rounded_rect_radii/push_clip_rounded_radiitake aCornerRadii,stroke_path_dashedaDashPattern. Lifted for the same reasonWindowInsetsis: a widget calling those methods cannot otherwise name their arguments. Re-exported throughfrust-core’s paint surface, so this is the same typescene::CornerRadiinames. The per-corner radii and dash-pattern vocabularyPaintScene’s own signatures name, re-exported fromfrust-sceneso a widget callingPaintScene::fill_rounded_rect_radii/PaintScene::push_clip_rounded_radii/PaintScene::stroke_path_dashedcan name their arguments through the same paint surface it already paints through (mirrors the crate-rootaccesskitre-export). Per-corner radii for a rounded rectangle, in the pre-transform coordinate space. - Dash
Pattern - The paint vocabulary
PaintScene’s per-corner and dashed methods name —fill_rounded_rect_radii/push_clip_rounded_radiitake aCornerRadii,stroke_path_dashedaDashPattern. Lifted for the same reasonWindowInsetsis: a widget calling those methods cannot otherwise name their arguments. Re-exported throughfrust-core’s paint surface, so this is the same typescene::CornerRadiinames. The per-corner radii and dash-pattern vocabularyPaintScene’s own signatures name, re-exported fromfrust-sceneso a widget callingPaintScene::fill_rounded_rect_radii/PaintScene::push_clip_rounded_radii/PaintScene::stroke_path_dashedcan name their arguments through the same paint surface it already paints through (mirrors the crate-rootaccesskitre-export). A stroke’s dash pattern: anonrun, anoffgap, and aphaseoffset into that repeating cycle — all lengths in the pre-transform coordinate space. - Discard
Scene - A
PaintScenesink that accepts every paint command and records nothing — the zero-GPU-cost target for a subtree that still needs itspaintpass driven for the pass’s side effects (hero-rect reporting throughPaintCtx::with_hero_registry, other paint-time widget state) even though its pixels will never be composited. The navigator’s transition machinery is the motivating case: a page whose resolved alpha is 0 still has to paint to report hero rects and advance animating children, but every command it emits is otherwise wasted GPU work. - Editing
State - The event-pass/IME-surface
EditingState— see this module’s own docs for the split againsttext::EditingState,frust_text::editor’s distinct, byte-indexed type.ImeContentTypeis the input-purpose hint an editable widget publishes on itsImeStateso a shell can lock a secret field’s keyboard down. The full editing state of a text field, the one struct every IME bridge syncs. - Event
Ctx - Context threaded into
crate::widget::Widget::event. - Event
Outcome - The result of a whole
crate::app::RenderRoot::eventpass. - Hero
Frames - A tagged-rect reporter threaded through the paint pass, letting a container discover where tagged (“hero”) descendants painted and drive a shared-element morph between two of them across a navigation transition.
- Image
Data - Owned shareable image resource.
- Image
Source - A decode-once, cheaply-clonable handle around a decoded RGBA8 image.
- ImeState
- The event-pass/IME-surface
EditingState— see this module’s own docs for the split againsttext::EditingState,frust_text::editor’s distinct, byte-indexed type.ImeContentTypeis the input-purpose hint an editable widget publishes on itsImeStateso a shell can lock a secret field’s keyboard down. The IME-relevant surface a focused editable widget publishes for the shell. - KeyEvent
- A keyboard key event delivered down the focus path (never hit-tested).
- Layout
Ctx - Context passed to
Widget::layout. - Line
- A single line.
- Modifiers
- The chord of modifier keys held when a
KeyEventfired. - Node
- The accessibility-node vocabulary a widget that contributes a semantics node needs — as opposed to one that only forwards a child’s.
- NodeId
- The accessibility-node vocabulary a widget that contributes a semantics node needs — as opposed to one that only forwards a child’s.
- Overlay
Key - The overlay registry’s own vocabulary, re-exported from
frust-coreso a design system naming a band, an input class, a light-dismiss policy or a surface identity does it through this one module: anOverlaySlot’s setters take exactly these types, and a widget that cannot name them cannot configure one. An overlay owner’s identity, allocated once by the owner and quoted back to it by everyInputEvent::Overlaythe root routes into its surface. - Overlay
Placement - The overlay-portal authoring surface: the slot a widget that floats its own surface holds, what that surface is anchored to, and the placement geometry every anchored pattern needs.
- Overlay
Slot - The overlay-portal authoring surface: the slot a widget that floats its own surface holds, what that surface is anchored to, and the placement geometry every anchored pattern needs.
- Paint
Ctx - Context passed to
Widget::paint. - Paint
Outcome - The result of a whole
crate::app::RenderRoot::paintpass. - Point
- A 2D point.
- Pointer
Event - A single pointer event in the coordinate space of the widget receiving it.
- Rect
- A rectangle.
- Rounded
Rect - A rectangle with rounded corners.
- Semantics
Ctx - Collects
accesskit::Nodes during a semantics pass, tracking the current absolute origin/size (mirroring paint’s origin threading) and the parent/child structure. - Semantics
Update - A collected accessibility tree produced by
RenderRoot::semantics. - Size
- A 2D size.
- Stroke
- The visual style of a stroke.
- Vec2
- A 2D vector.
- Widget
Id - A stable identity for a node in the widget tree.
- Window
Edge Insets - The inset vocabulary
LayoutCtx::window_insets/PaintCtx::window_insetsreturn — lifted because a widget that lays itself out around the status bar, notch, or on-screen keyboard cannot otherwise name the value those accessors hand it. A bar laying out around the iPadOS window control names the corner value,CornerInsets. Per-edge inset amounts, in logical pixels. - Window
Insets - The inset vocabulary
LayoutCtx::window_insets/PaintCtx::window_insetsreturn — lifted because a widget that lays itself out around the status bar, notch, or on-screen keyboard cannot otherwise name the value those accessors hand it. A bar laying out around the iPadOS window control names the corner value,CornerInsets. The window’s inset state, mirroring Flutter’sViewportMetrics(media_query.dart). - Window
Metrics - The window-shape value recovered via
use_context::<WindowMetrics>()insideComponent::build— lifted alongsideWindowInsetsfor the same reason: a widget or component laying itself out around window size/scale/orientation cannot otherwise name the value. SeeWindowMetrics’s own doc for the plain-value delivery contract, the alongside-not-superseding relationship withWindowInsets, and the derived-orientation/rebuild-cost notes. The window’s shape and platform-occlusion state, delivered to app code as a plainprovide_context-carried value — logical size, device-pixel scale, a derived orientation, and the currentWindowInsets.
Enums§
- Action
- The accessibility-node vocabulary a widget that contributes a semantics node needs — as opposed to one that only forwards a child’s.
- Brush
- Describes the color content of a filled or stroked shape.
- Cursor
Icon - The cursor vocabulary a widget requests through
EventCtx::set_cursor— lifted so a design system’s own controls can name a shape (Pointeron a button,Textover an editable,Grabbingon a live drag) without a directfrust-coredependency. Also re-exported flat asfrust::CursorIcon. The pointer cursor a widget asks the host to display. - Edit
Command - The clipboard/selection vocabulary an editable widget matches on —
InputEvent::EditCommandcarries one of these four verbs, already decoded from whatever chord, hardware key or edit-menu tap produced it. A widget answers copy/cut throughEventCtx::write_clipboardand asks for a paste throughEventCtx::request_paste; the shell owns the host clipboard at both ends. Also re-exported flat asfrust::EditCommand, for the same reasonCursorIconis: a design system’s public API can name a verb without authoring a widget. A semantic clipboard / selection command delivered to the focused editable. - Event
Result - What a widget did with an event.
- Fill
- Describes the rule that determines the interior portion of a shape.
- Hero
Directive - What a reported hero should do this paint — the reply
PaintCtx::report_herohands back to a tagged (“hero”) wrapper. - ImeContent
Type - The event-pass/IME-surface
EditingState— see this module’s own docs for the split againsttext::EditingState,frust_text::editor’s distinct, byte-indexed type.ImeContentTypeis the input-purpose hint an editable widget publishes on itsImeStateso a shell can lock a secret field’s keyboard down. What kind of content a focused editable field holds — the hint a widget publishes so each shell can configure the platform input method. - ImeEvent
- The event-pass/IME-surface
EditingState— see this module’s own docs for the split againsttext::EditingState,frust_text::editor’s distinct, byte-indexed type.ImeContentTypeis the input-purpose hint an editable widget publishes on itsImeStateso a shell can lock a secret field’s keyboard down. An input-method (IME) event delivered down the focus path (never hit-tested). - Input
Event - An input event delivered to the widget tree.
- Key
- A logical key press: either a semantic
NamedKeyor a run of typed text. - Live
- The accessibility-node vocabulary a widget that contributes a semantics node needs — as opposed to one that only forwards a child’s.
- Named
Key - A named (non-character) key: the control keys an editable widget reacts to.
- Orientation
- The window-shape value recovered via
use_context::<WindowMetrics>()insideComponent::build— lifted alongsideWindowInsetsfor the same reason: a widget or component laying itself out around window size/scale/orientation cannot otherwise name the value. SeeWindowMetrics’s own doc for the plain-value delivery contract, the alongside-not-superseding relationship withWindowInsets, and the derived-orientation/rebuild-cost notes. A window’s derived portrait/landscape orientation. - Outside
Tap - The overlay registry’s own vocabulary, re-exported from
frust-coreso a design system naming a band, an input class, a light-dismiss policy or a surface identity does it through this one module: anOverlaySlot’s setters take exactly these types, and a widget that cannot name them cannot configure one. What a registered surface wants to hear about a press that landed on nothing floated — the light-dismiss policy, a per-surface boolean everywhere this pattern exists. - Overlay
Align - The overlay-portal authoring surface: the slot a widget that floats its own surface holds, what that surface is anchored to, and the placement geometry every anchored pattern needs.
- Overlay
Anchor - The overlay-portal authoring surface: the slot a widget that floats its own surface holds, what that surface is anchored to, and the placement geometry every anchored pattern needs.
- Overlay
Band - The overlay registry’s own vocabulary, re-exported from
frust-coreso a design system naming a band, an input class, a light-dismiss policy or a surface identity does it through this one module: anOverlaySlot’s setters take exactly these types, and a widget that cannot name them cannot configure one. Which z-band a registered surface paints and hit-tests in. - Overlay
Input - The overlay registry’s own vocabulary, re-exported from
frust-coreso a design system naming a band, an input class, a light-dismiss policy or a surface identity does it through this one module: anOverlaySlot’s setters take exactly these types, and a widget that cannot name them cannot configure one. Whether a registered surface takes pointer input at all. - Overlay
Side - The overlay-portal authoring surface: the slot a widget that floats its own surface holds, what that surface is anchored to, and the placement geometry every anchored pattern needs.
- Pointer
Button - Which physical (or synthetic) button a pointer event carries.
- Pointer
Phase - The lifecycle phase of a pointer gesture.
- Role
- The accessibility-node vocabulary a widget that contributes a semantics node needs — as opposed to one that only forwards a child’s.
- Scroll
Delta - A scroll amount, in either discrete lines or continuous pixels.
- Theme
Text Color - Which themed color role a text’s glyphs default to when no explicit
.color()/.style()was set and a theme is active. - Theme
Text Type - Which type-scale role a text’s font FAMILY resolves from at layout, when
opted into with
TextView::themed_familyand a theme is active — one variant perTypeScaleslot (15 baseline roles plus their 15_emphasizedsiblings). - Tick
Class - The class of a continuation-frame request a widget makes during paint —
how urgent the next frame is, so the mobile frame gate can decide whether it
may be paced (see
crate::app::RenderRoot::paintand the frame gate). - Toggled
- The accessibility-node vocabulary a widget that contributes a semantics node needs — as opposed to one that only forwards a child’s.
Constants§
- PRESSED_
OPACITY - Pressed-state overlay opacity (source: androidx Compose Material3
StateTokensv0_210, retrieved 2026-07-17 — supersedes material-web v0.192’s 12%).
Traits§
- Paint
Scene - The renderer-agnostic paint target a widget draws into.
- Shape
- A generic trait for open and closed shapes.
- View
- A declarative description of a piece of UI.
- Visit
Pods - A field shape a container can hold children in, visitable in declaration
order — the traversal half of the
visit_children!seam. - Widget
- A retained UI element living in the widget tree.
Functions§
- any
- Erase
viewinto anAnyView— the free-function spelling ofAnyView::new, mirroring thetext(..)/button(..)view-fn vocabulary. - build_
child - Build a
ChildPodwrapping anAnyView’s element. - erase_
callback - Erase a view-held
Rc<dyn Fn(&mut State)>app-state callback into the widget-heldErasedCallbackadapter the interactive widgets invoke during the event pass. - erase_
callback_ arg - Like
erase_callback, but for callbacks that also carry a value argument (Checkbox’sbool, Slider’sf64). - place
- The overlay-portal authoring surface: the slot a widget that floats its own surface holds, what that surface is anchored to, and the placement geometry every anchored pattern needs.
- rebuild_
child - Reconcile one
AnyViewchild in place through itsChildPod. - rebuild_
children - Diff a child list against its live
ChildPods, extracting each child’sAnyViewthroughview_of(identity for a plainVec<AnyView>,|c| &c.viewfor Flex’sFlexChildwrapper) and its optionalChildKeythroughkey_of(|_| Nonefor keyless containers,|c| c.keyfor Flex) — the one shared reconciler for every multi-child container. - route_
event - Route a pointer/scroll/keyboard/IME event — or a broadcast — to a container’s children.
- route_
event_ single - Route a pointer/scroll event — or a broadcast — to a container’s single child.
- teardown_
child - Tear down one
AnyViewchild through itsChildPod.
Type Aliases§
- Color
- A convenient alias for the color type used for
Brush. - Erased
ArgCallback - A widget-held,
State-erased callback adapter carrying one value argument (seeerase_callback_arg). - Erased
Callback - A widget-held,
State-erased app-state callback adapter (seeerase_callback). - Typed
ArgCallback - A view-held, typed callback carrying one value argument (Checkbox’s
bool, Slider’sf64), erased toErasedArgCallbackon build.