Commit Graph

12112 Commits

Author SHA1 Message Date
Mitchell Hashimoto
e7c1b4dd05 benchmarks: Align buf to cache line for consistency (#8569)
This aligns the `buf` of `4096` bytes in the benchmarks to the cache
line, to ensure a consistent number of cache lines are used, and also to
avoid any sub-`usize` alignment issues as seen in
https://github.com/ghostty-org/ghostty/pull/8548.

This has less of an effect as
https://github.com/ghostty-org/ghostty/pull/8548, and looking at the
before and after of the current benchmarks in the repo doesn't show any
noticeable difference.

In my case, I've been comparing the `table` option with [uucode in this
branch](https://github.com/ghostty-org/ghostty/compare/main...jacobsandlund:jacob/uucode?expand=1),
and I did see a difference.

### Before

I ran the before code several times (6 with the exact same binary, but
several more with essentially the same code), always getting something
like this, with `table` edging out `uucode` by something like 3-4ms:

```
Benchmark 1: zig-out/bin/ghostty-bench +codepoint-width --data=data.txt --mode=table
  Time (mean ± σ):     927.8 ms ±   1.3 ms    [User: 883.7 ms, System: 42.5 ms]
  Range (min … max):   926.0 ms … 929.8 ms    10 runs

Benchmark 2: zig-out/bin/ghostty-bench +codepoint-width --data=data.txt --mode=uucode
  Time (mean ± σ):     930.9 ms ±   1.4 ms    [User: 886.8 ms, System: 42.5 ms]
  Range (min … max):   928.5 ms … 933.4 ms    10 runs
```

### After

After this change, it shows `uucode` coming in at 10-11ms (~1%) faster:

```
Benchmark 1: zig-out/bin/ghostty-bench +codepoint-width --data=data.txt --mode=table
  Time (mean ± σ):     930.6 ms ±   1.3 ms    [User: 886.5 ms, System: 42.4 ms]
  Range (min … max):   928.9 ms … 932.4 ms    10 runs

Benchmark 2: zig-out/bin/ghostty-bench +codepoint-width --data=data.txt --mode=uucode
  Time (mean ± σ):     920.1 ms ±   1.4 ms    [User: 876.3 ms, System: 42.1 ms]
  Range (min … max):   918.4 ms … 923.3 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
```

This ~1% faster time checks out, since from looking at the assembly,
it's an exact match minus this small place where the compiler can
optimize `uucode` a little better:

```
# both table.asm/uucode.asm:

   140                     const high = cp >> 8;
   141                     const low = cp & 0xFF;
** 142                     return self.stage3[self.stage2[self.stage1[high] + low]];

<+464>: ubfx   x12, x11, #8, #13
<+468>: ldrh   w12, [x27, x12, lsl #1]
<+472>: add    x11, x28, w11, uxtb #1
<+476>: ldrh   w11, [x11, x12, lsl #1]

# table.asm:

<+480>: lsl    x11, x11, #1

** 158                             table.get(@intCast(cp)).width);
   159                     }
   160                 }

<+484>: ldrb   w11, [x22, x11]

# uucode.asm:

** 148                 return @field(data(stages, cp), name);

<+480>: ldrh   w11, [x22, x11, lsl #1]
```

### More confusion with showing addresses

Confusingly, when I added `std.debug.print("buf addr={}\n",
.{@intFromPtr(&buf)})` to show the addresses, this somehow made the
`before` case show `uucode` as being faster. Then, when I added
alignment, `uucode` and `table` were taking about the same time
(**edit:** _uucode was only ~4 ms faster, but see more in "Edit: more
investigation"_)

If I run without the `std.debug.print` and with `--show-output`, the
times are different, so just making a note of this.

```
Benchmark 1: zig-out/bin/ghostty-bench +codepoint-width --data=data.txt --mode=table
  Time (mean ± σ):     904.2 ms ±   1.2 ms    [User: 884.6 ms, System: 40.3 ms]
  Range (min … max):   902.8 ms … 906.1 ms    10 runs

Benchmark 2: zig-out/bin/ghostty-bench +codepoint-width --data=data.txt --mode=uucode
  Time (mean ± σ):     892.7 ms ±   2.0 ms    [User: 873.2 ms, System: 40.1 ms]
  Range (min … max):   887.9 ms … 895.6 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
```

I think, even with this confusing case, aligning is going to be more
consistent than not.

### Edit: more investigation

I wasn't satisfied with the discovery that adding `std.debug.print` made
this difference and I wanted to dig in and figure out exactly what's
going on, but I didn't get a satisfactory answer. Here's what I tried:

* I compared the un-aligned addresses from `stepTable` and `stepUucode`,
but both seemed similar (not aligned to 128, different each run, but
aligned to 8). Note though that `uucode` was running ~1% faster still,
similar to the aligned case even though here it was un-aligned.
* Instead of doing `std.debug.print` in the step function, I printed in
teardown, just in case. This had no difference in the unaligned case,
but with alignment it brought the ~4 ms faster `uucode` (as noted above)
back closer to the original "after" at around 11-12 ms faster (~1%).
* I forced the `buf` in `stepUucode` to not be aligned (e.g. by making
it `= other_aligned_buf[3..4096 + 3]`). Still it was ~1% faster.
* I compared the assembly of `stepTable` and `stepUucode` for both
aligned and not aligned cases, including doing a diff of the diff of
these two across aligned and not aligned. The only difference between
`stepTable` and `stepUucode` is what's noted above, and nothing stood
out in the double diff.
* I tried going back to the original un-aligned non-printing code, but
then swapped the lines that get from `table` or `uucode`, so that
`stepTable` and `stepUucode` were actually doing the opposite. And the
result is`stepTable` (actually `uucode`) was 10-11 ms (~1%) faster, just
like the aligned case!

In summary, I wasn't able to replicate the original benchmark behavior
_and print out buffer addresses that pointed to alignment being the
issue_. I still feel like in theory aligning the buffer ought to make
the benchmark more reliable, and indeed the original un-aligned version
gives the result that is more of an outlier, but the evidence here is
weak, so I'm alright if we stick with the status quo and close. I think
a lesson here is benchmarks are hard to get precise.
2025-09-09 07:25:36 -07:00
Jacob Sandlund
77b4c52634 [benchmarks] Align buf to cache line for consistency 2025-09-08 17:59:17 -04:00
Mitchell Hashimoto
cd6820eb93 deps: update z2d to v0.8.0 (#8566)
Release notes at:
  https://github.com/vancluever/z2d/blob/v0.8.0/CHANGELOG.md

This is a small update and likely contains nothing related to Ghostty,
but I wanted to make sure it got in before the 1.2.0 release since it
contains the removal of non-functional code that wasn't compiling, just
for correctness' sake.

Also if for some reason ARGB/XRGB is needed for some utility purpose,
it's there now. 🙂
2025-09-08 13:58:40 -07:00
Chris Marchesi
813e01a813 deps: update z2d to v0.8.0
Release notes at:
  https://github.com/vancluever/z2d/blob/v0.8.0/CHANGELOG.md

This is a small update and likely contains nothing related to Ghostty,
but I wanted to make sure it got in before the 1.2.0 release since it
contains the removal of non-functional code that wasn't compiling, just
for correctness' sake.

Also if for some reason ARGB/XRGB is needed for some utility purpose,
it's there now. :)
2025-09-08 11:15:01 -07:00
Qwerasd
31e54ff44a comment + style changes 2025-09-08 10:40:56 -06:00
Mitchell Hashimoto
1feb398641 build(deps): bump namespacelabs/nscloud-cache-action from 1.2.16 to 1.2.17 (#8562)
Bumps
[namespacelabs/nscloud-cache-action](https://github.com/namespacelabs/nscloud-cache-action)
from 1.2.16 to 1.2.17.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/namespacelabs/nscloud-cache-action/releases">namespacelabs/nscloud-cache-action's
releases</a>.</em></p>
<blockquote>
<h2>v1.2.17</h2>
<h2>What's Changed</h2>
<ul>
<li>Delete existing files at path before creating bind mount, this was
already handled correctly for existing directories but not for
files</li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/namespacelabs/nscloud-cache-action/compare/v1.2.16...v1.2.17">https://github.com/namespacelabs/nscloud-cache-action/compare/v1.2.16...v1.2.17</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="a289cf5d2f"><code>a289cf5</code></a>
Merge pull request <a
href="https://redirect.github.com/namespacelabs/nscloud-cache-action/issues/33">#33</a>
from namespacelabs/delete-existing-files-at-path-befor...</li>
<li><a
href="3851f57081"><code>3851f57</code></a>
Delete existing files at path before creating bind mount</li>
<li><a
href="58efedf646"><code>58efedf</code></a>
Merge pull request <a
href="https://redirect.github.com/namespacelabs/nscloud-cache-action/issues/32">#32</a>
from namespacelabs/delete-existing-files-at-path-befor...</li>
<li><a
href="5e60691b8f"><code>5e60691</code></a>
Delete existing files at path before creating bind mount</li>
<li>See full diff in <a
href="https://github.com/namespacelabs/nscloud-cache-action/compare/v1.2.16...a289cf5d2fcd6874376aa92f0ef7f99dc923592a">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=namespacelabs/nscloud-cache-action&package-manager=github_actions&previous-version=1.2.16&new-version=1.2.17)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>
2025-09-08 07:07:58 -07:00
Mitchell Hashimoto
212b2aed30 build(deps): bump cachix/install-nix-action from 31.6.0 to 31.6.1 (#8561)
Bumps
[cachix/install-nix-action](https://github.com/cachix/install-nix-action)
from 31.6.0 to 31.6.1.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/cachix/install-nix-action/releases">cachix/install-nix-action's
releases</a>.</em></p>
<blockquote>
<h2>v31.6.1</h2>
<h2>What's Changed</h2>
<ul>
<li>ci: adjust oldest supported installer for macos-15 by <a
href="https://github.com/sandydoo"><code>@​sandydoo</code></a> in <a
href="https://redirect.github.com/cachix/install-nix-action/pull/252">cachix/install-nix-action#252</a></li>
<li>nix: 2.31.0 -&gt; 2.31.1 by <a
href="https://github.com/github-actions"><code>@​github-actions</code></a>[bot]
in <a
href="https://redirect.github.com/cachix/install-nix-action/pull/253">cachix/install-nix-action#253</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/cachix/install-nix-action/compare/v31...v31.6.1">https://github.com/cachix/install-nix-action/compare/v31...v31.6.1</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="7be5dee142"><code>7be5dee</code></a>
docs: update the readme</li>
<li><a
href="150afeae6c"><code>150afea</code></a>
Merge pull request <a
href="https://redirect.github.com/cachix/install-nix-action/issues/253">#253</a>
from cachix/create-pull-request/patch</li>
<li><a
href="cdda9d991c"><code>cdda9d9</code></a>
nix: 2.31.0 -&gt; 2.31.1</li>
<li><a
href="6f18c7d1a1"><code>6f18c7d</code></a>
Merge pull request <a
href="https://redirect.github.com/cachix/install-nix-action/issues/252">#252</a>
from cachix/fix-old-installer-darwin</li>
<li><a
href="f0f3cc651e"><code>f0f3cc6</code></a>
ci: adjust oldest supported installer for macos-15</li>
<li>See full diff in <a
href="56a7bb7b56...7be5dee142">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=cachix/install-nix-action&package-manager=github_actions&previous-version=31.6.0&new-version=31.6.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>
2025-09-08 07:07:48 -07:00
Mitchell Hashimoto
23b37147ec build(deps): bump softprops/action-gh-release from 2.3.2 to 2.3.3 (#8560)
Bumps
[softprops/action-gh-release](https://github.com/softprops/action-gh-release)
from 2.3.2 to 2.3.3.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/softprops/action-gh-release/releases">softprops/action-gh-release's
releases</a>.</em></p>
<blockquote>
<h2>v2.3.3</h2>
<!-- raw HTML omitted -->
<h2>What's Changed</h2>
<h3>Exciting New Features 🎉</h3>
<ul>
<li>feat: add input option <code>overwrite_files</code> by <a
href="https://github.com/asfernandes"><code>@​asfernandes</code></a> in
<a
href="https://redirect.github.com/softprops/action-gh-release/pull/343">softprops/action-gh-release#343</a></li>
</ul>
<h3>Other Changes 🔄</h3>
<ul>
<li>dependency updates</li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/asfernandes"><code>@​asfernandes</code></a>
made their first contribution in <a
href="https://redirect.github.com/softprops/action-gh-release/pull/343">softprops/action-gh-release#343</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/softprops/action-gh-release/compare/v2...v2.3.3">https://github.com/softprops/action-gh-release/compare/v2...v2.3.3</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md">softprops/action-gh-release's
changelog</a>.</em></p>
<blockquote>
<h2>2.3.3</h2>
<h2>What's Changed</h2>
<h3>Exciting New Features 🎉</h3>
<ul>
<li>feat: add input option <code>overwrite_files</code> by <a
href="https://github.com/asfernandes"><code>@​asfernandes</code></a> in
<a
href="https://redirect.github.com/softprops/action-gh-release/pull/343">softprops/action-gh-release#343</a></li>
</ul>
<h3>Other Changes 🔄</h3>
<ul>
<li>dependency updates</li>
</ul>
<h2>2.3.2</h2>
<ul>
<li>fix: revert fs <code>readableWebStream</code> change</li>
</ul>
<h2>2.3.1</h2>
<h3>Bug fixes 🐛</h3>
<ul>
<li>fix: fix file closing issue by <a
href="https://github.com/WailGree"><code>@​WailGree</code></a> in <a
href="https://redirect.github.com/softprops/action-gh-release/pull/629">softprops/action-gh-release#629</a></li>
</ul>
<h2>2.3.0</h2>
<ul>
<li>Migrate from jest to vitest</li>
<li>Replace <code>mime</code> with <code>mime-types</code></li>
<li>Bump to use node 24</li>
<li>Dependency updates</li>
</ul>
<h2>2.2.2</h2>
<h2>What's Changed</h2>
<h3>Bug fixes 🐛</h3>
<ul>
<li>fix: updating release draft status from true to false by <a
href="https://github.com/galargh"><code>@​galargh</code></a> in <a
href="https://redirect.github.com/softprops/action-gh-release/pull/316">softprops/action-gh-release#316</a></li>
</ul>
<h3>Other Changes 🔄</h3>
<ul>
<li>chore: simplify ref_type test by <a
href="https://github.com/steinybot"><code>@​steinybot</code></a> in <a
href="https://redirect.github.com/softprops/action-gh-release/pull/598">softprops/action-gh-release#598</a></li>
<li>fix(docs): clarify the default for tag_name by <a
href="https://github.com/muzimuzhi"><code>@​muzimuzhi</code></a> in <a
href="https://redirect.github.com/softprops/action-gh-release/pull/599">softprops/action-gh-release#599</a></li>
<li>test(release): add unit tests when searching for a release by <a
href="https://github.com/rwaskiewicz"><code>@​rwaskiewicz</code></a> in
<a
href="https://redirect.github.com/softprops/action-gh-release/pull/603">softprops/action-gh-release#603</a></li>
<li>dependency updates</li>
</ul>
<h2>2.2.1</h2>
<h2>What's Changed</h2>
<h3>Bug fixes 🐛</h3>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="6cbd405e2c"><code>6cbd405</code></a>
release 2.3.3</li>
<li><a
href="fbadcc90e8"><code>fbadcc9</code></a>
update to use <code>actions/checkout@v5</code></li>
<li><a
href="4a840061c4"><code>4a84006</code></a>
chore(deps): bump <code>@​types/node</code> from 20.19.10 to 20.19.11 in
the npm group (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/648">#648</a>)</li>
<li><a
href="7191749478"><code>7191749</code></a>
chore(deps): bump actions/checkout in the github-actions group (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/649">#649</a>)</li>
<li><a
href="126b1e7093"><code>126b1e7</code></a>
chore(deps): bump <code>@​types/node</code> from 20.19.9 to 20.19.10 in
the npm group (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/647">#647</a>)</li>
<li><a
href="f82d31e53e"><code>f82d31e</code></a>
chore(deps): bump the npm group with 3 updates (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/643">#643</a>)</li>
<li><a
href="f2352b97da"><code>f2352b9</code></a>
chore(deps): bump <code>@​types/node</code> from 20.19.2 to 20.19.7 in
the npm group (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/640">#640</a>)</li>
<li><a
href="f0b3259de2"><code>f0b3259</code></a>
chore(deps): bump the npm group across 1 directory with 4 updates (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/638">#638</a>)</li>
<li><a
href="f37a2f9143"><code>f37a2f9</code></a>
chore(deps): bump the npm group with 2 updates (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/635">#635</a>)</li>
<li><a
href="db560141c6"><code>db56014</code></a>
chore(deps): bump brace-expansion from 2.0.1 to 2.0.2 (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/634">#634</a>)</li>
<li>Additional commits viewable in <a
href="72f2c25fcb...6cbd405e2c">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=softprops/action-gh-release&package-manager=github_actions&previous-version=2.3.2&new-version=2.3.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>
2025-09-08 07:07:38 -07:00
dependabot[bot]
93cd1aca5f build(deps): bump namespacelabs/nscloud-cache-action
Bumps [namespacelabs/nscloud-cache-action](https://github.com/namespacelabs/nscloud-cache-action) from 1.2.16 to 1.2.17.
- [Release notes](https://github.com/namespacelabs/nscloud-cache-action/releases)
- [Commits](https://github.com/namespacelabs/nscloud-cache-action/compare/v1.2.16...a289cf5d2fcd6874376aa92f0ef7f99dc923592a)

---
updated-dependencies:
- dependency-name: namespacelabs/nscloud-cache-action
  dependency-version: 1.2.17
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-08 00:07:18 +00:00
dependabot[bot]
776323f8f8 build(deps): bump cachix/install-nix-action from 31.6.0 to 31.6.1
Bumps [cachix/install-nix-action](https://github.com/cachix/install-nix-action) from 31.6.0 to 31.6.1.
- [Release notes](https://github.com/cachix/install-nix-action/releases)
- [Changelog](https://github.com/cachix/install-nix-action/blob/master/RELEASE.md)
- [Commits](56a7bb7b56...7be5dee142)

---
updated-dependencies:
- dependency-name: cachix/install-nix-action
  dependency-version: 31.6.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-08 00:07:11 +00:00
dependabot[bot]
093f79d97b build(deps): bump softprops/action-gh-release from 2.3.2 to 2.3.3
Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 2.3.2 to 2.3.3.
- [Release notes](https://github.com/softprops/action-gh-release/releases)
- [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md)
- [Commits](72f2c25fcb...6cbd405e2c)

---
updated-dependencies:
- dependency-name: softprops/action-gh-release
  dependency-version: 2.3.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-08 00:07:03 +00:00
Jesse Miller
ecf3e2ad7d Position-independent font shaper caching
Use relative cluster positioning to allow identical texts runs in
different row positions to share the same cache entry.
2025-09-07 16:33:35 -06:00
Mitchell Hashimoto
155bd1dbed nix: remove unnecessary input override (#8558) 2025-09-07 13:36:56 -07:00
Mitchell Hashimoto
7582035a46 ci: working on snaps 2025-09-07 13:32:58 -07:00
Mitchell Hashimoto
e1627a80e9 ci: I think --ref can only be a branch/tag name... 2025-09-07 08:34:20 -07:00
Jeffrey C. Ollie
6d3bab725c nix: remove unnecessary input override 2025-09-07 10:32:46 -05:00
Mitchell Hashimoto
55798edc9b ci: checkout in trigger-snap 2025-09-07 08:22:33 -07:00
Mitchell Hashimoto
42a54d8d7f ci: try to checkout in snap.yml 2025-09-07 08:00:52 -07:00
Mitchell Hashimoto
c0b9bf77f0 ci: move snap build to separate workflow (#8405) 2025-09-07 07:55:25 -07:00
Jeffrey C. Ollie
cff32c527f ci: move snap build to separate workflow 2025-09-07 07:54:48 -07:00
Mitchell Hashimoto
aaaaf1c6ad ci: cleanups (#8556)
* Only update appcast (trigger macOS updates) on `main`-branch triggers
* Echo the release URLs for download as part of the job
* Remove the `release-pr` workflow. We can now use `release-tip`
manually dispatched on a branch because it won't update the appcast.
2025-09-06 21:00:57 -07:00
Mitchell Hashimoto
f198e5f163 ci: remove the release PR workflow
You can now use a dispatch of release tip; it'll only trigger a appcast
update when triggered on the main branch.
2025-09-06 20:49:52 -07:00
Mitchell Hashimoto
fc9c3dab67 ci: echo release URLs for tip releases 2025-09-06 20:48:47 -07:00
Mitchell Hashimoto
24b9e33a8c ci: only release tip releases when triggered from the main branch 2025-09-06 20:44:02 -07:00
Mitchell Hashimoto
6ceaa34a7c ci: do not run release tip workflow if corresponding commit released (#8551)
Fixes #8549

This also brings the release tip workflow more in line with the release
tag workflow by using a setup job to create outputs that are reused by
the other jobs.

This PR was almost fully written by AI (Amp) because being a YAML
engineer fucking sucks. I understand GHA and the changes look good to
me, but it's hard to tell until the job is run, AI or not. Full
prompt/context here:

https://ampcode.com/threads/T-e2d431ad-8be8-46d2-aaa3-9fae71f9ff31
2025-09-06 20:33:39 -07:00
Mitchell Hashimoto
f04d679b15 Update iTerm2 colorschemes (#8553)
Upstream revision:
b314fc5404
2025-09-06 20:21:08 -07:00
Mitchell Hashimoto
38544b7a8b ci: do not run release tip workflow if corresponding commit released
Fixes #8549

This also brings the release tip workflow more in line with the release
tag workflow by using a setup job to create outputs that are reused by
the other jobs.

https://ampcode.com/threads/T-e2d431ad-8be8-46d2-aaa3-9fae71f9ff31
2025-09-06 20:20:14 -07:00
mitchellh
ae95bb39ab deps: Update iTerm2 color schemes 2025-09-07 00:15:14 +00:00
Mitchell Hashimoto
ea878f9b2f fix(terminal): move cursor left if VS15 makes cell narrow (#8538)
Without this change, a phantom space appears after any character with
default emoji presentation that is converted to text with VS15. The only
other terminal I know of that respects variation selectors is Kitty, and
it walks the cursor back, which feels like the best choice, since that
way the behavior is observable (no way to know if the terminal supports
variation selectors otherwise without hard-coding that info per term)
and "dumb" programs like `cat` will output things correctly, and not
gain a phantom space after any VS15'd emoji.

> [!NOTE]
> ### Tests should be added for this behavior, including edge cases like
with cursor pending wrap
2025-09-06 13:49:21 -07:00
Qwerasd
fdd22ec786 fix(terminal): move cursor left if VS15 makes cell narrow
Without this change, a phantom space appears after any character with
default emoji presentation that is converted to text with VS15. The only
other terminal I know of that respects variation selectors is Kitty, and
it walks the cursor back, which feels like the best choice, since that
way the behavior is observable (no way to know if the terminal supports
variation selectors otherwise without hard-coding that info per term)
and "dumb" programs like `cat` will output things correctly, and not
gain a phantom space after any VS15'd emoji.
2025-09-06 13:46:14 -07:00
Mitchell Hashimoto
ae7061efb0 [benchmarks] Use std.mem.doNotOptimizeAway to avoid data collisions (#8548)
I've been playing with benchmarks over in my [branch swapping out
ziglyph for
uucode](https://github.com/ghostty-org/ghostty/compare/main...jacobsandlund:jacob/uucode?expand=1),
and I ran into an interesting issue where benchmarks were giving odd
numbers.

TL;DR: writing to `buf[0]` ends up slowing down the benchmark in
inconsistent ways because it's the same buffer that's being written and
read in the loop, so switching to `std.mem.doNotOptimizeAway` fixes
this.

## Full story:

I ran the `codepoint-width` benchmark with the following (and also did
similarly for `grapheme-bench` and `is-symbol`):

```
zig-out/bin/ghostty-gen +utf8 | head -c 200000000 > 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'
```

... and I was surprised to see that `uucode` was 3% slower than Ghostty,
despite similar implementations. I debugged this, bringing the `uucode`
implementation to the exact same assembly (minus offsets) as Ghostty,
even re-using the same table data (fun fact I learned is that even
though these tables are large, zig or LLVM saw they were byte-by-byte
equivalent and optimized them down to one table). Still though, 3%
slower.

Then I realized that if I wrote to a separate `buf` on `self` the
difference went away, and I figured out it's this writing to `buf[0]`
that is tripping up the CPU, because in the next outer loop it'll write
over that again when reading from the data file, and then it's read as
part of getting the code point.

### with buf[0]

```
Benchmark 1: zig-out/bin/ghostty-bench +codepoint-width --data=data.txt --mode=table
  Time (mean ± σ):     944.7 ms ±   0.8 ms    [User: 900.2 ms, System: 42.8 ms]
  Range (min … max):   943.4 ms … 945.9 ms    10 runs

Benchmark 2: zig-out/bin/ghostty-bench +codepoint-width --data=data.txt --mode=uucode
  Time (mean ± σ):     974.0 ms ±   0.7 ms    [User: 929.3 ms, System: 43.1 ms]
  Range (min … max):   973.3 ms … 975.2 ms    10 runs

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

### with mem.doNotOptimizeAway

```
Benchmark 1: zig-out/bin/ghostty-bench +codepoint-width --data=data.txt --mode=table
  Time (mean ± σ):     929.4 ms ±   2.7 ms    [User: 884.8 ms, System: 43.0 ms]
  Range (min … max):   926.7 ms … 936.3 ms    10 runs

Benchmark 2: zig-out/bin/ghostty-bench +codepoint-width --data=data.txt --mode=uucode
  Time (mean ± σ):     931.2 ms ±   2.5 ms    [User: 886.6 ms, System: 42.9 ms]
  Range (min … max):   927.3 ms … 935.7 ms    10 runs

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

### with buf[0], mode = .uucode

Another interesting thing is that with `buf[0]`, it's highly dependent
on the offsets somehow. If I switched the default mode line from `mode:
Mode = .noop` to `mode: Mode = .uucode`, it shifts the offsets ever so
slightly and even though that default mode is not getting used (since
it's passed in), it flips the results of the benchmark around:

```
Benchmark 1: zig-out/bin/ghostty-bench +codepoint-width --data=data.txt --mode=table
  Time (mean ± σ):     973.3 ms ±   2.2 ms    [User: 928.9 ms, System: 42.9 ms]
  Range (min … max):   968.0 ms … 975.9 ms    10 runs

Benchmark 2: zig-out/bin/ghostty-bench +codepoint-width --data=data.txt --mode=uucode
  Time (mean ± σ):     945.8 ms ±   1.4 ms    [User: 901.2 ms, System: 42.8 ms]
  Range (min … max):   943.5 ms … 948.5 ms    10 runs

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

looking at the assembly with `mode: Mode = .noop`:

```
# table.txt:

   165 	                // away
** 166 	                buf[0] = @intCast(width);

ghostty-bench[0x100017370] <+508>: strb   w11, [x21, #0x4]
ghostty-bench[0x100017374] <+512>: b      0x100017288               ; <+276> at CodepointWidth.zig:168:9
ghostty-bench[0x100017378] <+516>: mov    w0, #0x0                  ; =0 

# uucode.txt:

** 229 	                buf[0] = @intCast(width);

ghostty-bench[0x1000177bc] <+508>: strb   w11, [x21, #0x4]
ghostty-bench[0x1000177c0] <+512>: b      0x1000176d4               ; <+276> at CodepointWidth.zig:231:9
ghostty-bench[0x1000177c4] <+516>: mov    w0, #0x0                  ; =0 
```

vs `mode: Mode = .uucode`:

```
# table.txt:

** 166 	                buf[0] = @intCast(width);

ghostty-bench[0x100017374] <+508>: strb   w11, [x21, #0x4]
ghostty-bench[0x100017378] <+512>: b      0x10001728c               ; <+276> at CodepointWidth.zig:168:9
ghostty-bench[0x10001737c] <+516>: mov    w0, #0x0                  ; =0 

# uucode.txt:

** 229 	                buf[0] = @intCast(width);

ghostty-bench[0x1000177c0] <+508>: strb   w11, [x21, #0x4]
ghostty-bench[0x1000177c4] <+512>: b      0x1000176d8               ; <+276> at CodepointWidth.zig:231:9
ghostty-bench[0x1000177c8] <+516>: mov    w0, #0x0                  ; =0 
```

... shows the only difference is the offsets, which somehow have a large
impact on the result of the benchmark.
2025-09-06 12:48:40 -07:00
Mitchell Hashimoto
66b702f30c macOS: ghostty launched via CLI should come to front (#8546)
This fixes an issue I noticed where manually launching the `ghostty`
binary in the app bundle via the CLI would open the app but not create a
window or bring it to the front.
2025-09-06 12:45:29 -07:00
Mitchell Hashimoto
43d532475b macOS: probable cli should return false on macOS for desktop launch (#8544)
Fixes #8542

The comment explains why this is needed.
2025-09-06 12:45:11 -07:00
Jacob Sandlund
113e89b389 [benchmarks] Use std.mem.doNotOptimizeAway to avoid data collisions 2025-09-06 15:06:00 -04:00
Jeffrey C. Ollie
26e9b0a0f3 update zon2nix to version that builds with Zig 0.15 (#8545) 2025-09-06 09:58:24 -05:00
Mitchell Hashimoto
6324f2b3d8 macOS: ghostty launched via CLI should come to front
This fixes an issue I noticed where manually launching the `ghostty`
binary in the app bundle via the CLI would open the app but not create a
window or bring it to the front.
2025-09-06 07:16:51 -07:00
Jeffrey C. Ollie
314191737d update zon2nix to version that builds with Zig 0.15 2025-09-06 09:10:49 -05:00
Mitchell Hashimoto
6e1d6f3afe config: probable cli should return false on macOS for desktop launch
Fixes #8542

The comment explains why this is needed.
2025-09-06 07:09:09 -07:00
Mitchell Hashimoto
e4c3a56242 Micro-optimize GlyphKey Context (#8536)
Use fast hash function on key for better distribution.

Direct compare glyph in eql to avoid Packed.from() if not neccessary.

16% -> 6.4% reduction during profiling runs.
2025-09-05 15:25:14 -07:00
Jesse Miller
cf39d5c512 Glphkey.hash CityHash64 -> hash.int 2025-09-05 15:21:47 -07:00
Mitchell Hashimoto
6b21662219 Fix off-by-one error & adjust overline pos in cell height mod (#8022)
I noticed that there was an off-by-one error in cell height adjustment
when the number of pixels to add/subtract is odd. The metrics measured
from the top would be shifted by one less than they should, so, for
example, the underline position would move one pixel closer to the
baseline than it had been (or one pixel further away if subtracting).

Also noticed that the overline position was missing here, so added that.
2025-09-05 13:10:17 -07:00
Jesse Miller
8824256059 Micro-optimize GlyphKey Context
Use fast hash function on key for better distribution.

Direct compare glyph in eql to avoid Packed.from() if not neccessary.

16% -> 6.4% reduction during profiling runs.
2025-09-05 13:37:39 -06:00
Mitchell Hashimoto
15777050f3 apprt/gtk: set the title on the window immediately if set (#8535)
Fixes #5934

This was never confirmed to be a real issue on GTK, but it is
theoretically possible and good hygiene in general. Typically, we'd get
the title through a binding which comes from a bindinggroup which comes
from the active surface in the active tab. All of this takes multiple
event loop ticks to settle, if you will.

This commit changes it so that if an explicit, static title is set, we
set that title on startup before the window is mapped. The syncing still
happens later, but at least the window will have a title from the
initialization.
2025-09-05 12:03:03 -07:00
Mitchell Hashimoto
12bd7baaeb apprt/gtk: set the title on the window immediately if set
Fixes #5934

This was never confirmed to be a real issue on GTK, but it is
theoretically possible and good hygience in general. Typically, we'd get
the title through a binding which comes from a bindinggroup which comes
from the active surface in the active tab. All of this takes multiple
event loop ticks to settle, if you will.

This commit changes it so that if an explicit, static title is set, we
set that title on startup before the window is mapped. The syncing still
happens later, but at least the window will have a title from the
initialization.
2025-09-05 11:52:43 -07:00
Mitchell Hashimoto
0333a6f1d2 apprt/gtk: don't use Stacked for surface error status page (#8534)
Fixes #8533

Replace the usage of `Stacked` for error pages with programmatically
swapping the child of the `adw.Bin`.

I regret to say I don't know the root cause of this. I only know that
the usage of `Stacked` plus `Gtk.Paned` and the way we programmatically
change the paned position and stack child during initialization causes
major issues.

This change isn't without its warts, too, and you can see them heavily
commented in the diff.

(1) We have to workaround a GTK template double-free bug that is well
known to us: if you bind a template child that is also the direct child
of the template class, GTK does a double free on dispose. We workaround
this by removing our child in dispose. Valgrind verifies the fix.

(2) We have to workaround an issue where setting an `Adw.Bin` child
during a glarea realize causes some kind of critical GTK error that
results in a hard crash. We delay changing our bin child to an idle
tick.
2025-09-05 11:26:45 -07:00
Mitchell Hashimoto
ef822612d3 apprt/gtk: don't use Stacked for surface error status page
Fixes #8533

Replace the usage of `Stacked` for error pages with programmatically
swapping the child of the `adw.Bin`.

I regret to say I don't know the root cause of this. I only know that
the usage of `Stacked` plus `Gtk.Paned` and the way we programmatically 
change the paned position and stack child during initialization causes
major issues.

This change isn't without its warts, too, and you can see them heavily
commented in the diff. 

(1) We have to workaround a GTK template double-free bug that is well known 
to us: if you bind a template child that is also the direct child of the 
template class, GTK does a double free on dispose. We workaround this by
removing our child in dispose. Valgrind verifies the fix.

(2) We have to workaround an issue where setting an `Adw.Bin` child
during a glarea realize causes some kind of critical GTK error that
results in a hard crash. We delay changing our bin child to an idle
tick.
2025-09-05 11:14:53 -07:00
Jeffrey C. Ollie
a88e6cd428 renderer: add LUT-based implementation of isSymbol (#8528)
The LUT-based lookup gives a ~20%-30% speedup over the "naive" isSymbol
implementation.

<img width="1206" height="730" alt="Screenshot From 2025-09-04 22-45-10"
src="https://github.com/user-attachments/assets/09a8ef3a-8b4b-43ba-963a-849338307251"
/>
<img width="1206" height="730" alt="Screenshot From 2025-09-04 22-41-54"
src="https://github.com/user-attachments/assets/27962a88-f99c-446d-b986-30f526239ba3"
/>

Fixes #8523
2025-09-05 12:04:28 -05:00
Jeffrey C. Ollie
1ef220a679 render: address review feedback
1. `inline` the table get.
2. Delete unused functions on the LUT table.
3. Disable the isSymbol test under valgrind
2025-09-05 11:40:03 -05:00
Mitchell Hashimoto
0492cd16fa gtk-ng: deprecate detection of launch source (#8511)
Detecting the launch source frequently failed because various launchers
fail to sanitize the environment variables that Ghostty used to detect
the launch source. For example, if your desktop environment was launched
by `systemd`, but your desktop environment did not sanitize the
`INVOCATION_ID` or the `JOURNAL_STREAM` environment variables, Ghostty
would assume that it had been launched by `systemd` and behave as such.

This led to complaints about Ghostty not creating new windows when users
expected that it would.

To remedy this, Ghostty no longer does any detection of the launch
source. If your launch source is something other than the CLI, it must
be explicitly speciflied on the CLI. All of Ghostty's default desktop
and service files do this. Users or packagers that create custom desktop
or service files will need to take this into account.

On GTK, the `desktop` setting for `gtk-single-instance` is replaced with
`detect`. `detect` behaves as `gtk-single-instance=true` if one of the
following conditions is true:

1. If no CLI arguments have been set.
2. If `--launched-from` has been set to `desktop`, `dbus`, or `systemd`.

Otherwise `detect` behaves as `gtk-single-instance=false`.
2025-09-05 08:59:32 -07:00
Mitchell Hashimoto
587f47a587 apprt/gtk-ng: clean up our single instance, new window interactions
This removes `launched-from` entirely and moves our `gtk-single-instance`
detection logic to assume true unless we detect CLI instead of assume
false unless we detect desktop/dbus/systemd.

The "assume true" scenario for single instance is desirable because
detecting a CLI instance is much more reliable.

Removing `launched-from` fixes an issue where we had a
difficult-to-understand relationship between `launched-from`,
`gtk-single-instance`, and `initial-window`. Now, only
`gtk-single-instance` has some hueristic logic. And `initial-window`
ALWAYS sends a GTK activation signal regardless of single instance or
not.

As a result, we need to be explicit in our systemd, dbus, desktop files
about what we want Ghostty to do, but everything works as you'd mostly
expect.

Now, if you put plain old `ghostty` in your terminal, you get a new
Ghostty instance. If you put it anywhere else, you get a GTK single
instance activation call (either creates a first instance or opens a new
window in the existing instance). Works for launchers and so on.
2025-09-05 10:17:17 -05:00