posit-dev / posit-dev/positron

Tooltip is not dismissed by a keypress that starts a keybinding chord

Open
#15,399 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

area: ui
Dominant language
TypeScript
Stars
4.3k
Forks
184
Avg merge
1d 11h
Merged PRs (30d)
206

Description

System details:

Positron and OS details:

Positron dev build from main (fdf410ebd4), macOS 15 (Darwin 25.5.0). Reproduced against a disposable dev profile.

Session details:

n/a -- no interpreter needed.

Describe the issue:

A tooltip stays on screen through a keypress that should dismiss it, if that keypress starts a keybinding chord.

Action bar hovers are shown with persistence.hideOnKeyDown: true, so any key should hide them. HoverService._keyDown (src/vs/editor/browser/services/hoverService/hoverService.ts:517-529) asks keybindingService.softDispatch about the key first and returns early unless the result is NoMatchingKb. While a chord is pending, softDispatch returns MoreChordsNeeded, so the hide is skipped and the hover is left showing.

Chord mode self-expires after 5s of no interaction (abstractKeybindingService.ts:169), so the window is bounded, but the stale tooltip can outlive the UI it described.

Steps to reproduce the issue:

  1. Hover a top action bar button (e.g. New) and wait for its tooltip to appear.
  2. Without moving the pointer, press Cmd+K (the first key of a chord -- the status bar shows "(Ctrl+K) was pressed. Waiting for second key of chord...").
  3. Observe the tooltip is still visible.

For contrast, repeat with a plain key such as a in step 2: the tooltip hides immediately.

Observed via CDP, tooltip text read from .hover-contents 400ms after the keypress:

Step Chord key (Cmd+K) Plain key (a)
tooltip before keypress New File/Folder New File/Folder
tooltip after keypress New File/Folder (still up) null (hidden)

Expected or desired behavior:

A keypress that starts a chord should dismiss a hover shown with hideOnKeyDown, the same as any other key. Waiting for the second key of a chord is not a reason to keep a tooltip on screen.

Were there any error messages in the UI, Output panel, or Developer Tools console?

No. The hover is simply never asked to hide.


Found while triaging a Windows-only e2e flake in Positron Notebooks: Find and Replace > Verify search widget buttons show tooltips on hover. The test-side mitigation is in #15374, which clears a wedged chord in the shared hotKeys fixture; this issue is the underlying product behavior, which that PR does not change.

E2E Triage Diagnosis
🟢 High confidence -- While a keybinding chord is pending, HoverService._keyDown skips hiding the current hover, so a tooltip survives a keypress that would normally dismiss it. Reproduced deterministically. The same chord state does NOT block later hovers, so it explains the stuck-tooltip failure mode only.
  • Test: Positron Notebooks: Find and Replace > Verify search widget buttons show tooltips on hover
  • Targeted failure: expect(locator(.hover-contents)).not.toBeVisible() fails with a stale tooltip still up (pattern B). Pattern A (toContainText, no widget ever created) is NOT explained by this and remains open.
  • Signal: Pattern A (toContainText, no widget created) 10 occurrences over 21 days of 669 main runs, mostly win/electron but at least one ubuntu/electron, so it is not Windows-only. Pattern B (not.toBeVisible, tooltip stuck) 1 occurrence. An earlier 14-day query reported 2 and 1 because it caps occurrences per pattern.
  • Hypothesis: Confirmed by local repro over CDP: with a chord pending, a showing hover survives the keypress, while a plain key hides it immediately (hoverService.ts:517-529 returns early unless softDispatch reports NoMatchingKb, and a pending chord reports MoreChordsNeeded). Chord mode self-expires after 5s (abstractKeybindingService.ts:169). hotKeys.closeAllEditors presses Cmd+K Cmd+W in an afterEach, so a dropped second keypress leaks chord mode into the next test. Falsified by the same repro: a pending chord does not stop a new hover being created, so hoverService.ts:273-282 rejects nothing here and pattern A is unexplained. Also falsified: the disabled-flip hypothesis (Chromium probe shows no mouseleave when a hovered button is disabled, mouseenter is delivered to disabled buttons, and :hover stays true).
  • Supersedes: an earlier disabled-flip hypothesis for this test, and an intermediate chord-wedges-all-hovers hypothesis; both falsified by direct probes

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with HoverService._keyDown in src/vs/editor/browser/services/hoverService/hoverService.ts:517-529 and compare its softDispatch handling with the pending-chord behavior in abstractKeybindingService.ts:169. Reproduce with a visible action-bar tooltip followed by Cmd+K, then verify that a keypress starting a chord dismisses hovers configured with hideOnKeyDown, without changing plain-key behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
frontend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.