Skip to content

fix(editor): stop find-bar flicker when cancelling (#281) - #290

Open
Eswar0108 wants to merge 1 commit into
petertzy:mainfrom
Eswar0108:fix/find-bar-flicker-281
Open

Eswar0108 wants to merge 1 commit into
petertzy:mainfrom
Eswar0108:fix/find-bar-flicker-281

Conversation

@Eswar0108

Copy link
Copy Markdown
Collaborator

Summary

Fixes the flickering find bar described in #281. The flicker happens when hovering over the find-widget action buttons (Cancel/Close, find-in-selection, match arrows).

Root cause

This is a known Monaco find-widget bug (microsoft/monaco-editor#5208, #5296). When the find bar is open, the built-in action-bar tooltip wraps its label + keybinding onto two lines, growing tall enough to overlap the button it describes. That flips the hover state on/off, producing the visible flicker while cancelling.

Change

Adds a scoped CSS workaround in frontend/src/app/globals.css (same approach as PostHog/posthog@0037887):

  • While .monaco-editor .find-widget.visible is present, force the workbench hover container(s) into a single-row layout so the tooltip stays short and clear of the buttons.
  • Disable pointer-events on the open find-widget tooltip so it can never sit over / steal the hover from the buttons.

Scoped only to when the find widget is visible, so other tooltips are unaffected.

Validation

  • npm run build - compiles, TypeScript passes, :has(...) rule survives into built CSS
  • npm run lint - clean
  • npm test - 8/8 passing

Resolves #281

@karaaslanz karaaslanz left a comment •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks — the workaround direction makes sense, but the current selector prevents the rule from matching at all.
:has() takes relative selectors. When the argument does not start with an explicit combinator, it uses an implied descendant combinator. So:
body:has(body .monaco-editor .find-widget.visible)
asks for a body element that has another descendant body containing the visible find widget. A normal document cannot have a nested , so these rules never become active.
Please remove the extra descendant body from the :has() condition, e.g.:
body:has(.monaco-editor .find-widget.visible)
and re-validate the actual find-widget interaction after the change, not only build/lint output. A focused regression for the selector/active workaround would be useful if practical.
One additional note: the Monaco issue referenced in the PR reports that pointer-events: none alone did not stop the flicker in their reproduction, so please keep the runtime validation focused on whether the combined single-row + pointer-events workaround actually stops the cancel-button flicker.
The branch is also behind current main; please refresh it before the final merge/CI pass once the fix is updated.

@Eswar0108
Eswar0108 force-pushed the fix/find-bar-flicker-281 branch from 9e9ffdb to ef73235 Compare September 29, 2026 17:56
@Eswar0108

Copy link
Copy Markdown
Collaborator Author

Thanks — you're right on all counts, and both points are now addressed.

1. Invalid :has() selector (nested <body>). Correct: :has() takes relative selectors, so body:has(body .monaco-editor …) required a body inside a body and never matched. Fixed to:

body:has(.monaco-editor .find-widget.visible) .workbench-hover-container { … }

Added a NOTE comment explaining why the subject must not be repeated, and added a small static regression test (frontend/tests/find-widget-flicker.test.mjs, runs under npm test) that asserts the rule uses the valid relative selector and never reintroduces the body:has(body …) form.

2. pointer-events: none alone didn't stop the flicker in your Monaco repro. Good to know — I've kept the combined single-row layout (display:flex; flex-flow:row nowrap; gap:6px; align-items:center; white-space:nowrap) plus pointer-events: none for that reason. I'll be explicit in the PR notes that the dynamic menu interaction still needs to be confirmed visually in the packaged WebView (my env only validates build/lint/static-test, not the live widget).

3. Branch refreshed. Rebased onto current main (2838463).

Verified: npm run build (compiles + TS), npm run lint, npm test all pass on the rebased branch.

@karaaslanz karaaslanz left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code-level blocker from my previous review is resolved: the :has() selector is now in the active relative form, the static regression guard covers the nested-body mistake, the branch is current with main, and Frontend/Backend CI are green.
The remaining blocker is the runtime behavior we called out before. Because this fix is specifically for an interaction flicker, the static selector test cannot confirm that the combined single-row + pointer-events: none workaround actually stops the cancel-button flicker in the packaged WebView. The PR notes also say that live interaction has not yet been verified in that environment.
Once someone can confirm the real find-widget interaction in the packaged app, I’m comfortable doing the final approval pass.

This branch has not been deployed

No deployments
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.

Flickering While Cancelling the Find Bar

2 participants