- apprt-gtk: Ghostty's runtime+build-time version gating (at_least) with cargo features adw_1_3/adw_1_4/adw_1_5/gtk_4_16 (default on) and the fallbacks for older libraries: MessageDialog (adw < 1.5), clipboard dialog without SwitchRow, pre-Banner debug warning and child-exited widgets, the old about dialog, GTK 4.16 CSS error source bytes. The minimum stays GTK 4.14 / libadwaita 1.5 (Ghostty's floor). The root build links with -z lazy so version-gated symbols don't keep older libraries from loading. - ghostty-helpgen (port of helpgen.zig) generates CLI action help and keybinding action docs from doc comments at build time, replacing the checked-in help/*.txt; +help and +list-actions --docs stay byte-identical to Ghostty 1.3.1. - ghostty-bench: libc wcwidth mode and separate simd/table and uucode/table code paths like Zig. - ghostty-cli: Windows branches of edit-config, list-colors, list-keybinds and boo; ssh-cache DiskCache flock locking (no-op on Windows, as in Zig) with an exclusivity test. Test Plan: - cargo test --workspace - diff <(cargo run -q -- +list-actions --docs) \ <(ghostty +list-actions --docs)
5.4 KiB
compat-GC: GTK/libadwaita compat fallbacks, bench modes, helpgen, CLI Windows
Sub-notes: compat-GC-bench.md, compat-GC-helpgen.md, compat-GC-cli.md.
1. GTK / libadwaita compatibility (crates/ghostty-apprt-gtk)
Ghostty's own minimum (finding)
ZIG/src/build/SharedDeps.zig runs blueprint.zig over every entry of
gresource.blueprints, which refuses to compile a <maj>.<min>/x.blp if the
libadwaita headers are older than that version; the list contains 1.5/ files
(window, tab, command palette, ...). So Ghostty 1.3.1 cannot be built against
libadwaita < 1.5, and the Zig code calls gtk_css_provider_load_from_bytes
(4.12) and gtk_im_context_activate_osk (4.14) unguarded. Ghostty's real
minimum is therefore GTK 4.14 / libadwaita 1.5, which is what the crate
already required; I verified this by compiling with gtk4 features v4_8/v4_10
(fails on load_from_bytes/activate_osk) and v4_14 (compiles). The only
change to the requirement is dropping the unneeded gnome_44 feature. In Zig the
fallbacks below are only reachable in a (hypothetical) build against older
headers; they are ported with identical selection logic.
Version gating (gtk_version.rs, adw_version.rs)
Zig's atLeast = comptime header version AND runtime library version. Rust:
- cargo features are the "header version":
adw_1_3<adw_1_4<adw_1_5andgtk_4_16(gtk/v4_16); all are default.BUILD_LEVEL/const fn comptime_at_leastread them;at_least=comptime_at_least && runtime_at_least;runtime_at_least/runtime_untilunchanged.COMPTIME_VERSION(pkg-config) is kept for+versionoutput. - Types that Zig selects at comptime are selected with
cfg(feature = ...). - Debug builds only:
GHOSTTY_DEBUG_FAKE_GTK_VERSION/GHOSTTY_DEBUG_FAKE_ADW_VERSION(e.g.1.4.0) override the runtime version answers (fake_version.rs; no Zig counterpart) so runtime branches can be exercised on new libraries. - Root
build.rslinks the binary with-z lazy(Rust defaults to-z now) so symbols only used behind a runtime check (GTK 4.16gtk_css_section_get_bytes) don't stop an older library from loading the program, like Zig's lazy binding.
Fallbacks ported
| Zig | Rust |
|---|---|
class/dialog.zig Parent = AlertDialog / MessageDialog, present/close |
class/dialog.rs: DialogParent + present/close per cfg adw_1_5; macros dialog_subclass_wrapper!/impl_dialog_parent! give the three subclasses (close-confirmation, config-errors, clipboard) the right @extends chain and response override for both parents |
clipboard_confirmation_dialog.zig can_remember, template 1.4 vs 1.0 |
cfg_attr template resource ui/1.4 (adw_1_4) vs ui/1.0; remember_choice child only with SwitchRow; CAN_REMEMBER; remember=false without it |
debug_warning.zig Parent adw.Bin/gtk.Box, template 1.3/1.2 |
class/debug_warning.rs cfg adw_1_3 |
surface_child_exited.zig Banner / SurfaceChildExitedNoop |
class/surface_child_exited.rs: noop widget (no template, NOOP, close-request emitted from set_child_exited); Surface::child_exited returns false for the noop, as in Zig. NB: Zig has no 1.2/surface-child-exited.blp (the task text assumed one); the pre-Banner implementation is the Noop |
window.zig actionAbout |
adw::AboutDialog if supports_dialogs() else gtk::show_about_dialog |
application.zig signalCssParsingError (GTK >= 4.16 branch) |
css.rs: domain code message + \n<source bytes> (CssSection::bytes) behind gtk_4_16 + runtime check, plain line otherwise; tested via parsing_error_message |
| blueprint variants | build.rs already compiles 1.0/1.2/1.3/1.4/1.5 variants (same list as gresource.zig) into the gresource; the class selects at build level (as Zig) |
Verification
cargo clippy -p ghostty-apprt-gtk --all-targets -D warningsclean with default features AND withdefault = [](temporarily edited), i.e. both the new and the fallback code compile.- Default build: GTK app runs with the debug replay hook (paste dialog shows
GhosttyClipboardConfirmationDialogwith the remember switch; no GTK criticals). - Fallback build (
default = [], run via the replay hook): the paste confirmation and the close confirmation come up asadw::MessageDialog-basedGhosttyClipboardConfirmationDialog/GhosttyCloseConfirmationDialog(transient for the window), the binary has noBIND_NOW. - Workspace gate (excluding L1's in-progress
ghostty-lib):cargo clippy --workspace --all-targets -D warnings,cargo test --workspace,cargo +nightly fmt --allpass.+help,+list-actions [--docs],+list-keybinds --help,+show-config --helpare byte-identical to/usr/bin/ghostty.
Deviation found by the runtime check
Zig's GhosttyCloseConfirmationDialog registers a close-request signal; with
the MessageDialog (a GtkWindow) parent that name already exists in the class
ancestry and GObject aborts. Zig's fallback has the same latent bug (dead code
upstream). The fallback build here names it dialog-close-request
(close_confirmation_dialog.rs::CLOSE_REQUEST); default build unchanged.
Not testable here
Real old libraries (GTK < 4.16 / libadwaita < 1.5) are not installed; only the compile-time fallback selection and the version arithmetic are exercised.
2-4
See the sub-notes. Deviations vs the task text: Zig CodepointWidth has no
uucode mode (bench); Zig does no file locking on Windows, so the faithful
port is a no-op there (cli).