Skip to content

tooltip: Make show delay and grace period configurable with TooltipDefaults - #3376

Merged
madcodelife merged 2 commits into
mainfrom
tooltip-show-delay
Oct 6, 2026
Merged

madcodelife merged 2 commits into
mainfrom
tooltip-show-delay

Conversation

@madcodelife

@madcodelife madcodelife commented Oct 6, 2026 •

Copy link
Copy Markdown
Member

Description

Managed tooltips (the ones components set up through .tooltip(), shown by the per-window TooltipOverlay) had their timing hard-coded in gpui-base: a 500 ms show delay and a 300 ms grace period. Applications could not change either.

  • Application-wide: gpui_base::TooltipDefaults holds the show delay and grace period and is installed as a global, following the TextViewDefaults pattern. TooltipOverlay reads it on every show and hide request, so installing new defaults also applies to windows that are already open. Without it, timing is unchanged.
  • Per trigger: TooltipRequest::with_show_delay overrides the show delay for one request. The components with built-in tooltips expose it as tooltip_show_delay. A zero delay shows the tooltip immediately instead of going through a timer.
  • The grace period stays application-wide only: it governs moving from one trigger to another, so a per-trigger value has no clear meaning.
gpui_kit::init(cx);
TooltipDefaults::new()
    .with_show_delay(Duration::from_millis(300))
    .with_grace_period(Duration::from_millis(200))
    .install(cx);

Button::new("help")
    .tooltip("Help")
    .tooltip_show_delay(Duration::ZERO)

Direct GPUI .tooltip() calls (including Attachment's tooltip) bypass TooltipOverlay and are not affected; they keep using GPUI's own .tooltip_show_delay(). The docs say so.

TooltipRequest's setters now use the with_ prefix required for public data types with non-boolean fields: placement becomes with_placement and stays as a deprecated alias.

The Tooltip story gains a "Show delay" section with immediate, default and 1 s triggers in one row. The English and Chinese Tooltip docs (component and Base primitive) describe the timing and both settings.

This is an AI-assisted implementation.

Screenshot

Screen.Recording.2026-10-06.at.14.45.01.mov

Public API

gpui-base

  • gpui_base::TooltipDefaults — application-wide timing for tooltips shown through TooltipOverlay. Clone + Copy + Debug + PartialEq + Eq + Default; implements Global.
  • TooltipDefaults::new() -> Self — the Base defaults: 500 ms show delay, 300 ms grace period.
  • TooltipDefaults::with_show_delay(self, delay: Duration) -> Self — sets how long the pointer must rest on a trigger before its tooltip shows.
  • TooltipDefaults::with_grace_period(self, period: Duration) -> Self — sets how long a tooltip stays after the pointer leaves; entering another trigger within it switches immediately.
  • TooltipDefaults::show_delay(&self) -> Duration — reads the show delay.
  • TooltipDefaults::grace_period(&self) -> Duration — reads the grace period.
  • TooltipDefaults::install(self, cx: &mut App) — installs the defaults for the whole application.
  • TooltipDefaults::global(cx: &App) -> Self — returns the installed defaults, or the Base ones when none were installed.
  • TooltipRequest::with_show_delay(self, delay: Duration) -> Self — overrides TooltipDefaults::show_delay for this request.
  • TooltipRequest::with_placement(self, placement: Placement) -> Self — prefers a side for the tooltip; replaces placement.
  • TooltipRequest::placement — now #[deprecated], forwarding to with_placement.

gpui-component

  • gpui_component::tooltip::TooltipDefaults — re-export of gpui_base::TooltipDefaults.
  • Button::tooltip_show_delay(self, delay: Duration) -> Self — overrides the show delay of the button's tooltip.
  • Toggle::tooltip_show_delay(self, delay: Duration) -> Self — same, for Toggle.
  • Switch::tooltip_show_delay(self, delay: Duration) -> Self — same, for Switch.
  • Checkbox::tooltip_show_delay(self, delay: Duration) -> Self — same, for Checkbox.
  • Radio::tooltip_show_delay(self, delay: Duration) -> Self — same, for Radio.
  • Clipboard::tooltip_show_delay(self, delay: Duration) -> Self — same, for Clipboard.
  • InputGroupButton::tooltip_show_delay(self, delay: Duration) -> Self — same, for InputGroupButton.

Breaking Changes

TooltipRequest::placement is deprecated in favor of with_placement. It still compiles and behaves the same, with a deprecation warning.

- TooltipRequest::new(bounds, build).placement(Placement::Right)
+ TooltipRequest::new(bounds, build).with_placement(Placement::Right)

How to Test

  • cargo test -p gpui-base --lib tooltip — 5 passed, including the new show_delay_follows_defaults_and_request_override: with a 100 ms default the tooltip is absent at 99 ms and present at 100 ms, and a zero with_show_delay shows it synchronously.
  • cargo test -p gpui-component --lib — 603 passed (test_button_builder covers tooltip_show_delay).
  • RUSTFLAGS="-D warnings" cargo clippy -p gpui-base -p gpui-component --lib --tests -- --deny warnings and cargo clippy -p gpui-component-story -- --deny warnings — passed.
  • cargo fmt --check — passed.
  • cargo run, open Tooltip → Show delay on macOS: Immediate shows at once, Default after about 0.5 s, Slow after about 1 s, and moving between them within the grace period switches without waiting.

Checklist

  • I have read the CONTRIBUTING document and followed the guidelines.
  • Reviewed the changes in this PR and confirmed AI generated code (If any) is accurate.
  • Passed cargo run for story tests related to the changes.
  • Tested macOS, Windows and Linux platforms performance (if the change is platform-specific)

madcodelife and others added 2 commits October 6, 2026 14:45
…efaults`

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@madcodelife
madcodelife merged commit c0bebdc into main Oct 6, 2026
12 checks passed
@madcodelife
madcodelife deleted the tooltip-show-delay branch October 6, 2026 08:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant