Skip to content

fix(client): Ctrl+J newline + pane-click routing#136

Merged
phall1 merged 2 commits into
mainfrom
fix/input-mouse-routing
Jun 17, 2026
Merged

fix(client): Ctrl+J newline + pane-click routing#136
phall1 merged 2 commits into
mainfrom
fix/input-mouse-routing

Conversation

@phall1

@phall1 phall1 commented Jun 17, 2026

Copy link
Copy Markdown
Owner

Two release-hardening input/mouse bug fixes, batched. Both are client-side, localized, and covered by new regression tests.

1. Ctrl+J sent as CR instead of LF

fix(client): send Ctrl+J as LF, not CR

The stdin parser mapped both CR (0x0D) and LF (0x0A) to a bare Enter KeyEvent, and the Ctrl-letter arm explicitly excluded 0x0A. Since input is structured client→server (ADR-0008), the server encoder re-derived bytes from the event and emitted CR for Ctrl+J — so apps that distinguish Ctrl+J from Enter (e.g. Claude Code's "insert newline") saw a submit.

CR alone now maps to Enter; LF falls through to the Ctrl-letter arm → Ctrl+J → encoder reproduces 0x0A. In raw mode the host TTY sends CR for Return and LF only for Ctrl+J, so the split is unambiguous.

2. Pane clicks routed to the wrong pane

fix(client): hit-test mouse clicks against the inset content rect

The renderer tiles panes into a content rect inset by the status-bar row (and any sidebar columns), but route_mouse_event hit-tested against the full viewport. On a top/bottom split the layouts disagreed by the status-bar row → clicks near the divider focused/routed to the wrong pane, pane-local coords came out off-by-one, and a docked sidebar shifted every click by the strip width.

route_mouse_event now takes the same content_rect(viewport, has_bar, sidebar) the paint path uses and tiles via compute_layout_in, so hit-test rects match the screen cell-for-cell. Reserved-chrome clicks are dropped. Pre-existing bug, not a regression from the recent repaint commits.

Tests

  • parser round-trip: 0x0ACtrl+J
  • server encoder: Ctrl+J0x0A
  • mouse routing: status-bar-row click dropped under inset, mis-routed to bottom pane under the old full-viewport tiling

just ci green locally (fmt-check + lint + test + deny + docs).

🤖 Generated with Claude Code

phall1 and others added 2 commits June 17, 2026 00:35
The stdin parser mapped both CR (0x0D) and LF (0x0A) to a bare Enter
KeyEvent, and the Ctrl-letter arm explicitly excluded 0x0A. Because input
is structured client->server (ADR-0008), the server encoder re-derived
bytes from the event and emitted CR for Ctrl+J — so apps that distinguish
Ctrl+J from Enter (e.g. Claude Code's "insert newline") saw a submit
instead.

CR alone now maps to Enter; LF falls through to the Ctrl-letter arm and
becomes Ctrl+J, which the encoder reproduces as 0x0A. In raw mode the host
TTY sends CR for Return and LF only for Ctrl+J, so the split is
unambiguous. Adds a parser round-trip test and a server-encoder test
asserting Ctrl+J -> 0x0A.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Clicking a pane could focus or route input to the wrong one. The renderer
tiles panes into a content rect inset by the status-bar row (and any
sidebar columns), but route_mouse_event hit-tested against the full
viewport. On a top/bottom split the two layouts disagreed by the
status-bar row, so a click near the divider landed in the wrong pane and
pane-local coordinates came out off-by-one; a docked sidebar shifted every
click by the strip width.

route_mouse_event now takes the same content rect the paint path computes
(content_rect(viewport, has_bar, sidebar)) and tiles via compute_layout_in,
so the hit-test rects match what is on screen cell-for-cell. Clicks in the
reserved chrome (status-bar row, sidebar columns) miss every pane rect and
are dropped. DispatchCtx carries has_bar for this; the call site folds it
with the existing sidebar reservation. Adds a regression test pinning the
status-bar-row case.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@phall1 phall1 merged commit 921f1d1 into main Jun 17, 2026
3 checks passed
@phall1 phall1 deleted the fix/input-mouse-routing branch June 17, 2026 04:47
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.

1 participant