[BUG] Plugin Button loses a quick second click: it selects the label's text instead of pressing

Status Open
Reported on v2.1.290
Maintainer reply None cached
Activity 0 comments · opened Oct 6, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report
  • [x] I am using the latest version of Claude Code

What's Wrong?

In the fullscreen terminal, a click on a plugin Button that follows the previous click within about half a second never presses it. Claude Code treats it as a double click: it selects the word under the pointer and raises no ui.press.

This breaks every toggle a plugin draws. A section title that folds on click stays folded after a quick second click, and its text is left selected.

What Should Happen?

Every click on a plugin Button presses it, however soon it follows the last one. Clicking a Button never selects its label.

Error Messages/Logs

None.

Steps to Reproduce

  1. Run a plugin whose ui.render hook draws a Pane with a Button. Its onPress flips a boolean, and the label shows it, as in ▸ Section and ▾ Section. Open the pane with $.ui.open({ id, focus: true }) in a fullscreen terminal wide enough to dock it.
  2. Click the Button. It toggles.
  3. Within half a second, click the same spot again.
  4. The word under the pointer is highlighted as a selection. The Button did not toggle back.

A second click after a longer pause toggles as expected.

Claude Model

Not model-related.

Is this a regression?

Don't know.

Claude Code Version

2.1.290 (Claude Code)

Platform

Anthropic API

Operating System

macOS 15.7.3

Terminal/Shell

Herdr in Ghostty. Also reproduced in tmux 3.7c, with SGR mouse clicks sent 120 ms apart.

Additional Information

Where it comes from. Claude Code's own pressable components avoid this, and the plugin Button renderer doesn't:

  • One of Claude Code's own pressable components calls endClickChain() on its click event, so the next click starts a new chain. It also sets noSelect on its Box.
  • The plugin Button renderer's Box handles the click by blurring and stopping propagation. It doesn't call endClickChain() or set noSelect.
  • So dispatchMouseClick returns "handled", and the mouse handler resets clickCount only for "stray" or "repeat". The next press arrives with clickCount >= 2 and goes to onMultiClick, which selects the word. The release that follows dispatches no click.

Suggested fix. In the plugin Button renderer, call endClickChain() in the click handler and set noSelect on its Box.

A plugin can't work around it. The mod API can't end a click chain, mark text as not selectable, or clear a selection. $.ui.selection() only reads.

Related.

  • #99116 asks for a non-selectable prop, after a transcript selection spilled into a docked plugin Pane.
  • #99395 is a different lost click on plugin pane buttons, in the desktop app.

View original on GitHub ↗