feat(input): bypass mouse reporting while Shift is held - #103
Merged
Conversation
Applications that enable mouse reporting (?1000/1002/1006h) received every click, so text selection and link opening were unreachable while they ran. Holding Shift on press now keeps the whole press-drag-release local, the xterm convention other terminals follow.
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.
Summary
Inside any application that turns on mouse reporting —
vim,tmux,htop, Claude Code — clicking a URL did nothing and dragging selected nothing.handle_mouse_inputforwarded every left/middle/right click straight to the PTY whenevermouse_mode >= 1000, before the local selection and link paths ran, so the terminal's own mouse features were unreachable for as long as the application held the mouse. Plain-text URL detection (Grid::scan_urls) and OSC 8 links both worked at a shell prompt and both went dead inside those applications.This adds the xterm convention every other terminal implements: holding Shift on press bypasses mouse reporting for that interaction. The application still owns unmodified clicks, so no existing behaviour changes.
The bypass is latched at press time rather than sampled per event, so releasing Shift mid-drag does not hand the release to the application and leave a selection half-finished.
Changes
src/app_state.rs— newAppState.mouse_bypass_reporting: bool, set on a Shift press and cleared on release. Session-only, never persisted.src/app_event.rs— newforward_click_to_pty(mouse_mode, btn_code, bypass)decides between the PTY and local handling;handle_mouse_inputlatches the flag fromself.modifiersand consults the helper.handle_cursor_movedskipsreport_pty_mouse_movewhile the flag is set, so the drag paints a local selection instead of streaming motion reports.src/app_event_test.rs— tests for the forwarding rule.CHANGELOG.md— entry under[Unreleased]→Added.README.md— note the Shift modifier on the hyperlinks feature line.Design notes:
mouse_selectingcould not be reused as the bypass flag —send_pty_mouse_clickalready sets it to mean "left button is down" while reporting is active, so a separate flag keeps the two meanings apart. The helper is a free function of(mouse_mode, btn_code, bypass)so the rule is testable without a window, an event loop, or a PTY.How to test
Automated:
New tests:
click_is_forwarded_when_application_enabled_mouse_reporting,click_is_handled_locally_without_mouse_reporting,shift_click_bypasses_mouse_reporting,buttons_beyond_right_are_never_forwarded. Full suite: 1248 tests pass.Manual (end-to-end):
cargo run, then start something that grabs the mouse —vim,tmux, or Claude Code over SSH — and print a URL inside it.