Commit Graph

12460 Commits

Author SHA1 Message Date
Jon Parise
4989f92c71 shell-integration: remove redundant comments
I think the conditions are sufficiently self-descriptive.
2025-10-01 10:27:42 -04:00
Matthew Hrehirchuk
9407e0fd0d fix: cleaned up elvish and fish integrations for bin_dir 2025-09-30 22:26:07 -06:00
Matthew Hrehirchuk
4cc663fc60 feat: add GHOSTTY_BIN_DIR to path via shell integration 2025-09-30 11:26:20 -06:00
Mitchell Hashimoto
ceac472af0 Revert "renderer: slightly optimize screen copy" (#8974)
This reverts commit fcea09e413 because it
appears to be causing memory leaks.
2025-09-30 09:29:00 -07:00
Jeffrey C. Ollie
86fb03677a Revert "renderer: slightly optimize screen copy"
This reverts commit fcea09e413.
2025-09-30 11:07:25 -05:00
Mitchell Hashimoto
150fb18ca1 Inline All The Things (#8946)
I used the new CPU counter mode in Instruments.app to track down
functions that had instruction delivery bottlenecks (indicating i-cache
misses) and picked a bunch of trivial functions to mark as inline (plus
a couple that are only used once or twice and which benefit from
inlining).

The size of `macos-arm64/libghostty-fat.a` built with `zig build
-Doptimize=ReleaseFast -Dxcframework-target=native` goes from
`145,538,856` bytes on `main` to `145,595,952` on this branch, a
negligible increase.

These changes resulted in some pretty sizable improvements in vtebench
results on my machine (Apple M3 Max):
<img width="983" height="696" alt="image"
src="https://github.com/user-attachments/assets/cac595ca-7616-48ed-983c-208c2ca2023f"
/>

With this, the only vtebench test we're slower than Alacritty in (on my
machine, at 130x51 window size) is `dense_cells` (which, IMO, is so
artificial that optimizing for it might actually negatively impact real
world performance).

I also did a pretty simple improvement to how we copy the screen in the
renderer, gave it its own page pool for less memory churn. Further
optimization in that area should be explored since in some scenarios it
seems like as much as 35% of the time on the `io-reader` thread is spent
waiting for the lock.

> [!NOTE]
> Before this is merged, someone really ought to test this on an x86
processor to see how the performance compares there, since this *is*
tuning for my processor specifically, and I know that M chips have
pretty big i-cache compared to some x86 processors which could impact
the performance characteristics of these changes.
2025-09-30 08:13:39 -07:00
Qwerasd
c57c205672 fix test failures
Very weird failures, not 100% sure of the cause; regardless, this fixes
them.
2025-09-30 07:27:40 -07:00
Qwerasd
0388a2b396 terminal: inline all the things
A whole bunch of inline annotations, some of these were tracked down
with Instruments.app, others are guesses / just seemed right because
they were trivial wrapper functions.

Regardless, these changes are ultimately supported by improved vtebench
results on my machine (Apple M3 Max).
2025-09-30 07:27:40 -07:00
Qwerasd
43dd712053 termio: make trivial stream handler callbacks inline
Supported by benchmarks (vtebench on Apple M3 Max)
2025-09-30 07:27:40 -07:00
Qwerasd
4136c469fa datastruct: make trivial linked list ops inline
Supported by benchmarks (vtebench on Apple M3 Max)
2025-09-30 07:27:40 -07:00
Qwerasd
fcea09e413 renderer: slightly optimize screen copy
Changes it so that the renderer retains its own MemoryPool for PageList
pages so that new pages rarely need to be allocated when cloning the
screen. Also switches to using an arena allocator in `updateFrame` to
avoid having to deinit the cloned screen since instead we can just throw
out the memory.
2025-09-30 07:27:40 -07:00
Mitchell Hashimoto
31a4568193 lib-vt: Add SemanticVersion to provide SONAME versions (#8938)
- Provide SONAME versioned shared libraries with major version numbers
to separate ABI breaks

Adding a SemanticVersion to the shared library's module generates
symlings for `libghostty-vt.so.<major version>` and
`libghostty-vt.so.<major>.<minor>`

```
> zig build
> ls zig-out/lib/
libghostty-vt.so@  libghostty-vt.so.0@  libghostty-vt.so.0.1.0*
> readelf -d zig-out/lib/libghostty-vt.so

Dynamic section at offset 0x452858 contains 25 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [ld-linux-x86-64.so.2]
 0x000000000000000e (SONAME)             Library soname: [libghostty-vt.so.0]
...
 ```

Major versions are important for allowing multiple versions of a library to co-exist and let the SONAME section in an ELF binary request a specific major version of a shared library.[^1]

I believe the rules for updating SONAME versions match the SemVer spec for ABI changes.

> 1.    MAJOR version when you make incompatible API changes
> 2.    MINOR version when you add functionality in a backward compatible manner
> 3.    PATCH version when you make backward compatible bug fixes
[^2]

[^1]: https://www.man7.org/conf/lca2006/shared_libraries/slide5d.html 
[^2]: https://semver.org/#summary
2025-09-30 07:18:23 -07:00
azhn
837ac9be77 lib-vt: Add SemanticVersion to module
- Provide SONAME versioned shared libraries with major version numbers
to separate ABI breaks
2025-09-30 07:17:31 -07:00
Mitchell Hashimoto
0cc3728803 macOS: Focus Terminal App Intent (#8961)
Closes #8791 
Discussion: #8657 

### Summary
This adds the FocusTerminalIntent App Intent and related function
(focusSurface), allows external tools (such as Shortcuts/Siri) to
programmatically move focus to a specific terminal window or tab.

### Verification
This functionality has been tested across following scenarios,
confirming correct focus behavior for:

- Split Window
- Tab Group
- Quick Terminal

### Note
It is not supported to move focus to a split that is hidden by a zoomed
split. The same applies to the CloseTerminalIntent.

### AI Disclosure
This pull request was made with assistance from Claude Code.
I reviewed all AI-generated code and wrote the final output manually.
2025-09-30 06:55:49 -07:00
Mitchell Hashimoto
45e61b1a17 update deps files 2025-09-30 06:55:14 -07:00
Mitchell Hashimoto
6da3727431 deps: Replace ziglyph with uucode (#8757)
This replaces `ziglyph` with
[uucode](https://github.com/jacobsandlund/uucode), maintaining the
Ghostty unicode props and symbols tables, but now built with `uucode`
and Unicode 16.

See the above `uucode` repository for a description of the library, but
the short summary is that it aims to be a fast and flexible Unicode
library in Zig, that is very configurable during build time.

This PR adds tests to make sure that the symbol and props tables match
the previous built-by-ziglyph implementation (minus differences in
Unicode 16).

## Benchmarks

Also added are benchmarks comparing the Ghostty tables with `uucode`,
with the following results (MacBook Pro 2021 M1 16 GB).

Summary:

| Benchmark | Dataset | Table Time (ms) | uucode Time (ms) | Fastest |
Fastest Speedup |

|-----------|---------|-----------------|------------------|---------|----------------|
| codepoint-width | data.txt | 929.3 (± 2.3) | 924.1 (± 0.9) | uucode |
1.01x |
| | Arabic | 2,652.0 (± 21.0) | 2,589.0 (± 8.0) | uucode | 1.02x |
| | Japanese | 2,302.0 (± 1.0) | 2,250.0 (± 2.0) | uucode | 1.02x |
| | English | 1,770.0 (± 5.0) | 1,770.0 (± 5.0) | tie | 1.00x |
| grapheme-break | data.txt | 974.5 (± 1.2) | 977.4 (± 0.7) | table |
1.00x |
| | Arabic | 4,135.0 (± 22.0) | 4,037.0 (± 9.0) | uucode | 1.02x |
| | Japanese | 3,537.0 (± 3.0) | 3,459.0 (± 1.0) | uucode | 1.02x |
| | English | 4,799.0 (± 4.0) | 5,119.0 (± 2.0) | table | 1.07x |
| is-symbol | data.txt | 877.9 (± 2.0) | 883.5 (± 1.5) | table | 1.01x |
| | Arabic | 2,735.0 (± 8.0) | 2,611.0 (± 1.0) | uucode | 1.05x |
| | Japanese | 2,391.0 (± 2.0) | 2,276.0 (± 4.0) | uucode | 1.05x |
| | English | 2,450.0 (± 5.0) | 2,212.0 (± 2.0) | uucode | 1.11x |

Sources:

```
# data.txt
zig-out/bin/ghostty-gen +utf8 | head -c 200000000 > data.txt

# Arabic
curl -L "https://www.dropbox.com/scl/fi/86gjpfzopssavk2nzo69u/arwiki-20180920-corpus.xml.bz2?dl=1&e=1&file_subpath=%2Fdata&rlkey=dmjlaw1xegg8vsje4xrn040v8" | bzcat | head -c 1000000000 > arwiki-20180920-corpus.xml

# Japanese
curl -L "https://www.dropbox.com/scl/fi/vru4zxv5qff1klod9xiht/jawiki-20181001-corpus.xml.bz2?rlkey=utuuooiwyupws3x5517u8n8jl&e=1&dl=1" | bzcat | head -c 1000000000 > jawiki-20181001-corpus.xml

# English
curl -L "https://www.dropbox.com/scl/fi/la1nvupgk2honb3n6m9zc/enwiki-20181001-corpus.xml.bz2?rlkey=8vg4vokbaijh1lg5lw3ytc864&e=1&dl=1" | bzcat | head -c 1000000000 > enwiki-20181001-corpus.xml
```

### codepoint-width

data.txt

```
hyperfine --warmup 4 'zig-out/bin/ghostty-bench +codepoint-width --data=data.txt --mode=table' 'zig-out/bin/ghostty-bench +codepoint-width --data=data.txt --mode=uucode'
Benchmark 1: zig-out/bin/ghostty-bench +codepoint-width --data=data.txt --mode=table
  Time (mean ± σ):     929.3 ms ±   2.3 ms    [User: 884.8 ms, System: 42.1 ms]
  Range (min … max):   925.2 ms … 933.2 ms    10 runs

Benchmark 2: zig-out/bin/ghostty-bench +codepoint-width --data=data.txt --mode=uucode
  Time (mean ± σ):     924.1 ms ±   0.9 ms    [User: 879.0 ms, System: 43.3 ms]
  Range (min … max):   922.8 ms … 925.4 ms    10 runs

Summary
  zig-out/bin/ghostty-bench +codepoint-width --data=data.txt --mode=uucode ran
    1.01 ± 0.00 times faster than zig-out/bin/ghostty-bench +codepoint-width --data=data.txt --mode=table
```

Arabic

```
hyperfine --warmup 1 --runs=5 zig-out/bin/ghostty-bench +codepoint-width --data=arwiki-20180920-corpus.xml --mode=table zig-out/bin/ghostty-bench +codepoint-width --data=arwiki-20180920-corpus.xml --mode=uucode
Benchmark 1: zig-out/bin/ghostty-bench +codepoint-width --data=arwiki-20180920-corpus.xml --mode=table
  Time (mean ± σ):      2.652 s ±  0.021 s    [User: 2.458 s, System: 0.180 s]
  Range (min … max):    2.622 s …  2.677 s    5 runs

Benchmark 2: zig-out/bin/ghostty-bench +codepoint-width --data=arwiki-20180920-corpus.xml --mode=uucode
  Time (mean ± σ):      2.589 s ±  0.008 s    [User: 2.405 s, System: 0.181 s]
  Range (min … max):    2.583 s …  2.598 s    5 runs

Summary
  zig-out/bin/ghostty-bench +codepoint-width --data=arwiki-20180920-corpus.xml --mode=uucode ran
    1.02 ± 0.01 times faster than zig-out/bin/ghostty-bench +codepoint-width --data=arwiki-20180920-corpus.xml --mode=table
```

Japanese

```
hyperfine --warmup 1 --runs=5 zig-out/bin/ghostty-bench +codepoint-width --data=jawiki-20181001-corpus.xml --mode=table zig-out/bin/ghostty-bench +codepoint-width --data=jawiki-20181001-corpus.xml --mode=uucode
Benchmark 1: zig-out/bin/ghostty-bench +codepoint-width --data=jawiki-20181001-corpus.xml --mode=table
  Time (mean ± σ):      2.302 s ±  0.001 s    [User: 2.126 s, System: 0.173 s]
  Range (min … max):    2.301 s …  2.303 s    5 runs

Benchmark 2: zig-out/bin/ghostty-bench +codepoint-width --data=jawiki-20181001-corpus.xml --mode=uucode
  Time (mean ± σ):      2.250 s ±  0.002 s    [User: 2.074 s, System: 0.174 s]
  Range (min … max):    2.246 s …  2.251 s    5 runs

Summary
  zig-out/bin/ghostty-bench +codepoint-width --data=jawiki-20181001-corpus.xml --mode=uucode ran
    1.02 ± 0.00 times faster than zig-out/bin/ghostty-bench +codepoint-width --data=jawiki-20181001-corpus.xml --mode=table
```

English

```
hyperfine --warmup 1 --runs=5 zig-out/bin/ghostty-bench +codepoint-width --data=enwiki-20181001-corpus.xml --mode=table zig-out/bin/ghostty-bench +codepoint-width --data=enwiki-20181001-corpus.xml --mode=uucode
Benchmark 1: zig-out/bin/ghostty-bench +codepoint-width --data=enwiki-20181001-corpus.xml --mode=table
  Time (mean ± σ):      1.770 s ±  0.005 s    [User: 1.600 s, System: 0.168 s]
  Range (min … max):    1.766 s …  1.776 s    5 runs

Benchmark 2: zig-out/bin/ghostty-bench +codepoint-width --data=enwiki-20181001-corpus.xml --mode=uucode
  Time (mean ± σ):      1.770 s ±  0.005 s    [User: 1.598 s, System: 0.169 s]
  Range (min … max):    1.765 s …  1.775 s    5 runs

Summary
  zig-out/bin/ghostty-bench +codepoint-width --data=enwiki-20181001-corpus.xml --mode=uucode ran
    1.00 ± 0.00 times faster than zig-out/bin/ghostty-bench +codepoint-width --data=enwiki-20181001-corpus.xml --mode=table
```

### grapheme-break

data.txt

```
hyperfine --warmup 4 --runs=10 zig-out/bin/ghostty-bench +grapheme-break --data=data.txt --mode=table zig-out/bin/ghostty-bench +grapheme-break --data=data.txt --mode=uucode
Benchmark 1: zig-out/bin/ghostty-bench +grapheme-break --data=data.txt --mode=table
  Time (mean ± σ):     974.5 ms ±   1.2 ms    [User: 929.2 ms, System: 43.3 ms]
  Range (min … max):   972.7 ms … 976.8 ms    10 runs

Benchmark 2: zig-out/bin/ghostty-bench +grapheme-break --data=data.txt --mode=uucode
  Time (mean ± σ):     977.4 ms ±   0.7 ms    [User: 931.5 ms, System: 44.0 ms]
  Range (min … max):   976.4 ms … 978.5 ms    10 runs

Summary
  zig-out/bin/ghostty-bench +grapheme-break --data=data.txt --mode=table ran
    1.00 ± 0.00 times faster than zig-out/bin/ghostty-bench +grapheme-break --data=data.txt --mode=uucode
```

Arabic

```
hyperfine --warmup 1 --runs=5 zig-out/bin/ghostty-bench +grapheme-break --data=arwiki-20180920-corpus.xml --mode=table zig-out/bin/ghostty-bench +grapheme-break --data=arwiki-20180920-corpus.xml --mode=uucode
Benchmark 1: zig-out/bin/ghostty-bench +grapheme-break --data=arwiki-20180920-corpus.xml --mode=table
  Time (mean ± σ):      4.135 s ±  0.022 s    [User: 3.942 s, System: 0.186 s]
  Range (min … max):    4.111 s …  4.159 s    5 runs

Benchmark 2: zig-out/bin/ghostty-bench +grapheme-break --data=arwiki-20180920-corpus.xml --mode=uucode
  Time (mean ± σ):      4.037 s ±  0.009 s    [User: 3.867 s, System: 0.163 s]
  Range (min … max):    4.026 s …  4.048 s    5 runs

Summary
  zig-out/bin/ghostty-bench +grapheme-break --data=arwiki-20180920-corpus.xml --mode=uucode ran
    1.02 ± 0.01 times faster than zig-out/bin/ghostty-bench +grapheme-break --data=arwiki-20180920-corpus.xml --mode=table
```

Japanese

```
hyperfine --warmup 1 --runs=5 zig-out/bin/ghostty-bench +grapheme-break --data=jawiki-20181001-corpus.xml --mode=table zig-out/bin/ghostty-bench +grapheme-break --data=jawiki-20181001-corpus.xml --mode=uucode
Benchmark 1: zig-out/bin/ghostty-bench +grapheme-break --data=jawiki-20181001-corpus.xml --mode=table
  Time (mean ± σ):      3.537 s ±  0.003 s    [User: 3.337 s, System: 0.195 s]
  Range (min … max):    3.533 s …  3.541 s    5 runs

Benchmark 2: zig-out/bin/ghostty-bench +grapheme-break --data=jawiki-20181001-corpus.xml --mode=uucode
  Time (mean ± σ):      3.459 s ±  0.001 s    [User: 3.265 s, System: 0.191 s]
  Range (min … max):    3.458 s …  3.460 s    5 runs

Summary
  zig-out/bin/ghostty-bench +grapheme-break --data=jawiki-20181001-corpus.xml --mode=uucode ran
    1.02 ± 0.00 times faster than zig-out/bin/ghostty-bench +grapheme-break --data=jawiki-20181001-corpus.xml --mode=table
```

English

```
hyperfine --warmup 1 --runs=5 zig-out/bin/ghostty-bench +grapheme-break --data=enwiki-20181001-corpus.xml --mode=table zig-out/bin/ghostty-bench +grapheme-break --data=enwiki-20181001-corpus.xml --mode=uucode
Benchmark 1: zig-out/bin/ghostty-bench +grapheme-break --data=enwiki-20181001-corpus.xml --mode=table
  Time (mean ± σ):      4.799 s ±  0.004 s    [User: 4.587 s, System: 0.207 s]
  Range (min … max):    4.795 s …  4.807 s    5 runs

Benchmark 2: zig-out/bin/ghostty-bench +grapheme-break --data=enwiki-20181001-corpus.xml --mode=uucode
  Time (mean ± σ):      5.119 s ±  0.002 s    [User: 4.907 s, System: 0.208 s]
  Range (min … max):    5.116 s …  5.121 s    5 runs

Summary
  zig-out/bin/ghostty-bench +grapheme-break --data=enwiki-20181001-corpus.xml --mode=table ran
    1.07 ± 0.00 times faster than zig-out/bin/ghostty-bench +grapheme-break --data=enwiki-20181001-corpus.xml --mode=uucode
```

### is-symbol

data.txt

```
hyperfine --warmup 4 --runs=10 zig-out/bin/ghostty-bench +is-symbol --data=data.txt --mode=table zig-out/bin/ghostty-bench +is-symbol --data=data.txt --mode=uucode
Benchmark 1: zig-out/bin/ghostty-bench +is-symbol --data=data.txt --mode=table
  Time (mean ± σ):     877.9 ms ±   2.0 ms    [User: 832.2 ms, System: 43.8 ms]
  Range (min … max):   873.8 ms … 881.2 ms    10 runs

Benchmark 2: zig-out/bin/ghostty-bench +is-symbol --data=data.txt --mode=uucode
  Time (mean ± σ):     883.5 ms ±   1.5 ms    [User: 837.8 ms, System: 43.8 ms]
  Range (min … max):   881.9 ms … 886.8 ms    10 runs

Summary
  zig-out/bin/ghostty-bench +is-symbol --data=data.txt --mode=table ran
    1.01 ± 0.00 times faster than zig-out/bin/ghostty-bench +is-symbol --data=data.txt --mode=uucode
```

Arabic

```
hyperfine --warmup 1 --runs=5 zig-out/bin/ghostty-bench +is-symbol --data=arwiki-20180920-corpus.xml --mode=table zig-out/bin/ghostty-bench +is-symbol --data=arwiki-20180920-corpus.xml --mode=uucode
Benchmark 1: zig-out/bin/ghostty-bench +is-symbol --data=arwiki-20180920-corpus.xml --mode=table
  Time (mean ± σ):      2.735 s ±  0.008 s    [User: 2.548 s, System: 0.183 s]
  Range (min … max):    2.724 s …  2.743 s    5 runs

Benchmark 2: zig-out/bin/ghostty-bench +is-symbol --data=arwiki-20180920-corpus.xml --mode=uucode
  Time (mean ± σ):      2.611 s ±  0.001 s    [User: 2.427 s, System: 0.181 s]
  Range (min … max):    2.610 s …  2.612 s    5 runs

Summary
  zig-out/bin/ghostty-bench +is-symbol --data=arwiki-20180920-corpus.xml --mode=uucode ran
    1.05 ± 0.00 times faster than zig-out/bin/ghostty-bench +is-symbol --data=arwiki-20180920-corpus.xml --mode=table
```

Japanese

```
hyperfine --warmup 1 --runs=5 zig-out/bin/ghostty-bench +is-symbol --data=jawiki-20181001-corpus.xml --mode=table zig-out/bin/ghostty-bench +is-symbol --data=jawiki-20181001-corpus.xml --mode=uucode
Benchmark 1: zig-out/bin/ghostty-bench +is-symbol --data=jawiki-20181001-corpus.xml --mode=table
  Time (mean ± σ):      2.391 s ±  0.002 s    [User: 2.210 s, System: 0.178 s]
  Range (min … max):    2.387 s …  2.393 s    5 runs

Benchmark 2: zig-out/bin/ghostty-bench +is-symbol --data=jawiki-20181001-corpus.xml --mode=uucode
  Time (mean ± σ):      2.276 s ±  0.004 s    [User: 2.100 s, System: 0.173 s]
  Range (min … max):    2.274 s …  2.283 s    5 runs

Summary
  zig-out/bin/ghostty-bench +is-symbol --data=jawiki-20181001-corpus.xml --mode=uucode ran
    1.05 ± 0.00 times faster than zig-out/bin/ghostty-bench +is-symbol --data=jawiki-20181001-corpus.xml --mode=table
```

English

```
hyperfine --warmup 1 --runs=5 zig-out/bin/ghostty-bench +is-symbol --data=enwiki-20181001-corpus.xml --mode=table zig-out/bin/ghostty-bench +is-symbol --data=enwiki-20181001-corpus.xml --mode=uucode
Benchmark 1: zig-out/bin/ghostty-bench +is-symbol --data=enwiki-20181001-corpus.xml --mode=table
  Time (mean ± σ):      2.450 s ±  0.005 s    [User: 2.267 s, System: 0.179 s]
  Range (min … max):    2.446 s …  2.457 s    5 runs

Benchmark 2: zig-out/bin/ghostty-bench +is-symbol --data=enwiki-20181001-corpus.xml --mode=uucode
  Time (mean ± σ):      2.212 s ±  0.002 s    [User: 2.036 s, System: 0.173 s]
  Range (min … max):    2.208 s …  2.214 s    5 runs

Summary
  zig-out/bin/ghostty-bench +is-symbol --data=enwiki-20181001-corpus.xml --mode=uucode ran
    1.11 ± 0.00 times faster than zig-out/bin/ghostty-bench +is-symbol --data=enwiki-20181001-corpus.xml --mode=table
```
2025-09-30 06:54:17 -07:00
Mitchell Hashimoto
d261c0a60b Merge branch 'main' into jacob/uucode 2025-09-30 06:52:07 -07:00
Mitchell Hashimoto
449386001b gtk: some bell features need to happen on receipt of every BEL (#8962)
Some bell features should be triggered on the receipt of every BEL
character, namely `audio` and `system`. However, Ghostty was setting a
boolean to `true` upon the receipt of the first BEL. Subsequent BEL
characters would be ignored until that boolean was reset to `false`,
usually by keyboard/mouse activity.

This PR fixes the problem by ensuring that the `audio` and `system`
features are triggered every time a BEL is received. Other features
continue to be triggered only when the `bell-ringing` boolean state
changes.

Fixes #8957
2025-09-30 06:44:41 -07:00
Jeffrey C. Ollie
bdf07727ad gtk: some bell features need to happen on receipt of every BEL
Some bell features should be triggered on the receipt of every BEL
character, namely `audio` and `system`. However, Ghostty was setting a
boolean to `true` upon the receipt of the first BEL. Subsequent BEL
characters would be ignored until that boolean was reset to `false`,
usually by keyboard/mouse activity.

This PR fixes the problem by ensuring that the `audio` and `system`
features are triggered every time a BEL is received. Other features
continue to be triggered only when the `bell-ringing` boolean state
changes.

Fixes #8957
2025-09-30 06:40:34 -07:00
himura467
c58a8b27b6 chore: update iOS membership exceptions 2025-09-30 07:14:09 +09:00
himura467
373be61482 docs 2025-09-30 06:36:29 +09:00
himura467
b3d0b6a965 refactor: no need to set from for moveFocus probably 2025-09-30 05:58:21 +09:00
himura467
bc3d0b7cbc fix: the renderer's cursor remains in an unfocused state (block_hollow) 2025-09-30 05:21:56 +09:00
Mitchell Hashimoto
7ba9f9a21a gtk: make Enter confirm "Change Terminal Title" (#8949)
Fixes https://github.com/ghostty-org/ghostty/discussions/8697 by making
`OK` the suggested default and activating it by default.

Previously `OK` was `destructive` which imo is not a good approach for
just setting a terminal title.
2025-09-29 12:35:05 -07:00
Mitchell Hashimoto
0bddaed53b fix(font): Improve FreeType glyph measurements and add unit tests for face metrics (#8738)
Follow-up to #8720 adding

* Two improvements to FreeType glyph measurements:
- Ensuring that glyphs are measured with the same hinting as they are
rendered, ref
[#8720#issuecomment-3305408157](https://github.com/ghostty-org/ghostty/pull/8720#issuecomment-3305408157);
- For outline glyphs, using the outline bbox instead of the built-in
metrics, like `renderGlyph()`.
* Basic unit tests for face metrics and their estimators, using the
narrowest and widest fonts from the resource directory, Cozette Vector
and Geist Mono.

---

I also made one unrelated change to `freetype.zig`, replacing
`@alignCast(@ptrCast(...))` with `@ptrCast(@alignCast(...))` on line
173. Autoformatting has been making this change on every save for weeks,
and reverting the hunk before each commit is getting old, so I hope it's
OK that I use this PR to upstream this decree from the formatter.
2025-09-29 12:24:42 -07:00
Mitchell Hashimoto
b643d30d60 move test out of terminal to avoid lib-vt catch 2025-09-29 12:24:04 -07:00
Mitchell Hashimoto
f67a865cdd fix(font): Treat Powerline glyphs as normal characters for constraint width purposes (#8829)
Powerline glyphs were treated as whitespace, giving the preceding cell a
constraint width of 2 and cutting off icons in people's prompts and
statuslines. It is however correct to not treat Powerline glyphs like
other Nerd Font symbols; they should simply be treated as normal
characters, just like their relatives in the block elements unicode
block.

This resolves
https://discord.com/channels/1005603569187160125/1417236683266592798
(never promoted to an issue, but real and easy to reproduce).

**Tip**
<img width="215" height="63" alt="Screenshot 2025-09-21 at 16 57 58"
src="https://github.com/user-attachments/assets/81e770c5-d688-4d8e-839c-1f4288703c06"
/>

**This PR**
<img width="215" height="63" alt="Screenshot 2025-09-21 at 16 58 42"
src="https://github.com/user-attachments/assets/5d2dd770-0314-46f6-99b5-237a0933998e"
/>

The constraint width logic was untested but contains some quite subtle
interactions, so I wrote a suite of tests covering the cases I'm aware
of.

While working on this code I also resolved a TODO comment to add all the
box drawing/block element type characters to the set of codepoints
excluded from the minimum contrast settings.
2025-09-29 12:16:23 -07:00
Mitchell Hashimoto
25dab0ecd8 fix(font): Rewrite constraint code for improved icon scaling/alignment (#8563)
> This PR will probably need a rebase on the final outcome of #8550 and
~#8552~ #8580, but I'm putting it out here so folks can begin taking a
look if they want.

This is a rewrite of the code that applies scaling and alignment
constraints. The main intention is to further improve how Nerd Font
icons are matched to the primary font. This PR aligns the calculations
more closely with how the Nerd Font `font-patcher` script works, except
in two cases where we can easily do something unambiguously better (one
because of what's arguably a bug in the script, and one because we do
multi-cell alignment with knowledge of the pixel-rounded cell grid).

A goal of the rewrite is to make the scaling and alignment calculations
as clear and easy to follow as possible.

I'll lead with some screenshots. First the status quo, then this PR.
<img width="505" height="357" alt="Screenshot 2025-09-07 at 17 23 51"
src="https://github.com/user-attachments/assets/8e3ff9fd-3b66-4d54-be38-d54cf3b6cc5b"
/><img width="505" height="357" alt="Screenshot 2025-09-07 at 17 20 39"
src="https://github.com/user-attachments/assets/84fbe076-2e3f-4879-b9b2-91ce86b9ef5f"
/>

Relevant specs: macOS; 1920x1080; Ghostty config:
```ini
font-family = "CommitMono"
font-size = "15"
adjust-cell-height = "+20%"
```

**Points to note**

* Icons are generally larger, making better use of the available space.
* Icons are aligned nearly a pixel lower, better matching the text. This
is because alignment is now calculated from face metrics/bearings, not
the pixel-rounded cell. (See more below.)
* Relative sizes are better matched. Note especially that tall and
narrow icons, like the git branch symbol and icons depicting sheets of
paper, look conspicuously small in the status quo. With this PR, they're
better matched to other icons.
* Look at the letter Z icon I use as prompt character for zsh. It's
_tiny_ in the status quo, but properly sized with this PR. This
demonstrates the most important and clear-cut improvement we make over
`font-patcher`. (See more below.)
* Icons wider than a single cell are now left-aligned rather than
centered across two cells. I think this is preferable and makes better
use of space in most relevant contexts.
- Consider a Neovim bufferline showing the buffer title as a filetype
icon followed by the file name. Padding on the left would be a waste of
space, but having that extra space on the right can improve legibility.
- In listings, such as in the screenshots, columns look tidier when
their left edges are straight rather than ragged.
- This is how `font-patcher` does alignment, and thus what Nerd Font
users and UI designers expect.

**Implementation details**

I won't get too deep in the weeds here; see the code and comments. In
brief:

* `size_horizontal` and `size_vertical` are combined to a single `size`,
which can be `.none, .stretch, .fit, .cover` or `.fit_cover1`. The
latter implements the `pa` rule from `font-patcher`, except it works
better for icons that are small before scaling, like the letter Z prompt
in the screenshots. In short, it preserves aspect ratio while clamping
the size such that the icon `.cover`s at least one cell and `.fit`s
within the available space. See code comments and
ryanoasis/nerd-fonts/pull/1926 for details.
* An alignment mode `.center1` is added, implementing the centering rule
from `font-patcher` that I explained/defended above. In short, we center
the icon _in the first cell_, even it's allowed to span multiple cells.
For icons wider than a single cell, the lower bound that prevents them
from protruding to the left kicks in and turns this into left-alignment.
We keep the regular `.center` rule around for use with emojis, et
cetera.
* Scaling and alignment calculations only use the unrounded face metrics
and bearings. This ensures that pixel rounding of the cell and baseline,
and `adjust-cell-{width,height}`, don't affect scaling or relative
alignment; the icons are always scaled and aligned to the _face_. (The
one place we need to use cell metrics in the calculations is when we use
`cell_width` to obtain the inter-cell padding needed to correctly center
or right-align a glyph across two cells.)
- We can do this with impunity because we're blessed with sprite glyphs
in place of the "icons" that are actually box drawing and block graphics
characters 🙌

**Guide**

The meat of the changes is 100 % in `src/font/face.zig` and
`src/font/nerd_font_codegen.py`. Changes to other files only amount to
a) adding/changing some struct fields to get numbers to where they need
to be (see `src/font/Metrics.zig`), and b) collateral updates to make
otherwise unchanged code and tests work with/take advantage of the
modified structs.

Most files should have a clear and friendly diff. The exception is the
bottom half of `src/font/face.zig`, where the diff is meaningless and
the new code should just be reviewed on its own merits. This is the part
where the `constrain` function is rewritten and refactored. Scarred by
countless hours perusing `font-patcher`, I tried hard to make the math
and logic easy to follow here. I hope I have succeeded 🤞
2025-09-29 12:12:09 -07:00
Daniel Wennberg
e3ebdc7975 Rewrite constraint code for improved icon scaling/alignment 2025-09-29 12:09:21 -07:00
Mitchell Hashimoto
f73666a7a1 apprt/gtk: do not close window if tab overview is open with no tabs (#8955)
Fixes #8944

When we drag the only tab out of the tab overview, this triggers an
`n-pages` signal with 0 pages. If we close the window in this state, it
causes both Ghostty to exit AND the drag/drop to fail. Even if we
pre-empt Ghostty exiting by modifying the application class, the
drag/drop still fails and the application leaks memory and enters a bad
state.

The solution is to keep the window open if we go to `n-pages == 0` and
we have the tab overview open.

Interestingly, if you click to close the final tab from the tab
overview, Adwaita closes the tab overview so it still triggers the
window closing behavior (this is good, this is desired).
2025-09-29 10:53:56 -07:00
Mitchell Hashimoto
3fdb52e48d apprt/gtk: do not close window if tab overview is open with no tabs
Fixes #8944

When we drag the only tab out of the tab overview, this triggers
an `n-pages` signal with 0 pages. If we close the window in this state,
it causes both Ghostty to exit AND the drag/drop to fail. Even if we
pre-empt Ghostty exiting by modifying the application class, the
drag/drop still fails and the application leaks memory and enters a bad
state.

The solution is to keep the window open if we go to `n-pages == 0` and
we have the tab overview open.

Interestingly, if you click to close the final tab from the tab
overview, Adwaita closes the tab overview so it still triggers the
window closing behavior (this is good).
2025-09-29 10:48:22 -07:00
Mitchell Hashimoto
a2663692bb feat: enable scaling mouse-scroll-multiplier for both precision and discrete scrolling (#8927)
Resolves Issue: #8670 

Now precision and discrete scrolling can be scaled independently.
Supports following configuration,

```code
# Apply everywhere
mouse-scroll-multiplier = 3

# Apply separately
mouse-scroll-multiplier = precision:0.1,discrete:3 (default)

# Also it's order agnostic
mouse-scroll-multiplier = discrete:3,precision:2

# Apply one, default other
mouse-scroll-multiplier = precision:2
```

The default precision value is set 0.1, as it felt natural to me at
least on my track-pad. I've also set the min clamp value precision to
0.1 as 0.01 felt kind of useless to me but I'm unsure.
2025-09-29 10:21:36 -07:00
Mitchell Hashimoto
1031629741 config: modify MouseScrollMultiplier to lean on args parsing 2025-09-29 10:08:58 -07:00
Toufiq Shishir
9597cead92 add: unit tests for MouseScrollMultiplier parsing and formatting 2025-09-29 09:30:55 -07:00
Toufiq Shishir
33e0701965 feat: enable separate scaling for precision and discrete mouse scrolling 2025-09-29 09:30:55 -07:00
Mitchell Hashimoto
958751e12c Workaround for #8669 (#8838)
Changing `supportedModes` to `background` seems to have fixed #8669.

> Debugging AppIntents with Xcode is a pain. I had to delete all the
local builds to make it take effect. The build product of `zig` might
cause confusion if none of your changes reflect in the Shortcuts app.
There were too many ghosts on my computer. 👻👻👻

- Tahoe


https://github.com/user-attachments/assets/88d0d567-edf5-4a7e-b0a3-720e50053746

- Sequoia 


https://github.com/user-attachments/assets/a77f1431-ca92-4450-bce9-5f37ef232d4f
2025-09-29 09:30:01 -07:00
Mitchell Hashimoto
9ba45b2163 lib-vt: fix invalid Zig forwards 2025-09-29 09:18:43 -07:00
Mitchell Hashimoto
cc0b7f74fd lib-vt: document allocators 2025-09-29 09:12:12 -07:00
Mitchell Hashimoto
15670a77f3 lib-vt: document main html page 2025-09-29 08:59:16 -07:00
Mitchell Hashimoto
16077f0542 build: move entrypoint out to separate file 2025-09-29 08:51:56 -07:00
Mitchell Hashimoto
904e09a1da build: add NOINDEX argument for libghostty-vt docs 2025-09-29 08:48:07 -07:00
Mitchell Hashimoto
3a95920edf build: add Dockerfile to generate and server libghostty c docs 2025-09-29 08:33:58 -07:00
Mitchell Hashimoto
12d3c130c8 lib-vt: OSC data extraction boilerplate (#8950)
This adds functions to extra data out of OSC commands, but it is mostly
boilerplate since I only added one valid data extraction. 😄 The example
was updated to show this.

This also changes OSC strings to be null-terminated to ease lib-vt
integration. This shouldn't have any practical effect on terminal
performance, but it does lower the maximum length of OSC strings by 1
since we always reserve space for the null terminator.
2025-09-29 06:56:07 -07:00
Mitchell Hashimoto
3bc07c24aa lib-vt: OSC data extraction boilerplate
This also changes OSC strings to be null-terminated to ease lib-vt
integration. This shouldn't have any practical effect on terminal
performance, but it does lower the maximum length of OSC strings by 1
since we always reserve space for the null terminator.
2025-09-29 06:40:01 -07:00
Bernd Kaiser
41c1c6b3e6 gtk: make Enter confirm "Change Terminal Title" 2025-09-29 14:44:20 +02:00
Mitchell Hashimoto
c5145d552e build: use build options to configure terminal C ABI mode (#8945)
Fixes various issues:

- C ABI detection was faulty, which caused some Zig programs to use the
C ABI mode and some C programs not to. Let's be explicit.

- Unit tests now tests C ABI mode.

- Build binary no longer rebuilds on any terminal change (a regression).

- Zig programs can choose to depend on the C ABI version of the terminal
lib by using the `ghostty-vt-c` module.
2025-09-28 14:22:36 -07:00
Mitchell Hashimoto
f614fb7c1b build: use build options to configure terminal C ABI mode
Fixes various issues:

- C ABI detection was faulty, which caused some Zig programs to use
the C ABI mode and some C programs not to. Let's be explicit.

- Unit tests now tests C ABI mode.

- Build binary no longer rebuilds on any terminal change (a regression).

- Zig programs can choose to depend on the C ABI version of the terminal
  lib by using the `ghostty-vt-c` module.
2025-09-28 14:17:51 -07:00
Mitchell Hashimoto
08ecbe328a Update iTerm2 colorschemes (#8933)
Upstream release:
https://github.com/mbadolato/iTerm2-Color-Schemes/releases/tag/release-20250922-150534-d28055b
2025-09-28 13:37:38 -07:00
Mitchell Hashimoto
b73fdd4326 lib-vt C: More OSC parsing API (#8941)
This adds more of the OSC parsing API to the C library of
`libghostty-vt`. This adds the following:

* `ghostty_osc_next` - Push a single character into the OSC parser
* `ghostty_osc_reset` - Reset the parser state and free any temporary
memory
* `ghostty_osc_end` - End a parsing sequence and return the parsed
command
* `ghostty_osc_command_type` - Return the type of command parsed
* `examples/c-vt` is updated to use these new APIs
* Our Zig `osc.Command` tagged union is updated to use a new comptime
func to generate an ABI compatible tag for the C lib.
* **Important change:** Our Zig `osc.Parser.end` function was modified
to return a _pointer_ to the command within its own structure memory
rather than a copy. This eases the C API. This impacts the Zig side but
we ultimately copy it again [for now] in the main `terminal.Parser` so
end result is the same.
* Unit tests cover even the C lib
* Shuffled some code for maintainability

The plan is to use this opaque type with getters to ease ABI
compatibility going forward.
2025-09-28 13:37:23 -07:00
himura467
a6dd7bbeee refactor: improve asynchronous delay by delegating window/app activation process to animateIn 2025-09-29 02:02:42 +09:00