Tooltip is not dismissed by a keypress that starts a keybinding chord
area: ui
## 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 <kbd>Cmd</kbd>+<kbd>K</kbd> (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 <kbd>a</kbd> 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
<details>
<summary>🟢 <b>High confidence</b> -- 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.</summary>
- **Test:** [Positron Notebooks: Find and Replace > Verify search widget buttons show tooltips on hover](https://connect.posit.it/e2e-test-insights/?tab=test_health&repo=positron&test=Positron%20Notebooks%3A%20Find%20and%20Replace%20%3E%20Verify%20search%20widget%20buttons%20show%20tooltips%20on%20hover%7C%7C%7Ctest%2Fe2e%2Ftests%2Fnotebooks-positron%2Fnotebook-find-and-replace.test.ts)
- **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
</details>
1 条评论