Back to Projects
TUIX v0.2.0Beta

Last Updated: 2026-05-20

Input Handling

TUIX captures keyboard and mouse input on a dedicated background thread and delivers events to widgets via snapshots.

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. The main thread consumes events by calling input.get_snapshot(), which pops one event from each queue and returns them in a TuixInputSnapshot structure.

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.

snap = input.get_snapshot()

# Feed to interactive widgets
objects.tuix_choice_feed_input(obj, snap)
# or
objects.tuix_input_feed_input(obj, snap)

Snapshots are the bridge between the input thread and widget logic. You call get_snapshot() once per frame and pass the result to each widget that needs input.

Keyboard Events

Keyboard events contain key code, scan code, modifier flags, press/repeat state, timestamp, and up to 8 bytes of UTF-8 text.

FieldTypeDescription
btnintKey button identifier
codeintKey code
scancodeintHardware scan code
modifiersintModifier flags (Shift, Ctrl, Alt)
pressedint1 if key is down, 0 if up
repeatint1 if this is a key repeat event
timestampdoubleEvent timestamp
has_eventint1 if an event is present
textchar[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 TypeValueDescription
TUIX_MOUSE_NONE0No event
TUIX_MOUSE_PRESS1Button pressed
TUIX_MOUSE_RELEASE2Button released
TUIX_MOUSE_HOVER3Mouse moved (no button)
TUIX_MOUSE_DRAG4Mouse moved with button held
TUIX_MOUSE_SCROLL_UP5Scroll wheel up
TUIX_MOUSE_SCROLL_DOWN6Scroll wheel down
TUIX_MOUSE_DOUBLE_CLICK7Double-click detected
TUIX_MOUSE_HSCROLL_LEFT8Horizontal scroll left
TUIX_MOUSE_HSCROLL_RIGHT9Horizontal scroll right
ButtonValue
TUIX_BTN_LEFT0
TUIX_BTN_MIDDLE1
TUIX_BTN_RIGHT2
TUIX_BTN_X13
TUIX_BTN_X24

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 input, objects

# Start listening
input.listen()

# In your render loop
while running:
    snap = input.get_snapshot()
    objects.tuix_choice_feed_input(choice_obj, snap)
    objects.tuix_input_feed_input(input_obj, snap)
    # ... render ...

# Stop listening
input.stop()
Multi-Widget Input (v0.2.0 Limitation)In v0.2.0, the same snapshot is fed to all widgets. There is no focus system — every interactive widget processes the same keystroke. A focus routing mechanism is planned for v0.2.1.