[Bug] Fullscreen drag-select blocks TUI when DISPLAY points to unresponsive X socket
Bug Description
Fullscreen drag-select blocks the whole TUI when DISPLAY points at an X socket that never answers
Summary
In the fullscreen renderer, finishing a drag selection can block the entire
Claude Code process. The highlight stays on screen, keypresses are ignored,
Escape does nothing, and the only way out is to kill the terminal. The cause
is the Linux native clipboard path: when DISPLAY is set and neither xclip
nor xsel is installed, the bundled clipboard-napi addon'ssetLinuxClipboardText is called synchronously with no timeout. If the X
socket accepts the connection but never completes the handshake, that call
never returns and the event loop is stuck.
This is easy to hit in a devcontainer reached through VS Code Remote-SSH plus
Remote-Containers. The Remote-Containers server creates/tmp/.X11-unix/X<N> inside the container and sets DISPLAY=:<N> in
terminals. When the client machine has no X server behind the forwarding,
the socket accepts and then hangs forever.
Environment
- Claude Code 2.1.257 (BUILD_TIME 2026-09-01T05:28:54Z, GIT_SHA 2c673eef).
Same code path is present in 2.1.219 and 2.1.231.
- Linux x64 devcontainer, VS Code 1.134.0 integrated terminal
(TERM_PROGRAM=vscode), Remote-SSH into a Coder workspace, then
Remote-Containers.
tui: fullscreenin settings.json.DISPLAY=:20, no xclip/xsel/wl-copy installed.
Steps to reproduce
- Create a Unix socket that accepts connections and never replies, and point
DISPLAY at it. For example DISPLAY=:20 with a listener on
/tmp/.X11-unix/X20 that never writes. (In my case VS Code's
Remote-Containers server owns that listener.)
- Run
claudewith the fullscreen renderer enabled. - Drag-select any text with the mouse and release.
Expected
Selected text is copied (OSC 52 or a native tool) and the session keeps
responding. If the native path cannot reach the display, it fails fast and
falls back to OSC 52.
Actual
After the mouse release, no OSC 52 sequence is emitted, the process sits inpoll (wchan do_sys_poll), and it stops reacting to keyboard input and to
further mouse events. The last rendered frame is the selection highlight, so
it looks like a stuck selection or a frozen terminal.
Evidence
| DISPLAY | Result |
|--------------------|----------------------------------------------------------|
| :20 (hangs) | no OSC 52, wchan do_sys_poll, 0 bytes after a keypress |
| unset | OSC 52 emitted, keeps responding |
| :0 (refused) | OSC 52 emitted, keeps responding |
From the bundle: the Linux clipboard probe picks wl-copy, then xclip,
then xsel, then the addon whenever DISPLAY matches ^(unix)?:. The copy
path is copySelectionNoClear -> setClipboard -> native Linux copy and the
addon call is recordAddonWrite(addon.setLinuxClipboardText(text) !== false),
synchronous on the main thread.
Workarounds that confirm the cause
unset DISPLAYbefore launching: selection and copy work.CLAUDE_CODE_DISABLE_MOUSE=1: removes in-app selection, so the clipboard
path never runs.
/tui default: classic renderer, same effect.
Suggested fix
Do the addon write off the main thread with a bounded timeout, or probe the
display with a short timeout before choosing the addon. The forwarded X
socket case is common enough with VS Code remote setups that fail-fast
matters more than getting the native copy right. Existing issues #61936 and
#72173 describe the same symptom and attribute it to mouse tracking; the
mouse tracking is only what makes the in-app selection happen.
Environment Info
- Platform: linux
- Terminal: vscode
- Version: 2.1.257
- Feedback ID: c0b4ce39-ecc4-4a04-85e3-cdc9d7ad9eb9
Errors
[]