Skip to content

Enable SGR mouse tracking and parse mouse escape sequences in the TUI input loop #169

Description

@shouze

Context

There's currently no mechanism to receive mouse events. The TUI reads raw stdin chunks as strings in for await (const chunk of process.stdin) (src/tui.ts) and matches them against known keyboard escape sequences. Mouse clicks/wheel arrive on this same channel as SGR sequences (\x1b[<b;x;yM / ...m) once mouse reporting is enabled on the terminal.

Part of #166.

Solution

  • Enable mouse tracking (\x1b[?1000h\x1b[?1006h) on stdout when runInteractive() starts, next to the existing process.stdin.setRawMode(true).
  • Disable it (\x1b[?1000l\x1b[?1006l) in every exit path — the exit() cleanup function, and any other place that calls setRawMode(false) — so a killed/crashed process never leaves the user's terminal stuck in mouse-reporting mode.
  • Add a pure parser function (e.g. parseMouseEvent(sequence: string)) that recognizes SGR mouse sequences and returns a structured event ({ button, x, y, isRelease } or null for anything else). Place it in a new small module (e.g. src/render/mouse.ts or src/mouse.ts, to be decided based on whether it needs types.ts additions) so it can be unit-tested independently of the stdin loop.
  • Wire the parser into the main input loop in tui.ts: unrecognized/malformed sequences are ignored (no throw), preserving graceful degradation for terminals without mouse support.

Acceptance Criteria

  • Mouse tracking is active only while the TUI is running; verified that the terminal is not left in mouse-reporting mode after normal exit, Ctrl+C, and an unhandled error.
  • A well-formed SGR mouse sequence is parsed into a structured event; malformed or unrelated sequences return null and are silently ignored (no crash, no visual glitch).
  • Regular keyboard input continues to work unaffected (arrow keys, filter mode, etc. — full regression pass on existing shortcuts).

Definition of Done

  • bun test passes, including a new companion *.test.ts for the parser covering: valid click press/release, valid wheel up/down, malformed sequence, empty string, partial/truncated sequence.
  • bun run lint passes.
  • bun run format:check passes.
  • bun run knip passes (no unused exports/imports).
  • bun run build.ts compiles successfully.
  • No behavior change to existing keyboard shortcuts (manual regression check noted in the PR description).
  • Documentation updated if this introduces any new observable behavior (e.g. a note that mouse reporting is enabled during interactive sessions).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions