pub struct OverlayManager { /* private fields */ }Implementations§
Source§impl OverlayManager
impl OverlayManager
Sourcepub fn position_overlays(
&mut self,
anchor_bounds_fn: impl Fn(WidgetId) -> Option<Rect>,
viewport: impl Into<OverlayViewport>,
layout_direction: LayoutDirection,
)
pub fn position_overlays( &mut self, anchor_bounds_fn: impl Fn(WidgetId) -> Option<Rect>, viewport: impl Into<OverlayViewport>, layout_direction: LayoutDirection, )
Compute overlay positions based on anchor bounds.
Called after layout to position overlays correctly.
viewport is (width, height) used for clamping overlays to the visible area.
anchor_bounds_fn returns None when the anchor widget is no
longer in the arena (destroyed by a host’s rebuild while the
overlay is still up). In that case the overlay’s bounds are
left untouched — keeping it at its last valid position rather
than collapsing to the (0,0) origin from a Rect::ZERO
fallback.
Source§impl OverlayManager
impl OverlayManager
pub fn new() -> Self
Sourcepub fn version(&self) -> &Signal<u64>
pub fn version(&self) -> &Signal<u64>
Reactive handle bumped on every overlay mutation (show /
dismiss / cascade). Cheap clone. Same shape as
crate::shortcut::ShortcutRegistry::version.
Sourcepub fn show(&mut self, request: OverlayRequest) -> OverlayId
pub fn show(&mut self, request: OverlayRequest) -> OverlayId
Show a new overlay. Returns the OverlayId.
Sourcepub fn show_in_band(
&mut self,
request: OverlayRequest,
band: OverlayBand,
) -> OverlayId
pub fn show_in_band( &mut self, request: OverlayRequest, band: OverlayBand, ) -> OverlayId
Show a new overlay in an explicit z-band.
show is this with OverlayBand::Standard. The other
band exists for the touch text affordances — see
text_affordance — which must sit
under every menu and survive the presses that drive them.
A band below the top is inserted mid-stack, so
set_top_focus_restore — which addresses
the top of the stack — does not describe it. That is correct rather than
a limitation: an affordance in this band never takes focus from the
editor it belongs to, so it has no focus to restore.
Sourcepub fn show_for(
&mut self,
request: OverlayRequest,
duration: Duration,
) -> OverlayId
pub fn show_for( &mut self, request: OverlayRequest, duration: Duration, ) -> OverlayId
Show a new overlay that dismisses automatically after duration.
Sourcepub fn fade_duration(&self, id: OverlayId) -> Option<Duration>
pub fn fade_duration(&self, id: OverlayId) -> Option<Duration>
Public read-only accessor for the fade state. Returns the
duration if fade is configured, None otherwise. Used by
WidgetTree::dismiss_overlay to know whether to leave the
content active for the fade-out window.
pub fn next_auto_dismiss_deadline(&self) -> Option<Instant>
Sourcepub fn next_pointer_leave_deadline(&self) -> Option<Instant>
pub fn next_pointer_leave_deadline(&self) -> Option<Instant>
Earliest instant at which a DismissBehavior::PointerLeave overlay
whose leave-grace is already running becomes due for dismissal.
The counterpart of
next_auto_dismiss_deadline for the
hover-opened overlays (tooltips, hover submenus). Without it the event
loop has no reason to wake between the pointer’s last motion event and
the end of the grace window: next_timer_deadline would return None,
winit would sit in ControlFlow::Wait, and the overlay would stay on
screen until some unrelated input happened to redraw the window.
Sourcepub fn pause_auto_dismiss(&mut self, id: OverlayId)
pub fn pause_auto_dismiss(&mut self, id: OverlayId)
Pause the auto-dismiss timer for an overlay shown with
show_for. The remaining time
(auto_dismiss_after - elapsed) is stashed; subsequent calls
to next_auto_dismiss_deadline
ignore this overlay until resume_auto_dismiss
is called. Idempotent — pausing an already-paused overlay is
a no-op (the originally-stashed remaining time is preserved).
Used by ToastHost to implement hover-pause: when the user
is hovering over any live toast, all live toasts pause their
timers so the user can read each one without losing the
notification they’re about to act on.
No-op on overlays without auto_dismiss_after (persistent
overlays don’t have a timer to pause) and on unknown ids.
Sourcepub fn resume_auto_dismiss(&mut self, id: OverlayId)
pub fn resume_auto_dismiss(&mut self, id: OverlayId)
Resume an auto-dismiss timer paused via
pause_auto_dismiss. The stashed
remaining time becomes the new auto_dismiss_after, and
shown_at_real / shown_at_sim are reset to now so the
deadline computation works correctly. Idempotent — resuming
an un-paused overlay is a no-op.
Sourcepub fn is_auto_dismiss_paused(&self, id: OverlayId) -> bool
pub fn is_auto_dismiss_paused(&self, id: OverlayId) -> bool
Whether the auto-dismiss timer for an overlay is currently paused.
false for overlays without auto_dismiss_after, unknown ids,
and overlays whose timer is running.
Sourcepub fn bounds_for(&self, id: OverlayId) -> Option<Rect>
pub fn bounds_for(&self, id: OverlayId) -> Option<Rect>
Public accessor for an overlay’s currently-laid-out screen
rect. Returns None for unknown ids and for overlays that
have not yet been through a layout pass (bounds == Rect::ZERO
in that case, but we still hand it back — callers should not
trust a zero-sized rect for hit-test geometry).
Used by MenuList’s
safe-triangle submenu hover gate, which needs the open
submenu’s near-edge to test whether the cursor trajectory is
still headed toward the submenu.
Sourcepub fn dismiss_with_focus_restore(
&mut self,
id: OverlayId,
) -> (Vec<WidgetId>, Option<WidgetId>)
pub fn dismiss_with_focus_restore( &mut self, id: OverlayId, ) -> (Vec<WidgetId>, Option<WidgetId>)
Dismiss an overlay and all its children (cascade), returning the dismissed content widget IDs and the overlay’s focus_restore target.
Sourcepub fn dismiss_with_focus_restore_because(
&mut self,
id: OverlayId,
reason: DismissReason,
) -> (Vec<WidgetId>, Option<WidgetId>)
pub fn dismiss_with_focus_restore_because( &mut self, id: OverlayId, reason: DismissReason, ) -> (Vec<WidgetId>, Option<WidgetId>)
dismiss_with_focus_restore,
saying why.
Sourcepub fn dismiss_descendants_of(
&mut self,
parent: OverlayId,
preserve: Option<OverlayId>,
) -> (Vec<WidgetId>, Option<WidgetId>)
pub fn dismiss_descendants_of( &mut self, parent: OverlayId, preserve: Option<OverlayId>, ) -> (Vec<WidgetId>, Option<WidgetId>)
Dismiss all descendant overlays of parent, optionally preserving the
subtree rooted at preserve.
Sourcepub fn update_placement(&mut self, id: OverlayId, placement: OverlayPlacement)
pub fn update_placement(&mut self, id: OverlayId, placement: OverlayPlacement)
Update the placement of an existing overlay.
Sourcepub fn set_parent_overlay(&mut self, id: OverlayId, parent: Option<OverlayId>)
pub fn set_parent_overlay(&mut self, id: OverlayId, parent: Option<OverlayId>)
Update the parent-overlay link of an existing overlay. Used by the
modal-presentation pipeline to retroactively attach the dialog
scrim (pushed first, below the modal in the stack) to the modal
(pushed second) so that dismissing the modal cascades through
dismiss_immediate and also dismisses the scrim.
Sourcepub fn dismiss(&mut self, id: OverlayId) -> Vec<WidgetId>
pub fn dismiss(&mut self, id: OverlayId) -> Vec<WidgetId>
Dismiss an overlay and all its children (cascade). Returns the content widget IDs of all dismissed overlays.
Fade-aware: when an overlay was shown with
OverlayRequest::with_fade and is not yet fading out, this
method instead kicks off the fade-out tween on the framework-
owned opacity signal and marks dismiss_at, returning an
empty vec — the actual stack removal and content dormancy
happen later via
process_pending_fade_dismissals.
Cascaded descendants vanish with the leaf’s fade-out (they’re
typically submenus the user dismissed via the leaf, and a
per-descendant tween would compete with the leaf’s).
Sourcepub fn dismiss_because(
&mut self,
id: OverlayId,
reason: DismissReason,
) -> Vec<WidgetId>
pub fn dismiss_because( &mut self, id: OverlayId, reason: DismissReason, ) -> Vec<WidgetId>
dismiss, saying why — which is what the overlay’s
on_dismiss is handed.
Sourcepub fn process_pending_fade_dismissals(
&mut self,
now: Instant,
) -> Vec<(OverlayId, Vec<WidgetId>, Option<WidgetId>)>
pub fn process_pending_fade_dismissals( &mut self, now: Instant, ) -> Vec<(OverlayId, Vec<WidgetId>, Option<WidgetId>)>
Drain overlays whose real-clock fade-out tween has completed.
Call from the live layout pass; the framework dormants the
returned content widget IDs and restores focus where
appropriate. Each entry is
(overlay_id, dismissed_content_ids, focus_restore) so the
layout pass can run the same dormant-and-restore-focus flow
it uses for
dismiss_with_focus_restore.
Sourcepub fn process_pending_fade_dismissals_sim(
&mut self,
now_sim: Instant,
) -> Vec<(OverlayId, Vec<WidgetId>, Option<WidgetId>)>
pub fn process_pending_fade_dismissals_sim( &mut self, now_sim: Instant, ) -> Vec<(OverlayId, Vec<WidgetId>, Option<WidgetId>)>
Sim-clock variant for deterministic headless tests. Same
shape as process_pending_fade_dismissals
but reads dismissing_started_sim.
Sourcepub fn next_fade_dismiss_deadline(&self) -> Option<Instant>
pub fn next_fade_dismiss_deadline(&self) -> Option<Instant>
Earliest real-clock deadline at which a fading-out overlay wants to finish its dismissal. Used by the event-loop wakeup logic to schedule the next frame.
Sourcepub fn dismiss_top(
&mut self,
) -> Option<(OverlayId, Vec<WidgetId>, Option<WidgetId>)>
pub fn dismiss_top( &mut self, ) -> Option<(OverlayId, Vec<WidgetId>, Option<WidgetId>)>
Dismiss the topmost overlay unconditionally (e.g., ArrowLeft for submenu cascading). Returns the overlay ID, content widget IDs, and focus_restore target.
Sourcepub fn dismiss_top_because(
&mut self,
reason: DismissReason,
) -> Option<(OverlayId, Vec<WidgetId>, Option<WidgetId>)>
pub fn dismiss_top_because( &mut self, reason: DismissReason, ) -> Option<(OverlayId, Vec<WidgetId>, Option<WidgetId>)>
dismiss_top, saying why.
Sourcepub fn try_dismiss_top_on_escape(
&mut self,
) -> Option<(OverlayId, Vec<WidgetId>, Option<WidgetId>)>
pub fn try_dismiss_top_on_escape( &mut self, ) -> Option<(OverlayId, Vec<WidgetId>, Option<WidgetId>)>
Try to dismiss an overlay on Escape, respecting DismissBehavior.
Scans the stack top-down for the first overlay that Escape may close,
rather than consulting only stack.last(). Two reasons:
- A hover-opened overlay (
PointerLeave— every shown tooltip) is Escape-dismissible. WCAG 2.2 SC 1.4.13(a) requires content shown on hover to be dismissible without moving the pointer, and Escape is that mechanism; previously no key could close a plain tooltip. - A tooltip lives on the same stack as whatever it is anchored inside. Hovering a menu item long enough to raise its tooltip put a non-Escape overlay on top, so Escape silently did nothing at all until the tooltip’s own 100 ms leave-grace expired — the keystroke was swallowed, not forwarded to the menu underneath.
Manual overlays still block the scan: they are modal-ish by
construction and own the keystroke.
Sourcepub fn set_top_focus_restore(&mut self, focus_restore: WidgetId)
pub fn set_top_focus_restore(&mut self, focus_restore: WidgetId)
Set the focus_restore target for the topmost overlay.
Sourcepub fn dismiss_all(&mut self) -> Vec<WidgetId>
pub fn dismiss_all(&mut self) -> Vec<WidgetId>
Dismiss all overlays.
Returns the content widget IDs of all dismissed overlays.
Fires every dismissed overlay’s on_dismiss callback after the
stack is cleared — same contract as dismiss,
so wrappers like PopoverButton’s
popover_open signal flip back to false when a MenuItem
fires ctx.dismiss_all_overlays(). Without this, the trigger’s
next click would observe stale-true and silently retoggle
instead of reopening the menu.
Sourcepub fn dismiss_all_because(&mut self, reason: DismissReason) -> Vec<WidgetId>
pub fn dismiss_all_because(&mut self, reason: DismissReason) -> Vec<WidgetId>
dismiss_all, saying why.
Sourcepub fn dismiss_except(&mut self, keep: &HashSet<WidgetId>) -> Vec<WidgetId>
pub fn dismiss_except(&mut self, keep: &HashSet<WidgetId>) -> Vec<WidgetId>
Dismiss every overlay whose content is not in keep, running each
dismissed overlay’s on_dismiss. Used when opening a context menu: any
overlay that contains the right-clicked widget (e.g. the modal the editor
lives in) is kept, so the menu doesn’t tear down its own host.
Sourcepub fn dismiss_except_because(
&mut self,
keep: &HashSet<WidgetId>,
reason: DismissReason,
) -> Vec<WidgetId>
pub fn dismiss_except_because( &mut self, keep: &HashSet<WidgetId>, reason: DismissReason, ) -> Vec<WidgetId>
dismiss_except, saying why.
Sourcepub fn active_content_ids(&self) -> Vec<WidgetId>
pub fn active_content_ids(&self) -> Vec<WidgetId>
Get all active overlay content widget IDs (for rendering).
Sourcepub fn active_ids(&self) -> Vec<OverlayId>
pub fn active_ids(&self) -> Vec<OverlayId>
Get all active overlay IDs (for testing/querying). Excludes overlays currently fading out — once a dismiss has been requested the overlay is conceptually gone (the visible opacity tween is on the way to 0 and the deferred removal will fire on the next layout pass after the fade-out completes), so user code asking “is this overlay still up?” gets the expected answer.
Sourcepub fn anchor_for(&self, id: OverlayId) -> Option<WidgetId>
pub fn anchor_for(&self, id: OverlayId) -> Option<WidgetId>
Get the anchor widget for an overlay.
Sourcepub fn interactive_rects(&self) -> Vec<Rect>
pub fn interactive_rects(&self) -> Vec<Rect>
Screen rects of every overlay that is currently interactive —
open and not yet fading out, the same predicate
hit_test uses to route pointer events.
Zero-area entries are skipped: an overlay shown this frame has
not been through its first layout pass yet (bounds == Rect::ZERO), and a degenerate rect must not be mistaken for a
hit at the origin.
Consumed by the paint pass, which hands the list to
Widget::after_paint via
WidgetTreeView so chrome aggregators can subtract floating
content from the regions they publish — TitleBar carves these
out of the OS caption so an overlay above the title bar (the
hamburger MenuBar’s revealed bar, a tall modal) stays
clickable on Windows instead of dragging the window.
Sourcepub fn hit_test(&self, point: Point) -> Option<OverlayId>
pub fn hit_test(&self, point: Point) -> Option<OverlayId>
Check if a point hits any overlay (topmost first). Returns the overlay ID if hit, None if the point is outside all overlays.
Overlays whose fade-out has begun are skipped — the same predicate
active_ids uses. A dismissed-but-still-fading
overlay lingers in the stack until
process_pending_fade_dismissals
removes it; treating it as hittable would route clicks into the
vanishing content (and suppress outside-click dismissal of the
overlays beneath it) for the whole fade duration.
Sourcepub fn handle_click_outside(
&mut self,
point: Point,
) -> (Vec<WidgetId>, Option<WidgetId>, Vec<WidgetId>)
pub fn handle_click_outside( &mut self, point: Point, ) -> (Vec<WidgetId>, Option<WidgetId>, Vec<WidgetId>)
Handle a click-outside event: if the click is outside all overlays
with ClickOutside dismiss behavior, dismiss them.
Returns the content widget IDs of dismissed overlays (empty if none)
and the focus-restore target — the widget that was focused before
the bottommost dismissed overlay opened. Topmost overlays’
focus_restore would point inside an overlay that’s also being
dismissed in the same pass, which would leave focus on a
dormant widget; the bottommost target represents focus before
any of the dismissed overlays opened. Aligns the click-outside
path with the Esc / ArrowLeft-cascade paths, both of which
already restore focus from the dismissed overlay.
The third return value lists the anchor widgets of the dismissed
click-opened overlays (ClickOutside / EscapeOrClickOutside).
The dispatcher consumes a primary press that lands on one of these
anchors so the trigger merely closes its overlay rather than
reopening it; every other dismiss-press falls through to the widget
under the cursor (so one click both dismisses the overlay and
activates the control beneath). Hover-opened (PointerLeave)
overlays contribute no anchor — a press on their anchor passes
through, e.g. clicking a button that still has its tooltip up.
Sourcepub fn dismiss_outside_press(
&mut self,
point: Point,
busy: &[Point],
) -> (Vec<WidgetId>, Option<WidgetId>, Vec<WidgetId>)
pub fn dismiss_outside_press( &mut self, point: Point, busy: &[Point], ) -> (Vec<WidgetId>, Option<WidgetId>, Vec<WidgetId>)
handle_click_outside with the points at
which other contacts are holding a live press.
A press is only “outside” relative to the overlays nobody else is working in. A second finger landing on the page while the first is dragging a menu’s scrollbar is not a dismissal gesture; it is the second finger of a two-finger interaction, and closing the menu under the first one takes the interaction away mid-flight. Each busy point raises the floor of the layered rule to the overlay it is inside, so overlays at or below any busy contact survive and everything above still closes.
An empty busy is the historical behaviour exactly, which is what a
mouse-only tree always passes.
Sourcepub fn arm_dismiss(
&mut self,
pointer: PointerId,
point: Point,
busy: &[Point],
) -> DismissArm
pub fn arm_dismiss( &mut self, pointer: PointerId, point: Point, busy: &[Point], ) -> DismissArm
Arm an outside press for pointer at point, to be committed on its
release.
The direct-pointer half of outside-press dismissal. A mouse dismisses on
the press and falls through, because a cursor names one pixel and the
user aimed at it; a finger covers what it is about to actuate, so a tap
that closes a menu must close only the menu. Arming defers the decision
to the release and, while it stands, withholds the Down from whatever
is beneath — so if the press is cancelled, or slid onto the very overlay
it would have closed, the whole gesture delivers nothing at all.
Returns a zeroed DismissArm and stores nothing when the press would
close no overlay: an arm that has nothing to commit must not suppress
the press beneath it.
Sourcepub fn commit_dismiss(
&mut self,
pointer: PointerId,
point: Point,
) -> (Vec<WidgetId>, Option<WidgetId>, Vec<WidgetId>)
pub fn commit_dismiss( &mut self, pointer: PointerId, point: Point, ) -> (Vec<WidgetId>, Option<WidgetId>, Vec<WidgetId>)
Complete pointer’s armed dismissal at its release point.
Returns the same triple as
handle_click_outside, empty when the
pointer holds no arm.
The release point is re-tested, and only overlays the release is still
outside are closed. That is the slide-off case: a finger that lands
beside a menu, drags onto it and lifts there has changed its mind, and
the menu it is now touching must not be the thing it closes. The
suppressed Down means nothing beneath ever saw the press either, so an
aborted commit leaves the tree exactly as it found it.
Sourcepub fn abort_dismiss(&mut self, pointer: PointerId) -> bool
pub fn abort_dismiss(&mut self, pointer: PointerId) -> bool
Drop pointer’s arm without dismissing anything. Returns whether there
was one — a cancelled press, or a contact that ended without a release.
Sourcepub fn has_armed_dismiss(&self, pointer: PointerId) -> bool
pub fn has_armed_dismiss(&self, pointer: PointerId) -> bool
Whether pointer is holding an armed dismissal.
Sourcepub fn armed_pointers(&self) -> Vec<PointerId>
pub fn armed_pointers(&self) -> Vec<PointerId>
Every pointer currently holding an arm. Used by the dispatcher to drop arms whose contact has gone away without either releasing or cancelling.
Sourcepub fn set_content_bounds(&mut self, id: OverlayId, size: Size)
pub fn set_content_bounds(&mut self, id: OverlayId, size: Size)
Set the content bounds for an overlay (after its content has been laid out).
Sourcepub fn find_by_content(&self, content_id: WidgetId) -> Option<OverlayId>
pub fn find_by_content(&self, content_id: WidgetId) -> Option<OverlayId>
Get overlay by content widget ID (for routing events to the correct overlay).
Sourcepub fn bounds_for_content(&self, content_id: WidgetId) -> Option<Rect>
pub fn bounds_for_content(&self, content_id: WidgetId) -> Option<Rect>
Convenience accessor for the safe-triangle hover gate: returns
the bounds rect of the open overlay whose root content widget
id matches content_id, or None when no such overlay is
active. Equivalent to find_by_content + bounds_for chained.
Sourcepub fn set_dismiss(&mut self, id: OverlayId, behavior: DismissBehavior)
pub fn set_dismiss(&mut self, id: OverlayId, behavior: DismissBehavior)
Change the dismiss behavior of an active overlay in place.
Used by rich tooltips that promote from “ephemeral hover” to
“sticky panel” after a dwell timer: at t=2s the tooltip calls
this to swap PointerLeave for EscapeOrClickOutside, so the
overlay stops vanishing the moment the pointer leaves the
anchor. Also cancels any in-flight pointer-leave countdown.