fix(find): the find widget's tooltips stop being clipped away (#675) - #677
Merged
Conversation
Monaco mounts the hover for a find-widget button in a `.context-view` beside the editor and places it ABOVE the target, flipping below only when the tooltip would leave the window. The widget sits a title bar's height down, so the flip never fires and the tooltip lands in the strip `.pane` and `.editor-outer` clip — and behind the fixed title bar. Drop both clips while the widget is visible, and lift `.context-view` over the title bar. Nothing else escapes: Monaco clips its own content, and the widget itself, inside `.overflow-guard`.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this is
Closes #675, reported by @khbbkhbk with two screenshots: hovering any button in the first row of the editor's find/replace bar (Ctrl+F / Ctrl+H) either showed a sliver of a tooltip or one that flickered while the pointer sat still. The second row was fine.
Tooltips on that row are now fully visible, drawn over the tab-bar strip the way VS Code draws them over its tabs, and they no longer overlap the button that summoned them.
Mechanism
Monaco's find widget draws its button tooltips through the hover service, which appends a
.context-viewnext to the editor and places it above the target.hoverWidget.js'sadjustVerticalHoverPositionflips one below only when the tooltip would leave the window — measured in viewport coordinates, not against the editor. The widget sits a title bar's height down (36px here, tooltip ~25px), so the check passes with ~10px to spare, the flip never fires, and the tooltip lands at y≈14–39: inside the strip.paneand.editor-outerclip withoverflow: hidden, and behind.custom-title-bar, which isposition: fixed; z-index: 9999against the inlinez-index: 2576Monaco writes on the context view.Both had to go, or the tooltip is clipped in one case and painted under the title bar in the other. The second row was never affected because its tooltip fits inside the pane.
Measured on the reporter's configuration (editor toolbar hidden, so the widget hugs the pane's top edge), by hit-testing the tooltip box with
elementFromPoint:hover-contentshover-contentshover-contentshover-contents"Close (Escape)" now renders on one line, 103×25 at y13–38, clear of its button at y41–63 — that overlap is what the reported flicker was: the tooltip covered the button, the pointer entered the tooltip, the button's
mouseleavehid it, and the cycle repeated.Scope
overflow: visiblerather thanoverflow: clipwith anoverflow-clip-margin, which would bound the escape more tightly: per MDN's compat data WebKit shipsclipwithversion_added: falsefor the margin property, so that spelling degrades to a plain clip — a silent no-op on the macOS and Linux builds.clip-path: inset(-48px 0 0 0)expresses the intent exactly and fails differently: it creates a stacking context, trapping the tooltip below the title bar it has to paint over.Letting the panes go
visibleunconditionally would risk content spilling sideways during the pane's flex/opacity transitions, when Monaco's layout lags the animation — hence:has(.find-widget.visible). It turns out to be belt-and-braces: Monaco keeps its content and the find widget itself inside.overflow-guard, so.context-viewis the only child that can paint outside at all.Not touched: the preview's own find bar (
FindBar.svelte), which has its own tooltips and never had this problem; and the underlying limitation, which is that standalone Monaco mounts hovers in the editor's container rather than at the document root. Replacing the editor's find UI with the app's own find bar would settle both, and is a feature, not this fix.Tests
scripts/findWidgetTooltipClip.test.ts, two source-shape assertions. Revert either half of the fix and both go red — checked by flippingoverflow: visibleback tohiddenand dropping the z-index below the title bar's.The first anchors the CSS declaration, including the
:has()scoping. The second is the one worth having: it reads.context-view's z-index out ofsrc/styles.cssand.custom-title-bar's out ofTitleBar.svelteand asserts the first is larger. That coupling spans two files and nothing else records it — raise the title bar and the tooltips silently go back under it.scripts/exportFoldParity.test.tsneeded one change to accept the new CSS: its hand-rolled selector matcher answered'unsupported'for any compound containing an unmodelled:, and three export-fold assertions turn'unsupported'into a failure.:has()now gets the treatment:nth-*already had — stripped before the shape check, so a rule keyed on classes this element doesn't carry is still decided outright, and only a compound that otherwise matches has to admit it can't tell. The existing:has()rules in the sheet were never hit by this because they all contain[, which the matcher rejects earlier.Verification
Behaviour was measured in Chromium, against the dev server with
window.__TAURI_INTERNALS__stubbed so the frontend boots outside Tauri — that covers the WebView2 build the report came from, and it is whyoverflow-clip-marginwas ruled out by compat data rather than by running it.Also run from a local release build on macOS 26.5 (WKWebView): first and second row, toolbar shown and hidden, split view. Not run on Linux/WebKitGTK, and not on Windows itself — the reporter's exact platform is covered by reasoning plus the Chromium measurements, not by a run.