[PR #749] [CLOSED] fix(core): prevent input starvation from high-frequency mouse scroll events #755

Closed
opened 2026-03-02 23:47:58 +03:00 by kerem · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/anomalyco/opentui/pull/749
Author: @androolloyd
Created: 2/27/2026
Status: Closed

Base: mainHead: fix/mouse-scroll-flood-input-starvation


📝 Commits (1)

  • 2c83eb5 fix(core): prevent input starvation from high-frequency mouse scroll events

📊 Changes

4 files changed (+133 additions, -30 deletions)

View changed files

📝 packages/core/src/lib/parse.mouse.test.ts (+67 -13)
📝 packages/core/src/lib/parse.mouse.ts (+7 -2)
📝 packages/core/src/renderer.ts (+58 -13)
📝 packages/core/src/testing/integration.test.ts (+1 -2)

📄 Description

Summary

Fixes #748 — high-frequency scroll wheels (Logitech MX Master 3 free-spin) cause keyboard input loss and event loop starvation.

Changes

1. Forward remaining non-mouse data from mixed stdin chunks

stdinListener previously returned early after handleMouseData found any mouse events, silently dropping non-mouse data (keyboard input, focus-in/out sequences) that arrived in the same OS read. Now handleMouseData returns the consumed byte count and stdinListener forwards the remainder to StdinBuffer.

2. Coalesce consecutive scroll events within a chunk

Added coalesceScrollEvents() that merges adjacent same-direction scroll events at the same coordinates into a single event with accumulated delta. This reduces the number of hit tests, MouseEvent constructions, and renderable dispatches from O(n) to O(1) per direction per chunk.

3. Return consumed offset from parseAllMouseEvents

Changed parseAllMouseEvents return type from RawMouseEvent[] to { events: RawMouseEvent[], consumed: number } so callers know exactly how many bytes were consumed and can handle the remainder appropriately.

Testing

  • Updated all existing parseAllMouseEvents tests for new return type
  • Added 5 new tests for consumed byte tracking (trailing focus sequences, keyboard data, mixed buffers)
  • Updated integration.test.ts for new return type
  • All 196 tests pass (mouse parser + stdin buffer + integration)

🔄 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/749 **Author:** [@androolloyd](https://github.com/androolloyd) **Created:** 2/27/2026 **Status:** ❌ Closed **Base:** `main` ← **Head:** `fix/mouse-scroll-flood-input-starvation` --- ### 📝 Commits (1) - [`2c83eb5`](https://github.com/anomalyco/opentui/commit/2c83eb50a892ec600753f1e9a94a135d1cf258ca) fix(core): prevent input starvation from high-frequency mouse scroll events ### 📊 Changes **4 files changed** (+133 additions, -30 deletions) <details> <summary>View changed files</summary> 📝 `packages/core/src/lib/parse.mouse.test.ts` (+67 -13) 📝 `packages/core/src/lib/parse.mouse.ts` (+7 -2) 📝 `packages/core/src/renderer.ts` (+58 -13) 📝 `packages/core/src/testing/integration.test.ts` (+1 -2) </details> ### 📄 Description ## Summary Fixes #748 — high-frequency scroll wheels (Logitech MX Master 3 free-spin) cause keyboard input loss and event loop starvation. ## Changes ### 1. Forward remaining non-mouse data from mixed stdin chunks `stdinListener` previously returned early after `handleMouseData` found any mouse events, silently dropping non-mouse data (keyboard input, focus-in/out sequences) that arrived in the same OS read. Now `handleMouseData` returns the consumed byte count and `stdinListener` forwards the remainder to `StdinBuffer`. ### 2. Coalesce consecutive scroll events within a chunk Added `coalesceScrollEvents()` that merges adjacent same-direction scroll events at the same coordinates into a single event with accumulated `delta`. This reduces the number of hit tests, MouseEvent constructions, and renderable dispatches from O(n) to O(1) per direction per chunk. ### 3. Return consumed offset from `parseAllMouseEvents` Changed `parseAllMouseEvents` return type from `RawMouseEvent[]` to `{ events: RawMouseEvent[], consumed: number }` so callers know exactly how many bytes were consumed and can handle the remainder appropriately. ## Testing - Updated all existing `parseAllMouseEvents` tests for new return type - Added 5 new tests for consumed byte tracking (trailing focus sequences, keyboard data, mixed buffers) - Updated `integration.test.ts` for new return type - All 196 tests pass (mouse parser + stdin buffer + integration) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
kerem 2026-03-02 23:47:58 +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#755
No description provided.