I had a bit of the same annoyance as #9064. I agree that with balanced
padding, you should expect horizontal jitter when resizing horizontally,
and vertical jitter when resizing vertically. Diagonal jitter, however,
happened because the top padding was upper bounded by the left padding,
coupling the vertical and horizontal wobbling. This looks kind of janky,
and it's surprising that the balance between top and bottom padding
changes as you vary only the width of the window.
With this PR, the upper bound is instead equal to the maximum left
padding. Since this only depends on the config, not the current window
width, the diagonal wobbling is avoided. Both the top and left padding
still have the same range of motion as before.
An alternative could be to bound by the minimum or median left padding
instead. Open to suggestions.
**Before**
https://github.com/user-attachments/assets/d12c5870-f05d-450f-89fc-c59eab90e199
**After**
https://github.com/user-attachments/assets/35b80bb0-9ea2-41c1-8502-3a8eec51dbc6
## Description
This PR implements the basic functionality for "Liquid Glass" style
background support (#8155). I used OpenCode (Claude 4) in some capacity
to write this as I'm not super familiar with AppKit / SwiftUI. A good
chunk of this I still needed to write by hand since Claude doesn't
understand the Glass APIs, but I'm not 100% if the implementation here
makes the best decisions since the practices in Ghostty config and
separation of the AppKit code and SwiftUI seemed inconsistent to me.
Some of the combinations of options obviously create entirely unreadable
terminals, but I've found that regular glass and transparent with
opacity to be fairly readable. We *don't* enable this feature by default
since it would of course break existing users setups.
## Open Questions
- [x] How to determine the correct cornerRadius? For now this is
eyeballed, I can't see any macOS public API or clearly documented
constants.
- [x] Should boolean options be exposed for reasonable defaults?
- [x] Should the option need to be namespaced to macos-\*?
## Screenshots
0% Opacity, Regular
<img width="917" height="683" alt="image"
src="https://github.com/user-attachments/assets/ccb96ba7-5df2-4284-8526-e07bbb62e3e5"
/>
50% Opacity, Transparent
<img width="880" height="680" alt="image"
src="https://github.com/user-attachments/assets/5bdf12f9-3209-4aa9-8a4f-9a6eb4f95894"
/>
0% Opacity, Transparent
<img width="860" height="681" alt="image"
src="https://github.com/user-attachments/assets/1b33d400-4d8b-479a-94d7-47b844743e52"
/>
Reported by Mr. Hashimoto in discord.
These changes removedthe following warning:
`evaluation warning: 'system' has been renamed to/replaced by
'stdenv.hostPlatform.system'`
This adds a couple of Nix-based VM integration tests:
- Does `ghostty +version` run successfully?
- Can we create a new terminal window? (This is detected by setting the
background to a color that doesn't appear
normally on the desktop and seeing if we can detect that color in a
screenshot).
Obviously more can be done but I thought that these would be a couple of
good first steps.
The whole test suite can be run with `nix flake check`. Individual tests
can be run with a command like this:
```
nix run .#check.x86_64-linux.<test name>.driver
```
Bug: When toggling a Ghostty window between fullscreen and windowed mode
in the i3 window manager, or between tabbed mode and default tiling
mode, window borders would permanently stop being drawn around the
terminal window.
I bisected to find that the issue was first introduced in aa2dbe2.
The below explanation + the code in this PR was 100% generated by claude
code, since I don't know the first thing about x11 or terminal
development, and have never written any Zig before. I verified this code
change builds and solves the issue for me which I hope is more helpful
than just a bug report. If this code is actually garbage and the issue
should be fixed a different way it wouldn't shock me and this PR can
just be closed in favor of one from someone who knows what they're
doing.
Anyway this is the explanation that the llm generated:
Root cause was that syncAppearance() was updating X11 properties on
every call during window transitions, even when values hadn't changed.
These redundant property updates interfered with i3's border management.
The fix adds caching to syncBlur() and syncDecorations() to only update
X11 properties when values actually change, eliminating unnecessary
property changes during fullscreen transitions.
When toggling a Ghostty window between fullscreen and windowed mode in
the i3 window manager, window borders would disappear and not return.
Root cause was that syncAppearance() was updating X11 properties on
every call during window transitions, even when values hadn't changed.
These redundant property updates interfered with i3's border management.
The fix adds caching to syncBlur() and syncDecorations() to only update
X11 properties when values actually change, eliminating unnecessary
property changes during fullscreen transitions.
Closes#9894
**Problem**: Since #9850, a local build incorrectly identifies itself as
1.3.0 stable (in lieu of tip w/ commit info).
**Bug**: `@import("root")` in `Config.zig` resolves to the compilation
root (`main.zig`), not `build.zig` where the marker was defined. So
`@hasDecl` always returned false (i.e. all builds treated as
dependencies).
**Solution**: More or less @rockorager's original approach from #9850.
> _Use `@src().file` to get ghostty's source directory and compare it
with `b.build_root`. When they differ, ghostty is a dependency and we
skip git detection._
However, there is a potential edge case where if a downstream project
also has a `src/build/Config.zig` this will fail silently - seems
unlikely, but worth noting.
**Testing**:
```
$ zig build -p $HOME/.local -Doptimize=ReleaseFast
$ ghostty --version
Ghostty 1.3.0-main+a0a915a06
Version
- version: 1.3.0-main+a0a915a06
- channel: tip
```
---
> **AI Disclosure**: I used Claude Code to review and identify edge
cases.
Bumps
[actions/download-artifact](https://github.com/actions/download-artifact)
from 6.0.0 to 7.0.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/download-artifact/releases">actions/download-artifact's
releases</a>.</em></p>
<blockquote>
<h2>v7.0.0</h2>
<h2>v7 - What's new</h2>
<blockquote>
<p>[!IMPORTANT]
actions/download-artifact@v7 now runs on Node.js 24 (<code>runs.using:
node24</code>) and requires a minimum Actions Runner version of 2.327.1.
If you are using self-hosted runners, ensure they are updated before
upgrading.</p>
</blockquote>
<h3>Node.js 24</h3>
<p>This release updates the runtime to Node.js 24. v6 had preliminary
support for Node 24, however this action was by default still running on
Node.js 20. Now this action by default will run on Node.js 24.</p>
<h2>What's Changed</h2>
<ul>
<li>Update GHES guidance to include reference to Node 20 version by <a
href="https://github.com/patrikpolyak"><code>@patrikpolyak</code></a>
in <a
href="https://redirect.github.com/actions/download-artifact/pull/440">actions/download-artifact#440</a></li>
<li>Download Artifact Node24 support by <a
href="https://github.com/salmanmkc"><code>@salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/download-artifact/pull/415">actions/download-artifact#415</a></li>
<li>fix: update <code>@actions/artifact</code> to fix Node.js 24
punycode deprecation by <a
href="https://github.com/salmanmkc"><code>@salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/download-artifact/pull/451">actions/download-artifact#451</a></li>
<li>prepare release v7.0.0 for Node.js 24 support by <a
href="https://github.com/salmanmkc"><code>@salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/download-artifact/pull/452">actions/download-artifact#452</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/patrikpolyak"><code>@patrikpolyak</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/download-artifact/pull/440">actions/download-artifact#440</a></li>
<li><a href="https://github.com/salmanmkc"><code>@salmanmkc</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/download-artifact/pull/415">actions/download-artifact#415</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/download-artifact/compare/v6.0.0...v7.0.0">https://github.com/actions/download-artifact/compare/v6.0.0...v7.0.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="37930b1c2a"><code>37930b1</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/download-artifact/issues/452">#452</a>
from actions/download-artifact-v7-release</li>
<li><a
href="72582b9e0a"><code>72582b9</code></a>
doc: update readme</li>
<li><a
href="0d2ec9d4cb"><code>0d2ec9d</code></a>
chore: release v7.0.0 for Node.js 24 support</li>
<li><a
href="fd7ae8fda6"><code>fd7ae8f</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/download-artifact/issues/451">#451</a>
from actions/fix-storage-blob</li>
<li><a
href="d484700543"><code>d484700</code></a>
chore: restore minimatch.dep.yml license file</li>
<li><a
href="03a808050e"><code>03a8080</code></a>
chore: remove obsolete dependency license files</li>
<li><a
href="56fe6d904b"><code>56fe6d9</code></a>
chore: update <code>@actions/artifact</code> license file to 5.0.1</li>
<li><a
href="8e3ebc4ab4"><code>8e3ebc4</code></a>
chore: update package-lock.json with <code>@actions/artifact</code><a
href="https://github.com/5"><code>@5</code></a>.0.1</li>
<li><a
href="1e3c4b4d49"><code>1e3c4b4</code></a>
fix: update <code>@actions/artifact</code> to ^5.0.0 for Node.js 24
punycode fix</li>
<li><a
href="458627d354"><code>458627d</code></a>
chore: use local <code>@actions/artifact</code> package for Node.js 24
testing</li>
<li>Additional commits viewable in <a
href="018cc2cf5b...37930b1c2a">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>
Bumps
[actions/upload-artifact](https://github.com/actions/upload-artifact)
from 5.0.0 to 6.0.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/upload-artifact/releases">actions/upload-artifact's
releases</a>.</em></p>
<blockquote>
<h2>v6.0.0</h2>
<h2>v6 - What's new</h2>
<blockquote>
<p>[!IMPORTANT]
actions/upload-artifact@v6 now runs on Node.js 24 (<code>runs.using:
node24</code>) and requires a minimum Actions Runner version of 2.327.1.
If you are using self-hosted runners, ensure they are updated before
upgrading.</p>
</blockquote>
<h3>Node.js 24</h3>
<p>This release updates the runtime to Node.js 24. v5 had preliminary
support for Node.js 24, however this action was by default still running
on Node.js 20. Now this action by default will run on Node.js 24.</p>
<h2>What's Changed</h2>
<ul>
<li>Upload Artifact Node 24 support by <a
href="https://github.com/salmanmkc"><code>@salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/upload-artifact/pull/719">actions/upload-artifact#719</a></li>
<li>fix: update <code>@actions/artifact</code> for Node.js 24 punycode
deprecation by <a
href="https://github.com/salmanmkc"><code>@salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/upload-artifact/pull/744">actions/upload-artifact#744</a></li>
<li>prepare release v6.0.0 for Node.js 24 support by <a
href="https://github.com/salmanmkc"><code>@salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/upload-artifact/pull/745">actions/upload-artifact#745</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/upload-artifact/compare/v5.0.0...v6.0.0">https://github.com/actions/upload-artifact/compare/v5.0.0...v6.0.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="b7c566a772"><code>b7c566a</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/upload-artifact/issues/745">#745</a>
from actions/upload-artifact-v6-release</li>
<li><a
href="e516bc8500"><code>e516bc8</code></a>
docs: correct description of Node.js 24 support in README</li>
<li><a
href="ddc45ed9bc"><code>ddc45ed</code></a>
docs: update README to correct action name for Node.js 24 support</li>
<li><a
href="615b319bd2"><code>615b319</code></a>
chore: release v6.0.0 for Node.js 24 support</li>
<li><a
href="017748b48f"><code>017748b</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/upload-artifact/issues/744">#744</a>
from actions/fix-storage-blob</li>
<li><a
href="38d4c7997f"><code>38d4c79</code></a>
chore: rebuild dist</li>
<li><a
href="7d27270e0c"><code>7d27270</code></a>
chore: add missing license cache files for <code>@actions/core</code>,
<code>@actions/io</code>, and mi...</li>
<li><a
href="5f643d3c94"><code>5f643d3</code></a>
chore: update license files for <code>@actions/artifact</code><a
href="https://github.com/5"><code>@5</code></a>.0.1 dependencies</li>
<li><a
href="1df1684032"><code>1df1684</code></a>
chore: update package-lock.json with <code>@actions/artifact</code><a
href="https://github.com/5"><code>@5</code></a>.0.1</li>
<li><a
href="b5b1a91840"><code>b5b1a91</code></a>
fix: update <code>@actions/artifact</code> to ^5.0.0 for Node.js 24
punycode fix</li>
<li>Additional commits viewable in <a
href="330a01c490...b7c566a772">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>
We rely on temporarily setting ZDOTDIR to our `zsh` resource directory
to implement automatic shell integration. Setting ZDOTDIR in a system
file like /etc/zshenv overrides our ZDOTDIR value, preventing our shell
integration from being loaded.
The only way to prevent /etc/zshenv from being run is via the --no-rcs
flag. (The --no-globalrcs only applies to system-level files _after_
/etc/zshenv is loaded.) Unfortunately, there doesn't appear to be a way
to run a "bootstrap" script (to reimplement the Zsh startup sequence
manually, similar to how our bash integration works) and then enter an
interactive shell session.
https://zsh.sourceforge.io/Doc/Release/Files.html
Given all of the above, document this as an unsupported configuration
for automatic shell integration and point affected users at our manual
shell integration option.
See: #8000
- Removes unnecessary marker constant from build.zig that existed
solely to signal build root status
- Uses filesystem check (@src().file access) instead of compile-time
declaration lookup to detect when ghostty is a dependency
- Same behavior with less indirection: file resolves from build root
only when ghostty is the main project
We rely on temporarily setting ZDOTDIR to our `zsh` resource directory
to implement automatic shell integration. Setting ZDOTDIR in a system
file like /etc/zshenv overrides our ZDOTDIR value, preventing our shell
integration from being loaded.
The only way to prevent /etc/zshenv from being run is via the --no-rcs
flag. (The --no-globalrcs only applies to system-level files _after_
/etc/zshenv is loaded.) Unfortunately, there doesn't appear to be a way
to run a "bootstrap" script (to reimplement the Zsh startup sequence
manually, similar to how our bash integration works) and then enter an
interactive shell session.
https://zsh.sourceforge.io/Doc/Release/Files.html
Given all of the above, document this as an unsupported configuration
for automatic shell integration and point affected users at our manual
shell integration option.
Fixes#9905
This fixes a major compatibility issue with the CSI S sequence: When our
top margin is at the top (row 0) without left/right margins, we should
be creating scrollback. Previously, we were only deleting.
I'm going to push this to 1.3 just given the feature of regressing any
other VT behaviors from this.
Also note the TODO, we implement the scrollback behavior by treating it
logically like an `index` (but scrolling above the bottom region). This
is expensive for large N but in most cases scroll up is small. Still, we
should optimize this one day.
**AI disclosure:** I used AI to investigate the xterm behavior, but got
it to return line numbers for me to verify the logic myself. I also used
it to identify missing test cases and fill those out initially, but I
modified them myself after. The actual core logic was all hand-written.
Fixes#9905
This fixes a major compatibility issues with the CSI S sequence:
When our top margin is at the top (row 0) without left/right
margins, we should be creating scrollback. Previously, we were
only deleting.