Skip to content

ANSI printable-suppression window swallows real Tab within 50ms of Shift+Tab #5638

Closed

Description

@tig

Summary

AnsiInputProcessor's 50 ms printable-suppression window (the OnKeyboardEventParsed/ShouldSuppressFallbackKeyDown dedup of dual-reported keys) swallows a real \t keypress arriving within 50 ms of a parsed Shift+Tab (ESC[Z), because GetPrintableText () returns "\t" for both. Fast sequences like Shift+Tab then Tab lose the Tab.

Likely a regression caused by #5602 .

Found during

v2.5.0 ecosystem validation (#5630), porting tui-cs/Editor to a preview package built from #5416 head e8aba423 (2.5.0-tig-remove-cm-followup.2).

Repro / evidence

Impact

Dropped keystrokes under fast input on the ANSI driver (e.g., outdent-then-indent in an editor). Release-gating for v2.5.0 (#5630): fix or waive before Prepare Release.

Found by Claude (Fable 5) agents during the #5630 ecosystem-validation gate.

Activity

  1. changed the title [-]v2.5.0 preview: ANSI printable-suppression window swallows real Tab within 50ms of Shift+Tab[/-] [+]ANSI printable-suppression window swallows real Tab within 50ms of Shift+Tab[/+] on Aug 23, 2026
  2. added theissue type on Aug 23, 2026
  3. added this to the v2.x milestone on Aug 23, 2026
  4. YourRobotOverlord commented on Aug 23, 2026

    @YourRobotOverlord
    Collaborator

    I traced this through the history. The repro is valid, but #5602 is not causal: it changed only output-buffer dirty-row handling and did not touch the input pipeline.

    The current 50 ms implementation came from #5618 (b2525d126), merged six minutes after #5602. That may be the intended reference.

    There is a further nuance: the underlying Shift+Tab → Tab false positive predates #5618. The OnKeyboardEventParsed / ShouldSuppressFallbackKeyDown mechanism was introduced by #4927 (e532d6101). It already behaved as follows:

    1. ESC[Z is parsed as Key.Tab.WithShift.
    2. Shift-modified presses are allowed to arm printable suppression.
    3. GetPrintableText () returns "\t" for Key.Tab.WithShift.
    4. The next raw \t reaches fallback processing, matches the pending text, and is suppressed.

    Before #5618, that pending suppression had no expiry. #5618 narrowed it to 50 ms but retained the collision. Its coverage exercises kitty CSI-u plus legacy duplicates, not a complete legacy Shift+Tab report followed by a separate Tab keypress.

    So the attribution appears to be:

    The deeper problem is provenance: any parsed keyboard event can arm logic intended to deduplicate kitty plus legacy dual reports. ESC[Z is already a complete Shift+Tab report and should not arm suppression for a following raw Tab. A robust fix should restrict arming to inputs that can legitimately be dual-reported, or preserve parser provenance; matching only text plus elapsed time cannot reliably distinguish two physical keypresses.

  5. added 2 commits that reference this issue on Aug 23, 2026
    13db062
    8a4d450
  6. added a commit that references this issue on Aug 24, 2026
    59e6b4d
  7. added a commit that references this issue on Sep 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Type

Projects

Relationships

None yet

Development

No branches or pull requests

Issue actions