ddidderr 2e5ec06b4e fix(renderer): prevent display teardown starvation during output floods
Closing a busy split or confirming a tab close could freeze GTK while
unrealizing the GLArea. Both reported GDB traces show the main thread
waiting for the CPU frame-state mutex while the renderer keeps rebuilding
dense text. GTK unrealizes the display before stopping the workers, so
continuous output can keep the competing renderer active indefinitely.

Use parking_lot fair mutexes for CPU frame state and GPU draw state. A
waiting lifecycle or draw callback receives ownership instead of losing
it to the next frame update. Keep the existing lock order and resource
cleanup; no output, scrollback, or frame-rate limits are introduced. The
fair-lock handoff adds scheduling overhead when the locks are contended.

Correct the threading documentation: the CPU state is also accessed by
apprt callbacks, and the Rust-only mutex is therefore contended.

Test plan:
- Add a mock GPU regression continuously rebuilding 200x150 dense cells
  while another thread unrealizes and realizes the display. It failed
  its three-second deadline with the old locks and passes with fair locks.
- All 235 renderer/core tests pass, including Mesa EGL rendering tests.
- Clippy for renderer/core/GTK, all targets, passes with -D warnings.
- Nightly formatting check and release binary build pass.
- GTK/Wayland replay with font size 9 and 1 GiB scrollback runs base64
  floods in two splits, confirms split and tab closes, then successfully
  executes and renders a command in the surviving terminal.

Docs: docs/rewrite/ARCHITECTURE.md
2026-10-15 18:42:36 +02:00
2026-10-11 21:27:49 +02:00
2026-10-11 21:27:49 +02:00
2026-10-11 21:27:49 +02:00
2026-10-11 21:27:49 +02:00
2026-10-11 21:27:49 +02:00

ghostty-rs

A Rust rewrite of the Ghostty 1.3.1 terminal emulator for Linux (GTK4 + libadwaita, OpenGL).

It aims for behavioural parity with Ghostty: the same configuration file format, options, defaults and documentation; the same keybindings and actions; the same ghostty +action CLI; the same terminal emulation (including kitty keyboard/graphics protocols, OSC 8 hyperlinks, semantic prompts, synchronized output, tmux control mode); the same shell integration, themes and terminfo.

All of Ghostty's Zig code is ported: the Linux GTK app (verified at runtime and pixel-identical to Ghostty 1.3.1), the libghostty and libghostty-vt C APIs (same headers/ABI), WASM, crash reporting, and the macOS (Metal/CoreText) and Windows (ConPTY) code paths. macOS and Windows are compile-checked on Linux (just check-macos, just check-windows); the Windows test suites also run under Wine (just test-windows-wine), macOS has not been run natively. The Swift macOS app is not part of the port; it is a client of the libghostty C API.

The macOS app (original Swift app on the Rust core)

Ghostty's macOS app stays the original Swift app, unchanged. It is wired to the Rust core instead of the Zig core: the Rust libghostty exports the identical include/ghostty.h ABI. On a Mac with Xcode:

just macos-swift-app ../ghostty          # Release; or: just macos-swift-app ../ghostty Debug

This builds the Rust core as GhosttyKit.xcframework into <ghostty>/macos/, installs the resources into <ghostty>/zig-out/share (what the Xcode project bundles) and runs xcodebuild, mirroring zig build -Demit-macos-app. Not runnable on this Linux machine (DRY_RUN=1 previews the steps).

Building and running

Requirements: Rust (edition 2024), GTK ≥ 4.14, libadwaita ≥ 1.5, fontconfig, freetype, harfbuzz, Oniguruma, libepoxy, blueprint-compiler and glib-compile-resources at build time.

cargo run                      # open a terminal window running your shell
cargo run -- -e htop           # run a command
cargo run -- +list-themes      # CLI actions work like Ghostty's
cargo run --profile production # optimized build (LTO, no debug assertions)

Binaries run from this checkout's target/ (any profile) find resources/ (shell integration, themes, terminfo) automatically; installed binaries use the installed resources or GHOSTTY_RESOURCES_DIR. Your existing Ghostty config (~/.config/ghostty/config[.ghostty]) is used as-is.

Installing

just install /usr/local          # binary, share/ghostty, terminfo, desktop files,
                                 # completions, man pages, translations, icons
just install /usr false true     # system-package layout (lib/systemd/user)

Build-time resource directory

Set GHOSTTY_BUILD_RESOURCES_DIR while building or installing to embed an explicit resource directory:

GHOSTTY_BUILD_RESOURCES_DIR=/usr/share/ghostty cargo build --profile production
GHOSTTY_BUILD_RESOURCES_DIR=/usr/share/ghostty cargo install --path . --profile production
GHOSTTY_BUILD_RESOURCES_DIR=../share/ghostty cargo build --profile production

Absolute paths are used directly. Relative paths resolve from the running executable's directory, not the current working directory; ../share/ghostty allows moving an installed bin/ and share/ tree together. The directory contains themes/ and shell-integration/; these files still need to be installed separately (cargo install only installs the executable).

A nonempty runtime GHOSTTY_RESOURCES_DIR overrides the embedded path in every profile. The embedded path takes precedence over automatic resource discovery and does not require a terminfo sentinel. An unset or empty build option keeps the existing discovery rules, including the debug profile's preference for installed resources over the runtime override. Changing or unsetting the build option causes Cargo to rebuild resource lookup. Paths are literal: ~ and shell variables are not expanded by Ghostty. Flatpak's sandbox resource layout remains managed by its runtime integration.

Testing

just test      # cargo test --workspace (~3000 tests)
just clippy    # clippy with -D warnings

Every Zig test block of the ported files was ported to a Rust test. crates/ghostty-core/tests holds end-to-end tests that drive the real core, terminal and a real pty through a fake app runtime. ghostty-bench mirrors Ghostty's benchmark tool; terminal stream throughput is on par with the Zig build (see docs/rewrite/notes/perf-P1.md).

Verification

  • just difftest — differential fuzzing of the terminal core against Ghostty's own Zig code (sets up Zig 0.15.2 under target/).
  • just visual-parity — pixel comparison against the installed Ghostty in a headless nested weston.
  • just test-windows-wine — runs the Windows test suites (incl. ConPTY / cmd.exe end-to-end tests) under Wine with mingw-w64.
  • just check-all — native gate plus macOS/Windows/WASM checks.

Documentation

  • docs/rewrite/ARCHITECTURE.md – top-down decomposition, crate map, key design decisions, intentional omissions
  • docs/rewrite/STATUS.md – work package history
  • docs/rewrite/DEVIANT_FIXES.md – every intentional deviation from Ghostty (upstream bugs fixed instead of replicated; commits titled fix-deviant(...))
  • docs/rewrite/KNOWN_DIFFERENCES.md – remaining minor differences
  • docs/rewrite/notes/ – per-crate porting notes, deviations from Zig, audits and verification reports

License

MIT, like Ghostty. Bundled fonts and themes carry their own licenses (see crates/ghostty-font/res/ and resources/LICENSE-iTerm2-Color-Schemes).

S
Description
No description provided
Readme
36 MiB
0 Stars 1 Watchers 0 Forks
Languages
Rust 95%
C 1.5%
Shell 1.4%
HTML 0.6%
GLSL 0.3%
Other 1.1%