pub struct WidgetNode {Show 21 fields
pub widget: Box<dyn Widget>,
pub parent: Option<WidgetId>,
pub children: Vec<WidgetId>,
pub activation: ActivationState,
pub dirty: DirtyFlags,
pub bounds: Rect,
pub clips_children: bool,
pub ime: Option<ImeContext>,
pub event_pass_through: bool,
pub gesture_dead_zone: bool,
pub long_press_role: LongPressRole,
pub touch_action: TouchAction,
pub pan_claim: Option<PanClaim>,
pub overscroll_behavior: OverscrollBehavior,
pub drag_activation: DragActivation,
pub multi_contact: MultiContact,
pub keyboard_capture: bool,
pub hit_transparent: bool,
pub hit_slop: Option<HitSlop>,
pub no_hit_slop: bool,
pub last_painted_epoch: u64,
/* private fields */
}Expand description
A node in the widget arena storing a widget and its metadata.
Fields§
§widget: Box<dyn Widget>§parent: Option<WidgetId>§children: Vec<WidgetId>§activation: ActivationState§dirty: DirtyFlags§bounds: Rect§clips_children: boolWhen true, the paint pass clips child rendering to this widget’s bounds. Set by scroll areas and overflow-hidden containers.
ime: Option<ImeContext>Optional OS input-method (IME) descriptor. Some(..) declares this
node a text-input surface — the platform enables the OS IME (with the
descriptor’s purpose) while the node is focused. None (the default)
means no OS IME: enabling IME changes how text arrives, so the safe
common-case default is off. The platform reads the focused node’s
descriptor at focus-change time. See crate::ime.
event_pass_through: boolWhen true, hit-testing skips this node — pointer events fall
through to whatever sits behind it. Descendants are still
hit-tested normally (the recursion walks into children before
the pass-through check), so an interactive subtree under a
pass-through wrapper stays usable. Used by the debug inspector’s
HighlightLayer and HoverProbe to paint over the user’s
content without absorbing clicks. Default false.
gesture_dead_zone: boolWhen true, a pointer press anywhere in this widget’s subtree must
NOT arm a drag/swipe recognizer on any ancestor above this node —
the subtree is a gesture dead zone for ancestor gestures. Used so
interactive controls (buttons, a ⋮ menu) placed inside a draggable /
swipeable container (a dock-panel header, a card, a list row) can be
clicked without a few px of pointer jitter starting the ancestor’s drag.
The boundary is honored by PointerSequence member enrolment. Mirrors Electron’s
-webkit-app-region: no-drag. Default false. See the DeadZone
wrapper widget.
long_press_role: LongPressRoleWhat a hold on this node’s subtree means when the widget itself does
not say — the selector for the tree-owned long-press route. Default
LongPressRole::Auto. Set via .long_press_role(..). A node’s own
on_long_press always takes precedence over this, and a mouse never
consults it. See crate::widget_tree::touch_route.
touch_action: TouchActionWhat a direct pointer (touch, pen) is permitted to do to this node’s
subtree. Intersected with every ancestor’s on the way down by
WidgetTree::effective_touch_action — an ancestor can only narrow
what a descendant permits, never widen it. Default
TouchAction::AUTO (everything permitted). Set via
.touch_action(..). A mouse never consults this field. Read at press
time, to gate pan claimants and the two-contact pinch — see
crate::pointer::touch_action.
pan_claim: Option<PanClaim>This node’s declaration that it is a pan surface — it wants to
consume a direct pointer’s drag as content panning. None (the
default) means the node makes no such claim. WidgetTree:: pan_candidates collects every claim from a target up to the root.
Set via .pan_claim(..) or the .scroll_container(..) sugar. Read at
press time to build the chain a synthesised pan walks — see
crate::pointer::touch_action.
overscroll_behavior: OverscrollBehaviorWhether this node absorbs a scroll it cannot use, or lets it chain to
the next scrollable outward — the CSS overscroll-behavior model.
Read by WidgetTree::deliver_pan when it walks the claimant chain: an
OverscrollBehavior::Contain
claimant stops the chain even when it absorbed nothing, so a
self-contained panel never lets a boundary pan escape into the page
behind it. Default
Chain. Set via
.overscroll_behavior(..).
Declared on the node rather than left inside each scrollable’s own
on_scroll closure because the chain has to read it, and the chain
runs in the router, above every handler.
drag_activation: DragActivationWhen a drag on this node may begin relative to the press that starts
it. DragActivation::Auto — the
default — resolves to Immediate
for a precise pointer (today’s behaviour, unchanged) and to
AfterLongPress for a coarse pointer whose axis is already claimed by
a pan surface. Set via .drag_activation(..), read by the arbitration
when the node is enrolled as a sequence member.
multi_contact: MultiContactHow many simultaneous contacts this node’s gesture recognizers serve.
Default MultiContact::First — one press at a time, which is what
every widget written before the touch programme assumes. Under it a
second contact arriving while the first is live is terminated at this
node: not delivered to it, and not bubbled to an ancestor either, so two
fingers on a button inside a scroll area cannot start a pan with the
second finger. Set via .multi_contact(..).
keyboard_capture: boolWhen true and this widget holds keyboard focus, a KeyDown is
delivered straight to it without first running shortcut →
intent → action resolution. The node is a keyboard capture
surface: it wants every keystroke (including chords the host app
binds as Shortcuts — Ctrl+C, Ctrl+W, Alt+<letter>, …).
Used by a terminal emulator (which must forward Ctrl+C to the
child process, not trigger the app’s copy shortcut), a game
viewport, or a vim-mode editor. Honored by dispatch_event_impl,
which skips the shortcut block for a focused capture node.
Ctrl+Tab / Ctrl+Shift+Tab are reserved: dispatch_event_impl
cycles focus on that chord before dispatching to a focused capture
node, so no capture surface can trap the keyboard (WCAG 2.1.2).
Escape is not reserved — overlay back-navigation runs ahead of the
check only while an overlay is open, so a capture surface below no
overlay does see Escape. Default false.
hit_transparent: boolWhen true, this widget AND its entire subtree are invisible to
hit-testing: the recursion returns immediately without descending
into children, so the point falls through to whatever sits
behind. Unlike event_pass_through
(which is per-node — descendants stay hittable), this excludes
the whole subtree. Use for purely decorative overlays whose
children are themselves widgets — a count badge over a button, a
watermark, a status dot — so they never steal clicks meant for
the control underneath. Default false.
hit_slop: Option<HitSlop>Per-node override of the miss-only slop this node may earn, set via
.hit_slop(..). Second link of the precedence chain — it beats the
widget’s own Widget::hit_slop and the density default, and loses only
to no_hit_slop. None (the default) defers to
the widget, then to the density.
no_hit_slop: boolWhen true, this node is excluded from both hit-widening
mechanisms: it earns no slop outset in the miss-only pass, and its
Widget::hit_outset is ignored inside the exact pass. The head of the
precedence chain, set via .no_hit_slop().
Per-node, not per-subtree: a descendant may still widen. Excluding a
whole subtree from hit-testing is
hit_transparent’s job, and excluding a region
that hosts foreign content (a WebView surface) is exactly this flag on
that one node. Default false.
last_painted_epoch: u64The WidgetTree::paint_epoch at which this widget’s bounds were
last observed inside the window viewport by the paint pass.
The animation scheduler uses this to pause looping animations
for offscreen widgets: an animation whose
last_painted_epoch + 1 < tree.paint_epoch is considered
off-screen and skipped. 0 means “not yet painted”; visibility is
waived wholesale while tree.paint_epoch is itself 0, which keeps
headless tests (no render() call) from regressing.