vnm_terminal is a cross-platform terminal emulator for Windows, macOS, and
Linux. It is built on
vnm_terminal_surface,
which provides terminal parsing, process hosting (ConPTY/PTY), screen state,
and GPU-accelerated rendering, while this repository owns the application
window, command-line options, window chrome, and packaging-facing behavior.
Notable behavior:
- GPU glyph-atlas text rendering with MSDF and glyph renderers and LCD subpixel modes.
- Built-in window chrome on validated platforms, with
--native-titlebarto use the platform frame instead. - Safe clipboard defaults: OSC 52 clipboard writes from the hosted program are
denied unless explicitly allowed with
--osc52-clipboard allow. - Configurable paste shortcuts (
--paste-shortcut) and DEC synchronized-output scroll policy (--synchronized-output-scroll-policy).
Release source archives are attached to
GitHub releases as
vnm_terminal_v<version>_source.zip. They are generated by
tools/create_source_archive.ps1 and exclude generated CMDG build output and
repository metadata.
Binary packages may also be attached when the corresponding platform release build has produced them:
- Windows:
vnm_terminal_v<version>_w64.zipis a portable distribution. Unpack it and run the top-levelvnm_terminal.exelauncher. - macOS:
vnm_terminal_v<version>_macos_x64_unnotarized.zipcontains the app bundle. It is not Apple-notarized; see the macOS Bundle Build section for the Gatekeeper quarantine step.
On Linux, build from source as described below.
Source builds are the release baseline. Clone vnm_terminal_surface and
vnm_qml_chrome beside this repository, or pass
-DVNM_TERMINAL_SURFACE_SOURCE_DIR=<path> and
-DVNM_QML_CHROME_SOURCE_DIR=<path> during configure. Both dependencies are
version-gated against this app's project() version; installed CMake packages
are accepted only when they satisfy the same minimum versions. The release CI
source-dependency baseline tracks the master branches of
vnm_terminal_surface and vnm_qml_chrome; installed packages are supported by
CMake but are not the release validation baseline unless a release workflow
explicitly validates an installed-prefix build.
cmake -S . -B build -DBUILD_TESTING=ONTranscript capture/replay is sensitive debugging infrastructure and is compiled
out by default. Enable it only for local diagnostic builds with
-DVNM_TERMINAL_ENABLE_TRANSCRIPT_CAPTURE_REPLAY=ON. Distribution builds use
-DVNM_TERMINAL_DISTRIBUTION_BUILD=ON, which is incompatible with transcript
capture/replay.
Build from an x64 MSVC Developer Command Prompt or another shell where the Visual Studio C++ environment has already been initialized:
cmake --build build --target vnm_terminal --config Release.\build\Release\vnm_terminal.exeOn Windows, build the vnm_terminal target before launching the raw build
artifact. The build copies the required Qt runtime DLLs beside
vnm_terminal.exe and copies the platform plugin to platforms\. A stale build
directory created before that post-build deployment step must be rebuilt before
manual launch. Do not move the raw executable away from its neighboring DLLs and
platforms\ directory.
The app starts the platform default shell when no explicit command follows
--. On validated platforms it uses built-in window chrome by default; pass
--native-titlebar to use the platform frame instead.
Pass --text-renderer msdf or --text-renderer glyph before -- to force one
terminal text renderer for manual comparison. The default --text-renderer auto
uses the surface renderer's automatic selection and fallback behavior.
Pass --lcd-subpixel auto|none|rgb|bgr|vrgb|vbgr before -- to choose MSDF
LCD sampling. The default auto uses the display order reported by Qt and, on
Windows, falls back to the system ClearType orientation when Qt reports no
subpixel order.
Pass --selection-trace before -- to write selection diagnostics to stderr.
Diagnostic builds configured with
VNM_TERMINAL_ENABLE_TRANSCRIPT_CAPTURE_REPLAY=ON also accept
--capture-transcript <path> and --transcript-snapshot-diagnostics for
deterministic terminal replay diagnostics. Distribution builds omit those
options. Transcripts are sensitive: they include launch argv, launch cwd,
backend output bytes, typed and pasted input, resize, scroll, selection events,
and any optional snapshot text diagnostics.
Pass --disable-primary-repaint-recovery before -- to disable primary repaint
scrollback recovery for the launched session. It is enabled by default on
Windows and disabled by default elsewhere.
Pass --paste-shortcut <mode> before -- to choose the keyboard shortcut that
pastes clipboard text into the terminal. The default platform-default enables
Ctrl+V and Ctrl+Shift+V on every platform, plus Cmd+V on macOS.
ctrl-v-and-ctrl-shift-v keeps the Ctrl combinations
without the macOS Cmd+V shortcut, ctrl-shift-v restricts pasting to
Ctrl+Shift+V only, and disabled turns the paste shortcut off entirely. Mode
values are case-insensitive. Copy shortcuts are unaffected.
Synchronized-output scrolling is deferred until content publication by default.
Pass --synchronized-output-scroll-policy immediate-public before -- to
opt in to immediate public-projection scrolling during DEC synchronized-output
holds. Pass --synchronized-output-scroll-policy defer to request the default
policy explicitly. Policy values are case-insensitive.
Manual validation for immediate public scrolling should use an app build whose
post-build deployment step has copied the Qt DLLs and platforms\ plugin
beside vnm_terminal.exe. Diagnostic trace validation also requires a local
build configured with VNM_TERMINAL_ENABLE_TRANSCRIPT_CAPTURE_REPLAY=ON; those
transcript and wheel-trace flags are not present in distribution builds.
.\tools\synchronized_output_scroll_policy_repro.ps1 `
-TerminalExe .\build\Release\vnm_terminal.exe `
-Policy immediate-public `
-CaptureTranscript .\build\sync-scroll.ndjson `
-WheelTrace `
-TranscriptSnapshotDiagnosticsThe launcher validates that the selected app has the Qt runtime DLLs and
platforms\qwindows.dll plugin deployed beside it, or that it is a portable
launcher with that deployed layout under vnm_terminal_runtime\. It then passes
the policy and diagnostic flags to the app and runs the deterministic payload in
-PayloadOnly mode as the child process. During the repro, scroll the terminal
while the script is inside the hold. The transcript should show an immediate
effective policy for the hold, a PUBLIC_PROJECTION scroll snapshot before
release, no hidden sentinel rows or metadata before release, a release
reconciliation result, and the post-release suffix only after release.
Run a specific command by placing it after --:
.\build\Release\vnm_terminal.exe --window-size 1000x640 -- cmd.exeRun tests:
ctest --test-dir build -C Release --output-on-failureWindows portable zips use the same layout as the local portable distribution:
the top-level vnm_terminal.exe is a launcher, and the real Qt application plus
deployed runtime files live in vnm_terminal_runtime\.
Copy build_config.bat.example to build_config.bat, adjust the local Qt
MinGW, CMake, Ninja, vnm_terminal_surface, and vnm_qml_chrome paths, then
run:
build_portable.batThe script writes dist\portable_candidate\ and dist\vnm_terminal_v<version>_w64.zip,
where <version> is the project() version in CMakeLists.txt (derived from
the configured CMake cache, not hardcoded).
build_portable.bat is the release-provenance build path and requires Git
metadata for the app, vnm_terminal_surface, and vnm_qml_chrome checkouts.
When building from a source archive without .git directories, use the regular
CMake source build instructions above instead of this portable release script.
Portable releases are built with VNM_TERMINAL_DISTRIBUTION_BUILD=ON,
VNM_TERMINAL_ENABLE_PROFILING=OFF, and transcript capture/replay disabled.
They are packaged from the Qt MinGW kit and include the required Qt and MinGW
runtime DLLs beside the real application in vnm_terminal_runtime\. The build
info file records the app, surface, and chrome Git revisions used for the
package.
Launch the portable distribution through dist\portable_candidate\vnm_terminal.exe.
That top-level executable is a launcher; do not launch the raw
build_portable\vnm_terminal.exe as a substitute for portable validation.
Create the release source archive with:
powershell -NoProfile -ExecutionPolicy Bypass -File tools\create_source_archive.ps1The script writes dist\vnm_terminal_v<version>_source.zip and fails if the
archive would contain .git contents or generated
THIRD_PARTY/CMDG/CMDG/bin or THIRD_PARTY/CMDG/CMDG/obj output.
The macOS GitHub Actions workflow builds a Release vnm_terminal.app with
VNM_TERMINAL_DISTRIBUTION_BUILD=ON, VNM_TERMINAL_ENABLE_PROFILING=OFF, and
transcript capture/replay disabled, deploys its Qt runtime with macdeployqt,
ad-hoc signs the unsigned bundle, and uploads
vnm_terminal_v<version>_macos_x64_unnotarized.zip as a workflow artifact.
When a GitHub release is published, the workflow also attaches that ZIP to the
release. The bundle includes Contents/Resources/vnm_terminal_build_info.txt
with the app, surface, chrome, Qt, and build-configuration provenance used for
that artifact.
The macOS bundle is not Apple-notarized. Gatekeeper may block it on first run. Users who trust the downloaded build can remove the quarantine attribute:
xattr -dr com.apple.quarantine /path/to/vnm_terminal.app
open /path/to/vnm_terminal.appBSD 2-Clause. See LICENSE.