Terminal: a bare modifier keypress clears the selection when the kitty keyboard protocol is active, breaking Cmd+C copy
- Dominant language
- TypeScript
- Stars
- 193k
- Forks
- 42.4k
- PR merge metrics
- PR metrics pending
Description
Type: Bug
VS Code Version: 1.137.0 (645f29cc3176500b4b5762ba887cf2a7f0ffdf2c, stable)
OS Version: macOS 26.6.2 (25G83), arm64
Shell: fish 4.9.0 (Homebrew)
Extensions: reproduces in a clean profile — fresh `--user-data-dir`, `--extensions-dir` pointed at an empty directory, no settings changed
## Summary
With `terminal.integrated.enableKittyKeyboardProtocol` at its default (`true`), a **bare modifier keypress clears the terminal selection**. Because Cmd+C delivers the Cmd before the chord completes, Cmd+C can never copy: the selection is already gone when `CopySelection` runs, and it reports "The terminal has no selection to copy".
It only reproduces under a shell that negotiates the protocol. fish 4.x does; zsh does not.
## Minimal reproduction (no clipboard, no keybinding involved)
1. macOS, fish 4.x as the terminal shell. `fish --no-config` is sufficient — no user config needed.
2. Leave `terminal.integrated.enableKittyKeyboardProtocol` at its default `true`.
3. Open a terminal, run `echo hello`.
4. Select `hello` with the mouse.
5. **Tap and release Shift. Press nothing else.**
**Expected:** the selection is unaffected — a modifier alone is not input.
**Actual:** the selection is cleared; the highlight disappears.
Cmd+C is the user-visible consequence:
6. Select `hello` again, press Cmd+C.
**Expected:** `hello` on the clipboard.
**Actual:** notification "The terminal has no selection to copy".
Setting `"terminal.integrated.enableKittyKeyboardProtocol": false` and reloading the window fixes both. Toggling the setting flips the behaviour deterministically.
## Isolation
In one terminal, in one window, switching only the shell:
- `zsh` -> select -> Cmd+C: **copies**
- `exit`, `fish --no-config` -> select -> Cmd+C: **warning**
Ruled out by bisection against a clean profile: user settings, keybindings, extensions (95 of them), `globalStorage` state, and workspace state. The only variable that matters is the shell, and behind it the protocol.
Two things still work, which locates the failure in time:
- **Right-click -> Copy works.** No keyboard involved.
- **`terminal.integrated.copyOnSelection` works.** It copies at mouse-up, before any key is pressed.
So the selection genuinely exists after the drag, and is destroyed by the modifier.
## Cause
Under the kitty keyboard protocol, modifier keys report themselves as key events; in legacy mode a bare modifier sends nothing. That report is being treated as selection-clearing input.
The Cmd+C symptom then follows from `xtermTerminal.copySelection()`, which warns from its `else` branch when `hasSelection()` is false:
```ts
async copySelection(asHtml?: boolean, command?: ITerminalCommand): Promise {
if (this.hasSelection() || (asHtml && command)) {
...
} else {
this._notificationService.warn(localize('terminal.integrated.copySelection.noSelection', 'The terminal has no selection to copy'));
}
}
```
Suggested fix: do not treat a modifier-only key report as input for the purpose of clearing the selection.
For reference, fish's startup probe, captured from a pty:
```
\e[?u kitty keyboard protocol query
\e[>0q XTVERSION
\e]11;?\e\\ OSC 11 background colour
\e[?1049h enter alternate screen
\eP+q696e646e\e\\ XTGETTCAP "indn"
\eP+q71756572792d6f732d6e616d65\e\\ XTGETTCAP "query-os-name"
\e[?1049l leave alternate screen
\e[0c DA1
```
## Notes
Likely related to #304765 (Option+F / Option+B word navigation broken in terminal apps when the kitty keyboard protocol is enabled) — same setting, different key path.
Not a keybinding-resolution problem; the command dispatches normally:
```
[KeybindingService]: \ From 11 keybinding entries, matched workbench.action.terminal.copySelection,
when: terminalTextSelectedInFocused || terminalFocus && terminalHasBeenCreated && terminalTextSelected || ...
[KeybindingService]: + Invoking command workbench.action.terminal.copySelection.
```
Contributor guide
Assessment
This issue has not been assessed yet.