Utilities

Every mention of active terminal in this module refers to the first terminal device discovered.

The following streams/files are checked in the following order of priority (along with the rationale behind the ordering):

  • STDOUT: Since it’s where images will most likely be drawn.

  • STDIN: If output is redirected to a file or pipe and the input is a terminal, then using it as the active terminal should give the expected result i.e the same as when output is not redirected.

  • STDERR: If both output and input are redirected, it’s usually unlikely for errors to be.

  • /dev/tty: Finally, if all else fail, fall back to the process’ controlling terminal, if any.

The first one that is ascertained to be a terminal device is used for all terminal queries and terminal size computations.

Note

If none of the streams/files is a terminal device, then a warning is issued and affected functionality disabled.

Terminal Queries

Some functionalities of this library require the aquisition of certain information from the active terminal. A single iteration of this aquisition procedure is called a query.

A query involves three major steps:

  1. Clear all unread input from the terminal

  2. Write to the terminal

  3. Read from the terminal

For this procedure to be successful, it must not be interrupted.

About #1

If the program is expecting input, use read_tty() (simply calling it without any argument is enough) to read all currently unread input (without blocking) just before any operation involving a query.

About #2 and #3

After sending a request to the terminal, its response is awaited. The default wait time is 0.1 seconds but can be changed using set_query_timeout().

If the program includes any other function that could write to the terminal OR especially, read from the terminal or modify it’s attributes, while a query is in progress, decorate it with lock_tty() to ensure it doesn’t interfere.

For example, the TUI included in this package (i.e term_image) uses urwid which reads from the terminal using urwid.raw_display.Screen.get_available_raw_input(). To prevent this method from interfering with terminal queries, it is wrapped thus:

urwid.raw_display.Screen.get_available_raw_input = lock_tty(
    urwid.raw_display.Screen.get_available_raw_input
)
Also, if the active terminal is not the controlling terminal of the process using this library (e.g output is redirected to another terminal), ensure no process that can interfere with a query (e.g a shell) is currently running in the active terminal.
For instance, such a process can be temporarily put to sleep.

List of features that use terminal queries

In parentheses are the outcomes when the terminal doesn’t support queries or when queries are disabled.

  • Auto Cell Ratio (determined to be unsupported)

  • Support checks for Graphics-based Render Styles (determined to be unsupported)

  • Auto background color (black is used)

  • Alpha blend for pixels above the alpha threshold in transparent renders with Text-based Render Styles (black is used)

  • Workaround for ANSI background colors in text-based renders on the Kitty terminal (the workaround is disabled)

Note

This list might not always be complete. In case you notice

  • any difference with any unlisted feature when terminal queries are enabled versus when disabled, or

  • a behaviour different from the one specified for the listed features, when terminal queries are disabled,

please open an issue here.


The term_image.utils module provides the following public definitions.

Attention

Any other definition in this module should be considered part of the private interface and can change without notice.

term_image.utils.lock_tty(func)

Synchronizes access to the active terminal.

Parameters

func (Callable) – The function to be wrapped.

When any decorated function is called, a re-entrant lock is acquired by the current process or thread and released after the call, such that any other decorated function called within another thread or subprocess has to wait till the lock is fully released (i.e has been released as many times as acquired) by the current process or thread.

Note

It automatically works across parent-/sub-processes, started directly or indirectly via multiprocessing.Process (or a subclass of it) and their threads.

Important

It only works if multiprocessing.synchronize is supported on the host platform. If not supported, a warning is issued when starting a subprocess.

term_image.utils.read_tty(more=<function <lambda>>, timeout=None, min=0, *, echo=False)

Reads input directly from the active terminal with/without blocking.

Parameters
  • more (Callable[[bytearray], bool]) –

    A callable, which when passed the input recieved so far, as a bytearray object, returns a boolean. If it returns:

    • True, more input is waited for.

    • False, the input recieved so far is returned immediately.

  • timeout (Optional[float]) – Time limit for awaiting input, in seconds.

  • min (int) – Causes to block until at least the given number of bytes have been read.

  • echo (bool) – If True, any input while waiting is printed unto the screen. Any input before or after calling this function is not affected.

Returns

The input read (empty, if min == 0 (default) and no input is recieved before timeout is up).

Return type

Optional[bytes]

If timeout is None (default), all available input is read without blocking.

If timeout is not None and:

  • timeout < 0, it’s infinite.

  • min > 0, input is waited for until at least min bytes have been read.

    After min bytes have been read, the following points apply with timeout being the leftover of the original timeout, if not yet used up.

  • more is not given, input is read or waited for until timeout is up.

  • more is given, input is read or waited for until more(input) returns False or timeout is up.

Upon return or interruption, the active terminal is immediately restored to the state in which it was met.

Note

Currently works on UNIX only, returns None on any other platform or when there is no active terminal.

term_image.utils.set_query_timeout(timeout)

Sets the global timeout for Terminal Queries.

Parameters

timeout (float) – Time limit for awaiting a response from the terminal, in seconds.

Raises
  • TypeErrortimeout is not a float.

  • ValueErrortimeout is less than or equal to zero.

term_image.utils.DISABLE_QUERIES: bool = False

If True, Terminal Queries are disabled, thereby affecting all dependent features.

term_image.utils.SWAP_WIN_SIZE: bool = False

A workaround for some terminal emulators (e.g older VTE-based ones) that wrongly report window dimensions swapped.

If True, the dimensions reported by the terminal emulator are swapped.
This setting affects Auto Cell Ratio computation.