SGR mouse reports with non-numeric coordinates get reissued as keystrokes

Open Beginner friendly
#6,573 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
68/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Quiet
Tech stack
python
Domain
cli

Research direction

Start in _xterm_parser.py, where the mouse regex and reissue_sequence_as_keys fallback are defined. Trace how SGR mouse-shaped sequences are handled before the fallback, then verify that malformed \x1b[<...M/m reports are discarded while valid reports, negative coordinates, and ordinary key sequences remain unaffected.

Written by the indexing model from the issue text.

Description

Hello everyone !
Thank you for this library! I am using it for the mistral vibe CLI and encountered a bug.

SGR mouse reports with non-numeric coordinates get reissued as keystrokes

When a terminal emits a malformed SGR mouse report with non-numeric coordinates (e.g. \x1b[<32;NaN;NaNM), Textual fails to recognize it as a mouse event and falls back to reissue_sequence_as_keys, which re-emits each character as a keystroke. The result is garbage text dumped into the focused widget.

How to reproduce

This was reported by several Mistral Vibe CLI users across various configurations. I could reproduce it reliably in the VS Code integrated terminal by switching tabs using the side button of the mouse while hovering over the terminal.

During a focus/tab transition xterm.js's geometry is briefly invalid and it computes mouse cell coordinates as NaN, emitting reports like \x1b[<32;NaN;NaNM. In a Textual app this fills the focused input with [<32;NaN;NaNM.

What does textual

The mouse regex in _xterm_parser.py only matches decimal coordinates:

_re_mouse_event = re.compile("^" + re.escape("\x1b[") + r"(<?[-\d;]+[mM]|M...)\Z")

So \x1b[<32;NaN;NaNM doesn't match — that part is fine. The problem is the fallback: a sequence that is clearly a (broken) SGR mouse report still gets treated as user typing. \x1b[<...M/m is an unambiguous mouse-report shape; if the parameters are invalid, the right move is to drop it, not to type it.

Right now the only solution I found is to patch the textual xterm driver to filter these out. It'd be much nicer if Textual recognized the \x1b[<...M/m envelope and discarded reports with non-numeric coordinates rather than reissuing them as keys.

Suggested fix

Detect the SGR mouse envelope before the keystroke fallback and discard malformed instances. Valid reports (including negative SGR-Pixels coordinates) and all real key sequences should be untouched.

Happy to open a PR if this direction sounds good.

Dominant language
Python
Stars
37.3k
Forks
1.3k
PR merge metrics
No merged PRs in 30d

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from Textualize/textual

All issues in Textualize/textual

Similar issues

More Python issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.