Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Rikitav/Terminality/llms.txt

Use this file to discover all available pages before exploring further.

HostApplication is the singleton that owns the terminal session and drives the main UI loop. You retrieve it with HostApplication::Current(), call EnterTerminal() to configure raw input mode, hand it a root widget via RunUILoop(), and restore the terminal state with ExitTerminal() when the loop exits. The companion struct HostBackend provides the two platform calls the loop relies on: querying the viewport size and polling for input events.

Canonical app skeleton

Every Terminality application follows the same three-line lifecycle pattern:
int main()
{
    HostApplication& app = HostApplication::Current();
    app.EnterTerminal();
    app.RunUILoop(std::make_unique<MyRootWidget>());
    app.ExitTerminal();
    return 0;
}
RunUILoop blocks until the loop exits — either because RequestStop() was called, the user pressed Escape, or an overlay called Close() on itself. ExitTerminal() is always called after the loop returns to restore the original terminal state.

HostApplication

The application singleton. Non-copyable and non-movable; obtain the instance with Current().

Static methods

static HostApplication& Current();
Returns the process-wide HostApplication instance. The object is constructed on first call using a local static; it is safe to call from any thread before RunUILoop starts, but you must only call RunUILoop and NestUILoop from the thread that called Current() first.
static bool IsUiThread();
Returns true when called from the thread that started the UI loop. Use this as a guard when you need to distinguish the render thread from background threads before accessing shared engine state.

Terminal lifecycle

void EnterTerminal();
Switches the terminal into raw (unbuffered) input mode, hides the cursor, and performs any platform-specific setup required before the first render pass. Call this once before RunUILoop.
void ExitTerminal();
Restores the terminal to the state it was in before EnterTerminal() was called — cooked mode, visible cursor, and any platform-specific teardown. Call this after RunUILoop returns.

UI loop

void RunUILoop(std::unique_ptr<VisualTreeNode> root);
Pushes root as the first UILayer onto VisualTree, starts the DispatchTimer, and enters the event/render loop by calling NestUILoop internally. The method blocks until the layer’s Running flag is cleared.
root
std::unique_ptr<VisualTreeNode>
required
The root widget that fills the entire viewport. Ownership is transferred to the VisualTree. Passing nullptr throws std::runtime_error.
Throws std::runtime_error if a UI loop has already been started on another thread, or if root is nullptr.
void NestUILoop(UILayer& layer);
Runs an inner event/render loop that processes input and layout for layer until layer.Running becomes false. Used internally by dialogs and overlay windows (such as MessageBox and ContextMenu) to block the caller while the overlay is visible, without starting a new thread.
layer
UILayer&
required
The UILayer to drive. The layer must already be pushed onto VisualTree before this call. Set layer.Running to false (or call RequestStop()) to exit the nested loop.
void RequestStop();
Signals the DispatchTimer to stop, which causes the active NestUILoop iteration to exit on its next tick. This is the correct way to quit from inside a hotkey callback or event handler:
OnHotkey(InputModifier::None, InputKey::ESCAPE, [](ControlBase* self)
{
    HostApplication::Current().RequestStop();
});

HostBackend

A stateless utility struct that wraps the two platform-specific operations the UI loop calls every frame. You rarely need to call these directly, but they are part of the public API for testing and custom loop implementations.
static Size QueryViewportSize();
Returns the current terminal dimensions as a Size (width in columns, height in rows). The loop calls this every tick to detect resize events and trigger a layout pass.
return
Size
Terminal dimensions. Width is the column count; Height is the row count.
static InputEvent PollInput(std::chrono::milliseconds timeout);
Waits up to timeout for a key or mouse event from the terminal and returns it as an InputEvent. If no event arrives within the timeout, returns an InputEvent with Key == InputKey::None.
timeout
std::chrono::milliseconds
required
Maximum time to block waiting for input. The loop passes the remaining frame budget (typically a fraction of a 60 Hz frame) so that layout and rendering still run at a predictable rate.
return
InputEvent
The key event that arrived, or an event with Key == InputKey::None if the timeout elapsed without input.

Build docs developers (and LLMs) love