fix(client): Ctrl+J newline + pane-click routing#136
Merged
Conversation
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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 CRThe stdin parser mapped both CR (
0x0D) and LF (0x0A) to a bareEnterKeyEvent, and the Ctrl-letter arm explicitly excluded0x0A. 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 reproduces0x0A. 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 rectThe renderer tiles panes into a content rect inset by the status-bar row (and any sidebar columns), but
route_mouse_eventhit-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_eventnow takes the samecontent_rect(viewport, has_bar, sidebar)the paint path uses and tiles viacompute_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
0x0A→Ctrl+JCtrl+J→0x0Ajust cigreen locally (fmt-check + lint + test + deny + docs).🤖 Generated with Claude Code