Skip to main content

WidgetTree

Struct WidgetTree 

Source
pub struct WidgetTree { /* private fields */ }

Implementations§

Source§

impl WidgetTree

Source

pub fn sync_accessibility(&mut self) -> TreeUpdate

Build an AccessKit TreeUpdate from the current state of all active widgets. Call this once per frame, between layout and paint, and push the result to the accesskit_winit::Adapter. Caches the result and only rebuilds when layout has changed.

Source

pub fn dispatch_access_action( &mut self, node_id: NodeId, action: Action, data: Option<ActionData>, ops: &mut dyn WindowOps, ) -> bool

Dispatch a synthetic AccessKit action to the node identified by node_id (which may be a synthetic, widget-emitted child node — e.g. a rich-text TextRun). Resolves the owning widget exactly the way the platform AT adapter does (node_id_to_widget_id_maybe then widget_for_synthetic), builds a crate::event::WidgetEvent::AccessAction, and dispatches it through ops so actions that open windows / dialogs work.

Returns true when the action was consumed — a handler claimed it, focus moved, or the context-menu fallback opened a menu — and false when nothing acted on it, including when the target node resolves to no live widget. Callers are expected to surface that: an action a node never handles is a caller error, and reporting it as success (which is what “a widget existed at the target” amounted to) leaves an automation client chasing timing and coordinates for a UI that was never going to move.

This is the in-process equivalent of an OS screen reader invoking an action — the channel an automation harness uses to drive the UI without the OS AT layer.

Source

pub fn widget_for_synthetic(&self, node_id: NodeId) -> Option<WidgetId>

Look up the owning widget for a synthetic AccessKit NodeId emitted by push_text_run_child / push_paragraph_child. Used by handle_accessibility_actions to route an ActionRequest targeting a TextRun child back to the editor that owns it.

Source

pub fn accessibility_node(&self, id: WidgetId) -> AccessibilityInfo

Source

pub fn find_by_role(&self, role: Role) -> Option<WidgetId>

Source

pub fn find_by_label(&self, label: &str) -> Option<WidgetId>

Source

pub fn find_by_action(&self, action: Action) -> Option<WidgetId>

Source

pub fn text_content(&self, id: WidgetId) -> Option<String>

Get the text content of a widget from its accessibility name. Equivalent to the label set via AccessNodeBuilder::set_name, after override application.

Source

pub fn text_value(&self, id: WidgetId) -> Option<String>

Get the text value of a widget from its accessibility value. Equivalent to the value set via AccessNodeBuilder::set_value, after override application.

Source§

impl WidgetTree

Source

pub fn begin_external_drag( &mut self, position: Point, data: ExternalDropData, ops: &mut dyn WindowOps, )

Begin an external drag session at position carrying OS-delivered data. Establishes the initial hover target and feedback immediately.

Source

pub fn update_external_drag(&mut self, position: Point, ops: &mut dyn WindowOps)

Update an in-flight external drag as the OS reports pointer motion. No-op unless an external session is active.

Source

pub fn end_external_drag( &mut self, position: Point, data: ExternalDropData, ops: &mut dyn WindowOps, )

Complete an external drag with a drop at position, firing on_drop on the target. data is the authoritative payload read at drop time; if non-empty it replaces the session payload (some backends only have the full data at drop, not at enter). No-op unless an external session is active.

Source

pub fn cancel_external_drag(&mut self, ops: &mut dyn WindowOps)

Cancel an in-flight external drag (the pointer left the window or the OS aborted the operation) without dropping. No-op unless an external session is active.

Source

pub fn handle_os_drag_ended( &mut self, outcome: DropOutcome, ops: &mut dyn WindowOps, )

Resolve an OS (outbound) drag at its terminal event. Clears the global typed-payload stash and fires on_drag_ended(outcome) once on the source widget (set only on the window that started the drag). Routed here by teksilo-app when the platform backend reports DragEnded.

Source

pub fn abort_outbound_drag(&mut self)

Abort any outbound OS drag this tree participates in, used when the window is closing. If this tree is the drag source, the whole drag is ending (the source object dies with the window) — end the stash so a later genuine external drag can’t be mistaken for ours. If instead this is a non-source window currently holding the re-entered payload, hand it back to the stash so another window can still recover it. No on_drag_ended fires (the window and its handlers are being torn down).

Source§

impl WidgetTree

Source

pub fn dispatch_event_with_ops( &mut self, event: WidgetEvent, ops: &mut dyn WindowOps, )

Dispatch an event into the widget tree.

Routing rules:

  • Pointer events -> hit testing against layout tree
  • Keyboard/IME events -> focused widget
  • AccessKit actions -> target widget directly
  • Scroll events -> hit testing (scroll target under pointer)

Dispatch an event with the caller-supplied app-level WindowOps sink. teksilo-app calls this variant; handlers can reach the multi-window API synchronously (open_window creates the winit window inside the same call before returning).

Source

pub fn dispatch_event(&mut self, event: WidgetEvent)

Dispatch an event on a standalone tree (tests, headless scenarios). Handler code that calls ctx.open_window(...) from within this dispatch will panic — by design. See dispatch_event_with_ops for the app-facing variant.

Source

pub fn hit_test(&self, point: Point) -> Option<WidgetId>

Source

pub fn hit_test_excluding_overlay_and_widget( &self, point: Point, exclude_overlay: Option<OverlayId>, exclude_widget: Option<WidgetId>, ) -> Option<WidgetId>

Hit-test at a point, excluding a specific overlay and widget from consideration. Used during drag-and-drop to exclude the preview overlay and its content widget, so they don’t block hit-testing of the actual drop targets underneath.

Source§

impl WidgetTree

Source

pub fn focus_with_origin_ops( &mut self, id: WidgetId, origin: FocusOrigin, ops: &mut dyn WindowOps, )

Set focus to a specific widget with the given origin, invoking on_focus_lost / on_focus_gained handlers through the caller-supplied WindowOps sink.

teksilo-app drives in-dispatch focus changes through this method so that focus-triggered handlers can synchronously call ctx.open_window(...). Standalone callers (programmatic focus from framework code paths, tests) use focus_with_origin which wraps with NoopWindowOps.

WCAG 3.2.1 (On Focus). The capability above is a footgun: an on_focus handler that opens a window, navigates, or otherwise changes context merely because a control received focus is a Success Criterion 3.2.1 failure — keyboard users tabbing through the UI would trigger it unexpectedly. on_focus should only update local visual/reactive state. A debug-only guard (EventContext::open_window) warns if a synchronous context change is attempted from inside focus dispatch.

Source

pub fn focus_with_origin(&mut self, id: WidgetId, origin: FocusOrigin)

Set focus using NoopWindowOps. Programmatic / framework-internal callers. Handlers triggered from this path cannot ctx.open_window(...).

Source

pub fn focus(&mut self, id: WidgetId)

Set focus to a specific widget (programmatic origin, no ops).

Source

pub fn focus_ops(&mut self, id: WidgetId, ops: &mut dyn WindowOps)

Set focus — the dispatch-path variant that threads ops through to any on_focus_lost / on_focus_gained handlers.

Source

pub fn focused(&self) -> Option<WidgetId>

Get the currently focused widget.

Source

pub fn ime_context_for_focused(&self) -> Option<ImeContext>

The OS-IME descriptor of the currently focused widget, if it is a text-input surface. None when nothing is focused or the focused node is not text-editing. The platform layer reads this at focus-change time to enable/disable the OS input method and pick its purpose. See crate::ime.

