This PR modernizes our benchmarks. This PR focuses on the benchmark
_framework_ and not the benchmarks themselves. That will come in later
PRs.
We now produce two binaries with `-Demit-bench`: `ghostty-bench` and
`ghostty-gen`. The former is our benchmark tool. The latter is our
synthetic data generation tool. The benchmarking CLI usually takes in
data from the synthetic generator but we want to do that offline because
synthetic data generation can be slow and CPU intensive and mess up our
benchmarks.
Our previous benchmark-specific binaries (like
`ghostty-bench-codepoint-width`) are all gone. This is all executed as
subcommands in the format similar to Ghostty users: `ghostty-bench
+codepoint-width --other --args`.
Previously, synthetic data generation was a mess and all unified with
`ghostty-bench-stream` which is just nasty. A dedicated CLI now gets us
args like `ghostty-gen +osc --p-valid=0.5`. Neat!
## Signposts and Xcode/Instruments on macOS
The benchmark framework now automatically emits
[signposts](https://developer.apple.com/documentation/os/recording-performance-data)
around the code that is under test. This is surfaced in Instruments as a
region that you can visualize and zoom in on so you can omit any of the
other overhead.
Additionally, I've integrated benchmarks with libghostty and our Xcode
project so you can just right click a benchmark to open it in
Instruments.
These are macOS-specific niceties but the core benchmarking tool is
platform-agnostic.
## Generalized CLI Actions
The `src/cli/action.zig` file was generalized so that it can be shared
amongst our three action-ized binaries. The Ghostty-specific actions are
now in `src/cli/ghostty.zig`. As an added bonus, our action parsing is
now fully unit tested.
I don't like mixing refactors in with other tasks in PRs but in this
case this one was done to enable not one but two other consumers in the
same PR, so I think it fits.
## TODO
Some things I want to do before merge.
- [ ] Add flags to `ghostty-bench` to configure once mode vs duration
mode
This was in pursuit of trying to get line numbers in `zig build run` on
macOS to work, but I wasn't able to figure that out and this wasn't the
right path because static libs can't have dsyms. But, it may still be
useful to make the xcframework step dsym aware for future use so I'm
PRing this.
This also updates our libghostty build steps to use the new
`root_module` form which is recommend for Zig 0.14 and we forgot to
update long ago.
This was in pursuit of trying to get line numbers in `zig build run` on
macOS to work, but I wasn't able to figure that out and this wasn't the
right path because static libs can't have dsyms. But, it may still be
useful to make the xcframework step dsym aware for future use so I'm
PRing this.
Before, if the row count increase past the active area then we added new
rows to make sure that we had enough for the active area, but we didn't
make sure that the viewport pin wasn't below the active area pin, which
meant that later on if someone tried to get the bottom right pin for the
viewport it would overshoot and we'd use null. This resulted in either a
memory corruption bug in ReleaseFast if you scaled down the font while
scrolled up slightly, or in Debug mode it was just a crash.
Fixes#7893
Previously, custom shader cursor uniforms were only updated when the
cursor glyph was in the front (block) cursor list. This caused non-block
cursors (such as bar, underline, hollow block, and lock) to be missing
from custom shader effects.
This commit adds a helper to the cell contents struct to retrieve the
current cursor glyph from either the front or back cursor lists, and
updates the renderer to use this helper when setting custom shader
uniforms. As a result, custom shaders now receive correct cursor
information for all supported cursor styles.
The previous implementation wasn't quite working. This revision reworks
it in a few ways:
- Fix various syntax issues
- Redirect the `ssh` command to our 'ssh-integration' function
- Locate the `ghostty` binary using $GHOSTTY_BIN_DIR
- Use os:temp-dir to create our temporary directory
Also, consistently use 2-space indents, which is the Elvish standard.
This value is always set to a non-empty string, and we only need this
value after we've determined that 'ssh_hostname' is non-empty.
In bash and zsh, we also don't need to check for the 'ghostty' command
before we attempt to add the target to the cache. That command will
safely fail silently if it's not available.
This enables `systemd` to send SIGUSR2 to Ghostty to signal it to reload
the configuration. This is much easier and reliable than using a script
to search process listings for Ghostty's main PID to send the signal to.
The command to do so is:
`systemctl reload --user com.mitchellh.ghostty.service`
This allows `systemctl` to send SIGUSR2 to Ghostty to trigger a reload,
which is more convenient than scripting `ps` and `kill` to find the
Ghostty main PID.
The old math didn't allow fractional pixels on the left and bottom, and
stretched glyphs vertically since the height was always rounded up. At
very small font sizes this looked good, but at medium and even large
sizes this just made things inconsistent and janky.
These new calculations are practically pixel-identical to whatever
CoreText is doing in 99% of cases, and the remaining cases seem to be
some sort of auto-hinting since it's internal features of the glyph
getting repositioned.
Over all, I still prefer this to CoreText's quantize option, but if this
causes further issues we should probably just revert the whole thing and
go ahead and add an extra pixel of padding to the bottom and left...
The old math didn't allow fractional pixels on the left and bottom, and
stretched glyphs vertically since the height was always rounded up. At
very small font sizes this looked good, but at medium and even large
sizes this just made things inconsistent and janky.
These new calculations are practically pixel-identical to whatever
CoreText is doing in 99% of cases, and the remaining cases seem to be
some sort of auto-hinting since it's internal features of the glyph
getting repositioned.
Over all, I still prefer this to CoreText's quantize option, but if this
causes further issues we should probably just revert the whole thing and
go ahead and add an extra pixel of padding to the bottom and left...
Addresses #4156 and #5892, specifically by implementing @mitchellh's
[request](https://github.com/ghostty-org/ghostty/discussions/5892#discussioncomment-12283628)
for "opt-in shell integration".
## Problem
Ghostty's custom `xterm-ghostty` TERM value breaks terminal
functionality when SSHing to remote systems that lack the corresponding
terminfo entry. This affects enterprise environments, legacy servers,
and ephemeral instances.
## Solution
Adds two independent SSH integration flags within the existing
`shell-integration-features` configuration:
```
shell-integration-features = ssh-env,ssh-terminfo
```
- **`ssh-env`**: TERM compatibility fix (xterm-ghostty → xterm-256color)
+ environment variable propagation (COLORTERM, TERM_PROGRAM,
TERM_PROGRAM_VERSION)
- **`ssh-terminfo`**: Automatic terminfo installation on remote hosts
with caching and utility commands
Flags work independently and harmoniously when combined, allowing users
granular control over SSH integration behavior.
## Implementation
Adds SSH wrapper functions across bash, zsh, fish, and elvish that
handle TERM compatibility, environment propagation, and terminfo
installation. Follows the same pattern as existing shell integration
features - client-side only with graceful fallback behavior.
The flag-based approach allows users to choose exactly the features they
need:
- Environment compatibility only: `ssh-env`
- Terminfo installation only: `ssh-terminfo`
- Optimal experience: `ssh-env,ssh-terminfo`
- No SSH integration: omit both flags
## Evolution Note
Based on maintainer feedback, this evolved from a progressive
enhancement approach (`ssh-integration = basic | full`) to independent
flags within `shell-integration-features`. See discussion below for the
complete architectural evolution and rationale.
Continuation of discussion in
https://github.com/ghostty-org/ghostty/discussions/3134
This changes the behaviour of the new bold-color option to only affect
the default foreground text when set to a static colour. By using a
static colour, the remaining colours are rendered as bright.
For each config entry, add a comment specifying in which release it was
first added. In some cases I note when certain aspects of each config
entry were modified.