[BUG] Fullscreen TUI treats mouse side buttons as left and middle clicks, so the forward button pastes PRIMARY
What happens
In the fullscreen TUI, the mouse side buttons act as ordinary clicks.
- Mouse 4, the back button or BTN_SIDE, acts as a left click. It moves the prompt cursor to wherever the pointer is.
- Mouse 5, the forward button or BTN_EXTRA, acts as a middle click. On Linux that pastes the PRIMARY selection into the prompt.
Side buttons should do nothing unless I bind them. I use Mouse 4 as push-to-talk for a dictation app, so every press also clicks inside Claude Code. Mouse 5 drops whatever text I last selected anywhere on the desktop into my prompt.
Cause
Terminals report side buttons as SGR mouse codes 128 and 129. In foot's terminal.c, BTN_SIDE becomes X button 8 and BTN_EXTRA becomes 9. Then encode_xbutton maps buttons 8 to 11 to xbutton - 8 + 128. xterm uses the same encoding.
Claude Code decodes the button with button & 3 and never checks bit 128. So 128 reads as 0, left, and 129 reads as 1, middle. In the 2.1.278 bundle, the click handler starts with p=s.button&3 and then runs the Linux primary paste when p===1.
CLAUDE_CODE_DISABLE_MOUSE_CLICKS doesn't avoid this. Scroll mode only drops events where (button & 3) === 0, so code 129 still gets through as a middle click. CLAUDE_CODE_DISABLE_MOUSE avoids it, but that also kills wheel scrolling.
Reproduction
I ran Claude Code in a PTY with "tui": "fullscreen". I sent it the exact bytes foot sends for each button and rendered the screen with pyte. A fake wl-paste earlier on PATH returned PRIMARY_MARKER, so my real clipboard stayed out of it.
Mouse 5, empty prompt, bytes \x1b[<129;5;38M then \x1b[<129;5;38m:
wl-paste calls: 'wl-paste --primary --no-newline'
38|❯ PRIMARY_MARKER
Mouse 4 compared with a real left click. I typed abcdefghij, sent the click on the c, then typed X:
no click -> ❯ abcdefghijX
real left click, code 0 -> ❯ abXcdefghij
Mouse 4, code 128 -> ❯ abXcdefghij
To see it by hand, open fullscreen mode in foot or xterm, select some text in another window, and press the forward side button over the prompt.
Suggested fix
Ignore SGR codes with bit 128 set, or at least never treat them as left, middle or right. Those are buttons 8 to 11. I couldn't find anything in the TUI that uses them, so dropping them looks safe. Letting users bind them would be even better.
Related: #83487 is the same kind of decoder bug with the wheel and motion bits. #90086 is about CLAUDE_CODE_DISABLE_MOUSE_CLICKS missing a paste path.
Environment
- Claude Code 2.1.278,
"tui": "fullscreen" - Arch Linux, Omarchy, Hyprland, Wayland
- foot 1.28.0
- Logitech G309 mouse