Files
claude-code-haha/native
程序员阿江(Relakkes) 9e211624cb fix(computer-use): make a synthesized single click register as a click
A coordinate click on a list row or a button did nothing. It moved the pointer
(the row lit up on hover), the events reached the window, the tool reported
"Action completed" — and the control never activated. Clicking a text field
worked. Clicking the same row twice, as one `click_count: 2`, worked.

Measured on one real session against an Electron target: single clicks 1/7,
double clicks 3/3. The cleanest pair is two clicks 2px apart on the same
suggestion row, with the window active both times — the only variable was the
repeat count.

Two fields were wrong, both since the engine's first commit:

**Movement claimed to be part of a click.** The leading `mouseMoved` carried
`clickCount` = the repeat count (1 for a single click, 2 for a double) instead
of 0, so the target was told "a pointer belonging to click N arrived" before any
button went down. The June comment that introduced it explains the 1…N cadence
of the press/release pairs and says nothing about why the move takes it — a
field reused, not a decision. August then widened it: the same value started
being passed to `NSEvent.mouseEvent(clickCount:)` as well, under a `max(1, …)`
that made 0 unreachable.

**A press and its release were not tied together.** Each event took a fresh
`eventNumber`, and AppKit uses that number to read two events as one click.
A text field focuses on the press alone, so it worked; anything needing a
complete click did not.

Both now follow the reference implementation, read out of its disassembly: its
drag-movement events carry `clickCount = 0` while the surrounding down/up carry
1, and its press/release pairs share one event number (a drag's down and up
share one, the dragged steps in between share another).

Verified against the same task that failed: single click on the suggestion row
lands first try, 7 tool calls and 55s where the failing run took 31 calls and
402s, no retries and no double click.

The rule is now stated once in `mouseClickState(for:click:)` instead of spelled
out per event, and nine tests cover it — there were none. `pressure` and
`mouseEventClickState` appeared nowhere in the suite, and no test had ever
called `clickPoint`, which is how these values survived from the first commit
through several rounds of "fix the clicks".
2026-08-06 04:51:34 +08:00
..