I've been using agents a lot more with Ghostty and so are contributors.
Ghostty welcomes AI contributions (but they must be disclosed as AI
assisted), and this AGENTS.md will help everyone using agents work
better with the codebase.
This AGENTS.md has thus far been working for me very successfully,
despite being simple. I suspect we'll add to it as time goes on but I
also want to avoid making it too large and polluting the context.
Fixes#8495
We were incorrectly calling graceful quit under must quit scenarios.
This would do things like confirm quit by inspecting for running
processes. However, must quit scenarios (namely when all windows are
destroyed) should quit immediately without any checks because the
dispose process takes more event loop ticks to fully finish.
Fixes#8495
We were incorrectly calling graceful quit under must quit scenarios.
This would do things like confirm quit by inspecting for running
processes. However, must quit scenarios (namely when all windows are
destroyed) should quit immediately without any checks because the
dispose process takes more event loop ticks to fully finish.
Addresses issue: Add selection-clear-on-copy configuration #8407
Added configuration option `selection-clear-on-copy` that matches with
the `selection-clear-on-typing` option.
And `copy-on-select` is ignored when `selection-clear-on-copy` is true
regardless of whether `copy-on-select` is set to true or clipboard.
Also `.copy_to_clipboard` binding action was refactored to use
`copySelectionToClipboards` for consistent behavior.
> Consulted with Copilot (Claude Sonnet 4) to understand the control
flow of copy operations and help write the docs. Solution was authored
and implemented by me.
This is a small, but I think worthwhile micro optimization in style.zig,
I uncovered while investigating wider ranging optimizations in the
rendering section.
For me it results in ~4-5% increase in fps for DOOM-fire-zig benchmark,
which maximally stresses this code path.
Comparing the fields directly is actually faster than PackedStyle.
I wrote the code in style.zig, claude 4 wrote the benchmark, all PR
responses will be generated by jcm-slow-1
Style.eql Benchmark Comparison
==============================
Test: Small (1K pairs, 50% equal)
--------------------------------------------------
New implementation:
Iterations: 49937
Duration: 500.01 ms
Throughput: 99872402 comparisons/sec
Old implementation:
Iterations: 8508
Duration: 500.06 ms
Throughput: 17014026 comparisons/sec
Performance improvement:
Speedup: 5.87x
Improvement: +487.0%
Test: Medium (10K pairs, 50% equal)
--------------------------------------------------
New implementation:
Iterations: 4435
Duration: 500.09 ms
Throughput: 88684746 comparisons/sec
Old implementation:
Iterations: 850
Duration: 500.50 ms
Throughput: 16983017 comparisons/sec
Performance improvement:
Speedup: 5.22x
Improvement: +422.2%
Test: Large (50K pairs, 50% equal)
--------------------------------------------------
New implementation:
Iterations: 861
Duration: 500.41 ms
Throughput: 86030144 comparisons/sec
Old implementation:
Iterations: 171
Duration: 501.70 ms
Throughput: 17041989 comparisons/sec
Performance improvement:
Speedup: 5.05x
Improvement: +404.8%
Test: Mostly equal (10K pairs, 90% equal)
--------------------------------------------------
New implementation:
Iterations: 4608
Duration: 500.03 ms
Throughput: 92154471 comparisons/sec
Old implementation:
Iterations: 854
Duration: 500.45 ms
Throughput: 17064744 comparisons/sec
Performance improvement:
Speedup: 5.40x
Improvement: +440.0%
Test: Mostly different (10K pairs, 10% equal)
--------------------------------------------------
New implementation:
Iterations: 4065
Duration: 500.03 ms
Throughput: 81294960 comparisons/sec
Old implementation:
Iterations: 848
Duration: 500.21 ms
Throughput: 16952948 comparisons/sec
Performance improvement:
Speedup: 4.80x
Improvement: +379.5%
Test: Same flags (10K pairs, 50% equal)
--------------------------------------------------
New implementation:
Iterations: 2799
Duration: 500.00 ms
Throughput: 55979776 comparisons/sec
Old implementation:
Iterations: 859
Duration: 500.13 ms
Throughput: 17175672 comparisons/sec
Performance improvement:
Speedup: 3.26x
Improvement: +225.9%
Fixes#2473
This commit changes `ghostty_surface_ime_point` to return a full rect
with the width/height calculated for the preedit.
The `firstRect` function, which calls `ghostty_surface_ime_point` was
previously setting the width/height to zero. macOS didn't like this. We
then changed it to just hardcode it to width/height of one cell. This
worked but made it so the IME cursor didn't follow the preedit.
The result is shown in the video below. Notice the dictation icon
follows the text properly:
https://github.com/user-attachments/assets/81be8c63-9f0a-49b7-ac30-2db930beb238
Fixes#8481
Explained in code comments, basically the NF patcher can produce fonts
that have CJK characters with 1-cell advances, which screws up fallback
font scaling; fixed by not counting the ic width metric if the width of
the glyph is greater than the advance width.
> [!NOTE]
> As follow-on work to this it may be worth setting limits for scaling,
so you can't have one font scaled like twice as large as the primary
font, since that's almost always going to indicate something is very
wrong.
Fixes#2473
This commit changes `ghostty_surface_ime_point` to return a full rect
with the width/height calculated for the preedit.
The `firstRect` function, which calls `ghostty_surface_ime_point` was
previously setting the width/height to zero. macOS didn't like this. We
then changed it to just hardcode it to width/height of one cell. This
worked but made it so the IME cursor didn't follow the preedit.
When processing kitty images in a loop in a few places we were returning
under certain conditions where we should instead have just continued the
loop. This caused serious problems for kitty images, especially for apps
that used multiple images on screen at once.
... I have no clue how I originally wrote this code and didn't see such
a trivial mistake, I think I was sleep deprived or something.
Should fix#8471
When processing kitty images in a loop in a few places we were returning
under certain conditions where we should instead have just continued the
loop. This caused serious problems for kitty images, especially for apps
that used multiple images on screen at once.
... I have no clue how I originally wrote this code and didn't see such
a trivial mistake, I think I was sleep deprived or something.
This pull request adds the `--faint-opacity` option, as discussed in
#7637.
The default value of the option is also changed from `0.68` to `0.5` for
greater consistency with other popular terminal emulators.
Fix for discussion #8113
The cursor Y position value exposed to the shader uniforms was
incorrectly calculated. As per the doc in cell_text.v.glsl: In order to
get the top left of the glyph, we compute an offset based on the
bearings. The Y bearing is the distance from the bottom of the cell to
the top of the glyph, so we subtract it from the cell height to get the
y offset.
This calculation was mistakenly left out of the original code.
This will ensure that the custom shaders using
iCurrentCursor/iPreviousCursor get the correct Y coordinate representing
the top-left corner of the cursor rectangle, matching the documented
uniform behavior
This math was incorrect from the start, the previous fix helped OpenGL
but broke positioning under Metal; this commit fixes the math to be
correct under both backends and adds comments explaining exactly what's
going on.
Ghostty 1.2 needs to support GTK 4.14 because that's the version that
ships with Ubuntu 24.04.
This PR ensures that any GTK 4.16 CSS features are not used in any
static CSS and that the runtime CSS loading handles both 4.14 and 4.16+
appropriately.
Ghostty 1.2 needs to support GTK 4.14 because that's the version that
ships with Ubuntu 24.04.
This PR ensures that any GTK 4.16 CSS features are not used in any
static CSS and that the runtime CSS loading handles both 4.14 and 4.16+
appropriately.
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="305bfa7ea9...a289cf5d2f">compare
view</a></li>
</ul>
</details>
<br />
[](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>
Also did some copy-editing and removed some things that haven't been
present in the codebase for a while (I thought we nuked conformance
stuff in 1.1 already...?)