Skip to content

Terminal Engine And Screen State

This is the part of RoyalTerminal that behaves most like a terminal rather than a UI control. It is where bytes become a screen, modes affect input encoding, selections turn into exported text, and Unicode width rules determine how cells line up.

The screen model is explicit

RoyalTerminal exposes the screen state directly instead of hiding it behind a renderer-only abstraction. That is what makes it possible to support multiple VT processors, multiple renderers, capture/replay, search, snapshot export, and test-friendly host integration.

Core screen types

TypePurpose
TerminalCellOne grid cell, including codepoint or grapheme text, colors, attributes, hyperlink id, underline data, and width.
CellAttributesPacked attribute flags.
TerminalUnderlineStyleUnderline style enum.
CellDecorationsAdditional decoration flags such as overline.
TerminalHighlightKindSearch match, selected match, or hyperlink hover overlay category.
TerminalHighlightSpanViewport-local highlight span.
TerminalRowDirty-tracked row of cells.
TerminalScreenThe full scrollback-aware screen model, including hyperlinks, Kitty images, theme state, and viewport position.
TerminalKittyImageLayerKitty image z-order.
TerminalKittyImageSourceDecoded Kitty image payload.
TerminalKittyImagePlacementViewport-relative Kitty image placement.

Two VT engines, one processor boundary

RoyalTerminal uses one public processor contract and lets the host choose whether the implementation is fully managed or native.

TypeRole
IVtProcessorCore VT processor contract.
IVtProcessorFactoryFactory for processor creation.
INativeVtProcessorProviderOptional native VT provider contract.
VtProcessorPreferenceManaged, native, or automatic preference.
BasicVtProcessorPure C# fallback processor.
GhosttyVtProcessorNative Ghostty-backed processor.
GhosttyVtProcessorProviderNative provider used by the default factory.
DefaultVtProcessorFactoryPolicy object that selects managed or native processing.

In practice, this means the host can ask for strict native behavior, strict managed behavior, or native-when-available behavior without changing its session code.

Mode-aware host integration

The processor boundary is richer than "write bytes, get pixels". The host also needs cursor state, mode state, focus mode, and theme application.

TypePurpose
TerminalModeStateSnapshot of the major runtime VT modes.
TerminalCursorStyleHost-facing cursor style enum.
ITerminalThemeSinkApplies a new immutable theme to the active processor.
IKittyKeyboardStateSourceExposes Kitty keyboard flags.
ITerminalCursorStyleSourceExposes cursor shape and blink state.
ITerminalFocusEventModeSourceExposes focus event reporting state.
TerminalWin32InputModeTrackerTracks Win32 input mode and focus mode from terminal output.

These capabilities are what make TerminalControl able to encode input correctly without knowing which VT engine is active under the hood.

Endpoints and host-owned terminals

Not every RoyalTerminal host wants the built-in transport stack. Some applications already own the remote session or local terminal connection. That is why the endpoint contracts are public.

TypePurpose
ITerminalEndpointHost-owned terminal endpoint abstraction.
ITerminalInputSinkSends text or bytes into an endpoint.
ITerminalSelectionSourceExposes selection state and export behavior.
ITerminalModeSourceExposes mode state from an endpoint.
ITerminalScaleSinkReceives content scale changes.

Input encoding is part of the terminal model

Keyboard and pointer input are not generic UI events once you are inside a terminal. The active modes, pointer protocol, Kitty keyboard flags, and application keypad state all matter.

Event models

TypePurpose
TerminalInputActionHigh-level input action enum.
TerminalPointerEventKindPointer event kind enum.
TerminalMouseButtonPointer button enum.
TerminalModifiersModifier flags for terminal input.
TerminalKeyEventHost key event payload.
TerminalPointerEventHost pointer event payload.

Encoding and capability contracts

TypePurpose
TerminalKeyEncodingRequestKey encoding request payload.
TerminalPointerEncodingContextPointer encoding context.
ITerminalKeySequenceEncoderSourceCapability contract for key sequence encoding.
ITerminalPointerSequenceEncoderSourceCapability contract for pointer encoding.
ITerminalMouseReportingStateSourceCapability contract for current mouse reporting state.
TerminalPasteEncoderStatic helper for plain or bracketed paste sequences.

Terminals have a surprisingly large amount of public behavior around mouse state and viewport tracking. RoyalTerminal keeps that explicit because the UI layer needs it.

TypePurpose
TerminalMouseTrackingModeActive DEC mouse tracking mode.
TerminalMouseEncodingActive mouse encoding mode.
TerminalMouseModeStateSnapshot of current mouse-reporting behavior.
TerminalMouseModeTrackerIncremental parser that tracks mouse mode changes from terminal output.
TerminalMouseProtocolEncoderStatic encoder for X10, UTF-8, SGR, and URXVT mouse protocols.
TerminalViewportScrollStateViewport scrollbar state for native processors.
ITerminalViewportScrollSourceCapability contract for viewport scroll state.
TerminalSearchMatchSearch hit location.
ITerminalSearchSourceSearch capability contract.

Selection, snapshot export, and durable copies

Selections and snapshots sit right on the boundary between terminal logic and user workflows. That is why the contracts are in the core package instead of in Avalonia.

TypePurpose
TerminalSelectionRangeAbsolute selection range model.
ITerminalSelectionExportSourceSelection export capability contract.
ITerminalPasteSequenceEncoderSourcePaste sequence capability contract.
TerminalSnapshotExportFormatSnapshot export format enum.
TerminalSnapshotExportExtrasAdditional export detail flags.
TerminalSnapshotExportOptionsSnapshot export request model.
ITerminalSnapshotExportSourceSnapshot export capability contract.

Unicode is not an implementation detail

Terminal layout depends on Unicode width rules and grapheme boundaries, especially for emoji, combining marks, CJK full-width content, and selection fidelity. RoyalTerminal exposes these primitives because they affect correctness across the stack.

TypePurpose
TerminalCellWidthCalculatorWidth calculator used by the terminal stack.
CodepointUnicode codepoint wrapper with metadata helpers.
GraphemeGrapheme cluster slice.
GraphemeEnumeratorGrapheme enumerator over UTF-16 text.
GraphemeBreakClassGrapheme break class enum.
EastAsianWidthClassEast Asian width classification enum.

When something looks wrong in a terminal, it is often one of three things: the VT parser, the renderer, or width/grapheme handling. This is the layer where the parser and width logic meet.

MIT Licensed