Source

pub fn first_focusable_descendant(&self, root: WidgetId) -> Option<WidgetId>

Find the first focusable widget within a subtree, in traversal order — the widget Tab would land on first. Respects nested FocusScopes and scoped tab_index (not merely raw DFS order), so a modal’s initial focus matches its Tab order.

Source

pub fn is_active(&self, id: WidgetId) -> bool

Whether the given widget id currently exists and is active in the tree (not dormant, not destroyed). Callers that need to validate a user-supplied WidgetId before acting on it — e.g. the modal presentation path validating ModalRequest::focus_target — use this.

Source

pub fn widget_initial_focus_hint(&self, id: WidgetId) -> Option<WidgetId>

Walk the subtree rooted at id in depth-first order, returning the first widget-reported initial_focus_hint that resolves to an active descendant of id.

Used by the modal presentation pipeline to let a deferred-built content widget (e.g. MessageBox) direct focus to a specific descendant after build — even when wrapped in a surface widget like ModalContainer that doesn’t itself know the default button’s id. The framework walks in to find the first hint under the content root, which is tighter than falling all the way back to first_focusable_descendant.

Hints pointing at inactive or out-of-subtree ids are ignored; the walk continues so a shallow wrapper’s stale hint doesn’t hide a deeper child’s valid one.

Source

pub fn focus_origin(&self) -> Option<FocusOrigin>

How the currently focused widget gained focus.

Source

pub fn focus_visible_signal(&self) -> Signal<bool>

Input-modality “focus-visible” signal: true after keyboard input, false after pointer input. Focus rings observe this so they show only during keyboard navigation. See BuildContext::focus_visible.

Source

pub fn view_focus_active_for(&mut self, node_id: WidgetId) -> Signal<bool>

Reactive signal that is true when the nearest focusable ancestor of node_id (its “focus scope” — e.g. the enclosing data view) holds keyboard focus. With no focusable ancestor, returns a constant-true signal so selection renders active (the legacy behaviour for items outside any focus scope). Drives focus-aware selection in StandardItem.

Source

pub fn begin_view_focus(&mut self, node_id: WidgetId) -> Signal<bool>

Push node_id’s focus scope onto the build-time scope stack (creating its view_focus_signal if absent) so descendants built before arena parenting is wired (docked / virtualized rows) still read the correct view focus. Pair with end_view_focus.

Source

pub fn end_view_focus(&mut self)

Pop the innermost focus scope pushed by begin_view_focus.

Source

pub fn current_view_focus(&self) -> Option<Signal<bool>>

The innermost active build-time focus scope, if any.

Source§

impl WidgetTree

Source

pub fn layout(&mut self, proposal: SizeProposal)

Run the layout pass with the given size proposal, using NoopWindowOps. Handlers triggered from drag_tick / tooltip activation / etc cannot call ctx.open_window(...) from this path.

teksilo-app calls layout_with_ops with a real sink so those handlers can open windows.

Source

pub fn measure_root_intrinsic(&self, proposal: SizeProposal) -> Option<Size>

Measure the intrinsic size of the primary (non-overlay) content root(s) at proposal — e.g. { width: Some(w), height: None } for the natural height at a fixed width. Mirrors the overlay intrinsic pass below: it calls the root’s layout_response directly — NOT the activation-ignoring WidgetArena::measure_intrinsic — so a visible_when(false) / parked-Switcher descendant is excluded exactly as the real layout excludes it. A size-to-content window is therefore sized to what is actually shown. Computes sizes only (never writes bounds), so it is safe to call right after a layout pass.

Drives size-to-content windows (see WindowConfig::size_to_content): the native-window path has no in-tree overlay to size to content, so teksilo-app measures the root here and resizes the OS window to fit. Returns None if there is no active primary root; with more than one active primary root the per-axis maximum is returned (size-to-content is intended for single-primary-root windows).

Source

pub fn layout_with_ops( &mut self, proposal: SizeProposal, ops: &mut dyn WindowOps, )

Run the layout pass with the given size proposal, threading the app’s WindowOps sink through to drag_tick / tooltip / delayed-overlay handlers.

Source§

impl WidgetTree

Source

pub fn attach_tooltip( &mut self, anchor_id: WidgetId, content_id: WidgetId, delay: Duration, )

Attach a tooltip to a widget. The tooltip content widget must already be in the tree (typically added as a dormant widget during build).

Source

pub fn attach_tooltip_with_placement( &mut self, anchor_id: WidgetId, content_id: WidgetId, delay: Duration, placement: TooltipPlacement, )

Variant of attach_tooltip that opens the tooltip at the given TooltipPlacementSide for anchors stacked vertically (menu items, a vertical tab strip, list/tree rows) where Below would cover the next sibling.

Source

pub fn attach_tooltip_with_sticky( &mut self, anchor_id: WidgetId, content_id: WidgetId, delay: Duration, sticky_after: Option<Duration>, )

Attach a tooltip that auto-promotes to “sticky” after sticky_after elapses post-show. Used by rich tooltips implementing the sticky-on-dwell UX (typically 2 seconds).

The tooltip is shown normally after delay, then each subsequent layout pass checks whether sticky_after has elapsed since the overlay was shown. When it has, the tree calls promote_tooltip_to_sticky — the entry is flagged sticky (so pointer-leave no longer auto-dismisses) and the overlay’s dismiss behavior is swapped to EscapeOrClickOutside.

Source

pub fn attach_tooltip_with_sticky_sink( &mut self, anchor_id: WidgetId, content_id: WidgetId, delay: Duration, sticky_after: Option<Duration>, shown_at_sink: Rc<Cell<Option<Instant>>>, )

Variant of attach_tooltip_with_sticky that also takes a shared Rc<Cell<Option<Instant>>> “sink” the tree updates whenever the tooltip is shown or dismissed. The rich tooltip widget reads from this sink to drive its dwell indicator without needing a paint-gap heuristic.

Source

pub fn attach_tooltip_with_sticky_sink_placement( &mut self, anchor_id: WidgetId, content_id: WidgetId, delay: Duration, sticky_after: Option<Duration>, shown_at_sink: Rc<Cell<Option<Instant>>>, placement: TooltipPlacement, )

Variant of attach_tooltip_with_sticky_sink that also carries a TooltipPlacement — the full-featured path used by MenuItem / TabHeader / StandardItem rich + composite tooltips that want Side placement.

Source

pub fn is_descendant_of(&self, widget_id: WidgetId, ancestor: WidgetId) -> bool

Source

pub fn promote_tooltip_to_sticky(&mut self, content_id: WidgetId)

Promote a shown tooltip from “ephemeral hover” to “sticky”.

  • Flags the tooltip entry as sticky so tooltip_pointer_leave no longer auto-dismisses it,
  • Swaps the overlay’s dismiss behavior to EscapeOrClickOutside so clicking anywhere off the tooltip (or pressing Escape) closes it.

The entry is not removed: when the user later dismisses the sticky overlay, dormant_dismissed_content resets the entry back to its initial state so a future hover re-shows the tooltip from scratch.

Called from RichTooltipWidget (or by the auto-promote sweep) once the dwell timer reaches its threshold.

Source

pub fn next_timer_deadline(&self) -> Option<Instant>

Returns the earliest deadline for a pending tooltip or delayed overlay (if any).

Source

pub fn overlay_manager(&self) -> &OverlayManager

