# Data flow — microsoft/terminal

> Canonical page: https://codevetter.com/unpack/terminal/data-flow

# Data flow — microsoft/terminal

Scanned commit 7c92ecd037476f957809d0813b14d8bc44bb071a (2026-09-18). Generated by codevetter codevetter 1.12.0 on 2026-09-22.

The core data path is bidirectional ConPTY pipes. Outbound: keystrokes travel XAML -> TermControl/ControlCore -> ITerminalConnection::WriteInput (UTF-16 to UTF-8, overlapped WriteFile on the ConPTY input pipe). Inbound: ConptyConnection's dedicated _OutputThread ReadFile's the output pipe and raises the TerminalOutput event; ControlCore::_connectionOutputHandler takes the terminal write lock and calls Terminal::Write -> StateMachine::ProcessString -> OutputStateMachineEngine -> ITermDispatch handlers that mutate TextBuffer rows; the Atlas renderer then paints the buffer. Settings flow from settings.json + inbox defaults.json + dynamic generators + fragments through SettingsLoader's layered ParsedSettings into CascadiaSettings, with a directory watcher triggering throttled reloads. Command lines flow through CLI11 parsing into ActionAndArgs vectors executed by ShortcutActionDispatch; between processes, whole invocations are serialized into WM_COPYDATA blobs.
- Input path: key presses reach the WindowEmperor message loop (which pre-filters F7, Alt keyup, and Alt+Space because XAML cannot suppress them), then XAML -> TermControl key handlers -> ControlCore::_sendInputToConnection -> ITerminalConnection::WriteInput. — [src/cascadia/WindowsTerminal/WindowEmperor.cpp#L643-715](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/WindowsTerminal/WindowEmperor.cpp#L643-L715) [src/cascadia/TerminalControl/ControlCore.cpp#L490-492](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/TerminalControl/ControlCore.cpp#L490-L492)
- ConptyConnection::WriteInput serializes writers with a first-come-first-served ticket lock, drains any pending overlapped write via GetOverlappedResult, converts UTF-16 to UTF-8 into _writeBuffer, and issues an overlapped WriteFile on the ConPTY pipe; ERROR_BROKEN_PIPE tears the connection down. — [src/cascadia/TerminalConnection/ConptyConnection.cpp#L553-596](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/TerminalConnection/ConptyConnection.cpp#L553-L596)
- Output path: ConptyConnection::Start creates an overlapped 128KB pipe pair and ConPTY, then spawns 'ConptyConnection Output Thread' running _OutputThread which ReadFile's the pipe and raises the TerminalOutput event; ConPTY size/show/reparent changes go through ConptyResizePseudoConsole/ConptyShowHidePseudoConsole/ConptyReparentPseudoConsole. — [src/cascadia/TerminalConnection/ConptyConnection.cpp#L400-475](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/TerminalConnection/ConptyConnection.cpp#L400-L475) [src/cascadia/TerminalConnection/ConptyConnection.cpp#L602-656](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/TerminalConnection/ConptyConnection.cpp#L602-L656)
- ControlCore::_connectionOutputHandler receives the connection's TerminalOutput string, takes _terminal->LockForWriting() (a til::recursive_ticket_lock in TerminalCore), calls Terminal::Write, then flushes any _pendingResponses (e.g. DA/DSR replies) back to the connection. — [src/cascadia/TerminalControl/ControlCore.cpp#L2286-2298](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/TerminalControl/ControlCore.cpp#L2286-L2298) [src/cascadia/TerminalCore/Terminal.cpp#L965-1014](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/TerminalCore/Terminal.cpp#L965-L1014)
- Terminal::Write feeds the VT StateMachine::ProcessString; OutputStateMachineEngine translates C0/C1/ESC/CSI/OSC sequences into ITermDispatch calls (Print, PrintString, LineFeed, CursorBackward, DeviceAttributes...) that land on the TextBuffer (src/buffer/out/textBuffer.cpp) via the adapter layer. — [src/cascadia/TerminalCore/Terminal.cpp#L482-484](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/TerminalCore/Terminal.cpp#L482-L484) [src/terminal/parser/stateMachine.cpp#L14-32](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/terminal/parser/stateMachine.cpp#L14-L32) [src/terminal/parser/OutputStateMachineEngine.cpp#L59-166](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/terminal/parser/OutputStateMachineEngine.cpp#L59-L166) [src/buffer/out/textBuffer.cpp](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/buffer/out/textBuffer.cpp)
- Rendering: ControlCore owns an AtlasEngine (Direct2D/DirectWrite text rasterization with optional D3D backend and custom shaders) created lazily in TermControl; EnablePainting/size changes flow TermControl::_InitializeTerminal -> _core.Initialize/SizeOrScaleChanged. — [src/cascadia/TerminalControl/TermControl.cpp#L2861-2864](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/TerminalControl/TermControl.cpp#L2861-L2864) [src/cascadia/TerminalControl/TermControl.cpp#L1376-1434](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/TerminalControl/TermControl.cpp#L1376-L1434) [src/renderer/atlas/AtlasEngine.cpp](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/renderer/atlas/AtlasEngine.cpp)
- Settings flow: CascadiaSettings::LoadAll reads settings.json via til::io::read_file_as_utf8_string_if_exists, falls back to a Release-channel copy on Preview/Canary first-run, seeds from embedded resources IDR_USER_DEFAULTS + IDR_DEFAULTS, then runs SettingsLoader steps in fixed order: GenerateProfiles -> ApplyRuntimeInitialSettings -> MergeInboxIntoUserSettings -> FindFragmentsAndMergeIntoUserSettings -> FinalizeLayering -> DisableDeletedProfiles/FixupUserSettings/AddDynamicProfileFolders. — [src/cascadia/TerminalSettingsModel/CascadiaSettingsSerialization.cpp#L1226-1321](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/TerminalSettingsModel/CascadiaSettingsSerialization.cpp#L1226-L1321)
- Settings location: GetBaseSettingsPath returns the packaged LocalState folder, or %LOCALAPPDATA%\Microsoft\Windows Terminal for unpackaged builds, or the exe directory when a '.portable' marker file exists (portable mode). — [src/cascadia/TerminalSettingsModel/FileUtils.cpp#L13-70](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/TerminalSettingsModel/FileUtils.cpp#L13-L70)
- Write-back: LoadAll only writes settings.json when it was a first-time setup or when fixups/new dynamic profiles require persistence; otherwise it just caches a hash of file content+timestamp used by AppLogic::_ProcessLazySettingsChanges to skip redundant Jumplist rebuilds. — [src/cascadia/TerminalSettingsModel/CascadiaSettingsSerialization.cpp#L1297-1317](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/TerminalSettingsModel/CascadiaSettingsSerialization.cpp#L1297-L1317) [src/cascadia/TerminalApp/AppLogic.cpp#L252-268](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/TerminalApp/AppLogic.cpp#L252-L268)
- Command-line data flow: GetCommandLineW -> commandlineToArgArray -> CommandlineArgs -> AppCommandlineArgs (CLI11) producing std::vector<ActionAndArgs> -> TerminalPage::ProcessStartupActions which feeds each entry to _actionDispatch->DoAction, suspending to the dispatcher between panes/tabs so WinUI can lay out controls (GH#13136). — [src/cascadia/WindowsTerminal/WindowEmperor.cpp#L40-53](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/WindowsTerminal/WindowEmperor.cpp#L40-L53) [src/cascadia/TerminalApp/TerminalPage.cpp#L724-786](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/TerminalApp/TerminalPage.cpp#L724-L786)
- Cross-process handoff serializes GetCommandLineW + full environment block + CWD + nCmdShow into a length-prefixed byte blob delivered by WM_COPYDATA with TERMINAL_HANDOFF_MAGIC ('TERMINAL'), retried with exponential backoff for ~30s until the owner finishes creating its message window. — [src/cascadia/WindowsTerminal/WindowEmperor.cpp#L112-197](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/WindowsTerminal/WindowEmperor.cpp#L112-L197)
- Environment synthesis for each session: ConptyConnection injects WT_SESSION (plain GUID) and WT_PROFILE_ID (braced GUID), merges user 'environment' overrides, and maintains WSLENV so those variables propagate into WSL; initial env comes from til::env::from_current_environment or a serialized block for handoffs. — [src/cascadia/TerminalConnection/ConptyConnection.cpp#L58-148](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/TerminalConnection/ConptyConnection.cpp#L58-L148) [src/cascadia/TerminalConnection/ConptyConnection.cpp#L297-317](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/TerminalConnection/ConptyConnection.cpp#L297-L317)
- Defterm/inbound handoff: when _pipe is already set (connection received via CTerminalHandoff), Start() skips CreatePseudoConsole/_LaunchAttachedClient and only resizes/reparents/shows the existing HPCON, logging 'ConPtyConnectedToDefterm' instead of launching a client. — [src/cascadia/TerminalConnection/ConptyConnection.cpp#L407-449](https://github.com/microsoft/terminal/blob/7c92ecd037476f957809d0813b14d8bc44bb071a/src/cascadia/TerminalConnection/ConptyConnection.cpp#L407-L449)

Every claim links to its cited files at the pinned commit. Citations identify source evidence; they do not establish runtime correctness. Independent CodeVetter scan — not reviewed by upstream maintainers.

## Public product links

- [CodeVetter](https://codevetter.com/)
- [Download](https://codevetter.com/download)
- [Documentation](https://codevetter.com/docs/)
- [Source](https://github.com/Codevetter/codevetter)
