Expand description
Central tooltip controller — the first-class, wrapper-free tooltip path.
Any widget can declare hover help by storing a string in its
WidgetBase::tooltip (via
Widget::with_tooltip). Once per
frame the App finds the deepest hovered widget whose
tooltip_text is Some and feeds it
to [drive]. This module owns the single, app-wide state machine that
decides when a tip is visible and, while it is, submits it to the shared
render queue so it paints in the global-overlay pass
above all clips.
§One tip, app-wide
There is exactly one controller (a thread-local — the GUI is single
threaded, matching [super::timings] / [super::render]). Because it keys
off the deepest tipped widget, only one tip is ever live. It shares the
reshow window in [super::timings] with the legacy Tooltip
wrapper, so moving between a wrapped control and a with_tooltip control
still gets the fast “reshow” delay and never shows two tips at once.
§Timing
The state machine mirrors Tooltip::update_visibility:
initial delay → reshow delay when warm → autopop dismiss → hide-on-press /
hide-on-leave. It reuses [super::timings] wholesale rather than
duplicating the delays.
§Font — host contract (required)
The tip text is painted with the crate-wide font override
(font_settings::current_system_font),
read live on every paint so a tip re-renders in the new face the instant the
host swaps the system font. This library is deliberately font-free: it
ships no bundled fallback. Every host MUST call
font_settings::set_system_font with
a real font at startup, before any tip can appear. When no font is installed
the state machine still runs (timing, visibility) but [Controller::submit]
paints nothing — the tip is silently invisible. That is a host-setup bug,
not a headless-only edge case: the demos install their default font in
demo-ui::font_init::init precisely so tips are never blank. Tests install a
font explicitly via the same API.