From 91f1e72cd5a11ea6c0b569fcff039e813dee2014 Mon Sep 17 00:00:00 2001 From: Neil <4138956+nwparker@users.noreply.github.com> Date: Fri, 24 Apr 2026 22:14:30 -0700 Subject: [PATCH] fix(editor): stop infinitely flashing find-widget button tooltips (#1077) --- src/renderer/src/assets/main.css | 36 ++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/renderer/src/assets/main.css b/src/renderer/src/assets/main.css index 756b1b2c55c..52edf54fb3c 100644 --- a/src/renderer/src/assets/main.css +++ b/src/renderer/src/assets/main.css @@ -896,6 +896,42 @@ box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--warning, #f59e0b) 52%, transparent); } +/* Why: Monaco's find-widget button tooltips (Close, Find in Selection, etc.) + render inside a `.context-view` wrapper → `.workbench-hover-container` → + `.workbench-hover.compact`, positioned above the target button. The wrapper's + bounding box (z-index 2576, `pointer-events: auto`) overlaps the button hit + area, so as the tooltip appears it fires `mouseleave` on the button → 200ms + debounce → hover disposes → mouse is again "over" the button → `mouseover` + re-fires a new tooltip → loop. The visible effect is an infinitely flashing + tooltip that also blocks clicks on the button beneath it. The overlap is + only reliably reproducible when the right sidebar is open, because the find + widget's x-position shifts the wrapper onto the button rect; with the + sidebar closed the wrapper often lands slightly offset and doesn't intercept. + + These are compact tooltips (`HoverStyle.Pointer` → `.workbench-hover.compact`) + configured with `hideOnHover: true`, so the CompositeMouseTracker only tracks + the target element — not the wrapper. Making the entire wrapper chain + non-interactive breaks the overlap feedback loop without affecting tracker + logic, keyboard focus traps, or interactive markdown hovers (which are never + `.compact`). The `:has()` selector ensures we only disable pointer events on + context-views that actually contain a compact hover, leaving menus, dropdown + popups and other context-view consumers untouched. */ +.context-view:has(> .workbench-hover-container > .workbench-hover.compact), +.workbench-hover-container:has(> .workbench-hover.compact) { + pointer-events: none; +} + +/* Why: compact hovers for simple label strings (e.g. "Find in Selection (⌥⌘L)") + get `white-space: pre-wrap` inline-set by Monaco, so when the tooltip lands + near the viewport edge its max-width clamps and the label wraps to 2–3 lines, + pushing the tooltip down over the find-widget buttons. These labels are + single-line by design; forcing nowrap keeps the tooltip on one line and lets + the positioning logic flip/shift as needed to fit. Only applies to compact + hovers — markdown hovers still wrap normally. */ +.workbench-hover.compact .hover-contents { + white-space: nowrap !important; +} + /* ── Update card animations ───────────────────────────────────────── */ @keyframes update-card-enter {