Omniscio documentation
Browse all documentation
  1. Getting Started13
  2. Sessions & Agents121
  3. Inbox & Notifications65
  4. Projects & Tasks95
  5. Automation & Scheduling82
  6. Knowledge & Memory26
  7. AI Features66
  8. Integrations101
  9. Plugins & Marketplace34
  10. Cloud & Teams57
  11. Settings & Customization62
  12. Account & Billing28
  13. Troubleshooting86
  14. CLI & API Reference24
  15. Legal & Policies4
  16. Uncategorised17

Tooltips and key-caps

Hovering anything in Omniscio shows the app's own dark, themed bubble instead of the operating system's plain one. It waits a moment before appearing, follows a row as you scroll, and — on a control that has a keyboard shortcut — draws that shortcut's current key as a key-cap. The layer is installed per window, so it works in every panel, plugin panels included.

What it is

The tooltip layer is the thing that makes every hover description in the app look and behave the same, whichever way it was written. It is not a component you have to remember to use at each call site — it is a single listener that watches the whole window and upgrades whatever a control already says.

  • What it reads. In order of precedence: a control's plain hint text; an icon-only button's accessible name (its aria-label), which is what gives a bare icon button a description at all; the marker a hotkey button carries; and finally the standard accessibility shortcut attribute.
  • What it is not. It is not the keyboard-shortcut registry — it only displays keys. Rebinding still lives in keyboard-shortcuts.md.
  • Rich content uses the shared component. Where a description needs markup, a multiline block or a link inside it, the app uses a portaled component that draws the identical look; a parity test keeps the two in step.

Where to find it

  • Anywhere you hover — sidebar rows, toolbar and header buttons, tabs, menu items, settings rows, and panels built as plugins. Nothing has to opt in.
  • Settings → Appearance — the bubble's background, border and text colours travel with your theme, so a custom theme restyles them along with everything else (see visual-themes.md).
  • By keyboard — Tab to a control and its description appears, the same as hovering it.
  • The small "i" icon beside a setting or a label opens a longer explanation on hover or focus — that is the same layer, drawing a multiline bubble.
  • On a phone or tablet, there is no hover: the bubble never appears, and the description stays available to screen readers through the same accessible name.

How it behaves

It waits before it appears, and it is suppressed, not doubled. The bubble needs the pointer to settle on a control for a moment. The system's own tooltip never flashes alongside it: the moment the app claims a control, the real hint is stashed and blanked, and it is restored when you move away, click, or leave the window. If a re-render writes the text back mid-hover, it is blanked again — so a live-updating button cannot leak the system tooltip through.

It follows the list. Scroll while the bubble is up and it does not blink out: it tracks the row it belongs to. If a different described row scrolls under a stationary pointer, the description hands over to that row instead. If nothing described is under the pointer any more, it releases.

It stays on screen. A bubble near a window edge is repositioned so it is never cut off. Short text stays on one line; a longer hint wraps into a block instead of stretching across the screen.

The key is shown exactly once. A button that declares a hotkey gets its current key drawn as a key-cap — and if the button's own label also spells that key out, the written copy is dropped rather than shown twice. Key-caps are live and rebind-aware: change a binding under Settings → Keyboard shortcuts and the cap shows the new key immediately, on macOS in that platform's own notation.

Where it does not apply. A sandboxed plugin page gets the same styled bubble but never a key-cap (it is handed no key-cap builder), and an SVG element's own child <title> keeps its native behaviour.

For agents

The two halves

  • The interceptor: native-title-interceptor.ts — a document-level pointerover / focusin listener, installed by installNativeTitleInterceptor(target, opts), idempotent per document (__amcNativeTitleInterceptorInstalled) with a deferred install when document.body is not ready (the plugin preload runs at document start).
  • The component: Tooltip.tsx — @building-block group=ui-components reuse=Tooltip when="a portaled hover/focus help bubble — never a raw title attribute" contract=tooltip-adoption-contract; also InfoTooltip.tsx. 119 files import the component.
  • They deliberately do not share code (different runtimes — vanilla vs React); a parity test keeps their look in step, so a fix to one is not a fix to the other.

Resolvers and constants

Precedence in resolveHoverTarget: resolveTitleTarget → resolveAriaLabelTarget (selector button, [role="button"], a, non-empty aria-label, no visible text) → resolveHotkeyMarkerTarget (data-hotkey-action / data-hotkey-tasksv2, literals drift-asserted against hotkey-action-attr.ts) → resolveKeyshortcutsTarget (aria-keyshortcuts). A claim stashes and blanks the title, restoring it on leave, pointer-down and blur; a MutationObserver scoped to the hovered element re-blanks a rewritten title; scroll re-resolves rather than restoring. OPT_OUT_ATTR = 'data-native-title', SHOW_DELAY_MS = 400, MULTILINE_THRESHOLD = 60. The bubble is position: fixed, zIndex: 2147483646, pointerEvents: none, backdrop-filter: blur(16px), max-width: 20rem, role="tooltip", with literal fallbacks --tooltip-bg / --tooltip-border / --tooltip-fg / --shadow-tooltip.

Key-caps

opts.buildHotkeyHint / opts.buildKeyshortcutsHint are injected by each window; main.tsx passes the app builders, the plugin bridge (plugin-bridge-preload.ts) passes none, and a HUD that wants no caps passes { buildHotkeyHint: () => null } (recording-hud.tsx). The builder is appHotkeyBindingsForEl in app-hotkey-hint.ts. Theme mapping (tooltipBg → --tooltip-bg, tooltipBorder → --tooltip-border, tooltipText → --tooltip-fg) lives in custom-theme-service.ts.

Contract

Rules I1–I20 and their guards: tooltip-adoption-contract.md; the mechanism map is tooltips-system.md.

Related

Last verified 2026-10-06