Skip to content

feat(tooltip): add preferred placement and hide_active_tooltip API#2464

Open
gaoyia wants to merge 1 commit into
longbridge:mainfrom
gaoyia:patch-4
Open

feat(tooltip): add preferred placement and hide_active_tooltip API#2464
gaoyia wants to merge 1 commit into
longbridge:mainfrom
gaoyia:patch-4

Conversation

@gaoyia

@gaoyia gaoyia commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

Add TooltipPreferredPlacement (Auto, Left, Right, Above, Below, AboveCursor) so managed tooltips can be positioned relative to their trigger, with Auto keeping the existing above/below flip behavior. AboveCursor anchors the tooltip above the pointer and is useful for extremely narrow windows.

Also expose:

  • Button::tooltip_placement to choose a placement per button.
  • hide_active_tooltip to immediately dismiss the managed tooltip on the current window (e.g. before opening a menu), and dismiss tooltips on right/middle mouse down in addition to left.

The default placement is Auto, so existing call sites keep their current behavior.

Description

Managed tooltips (owned by each window's Root via TooltipOverlay) could previously only appear above or below their trigger, chosen automatically by available space. This is insufficient for extremely narrow windows, where there is no room above or below the trigger and the tooltip gets clipped.

This PR adds an opt-in TooltipPreferredPlacement so a tooltip can be explicitly placed to the Left, Right, Above, Below, or anchored AboveCursor. Internals:

  • tooltip_overlay_position now dispatches on the preferred placement; the previous auto-flip logic is preserved verbatim as tooltip_overlay_position_auto and used by Auto.
  • Left/Right/Above/Below reuse the existing four-edge clamp (clamp_tooltip_bounds).
  • AboveCursor uses a dedicated clamp_tooltip_above_cursor that clamps horizontally and against the bottom edge, but intentionally allows overflow past the top edge so the tooltip can fully render out of a short window.
  • The preferred placement and the cursor position (read via window.mouse_position() on hover) are threaded through TooltipContent and TooltipOverlayPositioner.

hide_active_tooltip is exposed to let callers dismiss the current tooltip immediately (e.g. before opening a menu). Managed elements now dismiss the tooltip on right/middle mouse down as well as left.

Auto is the default everywhere, so existing call sites are unaffected.

Break Changes

None.

How to Test

  • cargo test -p gpui-component — includes new unit tests tooltip_overlay_position_left_of_trigger and tooltip_overlay_position_above_cursor, alongside the existing placement tests.
  • cargo run — open the story gallery and hover tooltip triggers to confirm default (Auto) behavior is unchanged.
  • Manually verify a button configured with .tooltip_placement(TooltipPreferredPlacement::Left) shows its tooltip to the left, and that AboveCursor renders correctly near a screen edge / in a short window.

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)

Add `TooltipPreferredPlacement` (`Auto`, `Left`, `Right`, `Above`,
`Below`, `AboveCursor`) so managed tooltips can be positioned relative
to their trigger, with `Auto` keeping the existing above/below flip
behavior. `AboveCursor` anchors the tooltip above the pointer and is
useful for extremely narrow windows.

Also expose:
- `Button::tooltip_placement` to choose a placement per button.
- `hide_active_tooltip` to immediately dismiss the managed tooltip on
  the current window (e.g. before opening a menu), and dismiss tooltips
  on right/middle mouse down in addition to left.

The default placement is `Auto`, so existing call sites keep their
current behavior.
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