[PR #357] [MERGED] feat: add kitty event types #1259

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

📋 Pull Request Information

Original PR: https://github.com/anomalyco/opentui/pull/357
Author: @melMass
Created: 11/28/2025
Status: Merged
Merged: 11/28/2025
Merged by: @kommander

Base: mainHead: fix-kittykb-release


📝 Commits (2)

  • dac941b feat: add kitty event types
  • b16f23c feat(solid): add keyboard event options to useKeyboard hook

📊 Changes

5 files changed (+175 additions, -3 deletions)

View changed files

📝 packages/core/src/lib/parse.keypress-kitty.test.ts (+44 -0)
📝 packages/core/src/lib/parse.keypress-kitty.ts (+85 -0)
📝 packages/core/src/renderer.ts (+1 -1)
📝 packages/core/src/zig/terminal.zig (+25 -1)
📝 packages/solid/src/elements/hooks.ts (+20 -1)

📄 Description

For a nodegraph I'm prototyping in opentui I needed multiple key handling.
I'm using the solid flavor and the useKeyboard hook, looking into it I realized it was only listening keypress, tracing it up and using the raw renderer keyInput I wasn't receiving the release at all.

AI Summary (double checked/corrected)


Why this matters

Key release detection enables:

  • Simultaneous key handling - detect multiple keys held at once (e.g., diagonal movement with up+right)
  • Games and interactive apps - smooth movement, proper key state tracking
  • Hold-to-repeat vs tap - distinguish between holding a key and tapping it
  • Modifier key state - know when shift/ctrl/alt are released, not just pressed

Without release events, apps can only react to key presses one at a time with no way to know when a key is let go.

Problem

The Kitty Keyboard Protocol requires specific flags to report event types:

  • Bit 0 (1): Report alternate keys
  • Bit 1 (2): Report event types (press/repeat/release)

We were only enabling bit 0, so terminals never sent release events.

Additionally, arrow keys use a "legacy" format (CSI 1;modifiers:event_type LETTER) that wasn't being parsed.

Changes

Enable event type reporting

  • Changed default kitty_keyboard_flags from 0b00001 to 0b00011 in both Zig and TS
  • This enables press/repeat/release event reporting

Parse legacy arrow key format

  • Added parseKittyLegacy() to handle sequences like \x1b[1;1:3A (up arrow release)
  • Format: CSI 1;modifiers:event_type LETTER where:
    • modifiers: standard Kitty modifier mask
    • event_type: 1=press, 2=repeat, 3=release
    • LETTER: A=up, B=down, C=right, D=left, H=home, F=end, P-S=f1-f4

Improve Kitty keyboard capability detection

  • Added detection for CSI ? N u response pattern (sent by Ghostty, etc.)
  • Previously only detected via "kitty" string in terminal name

Enhanced useKeyboard hook (solid)

  • Added optional release flag to include release events
  • Added optional repeat flag to include repeat events
  • Same callback receives all events - use e.eventType to differentiate
  • Backwards compatible - existing code works unchanged

Example

// Simple press handling (unchanged)
useKeyboard((e) => console.log(`${e.name} pressed`));

// With release events - same callback, check eventType
useKeyboard((e) => {
  if (e.eventType === "press") {
    keys.add(e.name);
  } else if (e.eventType === "release") {
    keys.delete(e.name);
  }
}, { release: true });

BEFORE

https://github.com/user-attachments/assets/1323ce3f-f094-4691-8dda-a45aa2fa8bd1

AFTER

using {release:true} (so no repeat), repeat only repeat the last keypress if multiple are selected

https://github.com/user-attachments/assets/3b573fa5-3c66-432b-8207-05bb745c9324


🔄 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/357 **Author:** [@melMass](https://github.com/melMass) **Created:** 11/28/2025 **Status:** ✅ Merged **Merged:** 11/28/2025 **Merged by:** [@kommander](https://github.com/kommander) **Base:** `main` ← **Head:** `fix-kittykb-release` --- ### 📝 Commits (2) - [`dac941b`](https://github.com/anomalyco/opentui/commit/dac941b8964d02dd01269651ce4b22e6cb4b1cb6) feat: add kitty event types - [`b16f23c`](https://github.com/anomalyco/opentui/commit/b16f23cf1476126973fb1c1d972aa74962f67e0b) feat(solid): ✨ add keyboard event options to useKeyboard hook ### 📊 Changes **5 files changed** (+175 additions, -3 deletions) <details> <summary>View changed files</summary> 📝 `packages/core/src/lib/parse.keypress-kitty.test.ts` (+44 -0) 📝 `packages/core/src/lib/parse.keypress-kitty.ts` (+85 -0) 📝 `packages/core/src/renderer.ts` (+1 -1) 📝 `packages/core/src/zig/terminal.zig` (+25 -1) 📝 `packages/solid/src/elements/hooks.ts` (+20 -1) </details> ### 📄 Description For a nodegraph I'm prototyping in opentui I needed multiple key handling. I'm using the solid flavor and the useKeyboard hook, looking into it I realized it was only listening keypress, tracing it up and using the raw renderer `keyInput` I wasn't receiving the release at all. # AI Summary (double checked/corrected) --- ## Why this matters Key release detection enables: - **Simultaneous key handling** - detect multiple keys held at once (e.g., diagonal movement with up+right) - **Games and interactive apps** - smooth movement, proper key state tracking - **Hold-to-repeat vs tap** - distinguish between holding a key and tapping it - **Modifier key state** - know when shift/ctrl/alt are released, not just pressed Without release events, apps can only react to key presses one at a time with no way to know when a key is let go. ## Problem The Kitty Keyboard Protocol requires specific flags to report event types: - Bit 0 (1): Report alternate keys - Bit 1 (2): Report event types (press/repeat/release) We were only enabling bit 0, so terminals never sent release events. Additionally, arrow keys use a "legacy" format (`CSI 1;modifiers:event_type LETTER`) that wasn't being parsed. ## Changes ### Enable event type reporting - Changed default `kitty_keyboard_flags` from `0b00001` to `0b00011` in both Zig and TS - This enables press/repeat/release event reporting ### Parse legacy arrow key format - Added `parseKittyLegacy()` to handle sequences like `\x1b[1;1:3A` (up arrow release) - Format: `CSI 1;modifiers:event_type LETTER` where: - modifiers: standard Kitty modifier mask - event_type: 1=press, 2=repeat, 3=release - LETTER: A=up, B=down, C=right, D=left, H=home, F=end, P-S=f1-f4 ### Improve Kitty keyboard capability detection - Added detection for `CSI ? N u` response pattern (sent by Ghostty, etc.) - Previously only detected via "kitty" string in terminal name ### Enhanced `useKeyboard` hook (solid) - Added optional `release` flag to include release events - Added optional `repeat` flag to include repeat events - Same callback receives all events - use `e.eventType` to differentiate - Backwards compatible - existing code works unchanged ## Example ```tsx // Simple press handling (unchanged) useKeyboard((e) => console.log(`${e.name} pressed`)); // With release events - same callback, check eventType useKeyboard((e) => { if (e.eventType === "press") { keys.add(e.name); } else if (e.eventType === "release") { keys.delete(e.name); } }, { release: true }); ``` --- ## BEFORE https://github.com/user-attachments/assets/1323ce3f-f094-4691-8dda-a45aa2fa8bd1 ## AFTER using `{release:true}` (so no repeat), repeat only repeat the last keypress if multiple are selected https://github.com/user-attachments/assets/3b573fa5-3c66-432b-8207-05bb745c9324 --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
kerem 2026-03-14 09:27:08 +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#1259
No description provided.