Source

pub fn overlay_manager_mut(&mut self) -> &mut OverlayManager

Mutable access to the overlay manager. Used by the modal-presentation pipeline to wire up cascade-dismissal between paired overlays (e.g. the dialog scrim and the modal panel) via OverlayManager::set_parent_overlay.

Source

pub fn active_overlays(&self) -> Vec<OverlayId>

Source

pub fn overlay_content_bounds(&self, id: OverlayId) -> Option<Rect>

Laid-out bounds of an open overlay’s content surface.

This is the size the overlay pass actually measured — taken with an unbounded proposal, independent of the host tree’s own proposal — so it is the right thing to assert against for content that must cap or wrap itself (tooltips against TOOLTIP_MAX_WIDTH, popovers against their max height). Reading bounds(content_id) instead would report whatever the surrounding layout handed the widget.

Source

pub fn show_overlay(&mut self, request: OverlayRequest) -> OverlayId

Source

pub fn show_overlay_from_source( &mut self, source_widget: WidgetId, request: OverlayRequest, ) -> OverlayId

Show an overlay relative to a source widget, inheriting the source overlay ancestry and focus-restore behavior used during event dispatch.

Source

pub fn show_overlay_for( &mut self, request: OverlayRequest, duration: Duration, ) -> OverlayId

Source

pub fn dismiss_overlay(&mut self, id: OverlayId)

Dismiss an overlay programmatically. Uses NoopWindowOps for any focus-loss handlers it triggers — user code fires these from outside a dispatch.

Source

pub fn dismiss_overlay_with_ops( &mut self, id: OverlayId, ops: &mut dyn WindowOps, )

Dispatch-path variant that threads ops through to the focus-loss handler fired during dismissal.

Source

pub fn is_visible(&self, id: WidgetId) -> bool

Source§

impl WidgetTree

Source

pub fn bounds(&self, id: WidgetId) -> Rect

Source

pub fn last_pointer_position(&self) -> Option<Point>

Last known pointer position from a PointerMove event. Used by the safe-triangle submenu hover gate to compare the cursor trajectory against the open submenu’s bounds without requiring the gate’s evaluation site to receive a fresh PointerMove itself.

Source

pub fn widget_as_any(&self, id: WidgetId) -> Option<&dyn Any>

Borrow the widget at id as &dyn Any for concrete-type introspection. Uses the Widget::as_any hook — widgets that haven’t opted in return None. Primarily for tests that need to inspect a widget’s private Signal state.

Source

pub fn widget_as_any_mut(&mut self, id: WidgetId) -> Option<&mut dyn Any>

Mutable variant of widget_as_any. Widgets opt in by overriding Widget::as_any_mut. Used by tests that need to mutate widget state post-layout (e.g. declaring a logical AT parent on a SceneView after the arena allocated the inner widget’s WidgetId).

Source

pub fn children(&self, id: WidgetId) -> Vec<WidgetId>

Source

pub fn roots(&self) -> Vec<WidgetId>

Root widget ids of the arena (the entry points for a full widget-tree walk). Mirrors what the debug inspector starts its tree view from.

Source

pub fn widget_type_name(&self, id: WidgetId) -> Option<&'static str>

The concrete Rust type name of the widget at id (e.g. "teksilo_widgets::button::Button"), or None if the id isn’t in the arena. The same Widget::type_name() the inspector’s tree view labels rows with.

Source

pub fn widget_debug_string(&self, id: WidgetId) -> Option<String>

The widget at id formatted via its Debug impl — its constructor parameters / fields, the same “debug repr” the inspector’s Properties tab shows. None if the id isn’t in the arena.

Source

pub fn widget_clips_children(&self, id: WidgetId) -> bool

Whether the widget at id clips its children (e.g. ScrollArea, MaxSize). false if the id isn’t in the arena.

Source

pub fn last_proposal(&self) -> SizeProposal

The most recent layout proposal applied to this tree (the size last passed to layout / layout_with_ops). Lets a settle pass re-run layout at the current size without recomputing it from a surface dimension. Returns SizeProposal::exact(800.0, 600.0) on a tree that was never laid out.

Source

pub fn at_version(&self) -> &Signal<u64>

Monotonic accessibility-tree version. Bumped in sync_accessibility only when a rebuild produces a tree whose content actually differs from the cached one (cache hits don’t bump, and a rebuild that reproduces an identical TreeUpdate — e.g. from a shortcut-rebind / locale invalidation — doesn’t either). Saturating, so the monotonic contract holds past u64::MAX. Mirrors ShortcutRegistry::version: poll it to detect AT-tree changes without diffing the whole TreeUpdate.

Source

pub fn announcements_since(&self, seq: u64) -> Vec<Announcement>

Drain the captured live-region announcements with seq strictly greater than seq. See crate::accessibility::Announcement. The buffer is capped at 256 entries, so a caller that lags far behind sees only the retained tail. Read after a sync_accessibility (or a settle that ends in one) to observe announcements raised by the latest rebuild.

Source

pub fn parent(&self, id: WidgetId) -> Option<WidgetId>

Parent widget id in the arena graph, or None for roots.

Source

pub fn needs_layout(&self) -> bool

Source

pub fn needs_paint(&self) -> bool

Source

pub fn active_animation_count(&self) -> usize

Source

pub fn pending_tooltip_count(&self) -> usize

Source

pub fn has_idle_work(&self) -> bool

Whether there are pending idle callbacks to run.

Source

pub fn has_pending_modal_requests(&self) -> bool

Source

pub fn has_pending_modal_dismissal(&self) -> bool

Source

pub fn current_cursor(&self) -> CursorIcon

Source

pub fn hovered(&self) -> Option<WidgetId>

The widget currently under the pointer, if any. The framework updates this on PointerMove / hover routing; widgets that have captured the pointer or that opt out via event_pass_through affect what shows up here. Mirrors the private hovered field for read-only consumers (debug inspector, layout introspection).

Source

pub fn hovered_signal(&self) -> Signal<Option<WidgetId>>

Reactive handle to the hovered widget id. Cheap clone — the underlying Signal is shared. Set whenever hovered changes during dispatch, post-layout hover recovery, widget destruction, or overlay subtree dormancy. Intended for debug tooling that wants to react to hover without polling (the inspector’s hover tooltip).

Source

pub fn focused_signal(&self) -> Signal<Option<WidgetId>>

Reactive handle to the focused widget id. Mirror of hovered_signal for the focus chain; drives the inspector’s Focus tab without polling.

Source

pub fn run_idle_callbacks(&mut self, budget: Duration)

Drain and run all pending idle callbacks with the given time budget. Called by the event loop during idle periods between frames.

Source§

impl WidgetTree

Source

pub fn render(&mut self) -> Rc<RenderFrame>

Paint all active widgets and produce a RenderFrame. Uses per-widget paint caching: only widgets with needs_paint are re-painted; clean widgets reuse their cached paint output. Also caches the full assembled frame — if no widget needs painting, the previous frame is returned immediately.

Source

pub fn render_with_ops(&mut self, ops: &mut dyn WindowOps) -> Rc<RenderFrame>

Render a frame, threading the app’s WindowOps sink through any state-change-triggered handlers (data-driven rebuild, binding flush). Called by teksilo-app during its paint pipeline.

Source§

impl WidgetTree

Source

pub fn tooltip_content_within(&self, widget: WidgetId) -> Option<WidgetId>

