subsequence.keystroke ===================== .. py:module:: subsequence.keystroke .. autoapi-nested-parse:: Single-keystroke input listener for live compositions. Provides a background thread that reads individual keystrokes from stdin without requiring the user to press Enter. Designed to work alongside :class:`subsequence.display.Display` without conflicts — the display writes to **stderr** while this module reads from **stdin**. **Platform support:** Linux and macOS. Requires :mod:`tty` and :mod:`termios`, which are only available on POSIX systems. On unsupported platforms (e.g. Windows, or environments where stdin is not a real TTY), the listener starts in a degraded mode and logs a warning instead of raising an exception. Check :data:`HOTKEYS_SUPPORTED` at import time to know whether the current platform can support hotkeys. This module is used internally by :class:`subsequence.composition.Composition` when hotkeys are enabled via ``composition.hotkeys()``. You do not need to import it directly. Module Contents --------------- .. py:class:: KeystrokeListener Background daemon thread that reads single keystrokes from stdin. Puts stdin into *cbreak* mode so each keypress is delivered immediately, without waiting for Enter. Keystrokes are placed in a thread-safe queue and retrieved by the caller via :meth:`drain`. Terminal settings are always restored on shutdown, even if an exception occurs, so a crashed listener will not leave the terminal in a broken state. If the current platform does not support hotkeys (:data:`HOTKEYS_SUPPORTED` is ``False``), :meth:`start` logs a warning and returns immediately without starting the thread. All other methods remain safe no-ops. Example:: listener = KeystrokeListener() listener.start() # ...later, from the event loop... for key in listener.drain(): handle(key) listener.stop() Initialise the listener in a stopped state. .. py:method:: drain() -> List[str] Return all keystrokes that have arrived since the last drain. Non-blocking. Returns an empty list if nothing has been pressed, or if the listener is not active. Safe to call at any time. :returns: A list of single-character strings, one per keypress, in order. .. py:method:: start() -> None Start the background keystroke listener thread. Puts stdin into cbreak mode and begins reading. Call :meth:`stop` to restore normal terminal behaviour. Safe to call more than once — a second call while already running is a no-op. If :data:`HOTKEYS_SUPPORTED` is ``False``, logs a warning and returns without starting the thread. :attr:`active` will remain ``False``. .. py:method:: stop() -> None Signal the listener to stop and restore the terminal. Waits briefly for the background thread (it polls every ~0.1 s), then restores the terminal settings directly if the thread has not done so — a daemon thread killed at interpreter exit never runs its ``finally`` block, which used to leave the shell in cbreak mode (no echo) on most clean exits. Safe to call on an unsupported platform — it is a no-op.