[PR #757] [CLOSED] fix: forward unconsumed data after mouse sequence parsing #1541

Closed
opened 2026-03-14 09:42:13 +03:00 by kerem · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/anomalyco/opentui/pull/757
Author: @amosbird
Created: 3/1/2026
Status: Closed

Base: mainHead: fix/mouse-sequence-split-data-loss


📝 Commits (1)

  • 98813ca fix: forward unconsumed data after mouse sequence parsing

📊 Changes

4 files changed (+56 additions, -21 deletions)

View changed files

📝 packages/core/src/lib/parse.mouse.test.ts (+42 -10)
📝 packages/core/src/lib/parse.mouse.ts (+2 -2)
📝 packages/core/src/renderer.ts (+11 -8)
📝 packages/core/src/testing/integration.test.ts (+1 -1)

📄 Description

Summary

  • parseAllMouseEvents now returns a consumed byte offset alongside parsed events, telling the caller exactly how many bytes were successfully parsed
  • handleMouseData in the renderer forwards any unconsumed trailing data to _stdinBuffer.process() instead of silently dropping it

Problem

When a stdin chunk contains complete mouse escape sequences followed by a partial one (e.g. \x1b[<0;31;16M\x1b[<0;), parseAllMouseEvents parses the complete event but the partial trailing bytes are silently dropped. When the next stdin chunk arrives with the remainder (31;16M), it can't be parsed as a mouse event (no \x1b[ prefix), so it falls through to keyboard input handling — causing characters like 31M; to appear in the input box.

This is most commonly triggered by rapid mouse movement during terminal focus switches.

Changes

parse.mouse.ts: Changed parseAllMouseEvents return type from RawMouseEvent[] to { events: RawMouseEvent[]; consumed: number }.

renderer.ts: handleMouseData now checks if consumed < data.length and forwards the unconsumed remainder to _stdinBuffer.process(), which correctly handles partial CSI sequences with its existing buffering/timeout logic.

parse.mouse.test.ts: Updated all call sites for new return type. Added 5 new tests covering consumed offset behavior (full consumption, trailing non-mouse data, partial SGR sequences, empty/non-mouse input).

integration.test.ts: Updated helper to access .events from the new return type.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/anomalyco/opentui/pull/757 **Author:** [@amosbird](https://github.com/amosbird) **Created:** 3/1/2026 **Status:** ❌ Closed **Base:** `main` ← **Head:** `fix/mouse-sequence-split-data-loss` --- ### 📝 Commits (1) - [`98813ca`](https://github.com/anomalyco/opentui/commit/98813cad225f41bc536939e70905ccff1018883a) fix: forward unconsumed data after mouse sequence parsing ### 📊 Changes **4 files changed** (+56 additions, -21 deletions) <details> <summary>View changed files</summary> 📝 `packages/core/src/lib/parse.mouse.test.ts` (+42 -10) 📝 `packages/core/src/lib/parse.mouse.ts` (+2 -2) 📝 `packages/core/src/renderer.ts` (+11 -8) 📝 `packages/core/src/testing/integration.test.ts` (+1 -1) </details> ### 📄 Description ## Summary - `parseAllMouseEvents` now returns a `consumed` byte offset alongside parsed events, telling the caller exactly how many bytes were successfully parsed - `handleMouseData` in the renderer forwards any unconsumed trailing data to `_stdinBuffer.process()` instead of silently dropping it ## Problem When a stdin chunk contains complete mouse escape sequences followed by a partial one (e.g. `\x1b[<0;31;16M\x1b[<0;`), `parseAllMouseEvents` parses the complete event but the partial trailing bytes are silently dropped. When the next stdin chunk arrives with the remainder (`31;16M`), it can't be parsed as a mouse event (no `\x1b[` prefix), so it falls through to keyboard input handling — causing characters like `31M;` to appear in the input box. This is most commonly triggered by rapid mouse movement during terminal focus switches. ## Changes **`parse.mouse.ts`**: Changed `parseAllMouseEvents` return type from `RawMouseEvent[]` to `{ events: RawMouseEvent[]; consumed: number }`. **`renderer.ts`**: `handleMouseData` now checks if `consumed < data.length` and forwards the unconsumed remainder to `_stdinBuffer.process()`, which correctly handles partial CSI sequences with its existing buffering/timeout logic. **`parse.mouse.test.ts`**: Updated all call sites for new return type. Added 5 new tests covering `consumed` offset behavior (full consumption, trailing non-mouse data, partial SGR sequences, empty/non-mouse input). **`integration.test.ts`**: Updated helper to access `.events` from the new return type. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
kerem 2026-03-14 09:42:13 +03:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/opentui#1541
No description provided.