The content id of the tooltip anchored at widget or anywhere inside it.

The attach helpers keep the content id to themselves, so a test that needs to drive a tooltip’s own surface (promote it, focus into it) has no other way to name it. Matching the whole subtree, not just the id, is what makes this work for composing controls: Button keeps focus on its outer node but attaches its tooltip to an inner body root.

Source

pub fn tooltip_is_sticky_within(&self, widget: WidgetId) -> bool

Whether that tooltip has been promoted.

Promotion is the line between an informational tip and a panel the user asked for: it decides the AT role, the dismiss behaviour, and whether the surface takes a Tab stop.

Source

pub fn click(&mut self, id: WidgetId)

Simulate a click at the center of a widget.

Source

pub fn synthesise_tap(&mut self, id: WidgetId)

Synthesise a primary-button tap at the center of id’s resolved bounds. The OS hands the click off to the widget tree even though the click never went through the normal hit-test path. Used by the Windows custom-title-bar backend when WM_NCHITTEST reported HTMINBUTTON/HTMAXBUTTON/HTCLOSE for an area covering a ControlButton — the OS treated the area as non-client and WM_LBUTTONDOWN/UP never fired in widget land, so we re-issue a synthetic primary-button down

  • up on the right widget.

Equivalent semantics to Self::click; named differently so production call sites read clearly.

The tap runs on a standalone dispatch, so a handler it reaches cannot use the multi-window API. Call synthesise_tap_with_ops from anywhere that already holds a real WindowOps sink.

Source

pub fn synthesise_tap_with_ops(&mut self, id: WidgetId, ops: &mut dyn WindowOps)

synthesise_tap, dispatched over the caller’s app-level WindowOps sink.

A synthetic tap is a nested dispatch, and everything the tapped widget does happens inside it — including the intent it sends and the action that intent resolves to. Dispatching it standalone therefore hands that action a context with no window sink: ctx.open_window panics, and find_window / focus_window / close_window_by_id silently do nothing. That is how keyboard activation in a menu (Enter, Space, a mnemonic, type-ahead — all four route through EventContext::synthetic_click) lost the multi-window API that the same row reached fine by mouse.

Source

pub fn pointer_move(&mut self, position: Point)

Simulate pointer movement to a position.

Source

pub fn press_key(&mut self, key: Key, modifiers: Modifiers)

Simulate a key press (down + up), carrying the text the platform attaches to the key (Key::to_text).

That text is not decoration: Escape arrives as U+001B, and a widget that inspects text behaves differently with it than without. This helper used to send text: None for every key, so a whole class of bug was invisible to every test in the workspace — a field that swallowed Escape passed the suite while failing in the user’s hands.

Source

pub fn type_text(&mut self, _widget: WidgetId, text: &str)

Simulate typing text into the focused widget.

Source

pub fn pointer_down_button(&mut self, position: Point, button: PointerButton)

Simulate a pointer down at a specific position with a specific button.

Source

pub fn pointer_up_button(&mut self, position: Point, button: PointerButton)

Simulate a pointer up at a specific position with a specific button.

Source

pub fn drag(&mut self, from: Point, to: Point)

Simulate a drag from one position to another.

Source

pub fn armed_drag_observers(&self) -> &[WidgetId]

The draggable ancestors armed by the current pointer press — the observable state of the cross-widget tap-vs-drag disambiguation (see arm_drag_observers).

Empty when the press landed inside a gesture_dead_zone, or when the pressed widget carries its own drag (the innermost drag owns the gesture). Exposed so an app built on teksilo can assert the same thing this crate’s own gesture_dead_zone_blocks_ancestor_drag_arming asserts — that a press on an interactive control inside a draggable container cannot start the container’s drag. Read-only; test support.

Source

pub fn child_bounds(&self, parent: WidgetId, index: usize) -> Rect

Get bounds of a child by index.

Source

pub fn child_widget(&self, parent: WidgetId, index: usize) -> WidgetId

Get a child widget ID by index.

Source

pub fn advance_time(&mut self, duration: Duration)

Advance the simulated clock by the given duration. Triggers time-dependent behavior such as long-press gesture recognition and tooltip timers. Enables deterministic testing without real delays.

Source

pub fn simulated_now(&self) -> Instant

Get the current simulated clock value.

Source

pub fn tooltip_entry_count(&self) -> usize

Total number of live tooltip attachments, dead ones included.

Distinct from pending_tooltip_count, which only counts entries with a running dwell. This is the raw table size — the number that must stay flat across rebuilds, since attach_tooltip* is called from build() and the table is scanned on every pointer move, every layout pass and once per widget in the accessibility walk.

Source

pub fn widget_count(&self) -> usize

Every widget the arena still holds — active, dormant and orphaned alike.

The number a leak test must assert on. active_widget_count walks the tree from its roots and so cannot see the failure mode that matters here: a node kept alive in the arena with nothing pointing at it. A parentless orphan (tooltip content is ctx.added, hence parentless by construction) is invisible to every other count in this file, and to the accessibility tree, while still paying for itself in the arena’s slotmap forever.

Source

pub fn destroy_subtree_for_testing(&mut self, id: WidgetId)

Tear down a widget and everything it owns — its subtree, its tooltip, and the parentless content it built with add_detached.

The application-facing door is BuildContext::destroy_subtree; this is the same call for tests that hold the tree directly.

Source

pub fn mark_needs_paint(&mut self, id: WidgetId)

Mark a widget as needing repaint.

Source

pub fn set_dormant(&mut self, id: WidgetId)

Set a widget subtree as dormant.

Source

pub fn activate(&mut self, id: WidgetId)

Activate a dormant widget subtree.

Source

pub fn invalidate_all_paints(&mut self)

Invalidate all per-widget paint caches (paint AND post-paint) and the assembled frame cache. Forces every widget to repaint on the next render() call. Used by the glyph-atlas eviction recovery: after an eviction, any retained frame may hold quads whose atlas UVs now point at recycled slots.

Source§

impl WidgetTree

Source

pub fn new() -> Self

Source

