Skip to content

fix(terminal): intercept Cmd+V on macOS to prevent paste-then-edit garbling#100

Merged
DeadWaveWave merged 3 commits intoDeadWaveWave:mainfrom
yinuotxie:fix/terminal-paste-cursor-macos
Mar 30, 2026
Merged

fix(terminal): intercept Cmd+V on macOS to prevent paste-then-edit garbling#100
DeadWaveWave merged 3 commits intoDeadWaveWave:mainfrom
yinuotxie:fix/terminal-paste-cursor-macos

Conversation

@yinuotxie
Copy link
Copy Markdown
Contributor

@yinuotxie yinuotxie commented Mar 27, 2026

Summary

Fixes #88

On macOS, pasting text (Cmd+V) into a terminal node and then moving the cursor left to edit produces garbled characters from the end of the pasted text (e.g. pasting "...emoji" then typing yields "ijiji" instead of the intended input).

Root Cause

xterm.js's handlePasteEvent calls stopPropagation() but not preventDefault(). After the paste handler clears the hidden textarea, the browser's default action re-inserts the clipboard text. Subsequent input interacts with this stale textarea content, producing characters from the tail of the pasted text.

Fix

Intercept Cmd+V on macOS in handleTerminalCustomKeyEvent — the same approach already used for Ctrl+V on Windows:

  • event.preventDefault() blocks the native paste from reaching the textarea
  • readTextFromClipboard() fetches text via Electron clipboard IPC
  • terminal.paste(text) sends data directly through xterm.js's onData, bypassing the textarea entirely

Changes

  • inputBridge.ts: Add isMacTerminalPasteShortcut(), extend paste check to include macOS Cmd+V
  • terminalInputBridge.spec.ts: Add 8 new unit tests covering macOS paste, Cmd+C non-interference, Cmd+Shift+V non-interception, and Linux Meta+V behavior

Reproduction

  1. Open a terminal node in OpenCove, start Claude Code
  2. Paste CJK text ending with an English word (e.g. 示模型名、上下文进度条、费用,用简洁的 emoji)
  3. Press left arrow to move cursor back
  4. Type — before fix: garbled characters ("ijiji") from end of pasted text; after fix: correct input

After fix

Screenshot 2026-03-27 at 7 15 14 PM

Test plan

  • All 440 unit tests pass (131 test files)
  • isMacTerminalPasteShortcut tests: Cmd+V macOS ✓, Cmd+V Windows ✗, Ctrl+V macOS ✗, Cmd+Shift+V ✗, Meta+V Linux ✓
  • handleTerminalCustomKeyEvent tests: macOS Cmd+V paste ✓, Cmd+C non-interference ✓, Cmd+Shift+V non-interception ✓
  • Manual reproduction confirms fix resolves the garbled input

@DeadWaveWave
Copy link
Copy Markdown
Owner

感谢修复 #88,这个思路(拦截快捷键 → preventDefault/stopPropagation → 走 Electron clipboard → terminal.paste())看起来很合理。

有几个点想跟你对齐一下意图 / 现状:

  1. Meta 键的语义:在浏览器事件里,macOS 的 event.metaKey 是 ⌘ Command;Windows/Linux 一般对应 Win/Super 键。你这里 isMacTerminalPasteShortcut 目前在 Linux 上也会把 Meta+V 识别为 paste(测试里也断言了这一点)。我们有点困惑:Linux 终端更常见的复制/粘贴是 Ctrl+Shift+C/V(而 Ctrl+C 应该保留给 SIGINT 中断),Super+V 并不是常用约定。

    • 你是希望在 Linux 也支持 Super+V 粘贴吗?如果是,能说下你验证过的发行版/桌面环境/键盘布局/使用场景吗?
    • 如果不是,建议把这个 shortcut 限定为 macOS(或至少改名/注释说明),并移除 Linux 的期望测试,避免误导。
  2. 另一个用户反馈:Ubuntu 24.04 下在终端节点里想用 Ctrl+Shift+C 复制 / Ctrl+Shift+V 粘贴没成功(他们也提到 Ctrl+C 不行)。这个跟 [BUG] 在Claude code终端内粘贴文字后,再回到前面进行打字会出现错乱的bug #88 不是同一个原因,但可能反映 Linux 的终端式快捷键映射还没覆盖。你觉得这部分应该顺手在这个 PR 一并处理,还是另开 issue 单独做更合适?

  3. CI:ubuntu job 当前挂在 pty-host.crash-recovery 的 timeout,看起来像偶发 flake(不一定是这个 PR 引入)。方便的话麻烦 re-run 一下确认。

谢谢!

@yinuotxie
Copy link
Copy Markdown
Contributor Author

谢谢 review!

1) 确实是我疏忽了,之前只排除了 Windows 没有限定 macOS,导致 Linux 的 Super+V 也会误触发。已经加了 isMacPlatform() 做平台检测,严格限定为 macOS only,Linux 那条测试也删了,见 d1806f8

2) Linux Ctrl+Shift+C/V#88 不是同一个问题,已经单独开了 #114 跟进。

3) 新 commit 已经 push 了,CI 会重跑一轮,到时候看看 Ubuntu 那边的结果。

@DeadWaveWave
Copy link
Copy Markdown
Owner

CI 未通过,需要先先本地通过 pnpm pre-commit 再提交

yinuotxie and others added 2 commits March 30, 2026 13:19
…rbling (DeadWaveWave#88)

On macOS, xterm.js handles Cmd+V paste through its hidden textarea.
After pasting, the browser's default action re-inserts clipboard text
into the textarea (handlePasteEvent calls stopPropagation but not
preventDefault). Subsequent input reads stale textarea content,
producing garbled characters from the end of the pasted text.

Fix by intercepting Cmd+V in the custom key event handler (mirroring
the existing Windows Ctrl+V path): preventDefault blocks the native
paste, readTextFromClipboard fetches via Electron IPC, and
terminal.paste() sends data directly without touching the textarea.
Address PR review: isMacTerminalPasteShortcut was matching Meta+V on
Linux (Super key), which is not a standard paste shortcut. Add
isMacPlatform() guard so the shortcut only fires on macOS, and remove
the Linux Meta+V test assertion.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@yinuotxie yinuotxie force-pushed the fix/terminal-paste-cursor-macos branch from d1806f8 to 5909ede Compare March 30, 2026 05:31
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@DeadWaveWave DeadWaveWave merged commit fc7c948 into DeadWaveWave:main Mar 30, 2026
3 checks passed
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.

[BUG] 在Claude code终端内粘贴文字后,再回到前面进行打字会出现错乱的bug

2 participants