Input Handling
TUIX captures keyboard and mouse input on a dedicated background thread and delivers events to widgets via snapshots. In v0.3, input handling is automatic in the default builder pipeline.
Architecture
The input system runs as a background thread started by input.listen(). It reads raw platform events and enqueues them into two circular buffers: one for keyboard events and one for mouse events. Each buffer holds up to 128 events. In standard v0.3 usage, the frame loop and builder callbacks consume snapshots automatically.
Input Snapshots
A snapshot is a point-in-time capture of the input state. It contains the current terminal dimensions and pointers to keyboard and mouse event data.
# Automatic path (v0.3 default)
while running:
engine.main_loop()Snapshots are still the bridge between the input thread and widget logic. You can call input.get_snapshot() manually when needed, but the default v0.3 builder flow handles this for you.
Keyboard Events
Keyboard events contain key code, scan code, modifier flags, press/repeat state, timestamp, and up to 8 bytes of UTF-8 text.
| Field | Type | Description |
|---|---|---|
| btn | int | Key button identifier |
| code | int | Key code |
| scancode | int | Hardware scan code |
| modifiers | int | Modifier flags (Shift, Ctrl, Alt) |
| pressed | int | 1 if key is down, 0 if up |
| repeat | int | 1 if this is a key repeat event |
| timestamp | double | Event timestamp |
| has_event | int | 1 if an event is present |
| text | char[8] | UTF-8 text generated by the key |
Mouse Events
Mouse events capture position, button, and event type. The event system supports press, release, hover, drag, scrolling, and double-click.
| Event Type | Value | Description |
|---|---|---|
| TUIX_MOUSE_NONE | 0 | No event |
| TUIX_MOUSE_PRESS | 1 | Button pressed |
| TUIX_MOUSE_RELEASE | 2 | Button released |
| TUIX_MOUSE_HOVER | 3 | Mouse moved (no button) |
| TUIX_MOUSE_DRAG | 4 | Mouse moved with button held |
| TUIX_MOUSE_SCROLL_UP | 5 | Scroll wheel up |
| TUIX_MOUSE_SCROLL_DOWN | 6 | Scroll wheel down |
| TUIX_MOUSE_DOUBLE_CLICK | 7 | Double-click detected |
| TUIX_MOUSE_HSCROLL_LEFT | 8 | Horizontal scroll left |
| TUIX_MOUSE_HSCROLL_RIGHT | 9 | Horizontal scroll right |
| Button | Value |
|---|---|
| TUIX_BTN_LEFT | 0 |
| TUIX_BTN_MIDDLE | 1 |
| TUIX_BTN_RIGHT | 2 |
| TUIX_BTN_X1 | 3 |
| TUIX_BTN_X2 | 4 |
Platform Implementation
On Windows, the input thread uses ReadConsoleInputW to receive native KEY_EVENT_RECORD and MOUSE_EVENT_RECORD structures. A button state machine tracks press/release edges for accurate click detection. ENABLE_VIRTUAL_TERMINAL_INPUT is intentionally not used to avoid a Windows bug where SGR-encoded mouse events are misinterpreted as keyboard input.
On POSIX systems (Linux, macOS), the terminal is set to raw mode and a single pthread reads from stdin. Mouse events are parsed from SGR escape sequences. The terminal mode is restored when input.stop() is called.
Usage Pattern
from tuix.core import engine, input
input.listen()
while running:
engine.main_loop()
input.stop()