pub fn run_with_event_context<F>(&mut self, ops: &mut dyn WindowOps, f: F)
where F: FnOnce(&mut EventContext<'_>),

Run a closure with a fresh EventContext anchored at this tree, then collect any pending operations queued through the context (intents, modal requests, frame requests, idle callbacks…) so they take effect on the next event-loop tick.

Used by the teksilo-app event-loop dispatcher to deliver async-result callbacks (file dialogs, future background tasks) on the main thread with full handler-equivalent semantics. There is no source widget for app-level events, so intents are anchored at the tree’s first root id (or silently dropped when the tree is empty).

Source

pub fn has_pending_mount_actions(&self) -> bool

Whether any post-mount actions are waiting to run.

Source

pub fn run_mount_actions(&mut self, ops: &mut dyn WindowOps)

Drain and run every queued post-mount action with a fresh EventContext built over ops. The app loop calls this each iteration with a real WindowOps sink (so ctx.parent_window_handle() resolves); headless tests call it with a NoopWindowOps. Actions enqueued by an action (rare) are left for the next drain rather than run re-entrantly.

Source

pub fn set_window_state(&mut self, state: WindowState)

Attach the WindowState for this tree’s hosting window. Called by WindowManager::create_window.

Source

pub fn window_state(&self) -> Option<&WindowState>

Source

pub fn frame_request_handle(&self) -> Rc<Cell<bool>>

Clone the shared “frame requested” flag. Widgets stash this in their state and call .set(true) from inside frame-tick closures to chain-request another frame without needing mutable access to the tree. See RichTextEditor for the canonical use (caret blink, drag-select auto-scroll).

Source

pub fn wake_at_handle(&self) -> Rc<Cell<Option<Instant>>>

Clone the shared wake-at deadline cell. Widgets stash this in their state and call request_wake_at from frame-tick effects to schedule a one-shot deadline without keeping the event loop in Poll mode. On the next layout() at or past the deadline, the tree auto-arms frame_tick_requested so the effect runs on the wake-up pass. Canonical use: the rich text editor’s caret blink schedules a 500 ms wake instead of pumping every frame.

Source

pub fn request_wake_at(&self, at: Instant)

Schedule a one-shot frame wake at at. Merges with any existing deadline — keeps the earlier instant so the most urgent wake wins.

Source

pub fn frame_tick(&self) -> Signal<f32>

The per-frame delta-seconds signal. Observers fire only on frames the tree was asked to pump via request_frame; merely observing the signal does not keep the event loop awake. See BuildContext::frame_tick for widget-side access and BuildContext::request_frame for the opt-in request side.

Source

pub fn request_frame(&self)

Ask the tree to pump exactly one more frame. needs_redraw() returns true until the request is consumed by the next layout() call, which fires the per-frame tick signal and clears the flag. Observers that still need more frames (drag auto-scroll, caret blink, pending document events) must call request_frame() again from inside their tick closure.

Takes &self on purpose: widget handlers and per-frame effects receive a shared reference to the tree via EventContext / BuildContext, and the request flag is a Cell specifically so those shared paths can toggle it without ceremony.

Source

pub fn request_accessibility_update(&self)

Request that the AccessKit tree be re-walked on the next sync_accessibility. Takes &self (the flag is a Cell) so handlers and build() closures reaching the tree through a shared reference can request a re-walk without &mut access. The drain at the top of sync_accessibility flips a11y_dirty.

Source

pub fn a11y_request_handle(&self) -> Rc<Cell<bool>>

Clone the shared “accessibility re-walk requested” flag, for the same stash-and-toggle pattern as frame_request_handle.

Source

pub fn frame_requested(&self) -> bool

Whether a frame was explicitly requested. Exposed for tests and for the event-loop driver that decides when to schedule the next wake-up.

Source

pub fn frame_tick_deadline(&self) -> Option<Instant>

The next wake-up deadline for the per-frame-effect path, or None when no per-frame effect is armed.

This is the 60 Hz cap for continuous per-frame animations (Pulse, caret blink, drag auto-scroll, --cycle drivers). The per-frame-effect path used to force ControlFlow::Poll, which free-runs at the display’s refresh rate — so on a 300 Hz panel a single Pulse/Cycle rendered at 300 fps (measured ~45 % CPU) for motion that looks identical at 60 fps. Routing it through a fixed 16.667 ms deadline (folded into next_timer_deadline) makes it pace at 60 Hz regardless of refresh rate, matching the signal-tween AnimationScheduler and shader-quad AnimatedQuadRegistry, which already share the same interval.

A throttled subscriber (registered via FrameTickScheduler::subscribe_throttled — e.g. Cycle, whose visible child only changes once per period) stretches the deadline to its own interval: the loop then sleeps to the period instead of rendering identical 60 fps frames in between. The interval used is the minimum across all currently-visible subscribers, so a Cycle next to a Pulse still ticks at 60 Hz while a lone Cycle sleeps to its period. Raw request_frame consumers with no subscription fall back to 60 Hz.

Paces from last_frame_time so the cadence is drift-free; before the first render it fires on the next loop turn.

Source

pub fn subscribe_frame_tick(&self, owner: WidgetId) -> FrameTickSubscription

Subscribe owner to the per-frame-effect scheduler. The returned FrameTickSubscription is an RAII guard — drop it (typically by replacing the field on the owning widget on rebuild, or letting the widget’s Drop run) to remove the subscription. While the guard is alive, the tree will keep arming frame_tick_requested after every render in which owner was painted, and stop on frames where it wasn’t — so a subscribed widget hidden inside a non-selected Switcher branch contributes zero idle frames.

Apps should not call this directly — use BuildContext::subscribe_frame_tick from inside Widget::build.

Source

pub fn subscribe_frame_tick_throttled( &self, owner: WidgetId, interval: Duration, ) -> FrameTickSubscription

Like subscribe_frame_tick, but the owner only needs to wake at most once per interval while visible. Same visibility gate; between wakes the event loop sleeps to the interval deadline instead of rendering identical 60 fps frames. Use for effects whose visible output changes far less often than 60 Hz — e.g. Cycle’s once-per-period index advance.

Apps should not call this directly — use BuildContext::subscribe_frame_tick_throttled from inside Widget::build.

Source

pub fn set_app_context(&mut self, app_context: Rc<TreeAppContext>)

Replace the per-tree app context. Called by teksilo-app when constructing a window so the widget tree can reach the registered event source adapter and post subscription events through the event-loop proxy.

Source

pub fn app_context(&self) -> &Rc<TreeAppContext>

Get the per-tree app context. Used by BuildContext::subscribe_event and by the event-loop handler when dispatching incoming AppEvent::SubscriptionEvent.

Source

pub fn set_locale(&mut self, locale: String)

Switch the tree-level locale at runtime.

Updates locale_signal (a reactive Signal<Option<String>>) and marks all widgets dirty for relayout and repaint. Widgets are not rebuilt: per-string reactivity flows through LocalizedString::to_signal() which observes the teksilo-i18n manager, and anything else that depends on the tree-level locale can bind to locale_signal().

Source

pub fn locale(&self) -> Option<&str>

Currently active locale identifier, if any.

Source

pub fn locale_signal(&self) -> &Signal<Option<String>>

Reactive handle on the current locale. Mirrors locale() but updates observers when set_locale is called.

Source

pub fn with_theme(self, theme: Theme) -> Self

Source

pub fn with_text_backend(self, backend: Rc<RefCell<dyn TextBackend>>) -> Self

Source

pub fn with_title_bar_host(self, host: Rc<dyn PlatformTitleBarHost>) -> Self

Attach a platform host for custom window chrome. Set by the WindowManager when the application opts in via WindowConfig::custom_chrome(true). Widgets like TitleBar retrieve it from inside the root-builder closure via Self::title_bar_host.

Source

pub fn set_title_bar_host(&mut self, host: Rc<dyn PlatformTitleBarHost>)

Source

pub fn title_bar_host(&self) -> Option<Rc<dyn PlatformTitleBarHost>>

Get the platform title bar host, if one was attached. Returns None when the application did not opt into custom chrome, or when the platform does not support it (X11 without an EWMH-capable window manager, or a headless build).

Source

pub fn theme(&self) -> &Theme

Source

pub fn theme_signal(&self) -> &Signal<Theme>

Reactive handle on the current theme. Updates fire when set_theme is called; widgets that want theme-derived values to stay live should build derived signals via theme_signal.map(...) or combine with other inputs using .zip(...).

Source

pub fn needs_redraw(&self) -> bool

Whether any widget needs layout or paint (i.e., a redraw would be useful).

Uses has_running rather than has_active so that animations parked by the window-inactive gate stop forcing the event loop into ControlFlow::WaitUntil. Without this, an unfocused window would still wake at the animation frame interval and the pause would save nothing. Both the signal scheduler AND the shader-driven animated-quad registry are consulted — a ProgressBar::indeterminate whose widget has no pending paint dirt still needs the loop to keep waking at the animation frame interval so its phase advances.

Source

pub fn needs_render(&self) -> bool

Whether a render pass is needed (any widget needs layout or paint).

Source

pub fn needs_reconcile(&self) -> bool

Whether this tree has reactive work that only a layout() pass can turn into arena dirt — i.e. whether reconciling it right now could change what needs_render reports.

Read-only and cheap: O(unique bound sources) u64 comparisons plus one peek per registered animated signal. No arena walk, no rebuilds, no geometry. Asking does not consume the answer, so it can be asked every dispatch.

§Why this is exactly the right question, and no broader

teksilo_app::WindowManager::request_redraw_needing_render exists for ONE case: a handler in window A wrote a Signal that window B’s widgets also bind, and B — which never saw the event — must be reconciled before anyone can tell it needs repainting. Every OTHER thing layout_with_ops drives already has its own scheduling path and does not need this sweep:

  • tooltip dwell + sticky steps, delayed overlays, auto-dismiss, overlay fades, the animation scheduler, animated quads, gestures, wake_at and the 60 Hz frame tick are all timing driven, and every one of them contributes to next_timer_deadline — which request_redraw_due polls to wake precisely the due windows;
  • drag ticks follow that window’s own pointer stream;
  • a handler that called request_rebuild marked the arena directly, so needs_render() is already true without any reconcile.

So the two terms below are what the sweep uniquely covers: binding-registry staleness (the whole point), and a pending animate_to — which the scheduler has not started yet, so it contributes no deadline, and which only process_pending_animations (inside layout) can promote into one. The second term is belt-and-braces: arming an animation also advances the signal’s generation, so a bound animated signal is already covered by the first — but an animated signal registered without being bound would not be, and this makes that impossible to get wrong.

Source

pub fn register_animated_signal( &mut self, signal: &Signal<f32>, owner: WidgetId, )

Register a Signal<f32> for animation support. The framework checks registered signals each frame for pending animate_to requests. Called automatically by BuildContext::animated_signal()owner is ctx.self_id() of the widget whose build() created the signal. Used by the scheduler to pause/cancel animations when the owning widget is offscreen, dormant, or destroyed.

Source

pub fn has_active_animations(&self) -> bool

Whether any animation is currently running.

Source

pub fn mark_all_needs_paint_only(&mut self)

Mark the owning window as active (focused AND not occluded) or inactive. Propagates to the animation scheduler AND the animated-quad registry so both pause-resume in lockstep — no ticks, no frame wakes, no GPU submits.

On an actual state change it also fires window_active_signal (so build-time binders and DimWhenInactive react) and issues a global paint-only dirty mark, so every widget that reads PaintContext::window_active (caret gates, selection bands) repaints once. This is a repaint, not a relayout — geometry never changes when the window’s active state flips (the caret keeps its space). Window focus changes are rare and user-driven, so the O(n) mark is cheap and Mark every node paint-dirty (no relayout, no rebuild) so the next render re-runs their paint(). This is the paint-cache invalidation an off-thread source needs after posting a RepaintWindowRequest: a bare redraw request re-presents the cached frame, so a widget whose content changed off the UI thread (a terminal’s PTY output) must be marked dirty for its paint() to run again.

Source

pub fn set_window_active(&mut self, active: bool)

strictly lighter than set_theme’s mark_all_dirty (layout + paint).

Source

pub fn is_window_active(&self) -> bool

Whether the owning window is currently active (focused AND not occluded). The reactive companion is Self::window_active_signal.

Source

pub fn window_active_signal(&self) -> Signal<bool>

Reactive handle on window-active state. Fires when the window gains or loses active status. Bind at BindingLevel::RepaintOnly — an active-state flip never affects geometry. Starts true.

Source

pub fn register_animated_quad( &mut self, owner: WidgetId, kind: AnimatedQuadKind, ) -> AnimatedQuadHandle

Register a new animated quad for the currently-building widget. Called by crate::build_context::BuildContext::animated_quad; returns an opaque handle the widget stashes for its paint() call.

Source

pub fn animated_quad_count(&self) -> usize

Active animated-quad slot count. Test / debug helper.

Source

pub fn tick_gestures(&mut self, now: Instant)

Advance time-driven gesture recognizers (currently only crate::gesture::LongPressRecognizer) across every widget that has a gesture arena. Must be called by the event loop on each wake-up; otherwise long-press will never fire during an idle hold.

When a recognizer transitions to Recognized, the corresponding handler on the owning widget is invoked with a fresh EventContext, and any commands / overlay requests it emits are collected through the normal post-event path.

Source

pub fn tick_gestures_with_ops(&mut self, now: Instant, ops: &mut dyn WindowOps)

App-facing variant of tick_gestures that accepts a real WindowOps sink so gesture-recognized handlers can call the multi-window API synchronously.

Source

pub fn next_gesture_deadline(&self) -> Option<Instant>

Earliest wall-clock deadline at which any active gesture arena needs WidgetTree::tick_gestures called — typically a pending long-press timeout. Returns None when no recognizer is waiting.

Source

pub fn tick_animations(&mut self, duration: Duration)

Advance animations by simulated time (for deterministic testing). Pending animate_to requests are started at the current sim_clock, then time advances by duration, and the scheduler ticks at the new time.

Source

pub fn set_theme(&mut self, theme: Theme)

Switch the tree-level theme at runtime.

Updates theme_signal (a reactive Signal<Theme>) and marks all widgets dirty for relayout and repaint. Widgets are not rebuilt: the LayoutContext and PaintContext already resolve the current theme on every pass, and any widget that derives state from theme tokens should do so through a theme_signal() subscription rather than a build-time capture. Preserves focus, scroll offsets, and other interaction state.

Source

pub fn effective_text_scale(&self) -> f32

The combined effective text scale (user_text_scale * OS text_scale_factor). Read by the layout/paint walkers to populate ctx.text_scale for widgets that size from a source other than Theme.typography.

Source

pub fn text_scale_signal(&self) -> Signal<f32>

Reactive handle on Self::effective_text_scale. Build-time binders that must react to a scale change without their own rebuild path bind this (e.g. Calendar binds it at Rebuild level so its fixed cell constants recompute). Fires on set_user_text_scale / theme / OS-pref change.

Source

pub fn set_user_text_scale(&mut self, factor: f32)

Set the user-controlled global text-scale factor (1.0 = 100 %).

The factor multiplies with the OS accessibility text-scale preference to produce the rendered scale. Recomputes the effective theme and marks all widgets dirty so every text widget grows on the next pass; no rebuild, so focus/scroll/interaction state survive. Values outside [0.25, 8.0] are clamped. Persisted by the application via teksilo_settings::TEXT_SCALE_KEY.

Source

pub fn user_text_scale(&self) -> f32

The current user-controlled text-scale factor (1.0 = 100 %).

Source

pub fn arena_mark_needs_rebuild_for_testing(&mut self, id: WidgetId)

Rebuild a single composite widget: destroy old children, re-run build(), and wire up new children. Called from process_state_changes() when a binding at BindingLevel::Rebuild fires (data-driven rebuild). Theme and locale changes do not rebuild — they update reactive signals that widgets bind to via theme_signal() / locale_signal(). Test-only: force-mark a widget for rebuild on the next layout pass. Lets regression tests exercise the rebuild path without needing to trip a Signal binding. Exposed cross-crate (not #[cfg(test)]-gated) so widget-crate tests in teksilo-widgets and elsewhere can also drive rebuilds; the _for_testing suffix marks it as not intended for application code.

Source

pub fn set_layout_direction(&mut self, direction: LayoutDirection)

Set the layout direction (LTR/RTL). Marks all widgets as needing layout.

Source

pub fn layout_direction(&self) -> LayoutDirection

The current layout direction.

Source

pub fn set_accessibility_preferences( &mut self, high_contrast: bool, reduced_motion: bool, text_scale_factor: f64, )

Set OS-level accessibility preferences.

Called by teksilo-app after querying the platform layer. Updates the values fed into PaintContext and Environment on subsequent frames. Marks all widgets dirty so the new preferences take effect immediately.

Source

pub fn prefers_high_contrast(&self) -> bool

Whether the OS has requested high-contrast mode.

Source

pub fn prefers_reduced_motion(&self) -> bool

Whether the OS has requested reduced motion.

Source

pub fn text_scale_factor(&self) -> f64

OS text scaling factor (1.0 = normal).

Source

pub fn set_device_scale_factor(&mut self, scale_factor: f32)

Set the host window HiDPI device scale (physical px per logical px). Called by teksilo-app before each layout from platform_window.scale_factor(). Surfaced to widgets via LayoutContext::scale_factor. No dirty-marking: it rides the layout pass that follows, and a scale change already triggers a relayout.

Source

pub fn device_scale_factor(&self) -> f32

The host window HiDPI device scale most recently set (1.0 by default).

Source

pub fn set_clips_children(&mut self, id: WidgetId, clips: bool)

Mark a widget as clipping its children to its bounds (scroll areas).

Source

pub fn set_alignment(&mut self, id: WidgetId, alignment: Alignment)

Set a per-child alignment override on a widget.

Source

pub fn binding_registry(&self) -> &BindingRegistry

Get the binding registry for registering State→Widget bindings.

Source

pub fn shortcut_registry(&self) -> &ShortcutRegistry

Shared access to the shortcut registry. Widgets register their default shortcuts through here during build() (via BuildContext::register_shortcut); settings UIs and persistence layers read and mutate overrides directly.

Source

pub fn shortcut_registry_mut(&mut self) -> &mut ShortcutRegistry

Source

pub fn begin_key_capture( &mut self, callback: impl FnOnce(KeyStroke, &mut ShortcutRegistry, &mut EventContext<'_>) + 'static, ) -> CaptureHandle

Install a one-shot key-capture callback, returning a CaptureHandle whose Drop cancels the capture if it hasn’t already fired. The next KeyDown the tree receives bypasses shortcut-registry lookup and invokes the callback with:

  • the captured KeyStroke
  • mutable access to the registry (rebind in-place)
  • a mutable EventContext (so the handler can also emit commands, send intents, dismiss overlays, …)

Calling this while a previous capture is armed creates a separate slot; the prior handle, when eventually dropped, cancels only its own (now-orphaned) slot. The new capture wins.

Source

pub fn cancel_key_capture(&mut self)

Cancel any currently-armed key capture without invoking it. Equivalent to dropping the CaptureHandle, but exposed here so callers that lost the handle (or never kept one) can still bail out.

Source

pub fn is_capturing_keys(&self) -> bool

Whether a key-capture callback is currently armed.

Source

pub fn text_surfaces(&self) -> TextSurfaces

A cloneable view of this tree’s text surfaces, for a caller that must ask the question later, without a &WidgetTree in hand.

Source

pub fn focused_text_surface(&self) -> Option<Rc<dyn TextSurface>>

The text-editing widget that currently holds the keyboard focus.

None when focus is elsewhere — or nowhere — which is exactly what a host needs in order to know that a text chord is safe to route itself.

Source

pub fn focused_is_text_surface(&self) -> bool

Is the keyboard focus inside a widget that edits text?

The cheap half of focused_text_surface, for a host that only needs to decide whether to step aside.

Source

pub fn widget_type_histogram(&self) -> HashMap<&'static str, u32>

Histogram of widget concrete-type names across the active arena. Used by the widget.census telemetry emitter to surface “which widgets does this app actually use” data back to the framework. Keyed by std::any::type_name::<T>() of the concrete widget — a dotted, fully-qualified path like teksilo_widgets::button::Button.

&'static str keys: type_name_of_val returns a compile-time string, so the histogram preserves the static lifetime all the way to the wire-format prop. This avoids any allocation for the type-name strings themselves.

Cost: one Box<dyn Widget> indirection per active node plus a HashMap insert. Sub-millisecond on arenas with thousands of widgets. Safe to call every frame in tests; in production gate behind a periodic ticker (hourly or on-idle).

Source

pub fn active_widget_count(&self) -> usize

Number of active widgets in the arena. Cheap; matches the totals returned by widget_type_histogram when summed.

Source

pub fn take_close_window_request(&mut self) -> bool

Drain the “close this window” flag set by EventContext::close_window during dispatch. A guarded close — the app routes it through the window’s close guard.

Source

pub fn take_force_close_request(&mut self) -> bool

Drain the “close this window, no questions asked” flag set by EventContext::close_window_forced during dispatch. An unconditional close that bypasses the window’s close guard.

Source

pub fn take_pending_locale_request(&mut self) -> Option<String>

Drain the pending locale switch raised by EventContext::set_locale during dispatch. The app layer (WindowManager::drain_pending_locale_requests) parses the result and routes it through WindowManager::set_locale so the I18nManager’s active locale, version signal, and layout direction all stay in sync with the tree.

Source

pub fn take_pending_theme_request(&mut self) -> Option<Theme>

Drain the pending theme switch raised by EventContext::set_theme during dispatch. The app layer (WindowManager::drain_pending_theme_requests) routes it through WindowManager::set_theme so the new theme is applied to every window, not just the one whose handler requested it.

Source

pub fn take_pending_follow_system_request(&mut self) -> bool

Drain the pending “follow OS theme” request raised by EventContext::follow_system_theme during dispatch. The app layer (WindowManager::drain_pending_follow_system_requests) switches to ThemeMode::Native and recomputes the theme from the OS for every window. Returns true if a request was pending.

Source

pub fn take_pending_text_scale_request(&mut self) -> Option<f32>

Drain the pending text-scale change raised by EventContext::set_text_scale during dispatch. The app layer (WindowManager::drain_pending_text_scale_requests) routes it through WindowManager::set_text_scale so the new factor is applied to every window, not just the one whose handler requested it.

Source

pub fn drain_pending_modal_requests(&mut self) -> Vec<QueuedModalRequest>

Drain all pending modal requests recorded during event handling.

Each request includes the originating widget so higher layers can resolve routing and focus behavior relative to the source tree.

Source

pub fn drain_pending_modal_dismissal(&mut self) -> bool

Drain whether the current native modal window should be dismissed.

Source

pub fn add(&mut self, widget: impl Widget + 'static) -> WidgetId

Add a widget to the tree.

Source

pub fn add_boxed(&mut self, widget: Box<dyn Widget>) -> WidgetId

Add a pre-boxed widget to the tree.

Source

pub fn add_child( &mut self, parent: WidgetId, widget: impl Widget + 'static, ) -> WidgetId

Add a widget as a child of another widget.

Source

pub fn visible_when(&mut self, id: WidgetId, state: impl Into<Prop<bool>>)

Bind a widget’s visibility to a boolean prop or compatibility state binding. When false, the widget is set dormant; when true, it is activated. Accepts Signal<bool>, Prop<bool>, compatibility state bindings, or plain bool.

Source

pub fn activation_signal(&mut self, id: WidgetId) -> Signal<bool>

Install (or reuse) the activation signal on a node and return a handle to it. The framework sets it to false when the node is parked dormant (Switcher / visible_when) and true when it is re-activated — see crate::arena::WidgetArena::set_dormant / activate. The returned signal is initialised to the node’s current active state. Used by widgets owning a resource outside the paint pass (a native subview) that must hide/show it in lockstep with framework activation.

Source

pub fn set_opacity(&mut self, id: WidgetId, opacity: impl Into<Prop<f32>>)

Bind an opacity multiplier (0..1) to a widget. The render walker emits SetOpacity(value) before painting the widget’s subtree and RestoreOpacity afterwards, so the multiplier composes correctly with ancestor opacity scopes via the canvas’s stacked opacity model. Bound at Repaint level: opacity changes never trigger relayout. Pass any Prop<f32> or Signal<f32> source (typically an animated signal driven by a Fade wrapper).

Source

pub fn set_transform( &mut self, id: WidgetId, transform: impl Into<Prop<Transform2D>>, )

Bind a 2D affine transform to a widget. The render walker emits PushTransform(value) before painting the widget’s subtree and PopTransform afterwards; the renderer composes the transform onto its stack so nested wrappers and widget-internal canvas transforms compose correctly. Bound at Repaint level: visual- only transforms never trigger relayout. Wrappers that want the transform’s value change to also drive layout (e.g. Scale::reflow(true)) must additionally bind the driver signal to themselves at Relayout level — the transform prop itself stays at Repaint. Pass a Transform2D, Signal<Transform2D>, or Prop<Transform2D>.

Source

pub fn set_content_transform( &mut self, id: WidgetId, transform: impl Into<Prop<Transform2D>>, )

Like set_transform, but marks the transform as a content transform: it positions the node’s content within a fixed parent-space viewport (the node’s bounds) rather than transforming the node itself. Hit-testing then keeps the whole viewport interactive at any pan / zoom. Used by SceneView; see WidgetNode::content_transform.

Source

pub fn set_blur(&mut self, id: WidgetId, radius: impl Into<Prop<f32>>)

Bind a Gaussian-equivalent blur radius to a widget. The render walker emits BeginBlurredSubtree { bounds, radius } before painting the widget’s subtree and EndBlurredSubtree afterwards; the renderer redirects drawing into an intermediate texture, runs a dual-Kawase blur chain at the requested radius, and composites the blurred result back into the parent pass. Bound at Repaint level: blur radius changes never trigger relayout. Sub-perceptual radii (< 0.5) skip the Begin/End pair entirely so animated enable/disable patterns have zero per-frame cost when fully off. Pass any Prop<f32> or Signal<f32> source.

Source

pub fn enabled_when(&mut self, id: WidgetId, state: impl Into<Prop<bool>>)

Bind a widget’s enabled state to a boolean prop or compatibility state binding. When false, the widget and its entire subtree ignore all events but remain visible. Focus traversal skips disabled subtrees and AccessKit marks their nodes as disabled. Accepts Signal<bool>, Prop<bool>, compatibility state bindings, or plain bool.

The bound signal registers at BindingLevel::SubtreeRepaint: when it flips, the entire subtree rooted at id is marked for repaint (not relayout — geometry doesn’t change). Leaves like IconWidget then re-resolve their role color using the new PaintContext::effective_enabled value, so a disabled subtree’s icons and text dim automatically.

Source

pub fn effective_enabled_signal(&mut self, id: WidgetId) -> Signal<bool>

Reactive view of “is this widget effectively enabled?” — the AND of the widget’s own enabled_state and every ancestor’s. Self::is_enabled is the non-reactive equivalent; this method gives composite widgets a Signal<bool> for derived state.

Leaves (IconWidget, TextWidget, RectWidget) do NOT need this — they receive the resolved bool via crate::widget::PaintContext::effective_enabled at paint time. This method is for composites that want to derive cursor / custom paint roles / etc. reactively.

Install-or-reuse, exactly like Self::activation_signal: the signal lives on the node and the framework refreshes it from the live arena once per state-change pass (flush_effective_enabled_signals).

It is deliberately NOT a signal derived by walking the ancestor chain here. A widget’s parent is still None while its own build() runs — insert_widget inserts the node parentless and wires the parent link only after build() returns — so an ancestor walk performed from inside build() (which is how every caller uses this) sees an empty chain and would capture the widget’s OWN enabled prop as the whole answer, permanently. That was a real bug: a Button inside a disabled form stayed painted as if enabled.

The value is seeded from the live arena and corrected on the next flush, so a first-build() caller (parent not yet wired) and a rebuild caller (parent wired) both converge before anything paints.

Source

pub fn is_enabled(&self, id: WidgetId) -> bool

Whether a widget is effectively enabled. Returns false if the widget itself or any ancestor has enabled_state bound to false.

Source

pub fn set_tab_stop(&mut self, id: WidgetId, state: impl Into<Prop<bool>>)

Bind a widget’s Tab-key participation to a boolean prop or compatibility state binding. When false, the widget is removed from Tab / Shift+Tab traversal (cycle_focus) but remains reachable via request_focus and arrow-key navigation that calls request_focus. Implements the ARIA roving-tabindex pattern (HTML tabindex="-1" semantics). Accepts Signal<bool>, Prop<bool>, or plain bool.

Source

pub fn tab_stop(&self, id: WidgetId) -> bool

Current Tab-key participation for a widget. Returns the value of the tab_stop prop if bound, or true (the default) when no binding is present. Mirrors the filter used by cycle_focus — primarily for tests asserting the roving-tabindex contract.

Source

pub fn set_traversal_scope( &mut self, id: WidgetId, policy: TraversalScopePolicy, )

Declare id as a traversal-scope boundary with the given policy. cycle_focus then treats the node’s subtree as an independent Tab group: tab_index values inside it are scoped (they never collide with sibling scopes) and policy governs Tab at the scope’s ends.

The scope node is forced non-focusable — it is a transparent boundary, never itself a Tab stop. Called from BuildContext::set_traversal_scope (which the FocusScope wrapper widget invokes during build), and directly usable from tests with no dependency on the widgets crate.

Source

pub fn clear_traversal_scope(&mut self, id: WidgetId)

Remove a previously set traversal-scope marker from id (rebuild paths where a FocusScope is replaced by a non-scope widget). Leaves node_focusable untouched — a later handler-set application resets it.

Source

pub fn traversal_scope(&self, id: WidgetId) -> Option<TraversalScopePolicy>

Current traversal-scope policy on id, if any. For tests asserting the scope marker contract.

Source

pub fn set_theme_override( &mut self, id: WidgetId, f: impl Fn(&mut Theme) + 'static, )

Set a theme override on a widget. All descendants of this widget will see the modified theme during layout and paint. The override function receives a mutable Theme to modify.

tree.set_theme_override(panel_id, |theme| {
    theme.colors = ColorTokens::dark_default();
});
Source

pub fn resolved_theme(&self, id: WidgetId) -> Theme

Get the resolved theme for a specific widget (applying ancestor overrides).

Trait Implementations§

Source§

impl Default for WidgetTree

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.