I don’t know why the search-related commands were added as performable
keybinds in 240d5e0fc5, but **I asked
Claude to add some tests for that**
> This won't fix cmd+g/G not working when the search bar is focused.
This reverts commit 20cfaae2e5, reversing
changes made to 3509ccf78e.
This breaks some behaviours when there are multiple splits, which
requires another click to focus to another split in the same window
This is known issues before key-related PRs, tested on
fa9265636b.
The following config is mapped incorrectly to the menu shortcut:
```
keybind=A=goto_split:left
```
<img width="223" height="106" alt="image"
src="https://github.com/user-attachments/assets/b80da251-9cff-4b29-b143-64854a5c4271"
/>
Surfaces only accept `a` as a trigger to select left split, not
`shift+a`
- Expose that ID as the environment variable GHOSTTY_SURFACE_ID to
processes running in Ghostty surfaces.
- Add a function to the core app to search for surfaces by ID.
- ID is randomly generated, it has no other meaning other than as a
unique identifier for the surface. The ID also cannot be zero as that is
used to indicate a null ID in some situations.
- Expose that ID as the environment variable GHOSTTY_SURFACE_ID to
processes running in Ghostty surfaces.
- Add a function to the core app to search for surfaces by ID.
- ID is randomly generated, it has no other meaning other than as a
unique identifier for the surface. The ID also cannot be zero as that
is used to indicate a null ID in some situations.
Fixes#12020
The C header declared ghostty_surface_free_text with both a
ghostty_surface_t and ghostty_text_s* parameter, but the Zig
implementation only accepted a *Text parameter. This caused the surface
pointer to be interpreted as the text pointer, so the actual text
allocation was never freed.
I opted to keep the surface parameter to minimize the diff here. I'm not
sure why I thought I would need access to that surface pointer but just
want to fix the leak first.
Fixes#12020
The C header declared ghostty_surface_free_text with both a
ghostty_surface_t and ghostty_text_s* parameter, but the Zig
implementation only accepted a *Text parameter. This caused the
surface pointer to be interpreted as the text pointer, so the
actual text allocation was never freed.
- Fixes: https://github.com/ghostty-org/ghostty/issues/11964
Made a private enum type `VersionConfig` to reference whether the
release is a semver or tip, makes it easier for later in the view to
`switch` between cases.
I do think there could be a better place for this enum or we can get rid
of it, open to opinions. Right now version parsing is kind of duplicated
between `AboutView` and `UpdateModalView` so we can also extract to a
common helper if wanted.
Tested by manually setting `Marketing Version` in build settings to
`1.3.1`
<img width="412" height="532" alt="Screenshot 2026-03-30 at 18 31 15"
src="https://github.com/user-attachments/assets/285bb94d-138b-4169-bb66-684eb04b6ca3"
/>
`332b2aefc`
<img width="412" height="532" alt="Screenshot 2026-03-30 at 18 32 48"
src="https://github.com/user-attachments/assets/fea30d39-bea7-4885-8221-1696e148f45e"
/>
### AI Disclosure
I used Sonnet 4.6 to understand where the version strings came from and
in what format, it read release yml files to see what's going on. Then
it proposed really bad code so I manually went in and cleaned up the
view.
## Summary
- Move `sys/types.h` include into the `#else` branch of the existing
`_MSC_VER` guard
- MSVC does not ship `sys/types.h` (POSIX header), and already gets
`ssize_t` from `BaseTsd.h`
## Test plan
- [x] `zig build -Dapp-runtime=none` -- clean build
- [x] `zig build test -Dapp-runtime=none` on Windows (2606/2660 passed,
54 skipped)
- [x] `zig build test` on Linux (2658/2684 passed, 26 skipped)
- [x] `zig build test` on macOS (2658/2668 passed, 10 skipped)
- [x] `zig build test-lib-vt` on all 3 platforms
- [x] Zig examples build on all 3 platforms
- [x] CMake examples build on Windows (c-vt-cmake pass,
c-vt-cmake-static pass)
`GHOSTTY_KEY_DELETE` should be mapped to `KeyEquivalent.deleteForward`.
This fixes the correct symbol showing in the menu. Previously, both
`GHOSTTY_KEY_DELETE` and `GHOSTTY_KEY_BACKSPACE` were showing `⌫`, but
`GHOSTTY_KEY_DELETE` only worked for `fn+delete`.
Add the following keybind and observe the symbol in the menu:
```
keybind=delete=new_tab
```
<img width="535" height="318" alt="image"
src="https://github.com/user-attachments/assets/67ed7b5d-f848-42ee-a382-fe364d86cb2c"
/>
sys/types.h is a POSIX header that does not exist on MSVC. Move it
into the #else branch of the existing _MSC_VER guard that already
provides ssize_t via BaseTsd.h.
Replaces #11958
This exports the function table and makes it growable so that the
effects API can be used. It's still very not ergonomic to use the
effects API so I'm going to work on that next, but this at least makes
it _possible_. Zig 0.15.x is missing the ability to pass
`--growable-table` to the linker so we use binary patching to add it
(yay!) lol.
## Root cause
Zig 0.15.2 can produce macOS `.a` archives where some 64-bit Mach-O
members are only 4-byte aligned inside the archive. Recent Apple
`libtool -static` does not handle that layout correctly: it emits `not
8-byte aligned` warnings and, in the failing case, silently drops those
members when creating the combined static library.
In Ghostty, this happened in the Darwin `libtool` merge step that builds
`libghostty-fat.a`. The x86_64 input `libghostty.a` still contained the
expected `libghostty_zcu.o` and about 97 exported `_ghostty_` symbols,
but after `libtool -static` the output archive contained only 4 SIMD
symbols because `libghostty_zcu.o` had been discarded. The same warning
pattern also appeared in third-party input archives such as
`libfreetype.a` and `libz.a`, so this was not only a `libghostty.a`
problem.
## What needed to be done
The inputs to Apple `libtool` needed to be normalized before they were
merged.
The safest fix is to copy each input archive and run `ranlib -D` on the
copy before passing it to `libtool`. `ranlib` rewrites the archive into
a form that Apple’s linker tools accept, fixing the alignment/layout
issue without changing the archive’s semantic contents.
## Why this approach
An `ar x` -> `ar rcs` workaround can also make the warnings go away, but
it is a broader and riskier transformation. Extracting archive members
into a flat directory is not semantics-preserving:
- duplicate member basenames can collide
- non-`.o` members can be lost
- member order can change
That means an `ar`-based rearchive can silently change valid archives
while fixing alignment. `ranlib -D` avoids those hazards because it
rewrites the archive in place instead of flattening it through the
filesystem.
`-D` is also important because plain `ranlib` is not deterministic. In
local testing, `ranlib -D` still fixed the alignment issue, preserved
all 97 `_ghostty_` symbols, produced no `libtool` warnings, and was
byte-stable across repeated runs.
## Validation
This was reproduced directly:
- before normalization, running `libtool -static` on the affected x86_64
`libghostty.a` produced a `libghostty_zcu.o not 8-byte aligned` warning
and the output archive dropped from 97 `_ghostty_` symbols to 4
- after `ranlib -D`, the same `libtool -static` command preserved all 97
`_ghostty_` symbols and emitted no alignment warnings
After applying the normalization step, a clean `zig build` succeeded,
and the final macOS xcframework archive contained 97 `_ghostty_` symbols
in both the `x86_64` and `arm64` slices.
## Summary
This was not a Metal issue, not an Xcode project issue, and not a
stale-cache issue. The actual root cause was an Apple `libtool`
interoperability problem with Zig-produced macOS archives. The required
fix was to normalize each archive before the Darwin `libtool` merge
step, and `ranlib -D` is the least invasive way to do that while
preserving archive semantics.
Apple's recent libtool can warn about misaligned 64-bit archive members
and silently drop them when merging static libraries. In Ghostty this
showed up in the Darwin libtool step that builds libghostty-fat.a.
Normalize each input archive by copying it and running ranlib on the
copy
before handing it to libtool. That rewrites the archive into a layout
Apple's linker tools accept without flattening members through the
filesystem or changing Ghostty's archive format.
Rename the shared library visibility macro from GHOSTTY_EXPORT to
GHOSTTY_API across all public C headers. This applies to both the
libghostty-vt headers under include/ghostty/vt/ and the main
include/ghostty.h header.
This is a bit more idiomatic compared to other C libs and addresses the
fact that we're not always exporting...