Compare commits

...

4093 Commits
v1.1.3 ... main

Author SHA1 Message Date
Mitchell Hashimoto a4cb73db84
macOS: Session Search (#9945)
Replaces #9785 

This adds session search to the command palette on macOS. Session search
lets you jump to any running terminal based on title or working
directory. The command palette shows you the title, working directory,
and tab color (if any) to help you identify the terminal you care about.

This also enhances our command palette in general to support better
sorting, more stable sorts when keys are identical, etc.

## Demo


https://github.com/user-attachments/assets/602a9424-e182-4651-bf08-378e9c5e1616




## Future

Since this inherits the command palette infrastructure, we don't have
fuzzy search capabilities yet, but I still think this is useful already.
We should add fuzzy searching in the future.

Thanks @phaistonian for the inspiration here but I did do a full
rewrite.

**AI disclosure:** I used AI to assist with this in places, but I
understand everything and touched up almost everything manually.
2025-12-17 11:01:19 -08:00
Mitchell Hashimoto e1d0b22029
macos: allow searching sessions by color too 2025-12-17 10:52:03 -08:00
Mitchell Hashimoto 842583b628
macos: fix uikit build 2025-12-17 10:26:02 -08:00
Mitchell Hashimoto 829dd1b9b2
macos: focus shenangians 2025-12-17 10:13:53 -08:00
Mitchell Hashimoto e1356538ac
macos: show a highlight animation when a terminal is presented 2025-12-17 10:12:44 -08:00
Mitchell Hashimoto d23f7e051f
macos: stable sort for surfaces 2025-12-17 09:52:06 -08:00
Mitchell Hashimoto 1fd3f27e26
macos: show pwd for jump options 2025-12-17 09:47:16 -08:00
Mitchell Hashimoto b30e94c0ec
macos: sort in the focus jumps in other commands 2025-12-17 09:34:30 -08:00
Mitchell Hashimoto 835fe3dd0f
macos: add the active terminals to our command palette to jump 2025-12-17 09:30:39 -08:00
Mitchell Hashimoto e1e782c617
macos: clean up the way command options are built up 2025-12-17 09:10:46 -08:00
Mitchell Hashimoto 5d11bdddc3
macos: implement the present terminal action so we can use that 2025-12-17 09:04:51 -08:00
Mitchell Hashimoto 7e46200d31
macos: command palette entries support leading color 2025-12-17 08:56:22 -08:00
Mitchell Hashimoto c84113d199
font/coretext: Use positions to correct glyph placement (#9883)
This PR uses positions to get correct glyph placement, which affects a
small number of shaped runs but can even re-order glyphs from how
they're appearing on `main`. This came from an investigation in
https://github.com/jquast/wcwidth/issues/155#issuecomment-3630555803
that involved shaping text from the [Universal Declaration of Human
Rights](https://www.un.org/en/about-us/universal-declaration-of-human-rights)
in 500+ languages, taken from
[ucs-detect](https://github.com/jquast/ucs-detect) (but actually run
with [ttylang](https://github.com/jacobsandlund/ttylang) for more
consistent results).

The full result of running this with the commented out debug lines
enabled is here, showing 1704 differences (a small number compared to
the number of cells being rendered):
https://gist.github.com/jacobsandlund/9cb2c603308085fa03e758640583541e

Some positions are only a small offset that is applied to many letters
from a script (e.g. Syriac letters are getting offset by some small
amount).

There are more egregious cases, though. Consider Tai Tham vowels, that
[according to the Unicode core
spec](https://www.unicode.org/versions/Unicode17.0.0/core-spec/chapter-16/#G46437),
are rendered visually ahead of the consonant they follow in the text.
The Unicode spec oddly mentions this under the "New Tai Lue" section,
contrasting it with other Brahmi-derived scripts such as Tai Tham:

> This practice differs from the usual pattern for Brahmi-derived
scripts, in which all dependent vowels are stored in logical order after
their associated consonants, even when they are displayed to the left of
those consonants.

For example `"\u{1A2F}\u{1A70}"` renders like this on `main`:

<img width="608" height="90" alt="CleanShot 2025-12-12 at 09 25 16@2x"
src="https://github.com/user-attachments/assets/964063b7-59e7-43f7-b2c9-a0c0c827034a"
/>

And it now renders like this on the PR:

<img width="500" height="90" alt="CleanShot 2025-12-12 at 09 25 38@2x"
src="https://github.com/user-attachments/assets/b6dded0b-30cc-40d8-857d-06b64f7cf19d"
/>

This is the correct rendering as U+1A70 is "TAI THAM VOWEL SIGN OO" and
needs to render ahead of the U+1A2F "TAI THAM LETTER DA"

Note, this PR just fixes CoreText. I'll work on Harfbuzz right after
this, but I wanted to get this out first.

## vtebench

vtebench does show some potential impact on dense cells:


![output](https://github.com/user-attachments/assets/d6741f28-88b9-49a9-b8ef-1f5a61c346da)


![dense_cells](https://github.com/user-attachments/assets/ea18801c-4529-42db-b259-edbe4e4b939b)

This is the first time I've run `vtebench`, so to confirm it's
consistent I ran it again:


![output-2](https://github.com/user-attachments/assets/c418b4b2-18cc-47fd-8fc9-d1e4826942d3)


![dense_cells](https://github.com/user-attachments/assets/c70d573c-4282-4719-ac52-5121b0c155c6)

### AI disclaimer
I had been using Amp when I made this change, but looks like the thread
just fell off of recent threads (about a week ago). I think Amp was the
one to add the getPositionsPtr line and add `position` to the for loop.
I manually restructured the code around a separate `run_offset` and
`cell_offset`, and added the tests.
2025-12-17 08:46:12 -08:00
Mitchell Hashimoto d820a633ee
fix up typos 2025-12-17 08:34:31 -08:00
Jacob Sandlund aecdacbe49 Merge remote-tracking branch 'origin/main' into shaping-positions 2025-12-17 10:02:06 -05:00
Jacob Sandlund 139a23a0a2 Pull out debugging into a separate function. 2025-12-17 09:57:32 -05:00
Mitchell Hashimoto 6b04f75037
Fix (#9921) link opening by resolving existing relative paths (#9942)
This PR fixes an issue in the change I merged yesterday (#9921), which
was reported by @quonb. Apology

I verified the fix by testing a wide range of URL schemes:
```
echo "https://example.com"
echo "http://example.com"
echo "mailto:test@example.com"
echo "ftp://example.com/file.txt"
echo "file:/Users/you/file.txt"
echo "ssh:user@example.com"
echo "git://github.com/user/repo.git"
echo "ssh://example.com/path"
echo "tel:+12123456789"
echo "ipns://example.com/path"
echo "gemini://example.com/"
echo "gopher://example.com/1menu"
echo "news:comp.lang.zig"
  ```
2025-12-17 06:24:57 -08:00
Jacob Sandlund e28e4facf0 Merge remote-tracking branch 'origin/main' into shaping-positions 2025-12-17 09:18:10 -05:00
Elad Kaplan 67f9bb9e8a Fix link opening by resolving existing relative paths 2025-12-17 15:13:47 +02:00
Mitchell Hashimoto 50cb1bafd7
macOS: change `window` to `new-window` for `macos-dock-drop-behavior` (#9764)
Matches current option references and Swift implementation
2025-12-16 13:35:25 -08:00
Mitchell Hashimoto 072077d19d
gtk/opengl: print an error when OpenGL version is too old (#9586)
#1123 added a warning when the OpenGL version is too old, but it is
never used because GTK enforces the version set with
gl_area.setRequiredVersion() before prepareContext() is called: we end
up with a generic "failed to make GL context" error:
```
warning(gtk_ghostty_surface): failed to make GL context current: Unable to create a GL context warning(gtk_ghostty_surface): this error is almost always due to a library, driver, or GTK issue warning(gtk_ghostty_surface): this is a common cause of this issue: https://ghostty.org/docs/help/gtk-opengl-context
```

This patch removes the requirement at the GTK level and lets the ghostty
renderer check, now failing as follow:
```
info(opengl): loaded OpenGL 4.2
error(opengl): OpenGL version is too old. Ghostty requires OpenGL 4.3 warning(gtk_ghostty_surface): failed to initialize surface err=error.OpenGLOutdated warning(gtk_ghostty_surface): surface failed to initialize err=error.SurfaceError
```

(Note that this does not render a ghostty window, unlike the previous
error which rendered the "Unable to acquire an OpenGL context for
rendering." view, so while the error itself is easier to understand it
might be harder to view)

-----------------------

I looked for why I couldn't get a context at all mostly to see what
OpenGL 4.3 functions were required to see if there'd be easy fallbacks,
but it also took me a good 15 minutes this morning to understand that
there was nothing wrong with my gtk/mesa versions and it's just my
hardware being old, so I think it'd good to take in itself even if the
displaying itself is a bit meh.

Happy to try to display it in the error page if you think it's important
and I can figure out how (haven't looked much yet)
2025-12-16 13:34:14 -08:00
Dominique Martinet f37acdf6a0 gtk/opengl: print an error when OpenGL version is too old
#1123 added a warning when the OpenGL version is too old, but
it is never used because GTK enforces the version set with
gl_area.setRequiredVersion() before prepareContext() is called:
we end up with a generic "failed to make GL context" error:
warning(gtk_ghostty_surface): failed to make GL context current: Unable to create a GL context
warning(gtk_ghostty_surface): this error is almost always due to a library, driver, or GTK issue
warning(gtk_ghostty_surface): this is a common cause of this issue: https://ghostty.org/docs/help/gtk-opengl-context

This patch removes the requirement at the GTK level and lets the ghostty
renderer check, now failing as follow:
info(opengl): loaded OpenGL 4.2
error(opengl): OpenGL version is too old. Ghostty requires OpenGL 4.3
warning(gtk_ghostty_surface): failed to initialize surface err=error.OpenGLOutdated
warning(gtk_ghostty_surface): surface failed to initialize err=error.SurfaceError

(Note that this does not render a ghostty window, unlike the previous
error which rendered the "Unable to acquire an OpenGL context for
rendering." view, so while the error itself is easier to understand it
might be harder to view)
2025-12-16 13:30:37 -08:00
Mitchell Hashimoto 7d8bff27a0
ai: add /review-branch command (#9934)
This is a subcommand I've been using for some time. It takes an optional
issue/PR number as context and produces a prompt to review a branch for
how well it addresses the issue along with any isolated issues it spots.

Example:
https://ampcode.com/threads/T-019b2877-475f-758d-ae88-93c722561576
2025-12-16 13:27:14 -08:00
Mitchell Hashimoto a25a5360f3
ai: add /review-branch command
This is a subcommand I've been using for some time. It takes an optional
issue/PR number as context and produces a prompt to review a branch for
how well it addresses the issue along with any isolated issues it spots.

Example: https://ampcode.com/threads/T-019b2877-475f-758d-ae88-93c722561576
2025-12-16 13:23:39 -08:00
Mitchell Hashimoto ab3a3805aa
Fix macOS log command for Ghostty (#9933)
Corrected the command for viewing Ghostty logs on macOS.
2025-12-16 13:17:29 -08:00
IceCodeNew ccc2d32aa5
Fix macOS log command for Ghostty
Corrected the command for viewing Ghostty logs on macOS.
2025-12-17 05:16:27 +08:00
Mitchell Hashimoto 4827c7f53a
macOS: add `toggle_background_opacity` keybind action (#9117)
Related Issue: #5047 
Discussion: #4664 

### Investigation
The behavior of iTerm mentioned on the Discussion thread was as follows:

- `cmd + u` can be used to toggle "Use Transparency"
- The "Use Transparency" toggle operates on a per-surface basis
- The "Use Transparency" state persists even after reloading the config

### Summary
Based on the investigation and discussions in the preceding pull
requests, this implements the `toggle_background_opacity` keybind action
for macOS with the following specifications:

- Switches background opacity on a per-surface basis
- The background opacity state persists even after reloading the config
- Background opacity switching functionality is also available in Quick
Terminal
- Does nothing if `background-opacity` is set to 1 or higher
- Does nothing if in fullscreen mode

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

- Split Window
  - Each split window maintains synchronized background opacity states
- Tab Group
  - Background opacity states do not synchronize between tabs
- Quick Terminal
- Background opacity states remain synchronized even when windows are
closed
- Command Palette

### AI Disclosure
This pull request was made with assistance from Claude Code.
I reviewed all AI-generated code and wrote the final output manually.


https://github.com/user-attachments/assets/e46ff8f0-42f2-442f-97dd-d5f5c33b10f1
2025-12-16 13:11:51 -08:00
Mitchell Hashimoto 95f4093e96
macos: make syncAppearance a virtual method on BaseTerminalController 2025-12-16 12:59:56 -08:00
Mitchell Hashimoto f9a1f526c8
update some copy for the background opacity toggle 2025-12-16 11:40:12 -08:00
himura467 ba2cbef1f1 apprt/gtk: list `toggle_background_opacity` as unimplemented 2025-12-16 11:32:10 -08:00
himura467 8d49c698e4 refactor(macos): do nothing if in fullscreen 2025-12-16 11:32:10 -08:00
himura467 ded3dd4cbc refactor(macos): do nothing if `background-opacity >= 1` 2025-12-16 11:32:10 -08:00
himura467 4c6d3f8ed2 macos: add `toggle_background_opacity` keybind action 2025-12-16 11:32:10 -08:00
Mitchell Hashimoto 4883fd938e
config: better docs for split-preserve-zoom 2025-12-16 11:27:51 -08:00
Mitchell Hashimoto a1ffac3c58
introduce split-preserve-zoom config to maintain zoomed splits during navigation (#9089)
Closes #8458.

- Adds the split-preserve-zoom config option with a navigation flag.
- GTK and macOS runtimes now respect the flag so zoomed splits stay
zoomed when using split navigation. I've tested this on macOS (video
below), but have not tested on GTK.

This PR was written primarily with Codex CLI, using the
[gh-issue](https://github.com/ghostty-org/ghostty/blob/main/.agents/commands/gh-issue)
command.

Here is a short video of the debug build:


https://github.com/user-attachments/assets/3abea255-98e1-4a4f-9196-7c1b2663b9d2
2025-12-16 11:21:56 -08:00
lorenries d364e421a8 introduce split-preserve-zoom config to maintain zoomed splits during navigation 2025-12-16 11:14:09 -08:00
Mitchell Hashimoto 67eb480577
Adding keybind to the +list-themes TUI that would write out a file that contained themes (#8930)
This resolves issue: https://github.com/ghostty-org/ghostty/issues/8903,
so we can press 'w' when in TUI preview save mode to write a auto theme
config
2025-12-16 10:12:06 -08:00
greathongtu f7d0d72f19 remove auto theme include in config-template 2025-12-17 01:50:53 +08:00
Mitchell Hashimoto 29c0f982c3
Fix cmd-click opening of relative/local paths (#9921)
This PR fixes an issue #9563 where relative file paths were not being
resolved against the terminal’s current working directory before
opening.


#### Verification
Tested with directories containing:
```
/tmp/test/test
❯ du -h .
  0B    ./spaces-end
  0B    ./with dot.
  0B    ./space middle
8.0K    .
```

Parent directory resolution also works as expected:
```
/tmp/test/test
❯ du -h ..
  0B    ../test/spaces-end
  0B    ../test/with dot.
  0B    ../test/space middle
8.0K    ../test
 16K    ..
 ```
 
@mitchellh  
In your original description you mentioned that “Links should work for all situations as they do in iTerm2.”  
I noticed that, for example, when running `ls`, the paths are not clickable, while they are clickable in iTerm2.
If you think this case should also be handled, I can open a separate PR for it once this one is accepted.
2025-12-16 09:07:16 -08:00
Mitchell Hashimoto db4e8d76d8
macOS: save&restore quick terminal state (#9588)
Implements #8399. 

I didn't save `position` in this pr, since I don't see its necessity. 

Changing `quick-terminal-position` requires a relaunch; saving and
restoring this would have to deal with conflicts. I also don't see why a
user would change this frequently.

> [!NOTE]
> Used GPT to proofread my comments
2025-12-16 09:06:47 -08:00
Lukas d680404fae macOS: save&restore quick terminal state 2025-12-16 08:51:58 -08:00
greathongtu e58bbc1d3e
Merge branch 'ghostty-org:main' into feat-list-themes-write-config 2025-12-17 00:29:24 +08:00
Mitchell Hashimoto 72747a28af
OSC parser microbenchmarking (#9867)
Add options to the Ghostty benchmark tool to test the OSC parser in
isolation.

```
ghostty on  benchmark-osc [?] via  v0.15.2 via   impure (ghostty-env) took 5s
at 22:32:50 → ./zig-out/bin/ghostty-gen +osc --style=parser --p-valid=0.9 | head -c100000000 > osc.txt

ghostty on  benchmark-osc [?] via  v0.15.2 via   impure (ghostty-env)
at 22:32:52 → poop './zig-out/bin/ghostty-bench +osc-parser --data=osc.txt'
Benchmark 1 (12 runs): ./zig-out/bin/ghostty-bench +osc-parser --data=osc.txt
  measurement          mean ± σ            min … max           outliers
  wall_time           421ms ± 4.15ms     415ms …  430ms          0 ( 0%)
  peak_rss           5.89MB ± 74.1KB    5.73MB … 6.03MB          4 (33%)
  cpu_cycles         1.54G  ± 5.82M     1.54G  … 1.56G           2 (17%)
  instructions       4.12G  ± 15.6      4.12G  … 4.12G           1 ( 8%)
  cache_references   13.6M  ±  219K     13.3M  … 14.0M           0 ( 0%)
  cache_misses       72.7K  ± 16.5K     59.2K  …  121K           1 ( 8%)
  branch_misses      3.29M  ± 42.1K     3.23M  … 3.36M           0 ( 0%)
```
2025-12-16 07:27:16 -08:00
Mitchell Hashimoto 011cf0e067
ci: optimizations (#9926)
This adds a couple optimizations to our CI:

1. macOS matrix gone, only test that freetype builds in addition to
Coretext.
2. Move Flatpak out to a triggered build on main similar to snaps. This
was our longest build and avoiding it in PRs is a win since it rarely
fails.
2025-12-16 07:10:06 -08:00
Mitchell Hashimoto 064c5684f7
ci: color scheme GHA uploads to mirror (#9925)
This changes our GHA that updates our color schemes to also upload it to
our dependency mirror at the same time. This prevents issues where the
upstream disappears, which we've had many times.
2025-12-16 07:02:21 -08:00
Mitchell Hashimoto ef0fec473a
ci: move flatpak out to a triggered build similar to snap 2025-12-16 07:00:02 -08:00
Mitchell Hashimoto 1a8eb52e99
ci: disable many macOS builds we don't use
This disables a bunch of configurations that we don't need to actually 
test for. The main one we want to keep building is Freetype because we
sometimes use this to compare behaviors, but Coretext is the default.

This is one of the primary drivers of CI CPU time.
2025-12-16 06:56:42 -08:00
Mitchell Hashimoto 3f504f33e5
ci: color scheme GHA uploads to mirror
This changes our GHA that updates our color schemes to also upload it
to our dependency mirror at the same time. This prevents issues where
the upstream disappears, which we've had many times.
2025-12-16 06:47:29 -08:00
Mitchell Hashimoto cb45410dcc
Update iTerm2 colorschemes (#9900)
Upstream release:
https://github.com/mbadolato/iTerm2-Color-Schemes/releases/tag/release-20251201-150531-bfb3ee1
2025-12-16 06:40:19 -08:00
Mitchell Hashimoto 8ed7cce203
zsh: removed unused self_dir variable (#9924)
This came from the original Kitty script on which ours is based, but we
don't use it.
2025-12-16 06:38:56 -08:00
Jon Parise c4cd2ca81d zsh: removed unused self_dir variable
This came from the original Kitty script on which ours is based, but we
don't use it.
2025-12-16 08:27:00 -05:00
Elad Kaplan 24413a9a24 Add a description to the test section comment 2025-12-16 10:17:54 +02:00
Elad Kaplan 32395fd838 Fix cmd-click opening of relative/local paths 2025-12-16 10:09:07 +02:00
Mitchell Hashimoto 0a0068002a
Revert "macos: populate the sparkle:channel element" (#9918)
Reverts ghostty-org/ghostty#9906

cc @jparise
2025-12-15 12:28:53 -08:00
Mitchell Hashimoto 78e539d684
Revert "macos: populate the sparkle:channel element" 2025-12-15 12:28:40 -08:00
Mitchell Hashimoto 051e6543ff
Decouple balanced top and left window paddings to avoid diagonal resize jitter (#9518)
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
2025-12-15 12:11:04 -08:00
Mitchell Hashimoto 14539bc185
logging: document GHOSTTY_LOG and make it more flexible (#8815) 2025-12-15 11:58:42 -08:00
Jeffrey C. Ollie f8c03bb6f6 logging: document GHOSTTY_LOG and make it more flexible 2025-12-15 11:54:36 -08:00
Mitchell Hashimoto 6d2beed1b0
feat: add liquid glass background effect support (#8801)
## 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"
/>
2025-12-15 11:10:03 -08:00
Mitchell Hashimoto 4e10f27be4
config: macos blur settings enable blur on non-Mac 2025-12-15 11:00:53 -08:00
Mitchell Hashimoto 8482e0777d
macos: remove glass view on syncAppearance with blur 2025-12-15 10:58:35 -08:00
Mitchell Hashimoto a6ddf03a2e
remove the macos-background-style config 2025-12-15 10:54:35 -08:00
Mitchell Hashimoto bb23071166
config: change macos-background-style to be enums on background-blur 2025-12-15 10:42:21 -08:00
Justy Null 42493de098 fix: make titlebar transparent when using glass background style 2025-12-15 10:12:36 -08:00
Mitchell Hashimoto d5c378cd6b
minor style tweaks 2025-12-15 10:12:36 -08:00
Justy Null 45aceace72 fix: disable renderer background when macOS effects are enabled 2025-12-15 10:12:11 -08:00
Justy Null d40af61960 refactor: migrate background glass effect to new macos-background-style config 2025-12-15 10:10:51 -08:00
Justy Null a02364cbef feat: add liquid glass background effect support 2025-12-15 10:10:51 -08:00
Mitchell Hashimoto 0f98e3b905
nix: replace deprecated system with stdenv.hostPlatform.system (#9916)
Reported by Mr. Hashimoto in discord. 

These changes removedthe following warning:
`evaluation warning: 'system' has been renamed to/replaced by
'stdenv.hostPlatform.system'`
2025-12-15 10:07:20 -08:00
Uzair Aftab 07578d5e3f nix: replace deprecated system with stdenv.hostPlatform.system 2025-12-15 18:59:34 +01:00
Mitchell Hashimoto 4adc5ed850
Nix VM integration tests (#8339)
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
```
2025-12-15 09:47:32 -08:00
Mitchell Hashimoto 928398e47b
Fix i3 window border disappearing after fullscreen toggle (#8075)
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.
2025-12-15 09:45:22 -08:00
Mitchell Hashimoto 47462ccc95
clean up some blurring code 2025-12-15 09:40:10 -08:00
James Baumgarten 4ec8adc1b9 trailing whitespace 2025-12-15 09:33:19 -08:00
James Baumgarten b15f16995c Fix i3 window border disappearing after fullscreen toggle
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.
2025-12-15 09:33:00 -08:00
Mitchell Hashimoto 195c1561fa
refactor(build): simplify dependency detection logic (#9914)
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.
2025-12-15 08:46:02 -08:00
Mitchell Hashimoto 44b82e1eb1
macos: populate the sparkle:channel element (#9906)
This makes the update channel name available alongside the version,
data, etc., which we can use in our update view (on the Released line).

<img width="317" height="230" alt="CleanShot 2025-12-14 at 09 48 43@2x"
src="https://github.com/user-attachments/assets/b9695090-a219-44b7-b74e-0ba599ae5f52"
/>
2025-12-15 08:37:56 -08:00
Mitchell Hashimoto 6d671ff738
build(deps): bump actions/download-artifact from 6.0.0 to 7.0.0 (#9909)
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 />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/download-artifact&package-manager=github_actions&previous-version=6.0.0&new-version=7.0.0)](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-12-15 08:37:40 -08:00
Mitchell Hashimoto 09e3ca3e42
build(deps): bump actions/upload-artifact from 5.0.0 to 6.0.0 (#9910)
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 />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/upload-artifact&package-manager=github_actions&previous-version=5.0.0&new-version=6.0.0)](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-12-15 08:37:30 -08:00
Mitchell Hashimoto ac80418965
zsh: document unsupported system-level ZDOTDIR (#9911)
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
2025-12-15 08:37:15 -08:00
kadekillary a0a915a06f refactor(build): simplify dependency detection logic
- 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
2025-12-15 06:31:54 -06:00
Jon Parise b0c053cfb7 zsh: document unsupported system-level ZDOTDIR
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.
2025-12-14 20:24:41 -05:00
dependabot[bot] 7e5683ebfd
build(deps): bump actions/upload-artifact from 5.0.0 to 6.0.0
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 5.0.0 to 6.0.0.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](330a01c490...b7c566a772)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: 6.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-15 00:05:24 +00:00
dependabot[bot] bbda6c35e3
build(deps): bump actions/download-artifact from 6.0.0 to 7.0.0
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 6.0.0 to 7.0.0.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](018cc2cf5b...37930b1c2a)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: 7.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-15 00:05:17 +00:00
Mitchell Hashimoto 1d7fe9e70d
terminal: CSI S compatiblity improvements (#9907)
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.
2025-12-14 14:40:37 -08:00
Mitchell Hashimoto 1fdc0c0b9f
terminal: CSI S compatiblity improvements
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.
2025-12-14 14:36:42 -08:00
Jon Parise 786dc93438 macos: populate the sparkle:channel element
This makes the update channel name available alongside the version,
data, etc., which we can use in our update view (on the Released line).
2025-12-14 17:19:53 -05:00
mitchellh 3d5d170f8b deps: Update iTerm2 color schemes 2025-12-14 00:15:58 +00:00
Mitchell Hashimoto 2cc7341b08
macos: implement goto_window:next/previous (#9899) 2025-12-13 14:40:40 -08:00
Mitchell Hashimoto 628157619c
Update mirror for direct deps (#9898) 2025-12-13 14:38:35 -08:00
Mitchell Hashimoto 05ee9ae733
macos: implement goto_window:next/previousu 2025-12-13 14:33:17 -08:00
Mitchell Hashimoto 1a117c46e0
macos: fix missing goto_window union entry 2025-12-13 14:29:09 -08:00
Mitchell Hashimoto dfb94cd55d
apprt/gtk: clean up gotoWindow 2025-12-13 14:23:53 -08:00
Mitchell Hashimoto 4c2fb7ae0e
Update mirror for direct deps 2025-12-13 13:53:46 -08:00
Max Bretschneider bb246b2e0c Added null handling for findCustom 2025-12-13 13:45:45 -08:00
Max Bretschneider 7e0dc09873 Just using decl literals 2025-12-13 13:45:45 -08:00
Max Bretschneider 6230d134e1 Type-safe rework 2025-12-13 13:45:45 -08:00
Max Bretschneider 6b8a7e1dd1 Replaced direction switch, direclty handling next and previous now 2025-12-13 13:45:45 -08:00
Max Bretschneider b344c978d0 Added GOTO_WINDOW to actions enum 2025-12-13 13:45:45 -08:00
Max Bretschneider 4f02e6c096 Wrong action typo fix 2025-12-13 13:45:45 -08:00
Max Bretschneider afbcfa9e3d Added GOTO_WINDOW to actions 2025-12-13 13:45:44 -08:00
Max Bretschneider 55ae4430b9 Formatting 2025-12-13 13:45:44 -08:00
Max Bretschneider 3000136e61 Changed switching previous/next to have no duplication 2025-12-13 13:45:44 -08:00
Max Bretschneider 1c1ef99fb1 Window switching initial 2025-12-13 13:45:44 -08:00
Mitchell Hashimoto 1805a9cb87
fix: explicitly allow preservation for TERMINFO in shell-integration (#9891)
Due to security issues, `sudo` implementations may not preserve
environment variables unless appended with `--preserve-env=list`.

Problem context: https://github.com/ghostty-org/ghostty/discussions/9861
2025-12-13 08:41:28 -08:00
Mitchell Hashimoto 0a6311c819
input: shift+backspace in Kitty with only disambiguate should do CSIu (#9896)
Fixes #9868 (shift+backspace part only)

You have to use `fish_key_reader -V` to verify this since it uses
different modes than Kitty's key reader. This matches the encoding to
Kitty.
2025-12-13 07:21:10 -08:00
Mitchell Hashimoto c5d6b951e9
input: shift+backspace in Kitty with only disambiguate should do CSIu
Fixes #9868 (shift+backspace part only)
2025-12-13 07:18:22 -08:00
Lukas 91b4a218ca
macOS: change `window` to `new-window` for `macos-dock-drop-behavior`
Matches current option references and Swift implementation
2025-12-13 10:17:42 +01:00
definfo 4a04efaff1
fix: explicitly allow preservation for TERMINFO in shell-integration
Due to security issues, `sudo` implementations may not preserve
environment variables unless appended with `--preserve-env=list`.

Signed-off-by: definfo <hjsdbb1@gmail.com>
2025-12-13 16:55:41 +08:00
Mitchell Hashimoto 7a1ff7779b
feat: add readonly surface mode (#9130)
Tried my hand at #8432

Currently lacking tests and some sort of visual indicator that the
surface is locked.

Also, not entirely sure if I needed to touch `application.zig`.

Found what needed changing with help from Copilot (and added Docs w/
Copilot), but wrote most of the code myself.
2025-12-12 14:16:39 -08:00
Mitchell Hashimoto 182cb35bae
core: remove readonly check 2025-12-12 14:15:43 -08:00
Mitchell Hashimoto 19e0864688
macos: unintended change 2025-12-12 14:14:15 -08:00
Mitchell Hashimoto 43b4ed5bc0
macos: only show readonly badge on AppKit 2025-12-12 14:12:05 -08:00
Mitchell Hashimoto 6dcf75126b
macos: more strict detection for tab context menu (#9888)
We were accidentally modifying the "View" menu.
2025-12-12 14:09:39 -08:00
Mitchell Hashimoto ddaf307cf7
macos: more strict detection for tab context menu
We were accidentally modifying the "View" menu.
2025-12-12 14:05:46 -08:00
Mitchell Hashimoto 22b8809858
macos: add a popover to the readonly badge with info 2025-12-12 14:02:45 -08:00
Mitchell Hashimoto 173d8efd90
macos: add to context menu 2025-12-12 13:55:03 -08:00
Mitchell Hashimoto ceb1b5e587
macos: add a read-only menu item in View 2025-12-12 13:53:08 -08:00
Mitchell Hashimoto ec2638b3c6
macos: readonly badge 2025-12-12 13:46:28 -08:00
Mitchell Hashimoto dc7bc3014e
add apprt action to notify apprt of surface readonly state 2025-12-12 13:13:54 -08:00
Mitchell Hashimoto 262b82ab08
fix(docs): `window-decoration` is now `none` instead of `false` (#9887)
Heya,
super random but i saw this in the documentation and felt like it should
be fixed 😅
2025-12-12 13:08:27 -08:00
Mitchell Hashimoto 0bf3642939
core: manage read-only through queueIo 2025-12-12 13:08:03 -08:00
Michael Hazan 6dd9a74e6e fix(docs): `window-decoration` is now `none` instead of `false` 2025-12-12 22:56:06 +02:00
Mitchell Hashimoto c198c6dc69
fix: bash shell integration use-after-free bug from PR #9881 (#9885)
(Claude-generated content below)

## Fix bash shell integration use-after-free bug

### Problem

After updating to the latest `main` branch, Ghostty fails to launch with
bash shell integration enabled on Linux (Ubuntu 25.10). The terminal
window briefly appears and then closes with an error like:

```
/bin/sh: 1: ically: not found
```

The error message varies but typically contains fragments of words (like
"ically" from "automatically").

Related issue was possibly [reported in the comments of PR
#9881](https://github.com/ghostty-org/ghostty/pull/9881) shortly after
it was merged.

### Root Cause Analysis

The bug is a **use-after-free** in the bash shell integration setup.

In `setupBash()`, the `ShellCommandBuilder` is initialized with a
`stackFallback` allocator:

```zig
var stack_fallback = std.heap.stackFallback(4096, alloc);
var cmd = internal_os.shell.ShellCommandBuilder.init(stack_fallback.get());
```

When `cmd.toOwnedSlice()` is called, it returns a slice allocated from
the `stackFallback` allocator. Since the command string (e.g., "bash
--posix") easily fits within 4096 bytes, this memory is allocated on the
**stack**.

When `setupBash()` returns, the stack frame is deallocated, but the
returned `.shell` command still points to this now-invalid stack memory.
When the command is later used in `execCommand()` to build the `/bin/sh
-c "..."` invocation, it reads garbage data.

The garbage data often contains "ically" because it picks up fragments
from nearby memory—likely from the string literal "automatically" in the
comment on line 280:

```zig
// being manually sourced or automatically injected (from here).
```

This is a [known footgun with Zig's stackFallback
allocator](https://github.com/ziglang/zig/issues/16344) - memory
allocated from the stack portion becomes invalid once the stack frame is
exited.

### Bisect / Blame

The bug was introduced **~5 hours ago** (earlier today):

| Field | Value |
|-------|-------|
| **Commit** | `04fecd7c07fccad423ab1c33324a1997e142b6e2` |
| **PR** | [#9881](https://github.com/ghostty-org/ghostty/pull/9881)
(os/shell: introduce ShellCommandBuilder) |
| **Date** | Fri Dec 12 08:59:44 2025 -0500 |
| **Merged as** | `dd06d8a13` |

The previous implementation in commit `c0deaaba4` used
`std.mem.joinZ(alloc, " ", args.items)` which correctly allocated the
result using the arena allocator. The refactor to use
`ShellCommandBuilder` inadvertently changed the allocation strategy to
use stack memory for the returned value.

Other uses of `stackFallback` in the codebase are safe because they
either:
- Copy data to another allocator before the function returns (e.g.,
`env.put()` in `setupXdgDataDirs`)
- Use the data only within the function scope (e.g.,
`stream_handler.zig`)

### The Fix

Copy the command string to the arena allocator before returning:

```zig
const cmd_str = try cmd.toOwnedSlice();
return .{ .shell = try alloc.dupeZ(u8, cmd_str) };
```

This ensures the memory remains valid for the lifetime needed by the
caller, matching the behavior of other `stackFallback` usage patterns in
the codebase.

### Testing

- Verified the fix on Ubuntu 25.10 with Ghostty built from source
- Before fix: Terminal crashes immediately with "ically: not found"
error
- After fix: Terminal launches successfully with shell integration
working

```
info(io_exec): shell integration automatically injected shell=.bash
info(io_exec): started subcommand path=/bin/sh pid=...
info(surface): surface closed addr=...  # Normal close, no "abnormal process exit"
```

### Platform

Primarily affects Linux where `.shell` commands are wrapped in `/bin/sh
-c "..."`. macOS uses a different execution path via `login(1)`.
2025-12-12 12:11:06 -08:00
Mitchell Hashimoto 29fdb541d5
make all IO message queueing go through queueIo so we can intercept 2025-12-12 12:00:28 -08:00
Michael Bommarito 2d9c83dbb7 fix: bash shell integration use-after-free bug
The ShellCommandBuilder uses a stackFallback allocator, which means
toOwnedSlice() may return memory allocated on the stack. When setupBash()
returns, this stack memory becomes invalid, causing a use-after-free.

This manifested as garbage data in the shell command string, often
appearing as errors like "/bin/sh: 1: ically: not found" (where "ically"
was part of nearby memory, likely from the comment "automatically").

The fix copies the command string to the arena allocator before returning,
ensuring the memory remains valid for the lifetime of the command.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-12 13:36:36 -05:00
Mitchell Hashimoto b58ac983cf
docs changes 2025-12-12 07:29:46 -08:00
Matthew Hrehirchuk 6369aaa93e Merge branch 'main' of github.com:ghostty-org/ghostty into feat/read-only 2025-12-12 07:24:48 -08:00
Matthew Hrehirchuk 547bcd261d fix: removed apprt action for toggle_readonly 2025-12-12 07:24:22 -08:00
Matthew Hrehirchuk 12bb2f3f47 feat: add readonly surface mode 2025-12-12 07:24:22 -08:00
Mitchell Hashimoto dd06d8a13b
os/shell: introduce ShellCommandBuilder (#9881)
This builder is an efficient way to construct space-separated shell
command strings.

We use it in setupBash to avoid using an intermediate array of arguments
to construct our bash command line.
2025-12-12 07:09:58 -08:00
Mitchell Hashimoto c95801db85
CONTRIBUTING: limit AI assistance to code only (#9882)
I think at this point all moderators and helpers can agree with me in
that LLM-generated responses are a blight upon this Earth.

Also probably worth putting in a clause against AI-generated assets
2025-12-12 07:09:35 -08:00
Jacob Sandlund 075ef6980b Fix comment typo 2025-12-12 09:27:45 -05:00
Jon Parise 04fecd7c07 os/shell: introduce ShellCommandBuilder
This builder is an efficient way to construct space-separated shell
command strings.

We use it in setupBash to avoid using an intermediate array of arguments
to construct our bash command line.
2025-12-12 08:59:44 -05:00
Jacob Sandlund 6b1d1d7f9d Merge remote-tracking branch 'origin/main' into shaping-positions 2025-12-12 08:54:34 -05:00
Leah Amelia Chen 315c8852a8
CONTRIBUTING: reorganize paragraphs 2025-12-12 18:59:22 +08:00
Leah Amelia Chen 8a1bb215c1
CONTRIBUTING: further clarifications 2025-12-12 18:56:24 +08:00
Leah Amelia Chen 5e049e1b3a
CONTRIBUTING: AI-assisted != AI-generated 2025-12-12 18:53:10 +08:00
Leah Amelia Chen 65539d0d54
CONTRIBUTING: limit AI assistance to code only
I think at this point all moderators and helpers can agree with me in
that LLM-generated responses are a blight upon this Earth.

Also probably worth putting in a clause against AI-generated assets
(cf. the Commit Goods situation)
2025-12-12 18:43:51 +08:00
Mitchell Hashimoto 5aefb4b0a8
build(deps): bump cachix/install-nix-action from 31.8.4 to 31.9.0 (#9877)
Bumps
[cachix/install-nix-action](https://github.com/cachix/install-nix-action)
from 31.8.4 to 31.9.0.
<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.9.0</h2>
<h2>What's Changed</h2>
<ul>
<li>nix: 2.32.4 -&gt; 2.33.0 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/264">cachix/install-nix-action#264</a></li>
<li>chore(deps): bump peter-evans/create-pull-request from 7 to 8 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/cachix/install-nix-action/pull/263">cachix/install-nix-action#263</a></li>
<li>chore(deps): bump actions/checkout from 5 to 6 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/cachix/install-nix-action/pull/262">cachix/install-nix-action#262</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/cachix/install-nix-action/compare/v31.8.4...v31.9.0">https://github.com/cachix/install-nix-action/compare/v31.8.4...v31.9.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="4e002c8ec8"><code>4e002c8</code></a>
Merge pull request <a
href="https://redirect.github.com/cachix/install-nix-action/issues/262">#262</a>
from cachix/dependabot/github_actions/actions/checkout-6</li>
<li><a
href="65fe36965b"><code>65fe369</code></a>
Merge pull request <a
href="https://redirect.github.com/cachix/install-nix-action/issues/263">#263</a>
from cachix/dependabot/github_actions/peter-evans/cre...</li>
<li><a
href="c61d28fbcf"><code>c61d28f</code></a>
Merge pull request <a
href="https://redirect.github.com/cachix/install-nix-action/issues/264">#264</a>
from cachix/create-pull-request/patch</li>
<li><a
href="72e7d4072f"><code>72e7d40</code></a>
nix: 2.32.4 -&gt; 2.33.0</li>
<li><a
href="15a7ab2c66"><code>15a7ab2</code></a>
chore(deps): bump peter-evans/create-pull-request from 7 to 8</li>
<li><a
href="523410fd45"><code>523410f</code></a>
chore(deps): bump actions/checkout from 5 to 6</li>
<li><a
href="7e5978947b"><code>7e59789</code></a>
ci: drop macos-13 runner</li>
<li>See full diff in <a
href="0b0e072294...4e002c8ec8">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.8.4&new-version=31.9.0)](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-12-11 16:54:02 -08:00
Mitchell Hashimoto cba82e976c
macOS: Change Tab Title (#9879)
This adds the ability to change a _tab_ title. The previous
functionality was tied to a specific _surface_. A tab title will stick
to the current tab regardless of active splits and so on.

This follows the nomenclature that macOS terminal app does which is
"title vs terminal title" (although we explicitly use "tab" in various
places, I may remove that in the future).

**This is macOS only. GTK is tracked here: #9880**. I did macOS only
because thats the machine I'm on. It'll be trivial to add this to GTK,
too.

## Demo


https://github.com/user-attachments/assets/d9446785-d919-4212-8553-db50c56c8c2f

(The option is also in the main menu, the context menu, and the command
palette)

## AI Disclosure

This PR was done fully with Amp, I didn't write a single line of code at
the time of writing this PR description. I reviewed everything though
and fully understand it all. Its a mimic more or less of the prompt
surface title work (although we did unify some stuff like the apprt
action).
2025-12-11 16:53:50 -08:00
Mitchell Hashimoto 50bbced0c9
macos: add title override to restorable state 2025-12-11 16:40:09 -08:00
Mitchell Hashimoto 6105344c31
macos: add change tab title to right click menu 2025-12-11 16:30:06 -08:00
Mitchell Hashimoto 65c5e72d3e
macos: add tab title change to tab context menu 2025-12-11 16:24:50 -08:00
Mitchell Hashimoto 7b48eb5c62
macos: add change tab title to menu 2025-12-11 16:16:12 -08:00
Mitchell Hashimoto 65cf124e2c
core: change apprt action to enum value instead of a new one 2025-12-11 16:09:45 -08:00
dependabot[bot] 1f05625d3f
build(deps): bump cachix/install-nix-action from 31.8.4 to 31.9.0
Bumps [cachix/install-nix-action](https://github.com/cachix/install-nix-action) from 31.8.4 to 31.9.0.
- [Release notes](https://github.com/cachix/install-nix-action/releases)
- [Changelog](https://github.com/cachix/install-nix-action/blob/master/RELEASE.md)
- [Commits](0b0e072294...4e002c8ec8)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-12 00:06:57 +00:00
Mitchell Hashimoto e93a4a911f
macos: implement prompt_tab_title 2025-12-11 16:03:30 -08:00
Mitchell Hashimoto 32033c9e1a
core: prompt_tab_title binding and apprt action 2025-12-11 16:03:19 -08:00
Mitchell Hashimoto 2448a90c30
bash: use a shell command for shell integration (#9875)
Prior to #7044, on macOS, our shell-integrated command line would be
executed under `exec -l`, which causes bash to be started as a login
shell. This matches the macOS platform norms.

The change to direct command execution meant that we'd skip that path,
and bash would start as a normal interactive (non-login) shell on macOS.
We fixed this in #7253 by adding `--login` to the `bash` direct command
on macOS.

This avoided some of the overhead of starting an extra process just to
get a login shell, but it unfortunately doesn't quite match the bash
environment we get when shell integration isn't enabled (namely, `$0`
doesn't get the login-shell-identifying `-` prefix).

Instead, this change implements the approach proposed in #7254, which
switches the bash shell integration path to use a `.shell` command,
giving us the same execution environment as the non-shell-integrated
command.
2025-12-11 15:41:29 -08:00
Mitchell Hashimoto 4d757f0f28
macos: show tab color as header for menu item so its not grey 2025-12-11 14:43:26 -08:00
Mitchell Hashimoto 89bdee447f
macos: selected color in tab color menu should use target's color 2025-12-11 14:33:50 -08:00
Mitchell Hashimoto d77b7c32f9
feat(macos): add tab color picker to tab context menu (#9784)
<img width="1824" height="1488" alt="image"
src="https://github.com/user-attachments/assets/4a77f743-9eae-40bf-8cb4-d45d884a85a5"
/>
2025-12-11 14:27:25 -08:00
Mitchell Hashimoto 2331e17835
macos: change tab color label to circle 2025-12-11 14:18:57 -08:00
Jon Parise c0deaaba4e bash: use a shell command for shell integration
Prior to #7044, on macOS, our shell-integrated command line would be
executed under exec -l, which causes bash to be started as a login
shell. This matches the macOS platform norms.

The change to direct command execution meant that we'd skip that path,
and bash would start as a normal interactive (non-login) shell on macOS.
We fixed this in #7253 by adding `--login` to the `bash` direct command
on macOS.

This avoided some of the overhead of starting an extra process just to
get a login shell, but it unfortunately doesn't quite match the bash
environment we get when shell integration isn't enabled (namely, $0
doesn't get the login-shell-identifying "-" prefix).

Instead, this change implements the approach proposed in #7254, which
switches the bash shell integration path to use a .shell command, giving
us the same execution environment as the non-shell-integrated command.
2025-12-11 17:02:14 -05:00
Mitchell Hashimoto 6332fb5c01
macos: some cleanup 2025-12-11 13:59:06 -08:00
Mitchell Hashimoto f71a25a621
macos: make the tab color indicator SwiftUI 2025-12-11 13:57:39 -08:00
Mitchell Hashimoto c83bf1de75
macos: simplify terminal controller a bunch 2025-12-11 13:50:24 -08:00
Mitchell Hashimoto 1073e89a0d
macos: move context menu stuff in terminal window down to an ext 2025-12-11 13:40:01 -08:00
Mitchell Hashimoto f559bccc38
macos: clean up setting up the tab menu by using an NSMenu extension 2025-12-11 13:36:49 -08:00
Mitchell Hashimoto a0089702f1
macos: convert tab color view to SwiftUI 2025-12-11 13:27:51 -08:00
Jeffrey C. Ollie 5dd4e60c31
Fix typo in po/README_TRANS (#9870)
via the its -> via its
2025-12-11 10:06:54 -06:00
Jacob Sandlund 6addccdeeb Add shape Tai Tham vowels test 2025-12-11 10:48:28 -05:00
Mitchell Hashimoto 04913905a3
macos: tab color is codable for restoration 2025-12-11 07:24:46 -08:00
Mitchell Hashimoto 51589a4e02
macos: move TerminalTabColor to its own file 2025-12-11 07:23:51 -08:00
George Papadakis 1a65c1aae2 feat(macos): add tab color picker to tab context menu 2025-12-11 07:16:26 -08:00
Mitchell Hashimoto c45a762031
fix(terminal): increase grapheme_bytes instead of hyperlink_bytes during reflow (#9866)
Fixed: When reflowing content with many graphemes, the code incorrectly
increased hyperlink_bytes capacity
instead of grapheme_bytes, causing GraphemeMapOutOfMemory errors.

Added: An unit test for this specific issue. 

This PR was written primarily by Opus.

Closes: #9863
2025-12-11 07:06:51 -08:00
Devzeth b224b69054 fix(terminal): increase grapheme_bytes instead of hyperlink_bytes during reflow
When reflowing content with many graphemes, the code incorrectly increased hyperlink_bytes capacity
instead of grapheme_bytes, causing GraphemeMapOutOfMemory errors.
2025-12-11 07:03:12 -08:00
Mitchell Hashimoto 86503045e9
fix: prevent integer overflow in hash_map layoutForCapacity (#9871)
Closes #9862
2025-12-11 06:57:23 -08:00
Jacob Sandlund f4560390d7 Remove accidental changes to macos/text/run.ig 2025-12-11 09:35:52 -05:00
Jacob Sandlund 942f326c58 Merge remote-tracking branch 'origin/main' into shaping-positions 2025-12-11 09:32:01 -05:00
benodiwal 0d8c193bda
fix(terminal): prevent integer overflow in hash_map layoutForCapacity
Co-Authored-By: Sachin <sachinbeniwal0101@gmail.com>
2025-12-11 16:43:16 +05:30
Felipe M.B. 3b2f551dc0 Fix typo in po/README_TRANS
via the its -> via its
2025-12-11 07:54:20 -03:00
Jeffrey C. Ollie dd4493b153
Fix typo in po/README_CONTRIB (#9869)
Change translable to translatable.
2025-12-11 01:54:50 -06:00
Felipe M.B. f96aca7a3f Fix typo in po/README_CONTRIB
Change translable to translatable.
2025-12-11 04:13:19 -03:00
Mitchell Hashimoto 669733d597
macos: remove iOS signing (dev team) 2025-12-10 21:21:05 -08:00
Mitchell Hashimoto 4a6d551941
macos: don't put NSMenu extension in iOS build 2025-12-10 21:20:39 -08:00
Mitchell Hashimoto a531ea8b08
Add close tabs on the right action (#9783)
<img width="1694" height="1146" alt="image"
src="https://github.com/user-attachments/assets/f9e1e7e6-7cfe-4760-85fe-def7c10f4110"
/>
2025-12-10 21:09:13 -08:00
Mitchell Hashimoto 3352d5f081
Fix up close right description 2025-12-10 20:57:36 -08:00
Mitchell Hashimoto eb75d48e6b
macos: add xmark to other tab close items 2025-12-10 20:56:07 -08:00
Mitchell Hashimoto 1387dbefad
macos: target should be the correct target 2025-12-10 20:50:28 -08:00
Mitchell Hashimoto dc641c7861
macos: change to NSMenu extension 2025-12-10 20:47:15 -08:00
Mitchell Hashimoto f612e4632c
macos: clean up some style on tab bar context menu configuring 2025-12-10 20:43:43 -08:00
Jeffrey C. Ollie 01a75ceec4
benchmark: add option to microbenchmark OSC parser 2025-12-10 22:31:27 -06:00
Jeffrey C. Ollie cfdcd50e18
benchmark: generate more types of OSC sequences 2025-12-10 22:30:19 -06:00
Mitchell Hashimoto 4424451c59
macos: remove to "close to the right" 2025-12-10 20:28:27 -08:00
Jeffrey C. Ollie 10bac6a5dd
benchmark: use newer bytes api to generate ascii 2025-12-10 22:26:40 -06:00
Mitchell Hashimoto cca10f3ca8
Revert GTK UI changes, apple-sdk build stuff 2025-12-10 20:20:37 -08:00
George Papadakis 625d7274bf Add close tabs on the right action 2025-12-10 20:14:27 -08:00
Mitchell Hashimoto 894e8d91ba
macOS: fix tab context menu opens on macOS 26 with titlebar tabs (#9831)
Description:
Context menu works on tabs with titlebar-style=tabs on MacOS Tahoe 26

Closes #9817 

Demo:


https://github.com/user-attachments/assets/60eaae6e-a3ff-41eb-8c86-ba700490d6e2



Note:
- Tried first a passthrough-views approach, but AppKit’s internal
toolbar subviews continued intercepting right-clicks.
- Runtime subclassing proposed by Claude also worked but was rejected as
too fragile.
- Final solution routes secondary-click events at the window level using
sendEvent(_:), forwarding them to the tab bar only when the click is
visually within its bounds.

AI Disclosure:
AI (Claude Code and Codex) assisted with early explorations, but final
implementation was developed manually after evaluating and discarding
the unsafe subclassing approach proposed by Claude.
2025-12-10 20:12:30 -08:00
Mitchell Hashimoto 76c2de6088
macos: remove the tabBarView variable we can search it 2025-12-10 20:10:54 -08:00
Lukas 969bcbe8e3 Update macos/Sources/Features/Terminal/Window Styles/TitlebarTabsTahoeTerminalWindow.swift 2025-12-10 20:03:30 -08:00
Denys Zhak c0951ce6d8 macOS: fix tab context menu opens on macOS 26 with titlebar tabs 2025-12-10 20:03:30 -08:00
Mitchell Hashimoto 4a173052fb
macos: always use overlay scroller (#9865)
With this PR, the macos scrollbar always uses the overlay style. If the
OS preferred style is `.legacy`, we flash the scroller when the mouse is
moved over it, such that users can still click and drag without relying
on scroll wheels or gestures.

Implements #9610.

There are a few lines of code that could technically be removed after
this change as they're only needed to make surfaces work correctly with
the legacy scrollbar, but I decided to leave them in since they do no
harm (see code comments). This ensures correct behavior if, for whatever
reason, some corner case brings back the legacy scrollbar, or if someone
decides to experiment with scrollbar styles in the future.
2025-12-10 13:55:49 -08:00
Daniel Wennberg 93d77ae436 Always use overlay scroller, flash when mouse moved 2025-12-10 13:33:18 -08:00
Mitchell Hashimoto 7642b8bec4
build: highway system integration should default to false 2025-12-10 13:13:38 -08:00
Mitchell Hashimoto 143748a8d3
Add system integration for highway (#9642) 2025-12-10 13:00:46 -08:00
Mitchell Hashimoto af05397219
synthetic: make bytes generation more flexible (#9204) 2025-12-10 12:59:46 -08:00
Mitchell Hashimoto 260e6dea59
macOS: fix theme reloading (#9360)
### Background
After #9344, the Ghostty theme won't change after switching systems',
and reverting #9344 will bring back the issue it fixed.

The reason these two issues are related is because the scheme change is
based on changes of `effectiveAppearance`, which is also affected by
setting the window's `appearance` or changing
`NSAppearance.currentDrawing()`.

### Changes
Instead of observing `effectiveAppearance`, we now explicitly update the
color scheme of surfaces, so that we can control when it happens to
avoid callback loops and redundant updates.

### Regression Tests

- [x] #8282
- [x] Reloading with `window-theme = light` should update Ghostty with
the default dark theme with a dark window theme (break before
[#83104ff](83104ff27a))
- [x] `window-theme = light \n macos-titlebar-style = native` should
update Ghostty with the default dark theme with a light window theme
- [x] Reloading from the default config to `theme=light:3024
Day,dark:3024 Night \n window-theme = light`, should update Ghostty with
the theme `3024 Day` with a light window theme (break on
[#d39cc6d](d39cc6d478))
- [x] Using `theme=light:3024 Day,dark:3024 Night`; Switching the
system's appearance should change Ghostty's appearance (break on
[#d39cc6d](d39cc6d478))
- [x] Reloading from `theme=light:3024 Day,dark:3024 Night` with a light
window theme to the default config, should update Ghostty with the
default dark theme with a dark window theme
- [x] Reloading from the default config to `theme=light:3024
Day,dark:3024 Night \n window-theme=dark`, should update Ghostty with
the theme `3024 Night` with a dark window theme
- [x] Reloading from `theme=light:3024 Day,dark:3024 Night \n
window-theme=dark` to `theme=light:3024 Day,dark:3024 Night` with light
system appearance, should update Ghostty from dark to light
- [x] Reload with quick terminal open
2025-12-10 12:56:20 -08:00
Mitchell Hashimoto 581ed72efc
gtk: support GTK 4.20 media queries in runtime & custom css (#9520) 2025-12-10 12:55:25 -08:00
Mitchell Hashimoto 3ca6617a18
macos: teach agents about `zig build run` (#9758) 2025-12-10 12:53:06 -08:00
Mitchell Hashimoto b66e4dc2cb
build: skip git version detection when used as dependency (#9850)
When ghostty is used as a Zig dependency, detect this by comparing the
build root with ghostty's source directory. Skip git detection entirely
and use the version from build.zig.zon.

This fixes build failures when downstream projects have git tags that
don't match ghostty's version format. Previously, ghostty would read the
downstream project's git tags and panic at Config.zig:246 with:

\`\`\`
tagged releases must be in vX.Y.Z format matching build.zig
\`\`\`

**Reproduction:**
1. Create a project that uses ghostty as a Zig dependency
2. Tag the project with a version like \`v0.2.0\`
3. Run \`zig build\` → panic

**Fix:**
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.

Thread:
https://ampcode.com/threads/T-197e6c33-b8f8-4b23-8fc8-7f6b6edd9f35
2025-12-10 12:46:10 -08:00
Tim Culverhouse 05c704b247 build: skip git version detection when used as dependency
Detect if ghostty is being built as a dependency by comparing the build
root with ghostty's source directory. When used as a dependency, skip
git detection entirely and use the version from build.zig.zon.

This fixes build failures when downstream projects have git tags that
don't match ghostty's version format. Previously, ghostty would read
the downstream project's git tags and panic at Config.zig:246 with
"tagged releases must be in vX.Y.Z format matching build.zig".
2025-12-10 12:43:14 -08:00
Mitchell Hashimoto 3b31cef965
tmux: control mode core loop (no GUI connections yet) (#9860)
Related to #1935

This adds a new structure `terminal.tmux.Viewer` which continues
building on all the prior tmux control mode work to add a full
bidirectional reconciliation loop to discover and sync terminal states
from tmux to Ghostty and vice versa. **This is the core, cross-platform
business logic that will power the GUIs, later.**

Our prior work were protocol building blocks, and this PR is an actual
functional piece of work. You can now start Ghostty, run `tmux -CC
attach`, and we _will_ be creating full blown terminals internal that
capture the content and mirror the state exactly (barring inevitable
bugs in something this complex). But, we don't yet show them visually.
:) And we don't yet send inputs to it (it's a viewer only, for now).

**This sucked.** The control mode protocol is difficult, to put it
mildly, for a variety of reasons. Correctness of this is going to be
hard. Therefore, I focused really hard on this design to make it **fully
unit test friendly.** We're able to simulate full tmux sessions and runt
through our state machine and assert various states. I think this will
be critical to correctness as we eventually collect real world data.

> [!WARNING]
>
> This does actually have user-impacting changes! When you run `tmux -CC
attach` we will now run our full control mode client. This could result
in bugs or crashes or other problems. This only activates if you have a
real tmux session, though, so it should be avoidable by most users.
Since we don't actually take our state and send it to the GUI or
anything, this should be pretty safe.

**AI disclosure:** I used AI for a lot of the protocol reverse
engineering and documentation to figure out how it all works. I designed
the architecture myself and implemented most of it manually.
2025-12-10 12:40:58 -08:00
Mitchell Hashimoto 37f467c023
terminal/tmux: docs 2025-12-10 10:37:52 -08:00
Mitchell Hashimoto b3e7c92263
fmt 2025-12-10 10:34:37 -08:00
Mitchell Hashimoto 29bb18d8cd
terminal/tmux: grab tmux version on startup 2025-12-10 10:34:30 -08:00
Mitchell Hashimoto 58000f5821
terminal/tmux: build up pane states 2025-12-10 10:12:51 -08:00
Mitchell Hashimoto d7883fbde2
build(deps): bump peter-evans/create-pull-request from 7.0.11 to 8.0.0 (#9855)
Bumps
[peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request)
from 7.0.11 to 8.0.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/peter-evans/create-pull-request/releases">peter-evans/create-pull-request's
releases</a>.</em></p>
<blockquote>
<h2>Create Pull Request v8.0.0</h2>
<h2>What's new in v8</h2>
<ul>
<li>Requires <a
href="https://github.com/actions/runner/releases/tag/v2.327.1">Actions
Runner v2.327.1</a> or later if you are using a self-hosted runner for
Node 24 support.</li>
</ul>
<h2>What's Changed</h2>
<ul>
<li>chore: Update checkout action version to v6 by <a
href="https://github.com/yonas"><code>@​yonas</code></a> in <a
href="https://redirect.github.com/peter-evans/create-pull-request/pull/4258">peter-evans/create-pull-request#4258</a></li>
<li>Update actions/checkout references to <a
href="https://github.com/v6"><code>@​v6</code></a> in docs by <a
href="https://github.com/Copilot"><code>@​Copilot</code></a> in <a
href="https://redirect.github.com/peter-evans/create-pull-request/pull/4259">peter-evans/create-pull-request#4259</a></li>
<li>feat: v8 by <a
href="https://github.com/peter-evans"><code>@​peter-evans</code></a> in
<a
href="https://redirect.github.com/peter-evans/create-pull-request/pull/4260">peter-evans/create-pull-request#4260</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/yonas"><code>@​yonas</code></a> made
their first contribution in <a
href="https://redirect.github.com/peter-evans/create-pull-request/pull/4258">peter-evans/create-pull-request#4258</a></li>
<li><a href="https://github.com/Copilot"><code>@​Copilot</code></a> made
their first contribution in <a
href="https://redirect.github.com/peter-evans/create-pull-request/pull/4259">peter-evans/create-pull-request#4259</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/peter-evans/create-pull-request/compare/v7.0.11...v8.0.0">https://github.com/peter-evans/create-pull-request/compare/v7.0.11...v8.0.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="98357b18bf"><code>98357b1</code></a>
feat: v8 (<a
href="https://redirect.github.com/peter-evans/create-pull-request/issues/4260">#4260</a>)</li>
<li><a
href="41c0e4b789"><code>41c0e4b</code></a>
Update actions/checkout references to <a
href="https://github.com/v6"><code>@​v6</code></a> in docs (<a
href="https://redirect.github.com/peter-evans/create-pull-request/issues/4259">#4259</a>)</li>
<li><a
href="994332de4c"><code>994332d</code></a>
chore: Update checkout action version to v6 (<a
href="https://redirect.github.com/peter-evans/create-pull-request/issues/4258">#4258</a>)</li>
<li>See full diff in <a
href="22a9089034...98357b18bf">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=peter-evans/create-pull-request&package-manager=github_actions&previous-version=7.0.11&new-version=8.0.0)](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-12-10 09:23:40 -08:00
Jacob Sandlund 572c06f67d font/coretext: Use positions to fix x/y offsets 2025-12-10 09:47:42 -05:00
Mitchell Hashimoto bf46c4ebe7
terminal/tmux: many more output formats 2025-12-09 21:10:46 -08:00
Mitchell Hashimoto 4c30c5aa76
terminal/tmux: cleanup command queue logic 2025-12-09 20:31:51 -08:00
Mitchell Hashimoto 582ea5d84b
terminal/tmux: window add 2025-12-09 20:07:08 -08:00
Mitchell Hashimoto 1a2b3c165a
terminal/tmux: layoutChanged handling 2025-12-09 17:09:57 -08:00
dependabot[bot] 5df95ba210
build(deps): bump peter-evans/create-pull-request from 7.0.11 to 8.0.0
Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 7.0.11 to 8.0.0.
- [Release notes](https://github.com/peter-evans/create-pull-request/releases)
- [Commits](22a9089034...98357b18bf)

---
updated-dependencies:
- dependency-name: peter-evans/create-pull-request
  dependency-version: 8.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-10 00:07:05 +00:00
Mitchell Hashimoto 071070faa3
terminal/tmux: handle session_changed inside command loop 2025-12-09 14:21:07 -08:00
Mitchell Hashimoto 64ef640127
terminal/tmux: exhaustive switch for command 2025-12-09 13:56:16 -08:00
Mitchell Hashimoto 938e419e04
terminal/tmux: handle output events 2025-12-09 13:13:52 -08:00
Mitchell Hashimoto 50ac848672
terminal/tmux: capture both primary/alt screen 2025-12-09 13:00:40 -08:00
Mitchell Hashimoto a3e01581be
terminal/tmux: history capture clears active area 2025-12-09 11:33:06 -08:00
Mitchell Hashimoto b7fe9a926d
terminal/tmux: capture visible area after history 2025-12-09 11:22:14 -08:00
Mitchell Hashimoto 41bf541005
terminal/tmux: test helper 2025-12-09 10:53:52 -08:00
Mitchell Hashimoto e1e2791fb7
terminal/tmux: pane_history replays it into terminal 2025-12-09 10:00:43 -08:00
Mitchell Hashimoto f02a2d5eed
terminal/tmux: capture pane 2025-12-09 09:25:55 -08:00
Leah Amelia Chen cf06417b7d
gtk: fix xkb mapping not working in Linux (#9454) 2025-12-09 12:58:44 +08:00
Mitchell Hashimoto 766c306e04
terminal/tmux: pane history 2025-12-08 20:15:20 -08:00
Mitchell Hashimoto ea09d257a1
terminal/tmux: initialize panes 2025-12-08 11:54:48 -08:00
Mitchell Hashimoto 86cd489701
terminal/tmux: introduce command queue for viewer 2025-12-08 09:00:38 -08:00
Mitchell Hashimoto ec5a60a119
terminal/tmux: make sure we always have space for one action 2025-12-08 07:27:37 -08:00
Mitchell Hashimoto b26c42f4a6
terminal/tmux: better formatting for notifications and actions 2025-12-08 07:00:44 -08:00
Mitchell Hashimoto 52dbca3d26
termio: hook up tmux viewer 2025-12-08 07:00:43 -08:00
Mitchell Hashimoto 3cbc232e31
terminal/tmux: return allocated list of actions 2025-12-08 07:00:43 -08:00
Mitchell Hashimoto c1d686534e
terminal/tmux: list windows 2025-12-08 07:00:43 -08:00
Mitchell Hashimoto 4c3ef8fa13
terminal/tmux: viewer list windows state 2025-12-08 07:00:43 -08:00
Mitchell Hashimoto 0d75a78747
terminal/tmux: start viewer state machine 2025-12-08 07:00:43 -08:00
Mitchell Hashimoto af3a11b546
terminal/tmux: output has format/comptimeFormat 2025-12-08 07:00:43 -08:00
Mitchell Hashimoto 049b8826f6
macos: make QuickTerminalSize config C ABI compatible (#9837)
Hello! I did read `CONTRIBUTING.md`. I understand that the preference is
to receive pull requests for existing open issues and acknowledge that
I'm skipping a step wrt the preferred workflow since there aren't any
open issues yet for #8419. Living dangerously and hoping for the best
here. I hope you'll see that I'm acting in good faith 🤞.

In my attempts to debug why `quick-terminal-size` config wasn't working
reliably for me, I discovered that the
[`ghostty_config_quick_terminal_size_s`](08c9661683/include/ghostty.h (L460-L480))
struct used to initialize `QuickTerminalSize` in Swift-land, more often
than not, didn't match what I had in my config file (e.g.
`quick-terminal-size = 75%, 50%`)

<details>


08c9661683/include/ghostty.h (L460-L480)


08c9661683/macos/Sources/Ghostty/Ghostty.Config.swift (L507-L510)

</details>

Almost all mismatches seemed to be downstream of `tag` (for `primary`
and/or `secondary` `Size`) being an unexpected value for the
`ghostty_quick_terminal_size_tag_e` enum type, which led runtime
execution to fall into the `default` branch in this `switch` control
flow.


08c9661683/macos/Sources/Features/QuickTerminal/QuickTerminalSize.swift (L27-L38)

Looking at `src/config/CApi.zig`, `src/config/c_get.zig`,
`src/config/Config.zig`, and [Zig documentation for `extern
enum`](https://ziglang.org/documentation/master/#extern-enum), led me to
conclude that the crux of the issue is lack of guaranteed C ABI
compatibility for `Tag`


08c9661683/src/config/Config.zig (L7986-L7990)


08c9661683/include/ghostty.h (L461-L465)

Further research revealed that based on C language spec alone, one
cannot assume a fixed width for `enum` and that the behaviour is
compiler dependant. But given how the Zig documentation suggests using
`enum(c_int)` for C-ABI-compatible enums and extern enums + comments
elsewhere in `Config.zig` suggesting that `enum(c_int)` was chosen for
extern compatibility,


08c9661683/src/config/Config.zig (L4877)

I think that this fix (changing `enum(u8)` to `enum(c_int)`) is likely
the most straightforward and appropriate one.
2025-12-08 07:00:16 -08:00
Mitchell Hashimoto cad96134fc
build(deps): bump peter-evans/create-pull-request from 7.0.9 to 7.0.11 (#9839)
Bumps
[peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request)
from 7.0.9 to 7.0.11.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/peter-evans/create-pull-request/releases">peter-evans/create-pull-request's
releases</a>.</em></p>
<blockquote>
<h2>Create Pull Request v7.0.11</h2>
<h2>What's Changed</h2>
<ul>
<li>fix: restrict remote prune to self-hosted runners by <a
href="https://github.com/peter-evans"><code>@​peter-evans</code></a> in
<a
href="https://redirect.github.com/peter-evans/create-pull-request/pull/4250">peter-evans/create-pull-request#4250</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/peter-evans/create-pull-request/compare/v7.0.10...v7.0.11">https://github.com/peter-evans/create-pull-request/compare/v7.0.10...v7.0.11</a></p>
<h2>Create Pull Request v7.0.10</h2>
<p>⚙️ Fixes an issue where updating a pull request failed when targeting
a forked repository with the same owner as its parent.</p>
<h2>What's Changed</h2>
<ul>
<li>build(deps): bump the github-actions group with 2 updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/peter-evans/create-pull-request/pull/4235">peter-evans/create-pull-request#4235</a></li>
<li>build(deps-dev): bump prettier from 3.6.2 to 3.7.3 in the npm group
by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/peter-evans/create-pull-request/pull/4240">peter-evans/create-pull-request#4240</a></li>
<li>fix: provider list pulls fallback for multi fork same owner by <a
href="https://github.com/peter-evans"><code>@​peter-evans</code></a> in
<a
href="https://redirect.github.com/peter-evans/create-pull-request/pull/4245">peter-evans/create-pull-request#4245</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/obnyis"><code>@​obnyis</code></a> made
their first contribution in <a
href="https://redirect.github.com/peter-evans/create-pull-request/pull/4064">peter-evans/create-pull-request#4064</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/peter-evans/create-pull-request/compare/v7.0.9...v7.0.10">https://github.com/peter-evans/create-pull-request/compare/v7.0.9...v7.0.10</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="22a9089034"><code>22a9089</code></a>
fix: restrict remote prune to self-hosted runners (<a
href="https://redirect.github.com/peter-evans/create-pull-request/issues/4250">#4250</a>)</li>
<li><a
href="d4f3be6ce6"><code>d4f3be6</code></a>
fix: provider list pulls fallback for multi fork same owner (<a
href="https://redirect.github.com/peter-evans/create-pull-request/issues/4245">#4245</a>)</li>
<li><a
href="bc8a47f565"><code>bc8a47f</code></a>
build(deps-dev): bump prettier from 3.6.2 to 3.7.3 in the npm group (<a
href="https://redirect.github.com/peter-evans/create-pull-request/issues/4240">#4240</a>)</li>
<li><a
href="a67ef28ca5"><code>a67ef28</code></a>
build(deps): bump the github-actions group with 2 updates (<a
href="https://redirect.github.com/peter-evans/create-pull-request/issues/4235">#4235</a>)</li>
<li>See full diff in <a
href="84ae59a2cd...22a9089034">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=peter-evans/create-pull-request&package-manager=github_actions&previous-version=7.0.9&new-version=7.0.11)](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-12-08 06:55:48 -08:00
Mitchell Hashimoto bb49537a05
CONTRIBUTING: various improvements and clarifications (#9835)
Despite the existence of #6937 it seems that there are still quite a few
people who aren't sure of the norms surrounding how to use Ghostty's
discussion spaces, so I chose to spell it all out here.

Regarding AI policy I also added a section heavily discouraging AI
responses within PRs and contributing to platforms one can't test on. I
don't understand what is wrong with vibecoders on macOS who just think
that the GTK side will somehow Just Work, despite us being pretty much
the only major piece of software using zig-gobject that I know of.
2025-12-08 06:53:42 -08:00
Mitchell Hashimoto 6c33bf1f5e
Update iTerm2 colorschemes (#9832)
Upstream release:
https://github.com/mbadolato/iTerm2-Color-Schemes/releases/tag/release-20251201-150531-bfb3ee1
2025-12-08 06:52:49 -08:00
Mitchell Hashimoto 9cd96e4b64
quirks: remove type signature for inlineAssert (#9843)
Functions with different calling conventions are not compatible with
each other

Fixes all release builds + CI
2025-12-07 21:57:48 -08:00
Leah Amelia Chen 2ac9e03c52
quirks: remove type signature for inlineAssert
Functions with different calling conventions are not compatible with
each other

Fixes all release builds + CI
2025-12-08 13:19:16 +08:00
Mitchell Hashimoto 0bbd7c8f9a
os: fix off-by-one error in ShellEscapeWriter (#9842)
I am truly not sure why the tests never caught this, but I just fell for
the oldest trick in the book

Fixes a crash on GTK when a file is dragged then dropped into the
terminal - should not impact 1.2 as this is a casualty of the Zig 0.15
port
2025-12-07 21:17:12 -08:00
Leah Amelia Chen 6da2f0e3e7
os/shell: actually run tests 2025-12-08 13:04:20 +08:00
Leah Amelia Chen ed1d77d518
os: fix off-by-one error in ShellEscapeWriter
I am truly not sure why the tests never caught this, but I just fell for
the oldest trick in the book
2025-12-08 12:42:35 +08:00
dependabot[bot] 5131998eda
build(deps): bump peter-evans/create-pull-request from 7.0.9 to 7.0.11
Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 7.0.9 to 7.0.11.
- [Release notes](https://github.com/peter-evans/create-pull-request/releases)
- [Commits](84ae59a2cd...22a9089034)

---
updated-dependencies:
- dependency-name: peter-evans/create-pull-request
  dependency-version: 7.0.11
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-08 00:06:17 +00:00
Mitchell Hashimoto ddca4a8412
make our quirks assert use `std.debug.assert` in debug builds (#9838)
This fixes an issue I have on both macOS and Linux (ARM and x86_64)
where stack traces are broken for inlined functions. They don't point to
the proper location in the source code, making debugging difficult.

Release builds use the same previous function.

cc @qwerasd205
2025-12-07 14:17:30 -08:00
Mitchell Hashimoto 9d4f96381a
make our quirks assert use `std.debug.assert` in debug builds
This fixes an issue I have on both macOS and Linux (ARM and x86_64)
where stack traces are broken for inlined functions. They don't point to
the proper location in the source code, making debugging difficult.

Release builds use the same previous function.
2025-12-07 14:15:06 -08:00
Lars 0c9082eb72
macOS: fix theme reloading
### Background
After #9344, the Ghostty theme won't change after switching systems', and reverting #9344 will bring back the issue it fixed.

The reason these two issues are related is because the scheme change is based on changes of `effectiveAppearance`, which is also affected by setting the window's `appearance` or changing `NSAppearance.currentDrawing()`.

### Changes
Instead of observing `effectiveAppearance`, we now explicitly update the color scheme of surfaces, so that we can control when it happens to avoid callback loops and redundant updates.

### Regression Tests

- [x] #8282
- [x] Reloading with `window-theme = light` should update Ghostty with the default dark theme with a dark window theme (break before [#83104ff](83104ff27a))
- [x] `window-theme = light \n macos-titlebar-style = native` should update Ghostty with the default dark theme with a light window theme
- [x] Reloading from the default config to `theme=light:3024 Day,dark:3024 Night \n window-theme = light`, should update Ghostty with the theme `3024 Day` with a light window theme (break on [#d39cc6d](d39cc6d478))
- [x] Using `theme=light:3024 Day,dark:3024 Night`; Switching the system's appearance should change Ghostty's appearance (break on [#d39cc6d](d39cc6d478))
- [x] Reloading from `theme=light:3024 Day,dark:3024 Night` with a light window theme to the default config, should update Ghostty with the default dark theme with a dark window theme
- [x] Reloading from the default config to `theme=light:3024 Day,dark:3024 Night \n window-theme=dark`, should update Ghostty with the theme `3024 Night` with a dark window theme
- [x] Reloading from `theme=light:3024 Day,dark:3024 Night \n window-theme=dark` to `theme=light:3024 Day,dark:3024 Night` with light system appearance, should update Ghostty from dark to light
- [x] Reload with quick terminal open

# Conflicts:
#	macos/Sources/Features/Terminal/BaseTerminalController.swift
2025-12-07 09:18:45 +01:00
Leah Amelia Chen c9655eefe5
CONTRIBUTING: clarify discussion categories & discord channels 2025-12-07 13:08:42 +08:00
Leah Amelia Chen 90ab794457
CONTRIBUTING: tighten AI assistance disclosure requirements 2025-12-07 13:00:06 +08:00
voideanvalue aa504b2784 add assertionFailure for unexpected QuickTerminalSize tag 2025-12-07 00:51:37 +00:00
mitchellh 6e081b2c81 deps: Update iTerm2 color schemes 2025-12-07 00:15:51 +00:00
voideanvalue aa0afa2d02 fix C ABI compat for ghostty_quick_terminal_size_tag_e 2025-12-06 22:17:33 +00:00
Mitchell Hashimoto 08c9661683
ci: cancel prior test runs for the same git ref (#9819)
This should save on CI quite a bit. This will cancel our GHA runs when
you push to the same ref, except for `main`, where I want to make sure
every commit is tested.
2025-12-05 08:44:10 -08:00
Mitchell Hashimoto d09621fa11
ci: cancel prior test runs for the same git ref
This should save on CI quite a bit. This will cancel our GHA runs when
you push to the same ref, except for `main`, where I want to make sure
every commit is tested.
2025-12-05 08:43:26 -08:00
Mitchell Hashimoto e5def6f210
core: selection and copy bindings need to hold the big lock (#9818)
This was found by LLM hunting! We were not holding the lock properly
during these operations. There aren't any known cases where we can
directly attribute these races to issues but we did find at least one
consistent crash for a user when `linkAtPos` wasn't properly locked (in
another PR).

This continues those fixes.

https://ampcode.com/threads/T-6fc49f25-7f2f-4039-adb4-f86aaeced6d5
2025-12-05 08:36:47 -08:00
Mitchell Hashimoto f98b12579e
core: selection and copy bindings need to hold the big lock
This was found by LLM hunting! We were not holding the lock properly
during these operations. There aren't any known cases where we can
directly attribute these races to issues but we did find at least one
consistent crash for a user when `linkAtPos` wasn't properly locked (in
another PR).

This continues those fixes.
2025-12-05 08:33:11 -08:00
Mitchell Hashimoto 1207240cf1
core: hold lock during keyCallback when mouseRefreshLinks is called (#9813)
From #9812

I'm not sure if this is the root cause of the crash in #9812 but the
LLM-discovered issue that we are not holding a lock here appears to be a
real issue. I manually traced the code paths and thought about this and
looked where we call `mouseRefreshLinks` in other places and this
appears to be a real bug.
2025-12-04 19:49:35 -08:00
Mitchell Hashimoto 6b2097e872
core: hold lock during keyCallback when mouseRefreshLinks is called
From #9812

I'm not sure if this is the root cause of the crash in #9812 but the
LLM-discovered issue that we are not holding a lock here appears to be a
real issue. I manually traced the code paths and thought about this and
looked where we call `mouseRefreshLinks` in other places and this
appears to be a real bug.
2025-12-04 19:45:03 -08:00
Mitchell Hashimoto 3f241502c2
terminal/tmux: a lot more control mode parsing, functionality (#9803)
Continuing just build foundation for #1935. There are no user-facing
changes here.

- This adds more command parsing for control mode output. I _believe_ we
now parse enough to at least render everything initially for most tmux
sessions. At least, from the VT parsing side (we haven't done any GUI
work whatsoever to react to this).

- This also adds a new layout string parser, e.g.
`159x48,0,0{79x48,0,0,79x48,80,0}` into a useful struct. We'll need this
to convert our visible layouts into actual GUI components, eventually.

- This adds a new output format parser for commands such as
`list-windows`. Control mode sends output framed in `%begin/%end`
blocks, but the output is in an arbitrary format depending on the input
command and unrelated to control mode itself. The output format parser
will let us parse this output.

I think this is a good place to stop and PR. I think next up I might try
hooking up a state machine to `src/termio/stream_handler.zig` to start
actually working with this. Before that, it may behoove me to change
`stream_readonly` to support non-readonly operations via callback so I
can do DCS and maybe unit test this whole thing too.... we'll see where
the wind blows.

**AI disclosure:** AI wrote many tests and did a lot of implementation
here. I reviewed everything manually though and understand it all
completely.
2025-12-04 15:30:13 -08:00
Mitchell Hashimoto cf23d1c39d
core: rate limit BEL character processing (#9810)
If the BEL character is received too frequently, the GUI thread can be
starved and Ghostty will lock up and eventually crash. This PR limits
BEL handling to 1 per 100ms.

Fixes #9800.
2025-12-04 15:29:58 -08:00
Jeffrey C. Ollie 68426dc21a
core: rate limit BEL character processing
If the BEL character is received too frequently, the GUI thread can be
starved and Ghostty will lock up and eventually crash. This PR limits
BEL handling to 1 per 100ms.

Fixes #9800.
2025-12-04 12:32:58 -06:00
Cédric Bulteel 0a03434656 gtk: fix xkb mapping not working on linux
Signed-off-by: Cedric BULTEEL <cedric@oceanspy.com>
2025-12-04 19:19:13 +01:00
Mitchell Hashimoto 6b21b9147c
terminal/tmux: add output format parsing (minimal) 2025-12-03 20:23:28 -08:00
Mitchell Hashimoto b95965cb5a
terminal/tmux: add layout-change to control mode parsing 2025-12-03 13:27:37 -08:00
Mitchell Hashimoto 92ea8d0eb5
terminal/tmux: layout checksums 2025-12-03 13:27:37 -08:00
Mitchell Hashimoto dfa22379b2
terminal/tmux: layout string parser 2025-12-03 13:27:37 -08:00
Mitchell Hashimoto 7a9dc77a94
terminal/tmux: clean up error handling, explicit error sets 2025-12-03 13:27:36 -08:00
Mitchell Hashimoto 6e016ea81e
terminal: move tmux into folder 2025-12-03 13:27:36 -08:00
Mitchell Hashimoto 5bc78d59fb
terminal/tmux: add more control mode parsing keys 2025-12-03 13:27:36 -08:00
Mitchell Hashimoto 6502922bb6
build(deps): bump actions/checkout from 6.0.0 to 6.0.1 (#9791)
Bumps [actions/checkout](https://github.com/actions/checkout) from 6.0.0
to 6.0.1.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/checkout/releases">actions/checkout's
releases</a>.</em></p>
<blockquote>
<h2>v6.0.1</h2>
<h2>What's Changed</h2>
<ul>
<li>Update all references from v5 and v4 to v6 by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2314">actions/checkout#2314</a></li>
<li>Add worktree support for persist-credentials includeIf by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2327">actions/checkout#2327</a></li>
<li>Clarify v6 README by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2328">actions/checkout#2328</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/checkout/compare/v6...v6.0.1">https://github.com/actions/checkout/compare/v6...v6.0.1</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="8e8c483db8"><code>8e8c483</code></a>
Clarify v6 README (<a
href="https://redirect.github.com/actions/checkout/issues/2328">#2328</a>)</li>
<li><a
href="033fa0dc0b"><code>033fa0d</code></a>
Add worktree support for persist-credentials includeIf (<a
href="https://redirect.github.com/actions/checkout/issues/2327">#2327</a>)</li>
<li><a
href="c2d88d3ecc"><code>c2d88d3</code></a>
Update all references from v5 and v4 to v6 (<a
href="https://redirect.github.com/actions/checkout/issues/2314">#2314</a>)</li>
<li>See full diff in <a
href="1af3b93b68...8e8c483db8">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=6.0.0&new-version=6.0.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-12-03 13:18:57 -08:00
dependabot[bot] d926bd5376
build(deps): bump actions/checkout from 6.0.0 to 6.0.1
Bumps [actions/checkout](https://github.com/actions/checkout) from 6.0.0 to 6.0.1.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](1af3b93b68...8e8c483db8)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 6.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-03 00:07:23 +00:00
Mitchell Hashimoto b4a48303ed
build: fix path access to work with relative build roots (#9780)
## Problem

When ghostty is used as a dependency (e.g., in another Zig project), the
build can panic on Linux with:

\`\`\`
GhosttyDist.zig:173:34: 0x1768046 in exists (build.zig)
    if (std.fs.accessAbsolute(b.pathFromRoot(self.dist), .{})) {
\`\`\`

This happens because \`b.pathFromRoot()\` can return a relative path
(e.g., when the build root is \`.\`), but \`std.fs.accessAbsolute()\`
asserts the path must be absolute.

## Solution

Replace \`std.fs.accessAbsolute(b.pathFromRoot(...))\` with
\`b.build_root.handle.access(...)\`, which uses the build root's
directory handle directly and works correctly with relative paths.

Context:
https://ampcode.com/threads/T-7511e7e4-4b4a-4f11-9c3c-817aaa519b84
2025-12-02 11:13:52 -08:00
Mitchell Hashimoto 8d25ab0ae3
zsh: improve ZDOTDIR documentation (#9779)
The main thing to emphasize is that end users should never source
.zshenv directly; it's only meant to be used as part of our shell
injection environment.

At the moment, there's no way to guard against accidentally use, but we
can consider making e.g. GHOSTTY_SHELL_FEATURES always defined in this
environment to that it can be used to differentiate the cases.

In practice, it's unlikely that people actually source this .zshenv
script directly, so hopefully this additional documentation clarifies
things well enough.
2025-12-02 11:13:10 -08:00
Mitchell Hashimoto edfae7e41e
zsh: move version check to ghostty-integration (#9781)
The ghostty-integration script can be manually sourced, and it uses the
Zsh 5.1+ features, so that's a better place to guard against older Zsh
versions.

This also keeps the .zshenv script focused on just bootstrapping our
automatic shell integration.

I also changed the version check to a slightly more idiomatic pattern.
2025-12-02 11:12:49 -08:00
Mitchell Hashimoto ac5f8c3a1e
build(deps): bump softprops/action-gh-release from 2.4.2 to 2.5.0 (#9782)
Bumps
[softprops/action-gh-release](https://github.com/softprops/action-gh-release)
from 2.4.2 to 2.5.0.
<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.5.0</h2>
<!-- raw HTML omitted -->
<h2>What's Changed</h2>
<h3>Exciting New Features 🎉</h3>
<ul>
<li>feat: mark release as draft until all artifacts are uploaded by <a
href="https://github.com/dumbmoron"><code>@​dumbmoron</code></a> in <a
href="https://redirect.github.com/softprops/action-gh-release/pull/692">softprops/action-gh-release#692</a></li>
</ul>
<h3>Other Changes 🔄</h3>
<ul>
<li>chore(deps): bump the npm group across 1 directory with 5 updates by
<a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/softprops/action-gh-release/pull/697">softprops/action-gh-release#697</a></li>
<li>chore(deps): bump actions/checkout from 5.0.0 to 5.0.1 in the
github-actions group by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/softprops/action-gh-release/pull/689">softprops/action-gh-release#689</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/dumbmoron"><code>@​dumbmoron</code></a>
made their first contribution in <a
href="https://redirect.github.com/softprops/action-gh-release/pull/692">softprops/action-gh-release#692</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/softprops/action-gh-release/compare/v2.4.2...v2.5.0">https://github.com/softprops/action-gh-release/compare/v2.4.2...v2.5.0</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.5.0</h2>
<h2>What's Changed</h2>
<h3>Exciting New Features 🎉</h3>
<ul>
<li>feat: mark release as draft until all artifacts are uploaded by <a
href="https://github.com/dumbmoron"><code>@​dumbmoron</code></a> in <a
href="https://redirect.github.com/softprops/action-gh-release/pull/692">softprops/action-gh-release#692</a></li>
</ul>
<h3>Other Changes 🔄</h3>
<ul>
<li>dependency updates</li>
</ul>
<h2>2.4.2</h2>
<h2>What's Changed</h2>
<h3>Exciting New Features 🎉</h3>
<ul>
<li>feat: Ensure generated release notes cannot be over 125000
characters by <a
href="https://github.com/BeryJu"><code>@​BeryJu</code></a> in <a
href="https://redirect.github.com/softprops/action-gh-release/pull/684">softprops/action-gh-release#684</a></li>
</ul>
<h3>Other Changes 🔄</h3>
<ul>
<li>dependency updates</li>
</ul>
<h2>2.4.1</h2>
<h2>What's Changed</h2>
<h3>Other Changes 🔄</h3>
<ul>
<li>fix(util): support brace expansion globs containing commas in
parseInputFiles by <a
href="https://github.com/Copilot"><code>@​Copilot</code></a> in <a
href="https://redirect.github.com/softprops/action-gh-release/pull/672">softprops/action-gh-release#672</a></li>
<li>fix: gracefully fallback to body when body_path cannot be read by <a
href="https://github.com/Copilot"><code>@​Copilot</code></a> in <a
href="https://redirect.github.com/softprops/action-gh-release/pull/671">softprops/action-gh-release#671</a></li>
</ul>
<h2>2.4.0</h2>
<h2>What's Changed</h2>
<h3>Exciting New Features 🎉</h3>
<ul>
<li>feat(action): respect working_directory for files globs by <a
href="https://github.com/stephenway"><code>@​stephenway</code></a> in <a
href="https://redirect.github.com/softprops/action-gh-release/pull/667">softprops/action-gh-release#667</a></li>
</ul>
<h2>2.3.4</h2>
<h2>What's Changed</h2>
<h3>Bug fixes 🐛</h3>
<ul>
<li>fix(action): handle 422 already_exists race condition by <a
href="https://github.com/stephenway"><code>@​stephenway</code></a> in <a
href="https://redirect.github.com/softprops/action-gh-release/pull/665">softprops/action-gh-release#665</a></li>
</ul>
<h3>Other Changes 🔄</h3>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="a06a81a03e"><code>a06a81a</code></a>
release 2.5.0</li>
<li><a
href="7da8983734"><code>7da8983</code></a>
feat: mark release as draft until all artifacts are uploaded (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/692">#692</a>)</li>
<li><a
href="87973286a4"><code>8797328</code></a>
chore(deps): bump actions/checkout in the github-actions group (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/689">#689</a>)</li>
<li><a
href="1bfc62a71b"><code>1bfc62a</code></a>
chore(deps): bump the npm group across 1 directory with 5 updates (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/697">#697</a>)</li>
<li>See full diff in <a
href="5be0e66d93...a06a81a03e">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.4.2&new-version=2.5.0)](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-12-02 11:12:21 -08:00
dependabot[bot] 56d4e6d955
build(deps): bump softprops/action-gh-release from 2.4.2 to 2.5.0
Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 2.4.2 to 2.5.0.
- [Release notes](https://github.com/softprops/action-gh-release/releases)
- [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md)
- [Commits](5be0e66d93...a06a81a03e)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-02 03:08:36 +00:00
Jon Parise 6babcc97f5 zsh: move version check to ghostty-integration
The ghostty-integration script can be manually sourced, and it uses the
Zsh 5.1+ features, so that's a better place to guard against older Zsh
versions.

This also keeps the .zshenv script focused on just bootstrapping our
automatic shell integration.

I also changed the version check to a slightly more idiomatic pattern.
2025-12-01 20:34:55 -05:00
Tim Culverhouse 7fe3f5cd3f
build: fix path access to work with relative build roots
Replace std.fs.accessAbsolute(b.pathFromRoot(...)) with
b.build_root.handle.access(...) since pathFromRoot can return
relative paths, but accessAbsolute asserts the path is absolute.
2025-12-01 18:29:54 -06:00
Jon Parise da014d98cd zsh: improve ZDOTDIR documentation
The main thing to emphasize is that end users should never source
.zshenv directly; it's only meant to be used as part of our shell
injection environment.

At the moment, there's no way to guard against accidentally use, but we
can consider making e.g. GHOSTTY_SHELL_FEATURES always defined in this
environment to that it can be used to differentiate the cases.

In practice, it's unlikely that people actually source this .zshenv
script directly, so hopefully this additional documentation clarifies
things well enough.
2025-12-01 19:07:50 -05:00
Jon Parise 5714ed07a1
zsh: improve minimum version check (#9772)
- Handle autoload failures
- Prefer ">&2" to "/dev/stderr" for portability
- Quote commands for consistency and to avoid alias conflicts
2025-12-01 11:15:02 -05:00
Mitchell Hashimoto 09f7e38b45
GTK: followup update search state on activation (#9766)
followup from comment in this PR
https://github.com/ghostty-org/ghostty/pull/9765
2025-12-01 07:25:45 -08:00
Jon Parise b776b3df61 zsh: improve minimum version check
- Handle autoload failures
- Prefer ">&2" to "/dev/stderr" for portability
- Quote commands for consistency and to avoid alias conflicts
2025-12-01 10:19:00 -05:00
rhodes-b 27c82f739e only update search when going from inactive to active 2025-11-30 21:22:07 -06:00
rhodes-b 3ab49fdb5f only notify search change when widget was inactive 2025-11-30 21:06:25 -06:00
Mitchell Hashimoto 2a9a57daff
GTK: update search state from previous search on activation (#9765)
I think it makes sense that if there was already text from the previous
search that it should match based on that, this doesnt remove that it
highlights everything so you can press backspace to delete and start
from a empty search
2025-11-30 12:38:34 -08:00
Mitchell Hashimoto 750bb1fe33
core: encode mouse buttons 8 & 9 (back/forward) (#9761)
For some reason button 8 & 9 support is missing.
2025-11-30 12:37:33 -08:00
rhodes-b 7820608b04 if search has text already update the search state with matches 2025-11-30 14:32:13 -06:00
CJ van den Berg 7be28e7215
core: encode mouse buttons 8 & 9 (back/forward) 2025-11-30 17:53:21 +01:00
Mitchell Hashimoto 34fd1dd0f6
GTK: Search UI (#9756)
Fixes #189 

This adds the UI for search to GTK. There is still polish to be done in
follow-ups but this makes search work well with GTK to start!

**AI disclosure:** Believe it or not, almost this entire PR was
AI-written. Amp did an excellent job looking at our existing codebase,
comparing it to the macOS codebase, writing blueprint files, etc. I
reviewed everything written, modified some basics, and verified it
manually and under Valgrind.

## Demo

<img width="1654" height="1234" alt="CleanShot 2025-11-29 at 20 52
11@2x"
src="https://github.com/user-attachments/assets/0eb38367-398f-4165-9838-7a35465857bc"
/>

## Future Improvements

- When dragging the overlay, we should change the cursor and show drop
targets
- There's probably some small stylistic tweaks we can make to this
- I'm not sure the CSS is right for both light and dark modes so we may
need to tweak that
2025-11-30 07:24:36 -08:00
Mitchell Hashimoto c67bcf969c
apprt/gtk: switch to has-x and optional internals for search counts 2025-11-30 07:23:10 -08:00
Mitchell Hashimoto b8393fd4aa
apprt/gtk: comments 2025-11-30 07:23:10 -08:00
Mitchell Hashimoto e18a7d9501
apprt/gtk: drag 2025-11-30 07:23:10 -08:00
Mitchell Hashimoto f7a6822e30
apprt/gtk: enter/shift+enter for traversing search results 2025-11-30 07:23:10 -08:00
Mitchell Hashimoto 72b3c14833
clean up some stuff 2025-11-30 07:23:10 -08:00
Mitchell Hashimoto 56a76cc174
apprt/gtk: fix selected search label off by one 2025-11-30 07:23:10 -08:00
Mitchell Hashimoto eebce6a78c
apprt/gtk: hook up close search button 2025-11-30 07:23:10 -08:00
Mitchell Hashimoto 76496d40fd
apprt/gtk: hook up next/prev match 2025-11-30 07:23:10 -08:00
Mitchell Hashimoto 0ea85fc483
apprt/gtk: hook up search_total/search_selected apprt actions 2025-11-30 07:23:10 -08:00
Mitchell Hashimoto fc9b578ef4
apprt/gtk: hook up search-changed to start a search 2025-11-30 07:23:10 -08:00
Mitchell Hashimoto 0d32e7d814
apprt/gtk: escape to stop search and hide overlay 2025-11-30 07:23:09 -08:00
Mitchell Hashimoto 778b49c9a1
apprt/gtk: hook up start_search/end_search to set active state 2025-11-30 07:23:09 -08:00
Mitchell Hashimoto 027e5d631a
config: default search keybindings for Linux 2025-11-30 07:23:09 -08:00
Mitchell Hashimoto 548d1f0300
apprt/gtk: search overlay UI 2025-11-30 07:23:09 -08:00
Mitchell Hashimoto 832883b600
apprt/gtk: move surface event controllers, block events from revealers 2025-11-30 07:23:09 -08:00
Mitchell Hashimoto 4fef41bc83
terminal: renderstate needs to reset highlights on dirty (#9759)
This fixes memory corruption where future matches on a fully dirty row
would write highlights out of bounds. It was easy to reproduce in debug
by searching for `$` in `ghostty +boo`
2025-11-30 07:22:54 -08:00
Tim Culverhouse a58e33c06b PageList: preserve size.cols in adjustCapacity after column shrink
When columns shrink during resize-without-reflow, page.size.cols is
updated but page.capacity.cols retains the old larger value. When
adjustCapacity later runs (e.g., to expand style/grapheme storage),
it was creating a new page using page.capacity which has the stale
column count, causing size.cols to revert to the old value.

This caused a crash in render.zig where an assertion checks that
page.size.cols matches PageList.cols.

Fix by explicitly copying page.size.cols to the new page after
creation, matching how size.rows is already handled.

Amp-Thread-ID: https://ampcode.com/threads/T-976bc49a-7bfd-40bd-bbbb-38f66fc925ff
Co-authored-by: Amp <amp@ampcode.com>
2025-11-30 07:20:54 -08:00
Mitchell Hashimoto d7087627d7
terminal: renderstate needs to reset highlights on dirty
This fixes memory corruption where future matches on a fully dirty row
would write highlights out of bounds. It was easy to reproduce in debug
by searching for `$` in `ghostty +boo`
2025-11-30 07:18:42 -08:00
Jon Parise 51bda77e3a macos: teach agents about `zig build run` 2025-11-30 10:10:50 -05:00
Mitchell Hashimoto 73be3abf00
Update iTerm2 colorschemes (#9755)
Upstream release:
https://github.com/mbadolato/iTerm2-Color-Schemes/releases/tag/release-20251124-150533-2b326a8
2025-11-29 20:56:10 -08:00
mitchellh 643c5e00a0 deps: Update iTerm2 color schemes 2025-11-30 00:16:02 +00:00
Mitchell Hashimoto 3754a94cb5
Allow list-theme action with --plain to sort with --color argument (#9748)
not an accepted issue
https://github.com/ghostty-org/ghostty/discussions/9745 but it seemed
simple enough to add, pretty much copies how the previewer sorts based
on color

This allows --color argument to work when using --plain to sort the list
returned
2025-11-29 14:02:57 -08:00
Mitchell Hashimoto 7f950cc892
search: handle soft-wrapped lines in sliding window properly (#9753)
Fixes #9752
2025-11-29 10:56:11 -08:00
Mitchell Hashimoto 10f19ebdc3
search: handle soft-wrapped lines in sliding window properly
Fixes #9752
2025-11-29 07:32:06 -08:00
Mitchell Hashimoto 2fd48b433d
macos: `window-width/height` is accurate even with other widgets (#9747)
Fixes #2660

Rather than calculate our window frame size based on various chrome
calculations, we now utilize SwiftUI layouts and view intrinsic content
sizes with `setContentSize` to setup our content size ignoring all our
other widgets.

I'm sure there's some edge cases I'm missing here but this should be a
whole lot more reliable on the whole.
2025-11-29 06:56:18 -08:00
rhodes-b 351dd2ea51 allow list themes --plain to accept --color flag 2025-11-28 19:26:11 -06:00
Mitchell Hashimoto c75bade896
macos: `window-width/height` is accurate even with other widgets
Fixes #2660

Rather than calculate our window frame size based on various chrome
calculations, we now utilize SwiftUI layouts and view intrinsic content
sizes with `setContentSize` to setup our content size ignoring all our
other widgets.

I'm sure there's some edge cases I'm missing here but this should be a
whole lot more reliable on the whole.
2025-11-28 13:32:03 -08:00
Mitchell Hashimoto 9baf37a9b2
macOS: fix toggle_visibility behaviour with tabbed windows (#9742)
This fixes regression of #5690, which kind of comes from #9576. 

05b42919d5 (before #9576) has weird
behaviours too: restored windows are not properly focused. With this pr,
we only order `selectedWindow` front so we won't mess up with its
selection and focused state and the order of the tab group.


https://github.com/user-attachments/assets/8c3b120e-4077-4cb5-8ed3-9b46522e2f8e
2025-11-28 06:23:58 -08:00
Lukas 94f88c8b54
macOS: fix toggle_visibility behaviour with tabbed windows
This fixes regression of #5690, which kind of comes from #9576. 05b42919d5 (before #9576) has weird behaviours too, restored windows are not properly focused. With this pr, we only order `selectedWindow` front so we won't mess up with its selection state and the order of the tab group.
2025-11-28 10:14:07 +01:00
Mitchell Hashimoto 199119967b
Remove unused imports (#9736)
Done with AI:
https://ampcode.com/threads/T-07890fd7-5d5c-462a-8d50-ba7ac6565796

I'm reviewing it now, but if builds pass we're probably fine.
2025-11-27 13:52:28 -08:00
Mitchell Hashimoto dbfc3eb679
Remove unused imports 2025-11-27 13:37:53 -08:00
Mitchell Hashimoto d8aeffe1e9
macos: add hover styles to search buttons, cursor changes (#9734)
https://github.com/user-attachments/assets/72a561b5-f863-48c9-97cb-414ed89a8e3f
2025-11-27 13:22:02 -08:00
Mitchell Hashimoto 5c1679209d
macos: add hover styles to search buttons, cursor changes 2025-11-27 13:01:51 -08:00
Mitchell Hashimoto 4ff0e0c9d2
input: remove the unused end search entry in the palette 2025-11-27 07:21:59 -08:00
Mitchell Hashimoto 14899591ce
terminal: PageList search should halt when pin becomes garbage (#9722)
This means that the pin we're using to track our position in the
PageList was part of a node that got reused/recycled at some point. We
can't make any meaningful guarantees about the state of the PageList.

This only happens with scrollback pruning so we can treat it as a
complete search.
2025-11-26 16:48:30 -08:00
Mitchell Hashimoto 842becbcaf
terminal: PageList search should halt when pin becomes garbage
This means that the pin we're using to track our position in the
PageList was part of a node that got reused/recycled at some point. We
can't make any meaningful guarantees about the state of the PageList.

This only happens with scrollback pruning so we can treat it as a
complete search.
2025-11-26 16:36:44 -08:00
Mitchell Hashimoto c199a8fe7e
terminal: RenderState must consider first row in dirty page dirty (#9719)
Fixes #9718
2025-11-26 13:24:05 -08:00
Mitchell Hashimoto b96b55ebde
terminal: RenderState must consider first row in dirty page dirty 2025-11-26 13:20:16 -08:00
Mitchell Hashimoto e64ae2e966
macOS: refine Search UI (#9717)
- fix search dragging animation when corner is not changed
- use ConcentricRectangle on Tahoe


https://github.com/user-attachments/assets/64c294a7-70bd-484d-b153-4aa2d734b1a7
2025-11-26 12:36:24 -08:00
Lukas dc08d057fe
macOS: use ConcentricRectangle on Tahoe 2025-11-26 21:00:14 +01:00
Lukas cbcd52846c
macOS: fix search dragging animation when corner is not changed 2025-11-26 21:00:14 +01:00
Mitchell Hashimoto 48d11b1ce4
fix(macos): use strings' utf-8 lengths for libghostty calls (#9715)
Swift conveniently converts strings to UTF-8 encoded cstrings when
passing them to external functions, however our libghostty functions
also take a length and we were using String.count for that, which
returns the number of _characters_ not the byte length, which caused
searches with multi-byte characters to get truncated.

I went ahead and changed _all_ invocations that pass a string length to
use the utf-8 byte length even if the string is comptime-known and all
ASCII, just so that it's proper and if someone copies one of the calls
in the future for user-inputted data they don't reproduce this bug.

ref:
https://developer.apple.com/documentation/swift/string/count
https://developer.apple.com/documentation/swift/stringprotocol/lengthofbytes(using:)
2025-11-26 11:16:36 -08:00
Qwerasd 4b01163c79 fix(macos): use strings' utf-8 lengths for libghostty calls
Swift conveniently converts strings to UTF-8 encoded cstrings when
passing them to external functions, however our libghostty functions
also take a length and we were using String.count for that, which
returns the number of _characters_ not the byte length, which caused
searches with multi-byte characters to get truncated.

I went ahead and changed _all_ invocations that pass a string length to
use the utf-8 byte length even if the string is comptime-known and all
ASCII, just so that it's proper and if someone copies one of the calls
in the future for user-inputted data they don't reproduce this bug.

ref:
https://developer.apple.com/documentation/swift/string/count
https://developer.apple.com/documentation/swift/stringprotocol/lengthofbytes(using:)
2025-11-26 12:00:58 -07:00
Mitchell Hashimoto d213091452
renderer: manual selection should take priority over search matches (#9714)
Previously it was impossible to select a search match. Well, it was
selecting but it wasn't showing that it was selected.
2025-11-26 10:30:42 -08:00
Mitchell Hashimoto 9206b3dc9b
renderer: manual selection should take priority over search matches
Previously it was impossible to select a search match. Well, it was
selecting but it wasn't showing that it was selected.
2025-11-26 10:28:28 -08:00
Mitchell Hashimoto 3305455902
macOS: move search result counter inside text field (#9713)
Move the search result counter inside the search text field using an
overlay, preventing layout shift when results appear.

**Before:** The counter appeared as a separate element in the HStack,
causing the text field to shift when results loaded.

**After:** The counter is overlaid inside the text field on the right
side with reserved padding, eliminating layout shift.

---

**AI Disclosure: The was entirely authored with Claude Code,
specifically with Claude Opus 4.5.**
2025-11-26 10:07:15 -08:00
Mitchell Hashimoto d85fc62774
search: reset selected match when the needle changes 2025-11-26 10:04:28 -08:00
avarayr f5b923573d
macOS: move search result counter inside text field
Move the search result counter (e.g. "1/30") inside the search text
field using an overlay, preventing layout shift when results appear.

This PR was authored with Claude Code.
2025-11-26 13:04:05 -05:00
Mitchell Hashimoto 71a2dad929
macOS Search GUI (#9709)
#189 for macOS

This adds a search GUI for macOS, including macOS-standard menu bar
items, and keybindings that match other native macOS applications such
as Terminal app, Safari, and others. This introduces a new keybinding
action `start_search` to start a blank search for GUIs.

This PR also resolves a number of minor issues found in the search
subsystem and renderer related to search from prior PRs. This should
result in overall improved search stability. **Please note there are
still known issues (bottom of this PR).**

> [!WARNING]
>
> **A note on stability:** I know a lot of people are eager to have this
feature, and I'm excited
> for this feature to soon be available in tip releases. But note that
new features like this are
> always filled with performance issues, bugs, crashes, etc. That's the
point of tip releases:
> to find and address these before wider availability. We will do our
best to respond rapidly to
> major issues found in tip, but don't expect perfect functionality
immediately!

## Demo


https://github.com/user-attachments/assets/3b81752e-d7e5-4875-9864-92497333b23e

> [!NOTE]
>
> You can drag the search window to any of the four corners if its
getting in the way of reading the terminal.

## Known Issues

TODO prior to this PR merging:

- [x] Single-byte search terms cause a crash since our sliding window
can't handle it. This PR temporarily requires search terms with length
2+ before starting a search to avoid it. 😄
- [x] The way `ScreenSearch` prunes history is fundamental unsafe. With
a rapidly growing screen that could reach history limits and an active
search at the same time, Ghostty is almost guaranteed to crash
currently. The workaround is to not search actively scrolling screens
(new data) for now.
2025-11-26 09:09:55 -08:00
Mitchell Hashimoto 5b4394d211
macos: end_search for ending search 2025-11-26 08:57:24 -08:00
Mitchell Hashimoto c51170da9c
add end_search binding 2025-11-26 08:50:06 -08:00
Mitchell Hashimoto f7b14a0142
macos: debounce search requests with length less than 3 2025-11-26 08:50:06 -08:00
Mitchell Hashimoto 339abf97f7
macos: can allow single char searches now 2025-11-26 08:50:06 -08:00
Mitchell Hashimoto f91080a165
terminal: fix single-character search crashes 2025-11-26 08:50:06 -08:00
Mitchell Hashimoto f252db1f1c
terminal: handle pruning history for when active area removes it 2025-11-26 08:50:06 -08:00
Mitchell Hashimoto 330ce07d48
terminal: fix moving selection on history changing 2025-11-26 08:50:06 -08:00
Mitchell Hashimoto ad755b0e3d
core: always send start_search for refocus 2025-11-26 08:50:05 -08:00
Mitchell Hashimoto 1bb2d4f1c2
macos: only end search if we previously had one 2025-11-26 08:50:05 -08:00
Mitchell Hashimoto 48acc90983
terminal: search should reload active area if dirty 2025-11-26 08:50:05 -08:00
Mitchell Hashimoto 93656fca5a
macos: show progerss correctly for search 2025-11-26 08:50:05 -08:00
Mitchell Hashimoto 0e974f85ed
macos: fix iOS build 2025-11-26 08:50:05 -08:00
Mitchell Hashimoto 7320b234b4
core: surface sends search total/progress to apprt 2025-11-26 08:50:05 -08:00
Mitchell Hashimoto c20af77f98
macos: handle search progress/total apprt actions 2025-11-26 08:50:05 -08:00
Mitchell Hashimoto 2ee2d000f5
apprt actions for search progress 2025-11-26 08:50:05 -08:00
Mitchell Hashimoto d4a2f3db71
macos: search overlay shows search progress 2025-11-26 08:50:05 -08:00
Mitchell Hashimoto 7835ad0ea4
macos: more menu items 2025-11-26 08:50:05 -08:00
Mitchell Hashimoto 240d5e0fc5
config: default search keybindings for macos 2025-11-26 08:50:05 -08:00
Mitchell Hashimoto 3f7cfca4b4
macos: add find menu item 2025-11-26 08:50:05 -08:00
Mitchell Hashimoto 949a8ea53f
macos: dummy search state for iOS 2025-11-26 08:50:05 -08:00
Mitchell Hashimoto 5b2d66e261
apprt/gtk: disable search apprt actions 2025-11-26 08:50:04 -08:00
Mitchell Hashimoto cfbc219f5c
macos: enter and shift+enter move the results 2025-11-26 08:50:04 -08:00
Mitchell Hashimoto efc05523e0
macos: enter goes to next result 2025-11-26 08:50:04 -08:00
Mitchell Hashimoto 72708b8253
search: do not restart search if needle doesn't change 2025-11-26 08:50:04 -08:00
Mitchell Hashimoto 3ce19a02ba
macos: hook up the next/prev search buttons 2025-11-26 08:50:04 -08:00
Mitchell Hashimoto 15f00a9cd1
renderer: setup proper dirty state on search selection changing 2025-11-26 08:50:04 -08:00
Mitchell Hashimoto ad8a6e0642
search thread needs to take an allocated needle 2025-11-26 08:50:04 -08:00
Mitchell Hashimoto 5ee000f58f
macos: search input starts the search up 2025-11-26 08:50:04 -08:00
Mitchell Hashimoto 081d73d850
macos: changes to SearchState trigger calls to internals 2025-11-26 08:50:04 -08:00
Mitchell Hashimoto 56d4a7f58e
macos: start_search refocuses the search input 2025-11-26 08:50:04 -08:00
Mitchell Hashimoto c61d28a3a4
macos: esc returns focus back to surface 2025-11-26 08:50:04 -08:00
Mitchell Hashimoto b7e70ce534
apprt: end_search 2025-11-26 08:50:04 -08:00
Mitchell Hashimoto b084889782
config: cmd+f on macos start_search default 2025-11-26 08:50:04 -08:00
Mitchell Hashimoto bc44b187d6
macos: hook up start_search apprt action to open search 2025-11-26 08:50:04 -08:00
Mitchell Hashimoto aeaa8d4ead
add start_search binding and apprt action 2025-11-26 08:50:03 -08:00
Mitchell Hashimoto b87d57f029
macos: search overlay 2025-11-26 08:50:03 -08:00
Mitchell Hashimoto 20758fb80e
Misc search fixes (#9711)
- ScreenSearch has to restart on resize. We don't have any good way to
handle reflow since our search results are unpinned. We can look into
this later but this fixes correctness.
- PageList now tracks serial number by node that monotonically increases
on any alloc or reuse. Our screen search uses this to prune invalid
history results.
2025-11-26 08:49:54 -08:00
Mitchell Hashimoto 9b7753a36f
terminal: ScreenSearch prunes by min serial 2025-11-26 08:46:26 -08:00
Mitchell Hashimoto 30f189d774
terminal: PageList has page_serial_min 2025-11-26 08:41:26 -08:00
Mitchell Hashimoto e549af76fe
terminal: flattened highlights contain serial numbers for nodes 2025-11-26 08:36:29 -08:00
Mitchell Hashimoto 1786022ac3
terminal: ScreenSearch restarts on resize 2025-11-26 08:31:09 -08:00
Mitchell Hashimoto 8d11335ee4
terminal: PageList stores serial number for page nodes 2025-11-26 08:15:41 -08:00
Mitchell Hashimoto d9529947a4
apprt/gtk: (clipboard) fix GTK internal paste of UTF-8 content (#9710)
When pasting text in GTK, the current version properly prioritizes
text/plain;charset=utf-8 when the content is offered by another
application, but when pasting from ghostty to itself the mime type
selection algorithm prefers the offer order and matches `text/plain`,
which then converts non-ASCII UTF-8 into a bunch of escaped hex
characters (e.g. 日本語 becomes \E6\97\A5\E6\9C\AC\E8\AA\9E)

This is being discussed on the GTK side[1], but until everyone gets an
updated GTK it cannot hurt to offer the UTF-8 variant first (and one of
the GTK dev claims it actually is a bug not to do it, but the wayland
spec is not clear about it, so other clients could behave similarly)

Link: https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/9189 [1]
Fixes #9682
2025-11-26 06:19:18 -08:00
Dominique Martinet 53d0abf4dc apprt/gtk: (clipboard) fix GTK internal paste of UTF-8 content
When pasting text in GTK, the current version properly prioritizes
text/plain;charset=utf-8 when the content is offered by another
application, but when pasting from ghostty to itself the mime type
selection algorithm prefers the offer order and matches `text/plain`,
which then converts non-ASCII UTF-8 into a bunch of escaped hex
characters (e.g. 日本語 becomes \E6\97\A5\E6\9C\AC\E8\AA\9E)

This is being discussed on the GTK side[1], but until everyone gets an
updated GTK it cannot hurt to offer the UTF-8 variant first (and one of
the GTK dev claims it actually is a bug not to do it, but the wayland
spec is not clear about it, so other clients could behave similarly)

Link: https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/9189 [1]
Fixes #9682
2025-11-26 12:59:59 +00:00
Mitchell Hashimoto 14abc6a49d
search: navigable search results (previous/next) (#9702)
Continuing #189

This adds the `navigate_search:previous` and `next` key bindings which
allow search matches to be navigated. The currently selected search
match is highlighted using a new `search-selected-foreground/background`
configuration with a reasonable default.

As search results are navigated, the viewport moves to keep them
visible.

## Demo



https://github.com/user-attachments/assets/facc9f3e-e327-4c65-b5f7-0279480ac357
2025-11-25 11:13:37 -08:00
Mitchell Hashimoto 7fba2da404
better default search match color 2025-11-25 11:05:38 -08:00
Mitchell Hashimoto d0334b7ab6
search: scroll to selected search match 2025-11-25 11:05:38 -08:00
Mitchell Hashimoto ba7b816af0
core: bindings for navigate_search 2025-11-25 11:05:38 -08:00
Mitchell Hashimoto 880db9fdd0
renderer: hook up search selection match highlighting 2025-11-25 11:05:38 -08:00
Mitchell Hashimoto 333dd08c97
search: thread dispatches selection notices, messages 2025-11-25 11:05:38 -08:00
Mitchell Hashimoto a2a771bb6f
search: previous match 2025-11-25 11:05:38 -08:00
Mitchell Hashimoto c38e098c4c
search: fixup selected search when reloading active area 2025-11-25 11:05:38 -08:00
Mitchell Hashimoto 23479fe409
search: select next search match 2025-11-25 11:05:38 -08:00
Mitchell Hashimoto 08f57ab6d6
search: prune invalid history entries on feed 2025-11-25 11:05:38 -08:00
Mitchell Hashimoto 9511b237f3
macOS: fix the animation of showing&hiding command palette (#9698)
https://github.com/user-attachments/assets/0069d634-4156-486f-9b59-141fb4565a19

> [!NOTE]
> AI proofread my comments.
2025-11-25 09:47:12 -08:00
Mitchell Hashimoto 727430c110
benchmarks: align read_buf to cache line (#9700)
This aligns the `read_buf`s in `src/benchmark` to the cache line, so
that we don't leave that alignment up to chance in case it can very
slightly affect the benchmarks.

I ran the before and after on a few of the benchmarks and I don't think
it changes much (data is 200 MiB from `ghostty-gen`):

### codepoint-width

<img width="1738" height="470" alt="CleanShot 2025-11-25 at 09 10 14@2x"
src="https://github.com/user-attachments/assets/f4ea3014-db21-4a4a-8d67-49161829a4b4"
/>

### grapheme-break

<img width="1726" height="470" alt="CleanShot 2025-11-25 at 09 10 51@2x"
src="https://github.com/user-attachments/assets/d99d220b-3221-4adc-b7f5-58c7b86765bb"
/>

### is-symbol

<img width="1654" height="466" alt="CleanShot 2025-11-25 at 09 11 09@2x"
src="https://github.com/user-attachments/assets/d55e6c12-a650-49cc-aee9-b887eccd42dd"
/>

AI: no AI, just a simple replace.
2025-11-25 09:46:25 -08:00
Jacob Sandlund 807febcb5e benchmarks: align read_buf to cache line 2025-11-25 09:07:21 -05:00
Lukas 2a627a4665
macOS: fix the animation of showing&hiding command palette 2025-11-25 11:22:14 +01:00
Mitchell Hashimoto 94e52ffcfb
pkg/{highway,simdutf}: disable ubsan (#9696)
This causes linker issues for some libghostty users. I don't know why we
never saw these issues with Ghostty release builds, but generally
speaking I think its fine to do this for 3rd party code unless we've
witnessed an issue. And these deps have been stable for a long, long
time.
2025-11-24 21:23:11 -08:00
Mitchell Hashimoto ee5dde795a
fix(renderer): load linearized fg color for cursor cell (#9695)
It's clear from the surrounding code that the RGB values returned from
`cell_text_vertex` are expected to be linearized. This was not the case
for the cursor cell, resulting in the cursor text being too bright when
using `cursor-text = cell-background`.

Fixes #8353/#9138.

xref #8960, which would also fixe this issue, but I don't know where
that's heading
2025-11-24 21:22:02 -08:00
Mitchell Hashimoto c92a003325
pkg/{highway,simdutf}: disable ubsan
This causes linker issues for some libghostty users. I don't know why we
never saw these issues with Ghostty release builds, but generally
speaking I think its fine to do this for 3rd party code unless we've
witnessed an issue. And these deps have been stable for a long, long
time.
2025-11-24 21:18:49 -08:00
Daniel Wennberg d31be89b16 fix(renderer): load linearized fg color for cursor cell 2025-11-24 21:04:54 -08:00
Mitchell Hashimoto 6f0927c42a
Search binding, viewport rendering (#9687)
The march towards #189 continues.

This hooks up the search thread to the main surface and all the state
necessary for the renderer to show search results in the viewport! This
also adds a `search` binding which takes a query to start/stop a search.
**This still doesn't add any search GUI,** which will come later, the
internals must happen first.

A non-blank binding will start or change the search term. An empty
binding will stop search:

```
keybind = cmd+f=search:Hello
keybind = shift+cmd+f=search:
```

> [!NOTE]
>
> Obviously, search will eventually have a GUI. The point of this PR is
primarily to connect all the various internal systems more than
anything. GUI will come soon.

## Demo


https://github.com/user-attachments/assets/06af5a3b-280e-4804-b506-419b92a95f99

## Major Changes

The only major changes required as part of this is the introduction of
what I'm calling the terminal "highlight" system. This is a generic
system for highlighting portions of the terminal contents. These will
ultimately underpin what we currently call "selections" (selecting text
with your mouse/keyboard) but that is far too large a change to make in
one PR.

Therefore, this PR introduces highlights and the only consumer is the
entire search subsystem.

## Limitations

Still plenty of limitations we need to keep marching towards resolving:

- ~~Search matches are styled the same as selections. They should be
different.~~
- There is no way to iterate search matches, yet.
- There is no GUI for inputting a search query or viewing total matches,
yet.
- ~~I think searches are case-sensitive currently and they should
probably not be.~~ Done, for ASCII.

But hey, it's something!
2025-11-24 20:32:06 -08:00
Mitchell Hashimoto bb21c3d6b3
search: case-insesitive (ascii) search 2025-11-24 20:25:26 -08:00
Mitchell Hashimoto de16e4a92b
config: add selection-foreground/background 2025-11-24 20:16:01 -08:00
Mitchell Hashimoto a4e40c7567
set proper dirty state to redo viewport search 2025-11-24 19:55:27 -08:00
Mitchell Hashimoto 06981175af
renderer: reset search dirty state after processing 2025-11-24 19:55:27 -08:00
Mitchell Hashimoto d0e3a79a74
reset search on needle change or quit 2025-11-24 19:55:27 -08:00
Mitchell Hashimoto dd9ed531ad
render viewport matches 2025-11-24 19:55:27 -08:00
Mitchell Hashimoto 6c8ffb5fc1
renderer: receive message with viewport match selections
Doesn't draw yet
2025-11-24 19:55:27 -08:00
Mitchell Hashimoto 061d157b50
terminal: search should use active area dirty tracking 2025-11-24 19:55:27 -08:00
Mitchell Hashimoto 72921741e8
terminal: search.viewport supports dirty tracking for more efficient 2025-11-24 19:55:27 -08:00
Mitchell Hashimoto e49f4a6dbc
`search` binding action starts a search thread on surface 2025-11-24 19:55:27 -08:00
Mitchell Hashimoto 6623c20c2d
terminal: switch search to use flattened highlights 2025-11-24 19:55:27 -08:00
Mitchell Hashimoto 05d6315e82
terminal: add a SlidingWindow2 that uses highlights 2025-11-24 19:55:27 -08:00
Mitchell Hashimoto ec5bdf1a5a
terminal: highlights 2025-11-24 19:55:27 -08:00
Mitchell Hashimoto 56b69ff0fd
datastruct: make CircBuf use the assumeCapacity pattern 2025-11-24 19:55:27 -08:00
Mitchell Hashimoto 54370c22ba
renderer: use proper cell style for cursor-color/text (#9694)
Regression from render state work.
2025-11-24 19:55:14 -08:00
Mitchell Hashimoto 878ccd3f34
renderer: use proper cell style for cursor-color/text
Regression from render state work.
2025-11-24 19:52:21 -08:00
Mitchell Hashimoto a7d5a5a20e
Fix `pkg/freetype` LoadFlags struct to correctly match FreeType API (#9691)
The struct was missing padding at bit position 8, causing all subsequent
flag fields (bits 9+) to be misaligned by one bit position.

See:
https://freetype.org/freetype2/docs/reference/ft2-glyph_retrieval.html#ft_load_xxx
2025-11-24 19:35:58 -08:00
Qwerasd 6d65abc489 fix(pkg/freetype): fully correct load flags
These now properly match the FreeType API- compared directly in the unit
tests against the values provided by the FreeType header itself.

This was ridiculously wrong before, like... wow.
2025-11-24 17:57:02 -07:00
Qwerasd 3cd6939af6 pkg/freetype: add failing unit tests for LoadFlags 2025-11-24 17:35:53 -07:00
Qwerasd 6a9c869f9d Partially revert 25856d6 since it broke pkg/freetype tests 2025-11-24 17:24:47 -07:00
Pyry Takala 5bfeba6603 Fix LoadFlags struct bit alignment to match FreeType API
The struct was missing padding at bit position 8, causing all subsequent flag fields (bits 9+) to be misaligned by one bit position.

See: https://freetype.org/freetype2/docs/reference/ft2-glyph_retrieval.html#ft_load_xxx
2025-11-24 23:34:47 +00:00
Mitchell Hashimoto 8278718c57
Fix LangSet.hasLang() to compare against FcLangEqual instead of FcTrue (#9685)
FcLangSetHasLang returns FcLangResult enum values:
- FcLangEqual (0): Exact match
- FcLangDifferentTerritory (1): Same language, different territory
- FcLangDifferentLang (2): Different language
See also
https://www.freedesktop.org/software/fontconfig/fontconfig-devel/fclangsethaslang.html
and
https://codebrowser.dev/qt6/include/fontconfig/fontconfig.h.html#_FcLangResult

The previous comparison to FcTrue (1) caused:
- Exact matches (0) to incorrectly return false
- Partial matches (1) to incorrectly return true

This fix changes the comparison to FcLangEqual (0) so hasLang()
correctly returns true only for exact language matches.
2025-11-24 13:13:51 -08:00
Pyry Takala d4c2376c2d Fix LangSet.hasLang() to compare against FcLangEqual instead of FcTrue
FcLangSetHasLang returns FcLangResult enum values:
- FcLangEqual (0): Exact match
- FcLangDifferentTerritory (1): Same language, different territory
- FcLangDifferentLang (2): Different language

The previous comparison to FcTrue (1) caused:
- Exact matches (0) to incorrectly return false
- Partial matches (1) to incorrectly return true

This fix changes the comparison to FcLangEqual (0) so hasLang()
correctly returns true only for exact language matches.

Fixes emoji font detection which relies on checking for 'und-zsye'
language tag support.
2025-11-24 20:34:07 +00:00
Mitchell Hashimoto b5dfe5dbfe
Add GHOSTTY_QUICK_TERMINAL for quick terminal detection (#9673)
## Summary

Adds a new environment variable `GHOSTTY_QUICK_TERMINAL=1` that is set
when a terminal surface is launched as a quick terminal. This allows
shell configurations to conditionally adjust behavior based on whether
the terminal is a quick terminal.

Closes #3985

<img width="1430" height="228" alt="CleanShot 2025-11-23 at 12 39 27
png"
src="https://github.com/user-attachments/assets/1085c19b-9d58-4603-a03d-662bfde47095"
/>

## Motivation

Quick terminals are designed as ephemeral, singleton windows for quick
commands. Many users (especially tmux users) have shell configurations
that automatically attach to or start tmux sessions on terminal launch.
This automatic behavior conflicts with the quick terminal use case.

Example from the issue:
```zsh
# Users want to skip this in quick terminals
if [[ -z "$TMUX" ]]; then
  tmux attach || tmux new
fi

With this PR, users can now detect quick terminals and adjust their shell behavior:
if [[ -z "$TMUX" ]] && [[ -z "$GHOSTTY_QUICK_TERMINAL" ]]; then
  tmux attach || tmux new
fi
```

## Implementation

- macOS: Added GHOSTTY_QUICK_TERMINAL=1 to SurfaceConfiguration
environment variables in QuickTerminalController.swift:345-351
- Linux/GTK: Added environment variable check in
src/apprt/gtk/class/surface.zig:1469-1472 within defaultTermioEnv()

 The environment variable is automatically inherited by split surfaces.

## Note on Scripting API

I'm aware that @rhodes-b mentioned this functionality was planned for
the scripting API (issue #3985). However, I believe this simpler
environment variable approach provides immediate value for tmux users
and shell configuration use cases, while the scripting API can later
provide more comprehensive surface introspection capabilities.

## AI Assistance Disclosure

This PR was written with Claude Code assistance. The Linux/GTK
implementation was fully AI-generated. I implemented the mac version
myself after Claude Code helped me understand the codebase architecture
and locate the appropriate files.
2025-11-24 08:21:21 -08:00
Mitchell Hashimoto 98e7c17fcc
unicode: fix VS15/VS16 check to consider emoji bases (#9679)
This PR builds on https://github.com/ghostty-org/ghostty/pull/9678 ~so
the diff from there is included here (it's not possible to stack PRs
unless it's a PR against my own fork)--review that one first!~

This PR fixes an issue with the VS15/VS16 handling in terminal `print`,
where before we didn't check for valid sequences if the base code point
is an emoji. This meant that a VS15 after an emoji that isn't part of a
valid sequence would narrow the cell, despite that the emoji doesn't
have a text presentation.

This PR also uses a single `is_emoji_vs_base` instead of the
`is_emoji_vs_emoji` and `is_emoji_vs_text`. See the [uucode
comment](215ff09730/src/config.zig (L239-L254))
for why I'm recommending this.

AI was used in some of the uucode changes in
https://github.com/ghostty-org/ghostty/pull/9678 (Amp--primarily for
tests), but everything was carefully vetted and much of it done by hand.
This PR was made without AI.
2025-11-24 08:20:07 -08:00
Jacob Sandlund a0203e8d1a Merge remote-tracking branch 'upstream/main' into vs-correctness 2025-11-24 10:47:22 -05:00
Mitchell Hashimoto 38fbbba8e9
deps: Update uucode to latest (#9678)
This updates uucode to the latest version, with the following changes:
b309dfb4e2...31655fba3c

For this PR, the new `uucode` version has two changes that contribute to
the diff:

* The `grapheme_break` now includes `emoji_modifier` and
`emoji_modifier_base`, so we don't need to grab those from
`is_emoji_modifier` and `is_emoji_modifier_base`.
* The `wcwidth` calculation has been split into `wcwidth_standalone`
(width of a code point when it's the only code point in a grapheme) and
`wcwidth_zero_in_grapheme` (whether the code point is _not_ contributing
to the width of a multi-code-point grapheme). To keep the current
Ghostty behavior for this PR, this sets `width` to 0 if
`wcwidth_zero_in_grapheme`, but with the exception of
`is_emoji_modifier` (see comment).
* While this PR isn't affected by it, take a look at
[wcwidth.zig](https://github.com/jacobsandlund/uucode/blob/main/src/x/config_x/wcwidth.zig)
for the considerations that went into determining the width of a code
point, along with many comments.
* See
[x/grapheme.zig](https://github.com/jacobsandlund/uucode/blob/main/src/x/grapheme.zig)
for the calculation of the width of a grapheme based on the width of the
code points with exceptions, again with many comments.
* See
[resources/wcwidth](https://github.com/jacobsandlund/uucode/tree/main/resources/wcwidth)
for a comparison of other unicode libraries calculation of "wcwidth".

PRs will follow this in a moment to also take advantage of the new
`uucode` version for:

* Better grapheme segmentation
* Correct VS15/VS16 handling
* More correct cell width calculation (especially certain scripts such
as Devanagari)
2025-11-24 07:31:22 -08:00
Mitchell Hashimoto d3f24179c9
build(deps): bump peter-evans/create-pull-request from 7.0.8 to 7.0.9 (#9676)
Bumps
[peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request)
from 7.0.8 to 7.0.9.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/peter-evans/create-pull-request/releases">peter-evans/create-pull-request's
releases</a>.</em></p>
<blockquote>
<h2>Create Pull Request v7.0.9</h2>
<p>⚙️ Fixes an <a
href="https://redirect.github.com/peter-evans/create-pull-request/issues/4228">incompatibility</a>
with the recently released <code>actions/checkout@v6</code>.</p>
<h2>What's Changed</h2>
<ul>
<li>~70 dependency updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a></li>
<li>docs: fix workaround description about <code>ready_for_review</code>
by <a href="https://github.com/ybiquitous"><code>@​ybiquitous</code></a>
in <a
href="https://redirect.github.com/peter-evans/create-pull-request/pull/3939">peter-evans/create-pull-request#3939</a></li>
<li>Docs: <code>add-paths</code> default behavior by <a
href="https://github.com/joeflack4"><code>@​joeflack4</code></a> in <a
href="https://redirect.github.com/peter-evans/create-pull-request/pull/3928">peter-evans/create-pull-request#3928</a></li>
<li>docs: update to create-github-app-token v2 by <a
href="https://github.com/Goooler"><code>@​Goooler</code></a> in <a
href="https://redirect.github.com/peter-evans/create-pull-request/pull/4063">peter-evans/create-pull-request#4063</a></li>
<li>Fix compatibility with actions/checkout@v6 by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/peter-evans/create-pull-request/pull/4230">peter-evans/create-pull-request#4230</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/joeflack4"><code>@​joeflack4</code></a>
made their first contribution in <a
href="https://redirect.github.com/peter-evans/create-pull-request/pull/3928">peter-evans/create-pull-request#3928</a></li>
<li><a href="https://github.com/Goooler"><code>@​Goooler</code></a> made
their first contribution in <a
href="https://redirect.github.com/peter-evans/create-pull-request/pull/4063">peter-evans/create-pull-request#4063</a></li>
<li><a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> made
their first contribution in <a
href="https://redirect.github.com/peter-evans/create-pull-request/pull/4230">peter-evans/create-pull-request#4230</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/peter-evans/create-pull-request/compare/v7.0.8...v7.0.9">https://github.com/peter-evans/create-pull-request/compare/v7.0.8...v7.0.9</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="84ae59a2cd"><code>84ae59a</code></a>
fix: compatibility with actions/checkout@v6 (<a
href="https://redirect.github.com/peter-evans/create-pull-request/issues/4230">#4230</a>)</li>
<li><a
href="b4733b9419"><code>b4733b9</code></a>
build(deps-dev): bump js-yaml from 4.1.0 to 4.1.1 (<a
href="https://redirect.github.com/peter-evans/create-pull-request/issues/4222">#4222</a>)</li>
<li><a
href="0edc001d28"><code>0edc001</code></a>
build(deps-dev): bump the npm group with 2 updates (<a
href="https://redirect.github.com/peter-evans/create-pull-request/issues/4201">#4201</a>)</li>
<li><a
href="430aea0fb1"><code>430aea0</code></a>
build(deps): bump the github-actions group with 3 updates (<a
href="https://redirect.github.com/peter-evans/create-pull-request/issues/4200">#4200</a>)</li>
<li><a
href="46cdba753c"><code>46cdba7</code></a>
build(deps-dev): bump the npm group with 3 updates (<a
href="https://redirect.github.com/peter-evans/create-pull-request/issues/4185">#4185</a>)</li>
<li><a
href="b937339b17"><code>b937339</code></a>
build(deps): bump the github-actions group with 2 updates (<a
href="https://redirect.github.com/peter-evans/create-pull-request/issues/4184">#4184</a>)</li>
<li><a
href="e9af275c37"><code>e9af275</code></a>
ci: update dependabot config</li>
<li><a
href="d3e081a03a"><code>d3e081a</code></a>
build(deps-dev): bump <code>@​types/node</code> from 18.19.127 to
18.19.128 (<a
href="https://redirect.github.com/peter-evans/create-pull-request/issues/4178">#4178</a>)</li>
<li><a
href="9ec683ee07"><code>9ec683e</code></a>
build(deps-dev): bump <code>@​types/node</code> from 18.19.125 to
18.19.127 (<a
href="https://redirect.github.com/peter-evans/create-pull-request/issues/4165">#4165</a>)</li>
<li><a
href="65d8d10bf7"><code>65d8d10</code></a>
build(deps-dev): bump ts-jest from 29.4.2 to 29.4.4 (<a
href="https://redirect.github.com/peter-evans/create-pull-request/issues/4163">#4163</a>)</li>
<li>Additional commits viewable in <a
href="271a8d0340...84ae59a2cd">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=peter-evans/create-pull-request&package-manager=github_actions&previous-version=7.0.8&new-version=7.0.9)](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-11-24 07:23:11 -08:00
Jacob Sandlund 8f033c7022 Add test with just a single emoji followed by VS15 (invalid) 2025-11-24 09:26:01 -05:00
Jacob Sandlund b58656be8a Merge branch 'uucode-update' into vs-correctness 2025-11-24 09:14:32 -05:00
Jacob Sandlund 61c7381452 Update comment. PR for wcwidth_standalone might be a bit 2025-11-24 09:14:03 -05:00
Jacob Sandlund 808d31f6ee nix cache --update 2025-11-24 09:13:19 -05:00
Jacob Sandlund e4c5670266 Merge branch 'uucode-update' into vs-correctness 2025-11-24 08:29:51 -05:00
Jacob Sandlund 2b6c309217 Update uucode to latest 2025-11-24 08:29:27 -05:00
Jacob Sandlund c3c9181e7a Merge branch 'uucode-update' into vs-correctness 2025-11-23 23:05:22 -05:00
Jacob Sandlund 6e0e1d1388 update uucode to latest 2025-11-23 23:05:03 -05:00
Jacob Sandlund 55c1cb3aad Merge branch 'uucode-update' into vs-correctness 2025-11-23 22:56:15 -05:00
Jacob Sandlund 62ec34072f fix typo 2025-11-23 22:56:00 -05:00
Jacob Sandlund 36c3295806 unicode: don't narrow invalid text presentation (VS15) sequences 2025-11-23 22:39:21 -05:00
dependabot[bot] 6588e1e9e7
build(deps): bump peter-evans/create-pull-request from 7.0.8 to 7.0.9
Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 7.0.8 to 7.0.9.
- [Release notes](https://github.com/peter-evans/create-pull-request/releases)
- [Commits](271a8d0340...84ae59a2cd)

---
updated-dependencies:
- dependency-name: peter-evans/create-pull-request
  dependency-version: 7.0.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-24 00:08:15 +00:00
Jacob Sandlund 97926ca307 Update uucode to the latest, for future width and grapheme break changes 2025-11-23 17:26:25 -05:00
Vinícius Soares 92aa960381 Add flag for quick terminal 2025-11-23 12:43:11 -03:00
Mitchell Hashimoto 6b28671ead
macOS: Only change the icon if needed (#9670)
Fixes #9666

> [!NOTE]
> AI proofread my comments
2025-11-22 14:43:12 -08:00
Mitchell Hashimoto 4e6498a04c
renderer: make cursorStyle depend on RenderState (#9672)
This makes `cursorStyle` utilize `RenderState` to determine the
appropriate cursor style. This moves the cursor style logic outside the
critical area, although it was cheap to begin with.

This always removes `viewport_is_bottom` which had no practical use.
2025-11-22 14:41:25 -08:00
Mitchell Hashimoto df466f3c73
renderer: make cursorStyle depend on RenderState
This makes `cursorStyle` utilize `RenderState` to determine the
appropriate cursor style. This moves the cursor style logic outside the
critical area, although it was cheap to begin with.

This always removes `viewport_is_bottom` which had no practical use.
2025-11-22 14:36:53 -08:00
Lukas 6f75cc56f6
macOS: Only change the icon if needed
Fixes #9666
2025-11-22 16:48:39 +01:00
Mitchell Hashimoto 6e9412cbab
build(deps): bump actions/checkout from 5.0.1 to 6.0.0 (#9659)
Bumps [actions/checkout](https://github.com/actions/checkout) from 5.0.1
to 6.0.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/checkout/releases">actions/checkout's
releases</a>.</em></p>
<blockquote>
<h2>v6.0.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Update README to include Node.js 24 support details and requirements
by <a href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a>
in <a
href="https://redirect.github.com/actions/checkout/pull/2248">actions/checkout#2248</a></li>
<li>Persist creds to a separate file by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2286">actions/checkout#2286</a></li>
<li>v6-beta by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2298">actions/checkout#2298</a></li>
<li>update readme/changelog for v6 by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2311">actions/checkout#2311</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/checkout/compare/v5.0.0...v6.0.0">https://github.com/actions/checkout/compare/v5.0.0...v6.0.0</a></p>
<h2>v6-beta</h2>
<h2>What's Changed</h2>
<p>Updated persist-credentials to store the credentials under
<code>$RUNNER_TEMP</code> instead of directly in the local git
config.</p>
<p>This requires a minimum Actions Runner version of <a
href="https://github.com/actions/runner/releases/tag/v2.329.0">v2.329.0</a>
to access the persisted credentials for <a
href="https://docs.github.com/en/actions/tutorials/use-containerized-services/create-a-docker-container-action">Docker
container action</a> scenarios.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/actions/checkout/blob/main/CHANGELOG.md">actions/checkout's
changelog</a>.</em></p>
<blockquote>
<h1>Changelog</h1>
<h2>V6.0.0</h2>
<ul>
<li>Persist creds to a separate file by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2286">actions/checkout#2286</a></li>
<li>Update README to include Node.js 24 support details and requirements
by <a href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a>
in <a
href="https://redirect.github.com/actions/checkout/pull/2248">actions/checkout#2248</a></li>
</ul>
<h2>V5.0.1</h2>
<ul>
<li>Port v6 cleanup to v5 by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2301">actions/checkout#2301</a></li>
</ul>
<h2>V5.0.0</h2>
<ul>
<li>Update actions checkout to use node 24 by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2226">actions/checkout#2226</a></li>
</ul>
<h2>V4.3.1</h2>
<ul>
<li>Port v6 cleanup to v4 by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2305">actions/checkout#2305</a></li>
</ul>
<h2>V4.3.0</h2>
<ul>
<li>docs: update README.md by <a
href="https://github.com/motss"><code>@​motss</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1971">actions/checkout#1971</a></li>
<li>Add internal repos for checking out multiple repositories by <a
href="https://github.com/mouismail"><code>@​mouismail</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1977">actions/checkout#1977</a></li>
<li>Documentation update - add recommended permissions to Readme by <a
href="https://github.com/benwells"><code>@​benwells</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2043">actions/checkout#2043</a></li>
<li>Adjust positioning of user email note and permissions heading by <a
href="https://github.com/joshmgross"><code>@​joshmgross</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2044">actions/checkout#2044</a></li>
<li>Update README.md by <a
href="https://github.com/nebuk89"><code>@​nebuk89</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2194">actions/checkout#2194</a></li>
<li>Update CODEOWNERS for actions by <a
href="https://github.com/TingluoHuang"><code>@​TingluoHuang</code></a>
in <a
href="https://redirect.github.com/actions/checkout/pull/2224">actions/checkout#2224</a></li>
<li>Update package dependencies by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2236">actions/checkout#2236</a></li>
</ul>
<h2>v4.2.2</h2>
<ul>
<li><code>url-helper.ts</code> now leverages well-known environment
variables by <a href="https://github.com/jww3"><code>@​jww3</code></a>
in <a
href="https://redirect.github.com/actions/checkout/pull/1941">actions/checkout#1941</a></li>
<li>Expand unit test coverage for <code>isGhes</code> by <a
href="https://github.com/jww3"><code>@​jww3</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1946">actions/checkout#1946</a></li>
</ul>
<h2>v4.2.1</h2>
<ul>
<li>Check out other refs/* by commit if provided, fall back to ref by <a
href="https://github.com/orhantoy"><code>@​orhantoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1924">actions/checkout#1924</a></li>
</ul>
<h2>v4.2.0</h2>
<ul>
<li>Add Ref and Commit outputs by <a
href="https://github.com/lucacome"><code>@​lucacome</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1180">actions/checkout#1180</a></li>
<li>Dependency updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>- <a
href="https://redirect.github.com/actions/checkout/pull/1777">actions/checkout#1777</a>,
<a
href="https://redirect.github.com/actions/checkout/pull/1872">actions/checkout#1872</a></li>
</ul>
<h2>v4.1.7</h2>
<ul>
<li>Bump the minor-npm-dependencies group across 1 directory with 4
updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1739">actions/checkout#1739</a></li>
<li>Bump actions/checkout from 3 to 4 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1697">actions/checkout#1697</a></li>
<li>Check out other refs/* by commit by <a
href="https://github.com/orhantoy"><code>@​orhantoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1774">actions/checkout#1774</a></li>
<li>Pin actions/checkout's own workflows to a known, good, stable
version. by <a href="https://github.com/jww3"><code>@​jww3</code></a> in
<a
href="https://redirect.github.com/actions/checkout/pull/1776">actions/checkout#1776</a></li>
</ul>
<h2>v4.1.6</h2>
<ul>
<li>Check platform to set archive extension appropriately by <a
href="https://github.com/cory-miller"><code>@​cory-miller</code></a> in
<a
href="https://redirect.github.com/actions/checkout/pull/1732">actions/checkout#1732</a></li>
</ul>
<h2>v4.1.5</h2>
<ul>
<li>Update NPM dependencies by <a
href="https://github.com/cory-miller"><code>@​cory-miller</code></a> in
<a
href="https://redirect.github.com/actions/checkout/pull/1703">actions/checkout#1703</a></li>
<li>Bump github/codeql-action from 2 to 3 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1694">actions/checkout#1694</a></li>
<li>Bump actions/setup-node from 1 to 4 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1696">actions/checkout#1696</a></li>
<li>Bump actions/upload-artifact from 2 to 4 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1695">actions/checkout#1695</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="1af3b93b68"><code>1af3b93</code></a>
update readme/changelog for v6 (<a
href="https://redirect.github.com/actions/checkout/issues/2311">#2311</a>)</li>
<li><a
href="71cf2267d8"><code>71cf226</code></a>
v6-beta (<a
href="https://redirect.github.com/actions/checkout/issues/2298">#2298</a>)</li>
<li><a
href="069c695914"><code>069c695</code></a>
Persist creds to a separate file (<a
href="https://redirect.github.com/actions/checkout/issues/2286">#2286</a>)</li>
<li><a
href="ff7abcd0c3"><code>ff7abcd</code></a>
Update README to include Node.js 24 support details and requirements (<a
href="https://redirect.github.com/actions/checkout/issues/2248">#2248</a>)</li>
<li>See full diff in <a
href="93cb6efe18...1af3b93b68">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=5.0.1&new-version=6.0.0)](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-11-22 06:50:34 -08:00
Mitchell Hashimoto 6529baea46
Change renderer from screen clones to new `RenderState` (#9662)
This adds a new API called `RenderState` that produces the proper state
required for a renderer to draw a viewport and updates our renderer to
use it instead of the prior screen clone method.

The newsworthy change is here is that we've shortened the critical area
where the renderer holds the terminal lock and blocks IO by anywhere
from **2x to 5x faster**, and in about half the frames we're now in the
critical area for **zero microseconds** because `RenderState` has much
better dirty/damage tracking.

**For libghostty Zig users**, this API is available to the Zig module
and can be used to create your own renderers (to any artifact, it
doesn't have to be graphical! It is even useful for text like a tmux
clone or something).

## Differences vs Old Method

The renderer previously called `Screen.clone`. This produces a copy of
all the screen data (even stuff the renderer may not need) and attempts
to create a standalone, fully functional `Screen` allocation. I didn't
microbenchmark this to understand exactly where the slowdown was, but I
think it was based primarily in two places:

- Screens have a minimum allocation of two Ghostty "pages" which are
quite large. I think this allocation was the primary expensive part.
Without refactoring our entire Screen/PageList work, this was
unavoidable.
- The clone was unconditional and would produce a fully new Screen on
every frame.

The new structure `RenderState` is stateful and each frame calls
`update` on the prior value and it modifies itself in place. This
addresses the above two points in a few ways:

- Allocation is minimized to only what we need, no full pages.
- Since it is stateful (updating in-place), we only change dirty data
and don't need to copy everything. **Note the benchmarks below only test
_full updates_, so you aren't even seeing the benefits of this!**
- Also since it is stateful, we cache expensive calculations (such as
for selections) so future screen updates can reuse those cached values
rather than recompute them.
- We retain memory from prior updates even when the screen is dirty, so
even in dirty states, it's unlikely we allocate.

More details in the "Design" section.

## Benchmarks

Here are some microbenchmarks on the previous render critical area
versus the new one.

For each of the benchmarks below, ignore the time units (milliseconds)
and instead **focus on the relative speedup.** The benchmarks are all
doing a full render frame setup around 1000 times, because the actual
cost of a frame update is in dozens or hundreds of microseconds.

> [!NOTE]
>
> I'm still working on some more benchmarks before merging. I'll update
this space.

### Full screen, single style

<img width="1542" height="480" alt="CleanShot 2025-11-21 at 07 35 13@2x"
src="https://github.com/user-attachments/assets/c28c9f33-d1aa-4723-8a8e-3c6d70fe3667"
/>

### Full screen, plaintext

<img width="1642" height="612" alt="CleanShot 2025-11-21 at 07 36 06@2x"
src="https://github.com/user-attachments/assets/b51f57cf-7c48-46c8-a347-8ecc0bdd3d47"
/>

### Full screen, different style per cell (pathological case)

<img width="1704" height="456" alt="CleanShot 2025-11-21 at 07 37 55@2x"
src="https://github.com/user-attachments/assets/71a98250-d8d1-47ab-ae69-5e6b3b60bf2d"
/>

### Critical Area: Typing at Shell Prompt

| This PR | Main Branch |
---------|--------
| <img width="1064" height="764" alt="CleanShot 2025-11-21 at 14 44
31@2x"
src="https://github.com/user-attachments/assets/8a0ab3a1-3d68-41f0-9469-bc08a4569286"
/> | <img width="1040" height="684" alt="CleanShot 2025-11-21 at 14 47
10@2x"
src="https://github.com/user-attachments/assets/04ffa607-8841-436b-b6e9-eeeb6ee9482d"
/> |

### Critical Area: Neovim Scrolling

| This PR | Main Branch |
---------|--------
| <img width="1054" height="748" alt="CleanShot 2025-11-21 at 14 45
06@2x"
src="https://github.com/user-attachments/assets/ccafaee8-720f-41be-820d-fd705835607a"
/> | <img width="1068" height="796" alt="CleanShot 2025-11-21 at 14 47
48@2x"
src="https://github.com/user-attachments/assets/68087496-d371-4c7c-8b4c-b967dbaeaa7c"
/> |

### Critical Area: `btop -u 100`

This is closer to a pathological case, about as close as you get with a
real tool in the wild. `btop` uses hundreds of unique styles and updates
many cells across many rows very frequently (every 100ms in this case).
You can see that some of our frame times in this case are similar but
there are _so many more near-idle frames_ thanks to our dirty tracking.

| This PR | Main Branch |
---------|--------
| <img width="1088" height="900" alt="CleanShot 2025-11-21 at 14 45
44@2x"
src="https://github.com/user-attachments/assets/ea63f0eb-f06e-4d00-95a3-c55a3755cc67"
/> | <img width="1078" height="906" alt="CleanShot 2025-11-21 at 14 48
18@2x"
src="https://github.com/user-attachments/assets/cef360de-2b12-440f-8c4c-6a69b5ce4058"
/> |

### "DOOM Fire" 

Fullscreen on my macOS when from 770 FPS to ~808 FPS consistently, a
solid 5% increase repeatedly.

<img width="3520" height="2392" alt="CleanShot 2025-11-21 at 07 45
29@2x"
src="https://github.com/user-attachments/assets/033effca-0abb-4ff8-a21b-83214d118d12"
/>


### IO 

While this was rendering focused, the smaller critical area does help IO
performance a bit.

We've already tracked down the remaining issues to the IO thread going
to sleep and overhead with context switching. We're investigating
switching to a spin lock for the IO thread only in another track of
work.

> [!NOTE]
>
> **This is comparing with `main`, which already has a 20-30%
performance improvement over v1.2.3.**

<img width="982" height="698" alt="image"
src="https://github.com/user-attachments/assets/52a86f6c-6f09-45fe-9ac7-ca62c7ac6ee4"
/>

## Design

The design of the API is a _stateful_ `RenderState` struct that you call
`update` on each frame with the target terminal, and it only updates
what is needed. RenderState keeps track of rows, cells, hyperlinks,
selections, etc.

```zig
// Start empty
var state: terminal.RenderState = .empty;
defer state.deinit(alloc);

// Each frame update it with a terminal. 
// THIS IS THE ONLY PART THAT ACCESS `t`
try state.update(alloc, &t);

// Access render data (can be outside any locking for `t`)
...
```

The ergonomics of the `RenderState` structure a wee bit clunky because
we make use of struct-of-arrays (SoA, Zig's MultiArrayList) to better
optimize cache locality for renderer data vs. update data (what we need
to update the render state is different from what we need to draw).

Once you get used to the API though, it's pretty beautiful. I mean, look
at this:

```zig
        for (
            0..,
            row_data.items(.raw),
            row_data.items(.cells),
        ) |y, row, cells| {
            const cells_slice = cells.slice();
            for (
                0..,
                cells_slice.items(.raw),
                cells_slice.items(.grapheme),
            ) |x, cell, graphemes| {
```

## Improvements

This PR makes various improvements across the board:

- It bears repeating in case it was missed previously that the critical
area time of a render has gone down 2x to 5x when there is work and is
now free when there is no work (the previous implementation always did
work).
- Font shaping is much more efficient now and only requires access to a
render state.
- Selection handling is now cached and works with dirty tracking.
Previously, if you had an active selection, we'd search the entire
screen multiple times (like... once per row). Yikes.
- Hyperlink handling is _much_ more efficient. Instead of iterating
through the entire screen contents _per configured link_ we now cache
the screen contents as a string and search one whole string multiple
times. Obvious, but we didn't do this before.
- The `contrainedWidth` and `rowNeverExtendBg` helper methods are now
both much more efficient and live within the renderer package rather
than being awkwardly in the terminal package.

## Future Notes

- Our `terminal.Selection` API is very bad. It conceptually makes sense
and I understand why I designed it this way (easy) but it makes it hard
to render or manipulate performantly.

**AI Disclosure:** AI was used only to assist with writing some tests
and converting some tests. The primary logic is all organic, meatbag
produced.
2025-11-22 06:36:05 -08:00
Mitchell Hashimoto 3283f57fd2
lib-vt: expose RenderState API 2025-11-21 16:01:22 -08:00
Mitchell Hashimoto 82f5c1a13c
renderer: clear renderstate memory periodically 2025-11-21 09:03:03 -08:00
Mitchell Hashimoto 2ecaf4a595
font/shaper: fix harfbuzz tests 2025-11-20 22:00:44 -08:00
Mitchell Hashimoto 3d56a3a02b
font/shaper: remove old pre-renderstate logic 2025-11-20 22:00:44 -08:00
Mitchell Hashimoto c892599385
terminal: cache some selection state to make render state faster 2025-11-20 22:00:44 -08:00
Mitchell Hashimoto 7728620ea8
terminal: render state dirty state 2025-11-20 22:00:44 -08:00
Mitchell Hashimoto 86fcf9ff4a
terminal: render state selection 2025-11-20 22:00:44 -08:00
Mitchell Hashimoto a15f13b962
terminal: renderstate tests 2025-11-20 22:00:43 -08:00
Mitchell Hashimoto 5d58487fb8
terminal: update renderstate to use new assert 2025-11-20 22:00:43 -08:00
Mitchell Hashimoto 6e5e24c3ca
terminal: fix lib-vt test builds 2025-11-20 22:00:43 -08:00
Mitchell Hashimoto cd00a8a2ab
renderer: handle normal non-osc8 links with new render state 2025-11-20 22:00:43 -08:00
Mitchell Hashimoto fa26e9a384
terminal: OSC8 hyperlinks in render state 2025-11-20 22:00:43 -08:00
Mitchell Hashimoto 81142265aa
terminal: renderstate stores pins 2025-11-20 22:00:43 -08:00
Mitchell Hashimoto b8363a8417
terminal: update render state for new dirty tracking 2025-11-20 22:00:43 -08:00
Mitchell Hashimoto cc268694ed
renderer: convert bg extend to new render state 2025-11-20 22:00:43 -08:00
Mitchell Hashimoto 07115ce9a9
terminal: render state contains raw row data 2025-11-20 22:00:43 -08:00
Mitchell Hashimoto d1e87c73fb
terminal: renderstate now has terminal colors 2025-11-20 22:00:43 -08:00
Mitchell Hashimoto ebc8bff8f1
renderer: switch to using render state 2025-11-20 22:00:43 -08:00
Mitchell Hashimoto 9162e71bcc
terminal: render state contains cursor state 2025-11-20 22:00:43 -08:00
Mitchell Hashimoto 2d94cd6bbd
font: update shaper to support new renderstate 2025-11-20 22:00:43 -08:00
Mitchell Hashimoto 29db3e0295
terminal: setup selection state on render state 2025-11-20 22:00:43 -08:00
Mitchell Hashimoto 0e13fd6b73
terminal: add more render state tests 2025-11-20 22:00:42 -08:00
Mitchell Hashimoto 4caefb807c
terminal: fix up some performance issues with render state 2025-11-20 22:00:42 -08:00
Mitchell Hashimoto 5d85f2382e
terminal: render state needs to preserve as much allocation as possible 2025-11-20 22:00:42 -08:00
Mitchell Hashimoto a860801323
terminal: updating render state with tests 2025-11-20 22:00:42 -08:00
Mitchell Hashimoto 3f7cee1e99
terminal: render state fixes for empty cells 2025-11-20 22:00:42 -08:00
Mitchell Hashimoto 040d7794af
renderer: build up render state, rebuild cells with it 2025-11-20 22:00:42 -08:00
Mitchell Hashimoto a66963e3f8
terminal: full redraw state tracking on render state 2025-11-20 22:00:42 -08:00
Mitchell Hashimoto bbbeacab79
terminal: renderstate needs dirty state 2025-11-20 22:00:42 -08:00
Mitchell Hashimoto 60fe4af8ac
terminal: render state style get requires non-default style 2025-11-20 22:00:42 -08:00
Mitchell Hashimoto 789b3dd38d
terminal: RenderState.row_data is a MultiArrayList 2025-11-20 22:00:42 -08:00
Mitchell Hashimoto 7195cab7d3
benchmark: add RenderState to ScreenClone benchmark 2025-11-20 22:00:42 -08:00
Mitchell Hashimoto a90fe1656a
terminal: RenderState 2025-11-20 22:00:42 -08:00
Mitchell Hashimoto 5f3645433c
font: round cell height from line height instead of ceiling (#9648)
This change should give more consistent results between high and low DPI
displays, and generally approximate the authorial intent of the metrics
a little better.

Also changed the cell height adjustment to prioritize the top or bottom
when adjusting by an odd number depending on whether the face is higher
or lower in the cell than it "should" be. This should make it easier for
users who have an issue with a glyph protruding from the cell to adjust
the height and resolve it.
2025-11-20 20:00:26 -10:00
Mitchell Hashimoto ffe4afe538
fix(font/CoreText): make system fallback fonts work again (#9649)
The code that re-creates the font descriptor from scratch using the same
attributes also rubs off the magic dust that makes CoreText not throw a
fit at us for using a "hidden" system font (name prefixed with a dot) by
name when we use the descriptor. This means that a small subset of chars
that only have glyphs in these fallback system fonts like ".CJK Symbols
Fallback HK Regular" and ".DecoType Nastaleeq Urdu UI" would not be able
to be rendered, since when we requested the font with the non-magical
descriptor CoreText would complain in the console and give us Times New
Roman instead.

Using `CTFontDescriptorCreateCopyWithAttributes` to clear the charset
attribute instead of recreating from scratch makes the copy come out
magical, and CoreText lets us instantiate the font from it, yippee!

### ℹ️ For anyone who came to this PR from a search engine rabbit hole
trying to figure this out for your own code:
It seems like if you want to use one of these fonts, you have to avoid
creating a new descriptor from scratch with the name. To create a
descriptor with one of these names that CoreText won't get upset about,
you have to get it in one of these ways (there may be others but these
are ones that definitely work at time of writing):
- Get it from `CTFontCreateForString`(`WithLanguage`) with a character
only provided by that font.
- Get it from `CTFontCreateUIFontForLanguage` or any of the mechanisms
for generally receiving a system font that you don't necessarily have
full control over the exact choice of font with.
- Get it from a collection created with
`CTFontCollectionCreateMatchingFontDescriptors`
- Get it from `CTFontCreateWithGraphicsFont` ... and it seems that for
now, `CGFontCreateWithFontName` lets you use these "hidden" names
without complaining :)

I wouldn't trust any of these methods to necessarily *continue* working
in to the future, since Apple seems to be trying to dissuade
*intentional* use of any particular named hidden system font.
Realistically, the `CreateForString` option is the most likely to stick
around.

If all else fails, check FireFox or Chrome's source code to see how
they're solving it in current year.

And to help it get indexed for those looking for it...
<details>
<summary>CoreText's angry message</summary>

```
CoreText note: Client requested name ".CJKSymbolsFallbackHK-Regular", it will get TimesNewRomanPSMT rather than the intended font. All system UI font access should be through proper APIs such as CTFontCreateUIFontForLanguage() or +[NSFont systemFontOfSize:].
CoreText note: Set a breakpoint on CTFontLogSystemFontNameRequest to debug.
```

</details>
2025-11-20 19:59:34 -10:00
dependabot[bot] 491e724586
build(deps): bump actions/checkout from 5.0.1 to 6.0.0
Bumps [actions/checkout](https://github.com/actions/checkout) from 5.0.1 to 6.0.0.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](93cb6efe18...1af3b93b68)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 6.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-21 00:07:57 +00:00
Mitchell Hashimoto 9955b43e0c
Underline Drawing Fixes (#9654)
Reworked the undercurl and dotted underline to use z2d, the undercurl is
almost identical (slightly better, it has rounded end caps now) but
without the really complicated code, and the dotted underline is greatly
improved since it now draws as anti-aliased dots that are evenly spaced
instead of rectangles that might have uneven spacing at the wrong font
size.

Also fixes #9394 since I added code that makes sure that none of the
underlines is drawn off of the edge of the canvas (the padding only goes
so far, after all).

|Size|Adjustments|Before|After|
|-|-|-|-|
|32|none|<img width="640" height="964" alt="image"
src="https://github.com/user-attachments/assets/20e44d89-5825-496e-b197-bd1ca6c685f7"
/>|<img width="640" height="964" alt="image"
src="https://github.com/user-attachments/assets/b1fb8499-26fd-42ec-8186-1677ab29048b"
/>|
|11|none|<img width="234" height="358" alt="image"
src="https://github.com/user-attachments/assets/5db89f15-128c-4780-826c-a4f59026a0af"
/>|<img width="234" height="358" alt="image"
src="https://github.com/user-attachments/assets/c9a2855a-284e-46d8-b824-0ada2a0ac386"
/>|
|9|underline +8, overline -8|<img width="206" height="294" alt="image"
src="https://github.com/user-attachments/assets/7b3a6d7e-9bb5-4ebb-8881-57878553a47d"
/>|<img width="206" height="294" alt="image"
src="https://github.com/user-attachments/assets/3a8dc97e-7f71-4c6b-821c-49262e6ff9a9"
/>|
2025-11-20 11:09:05 -10:00
Qwerasd 3280cf7d34 font/sprite: rework dotted underline
Draw proper anti-aliased dots now instead of rectangles, thanks to z2d
this is very easy to do, and the results are very nice, no more weird
gaps in dotted underlines if your cell is the wrong number of pixels
across.
2025-11-20 13:36:09 -07:00
Qwerasd 81a6c24186 font/sprite: rework undercurl, fix out of bounds underlines
Use z2d to draw the undercurl instead of the manual raster code we had
before- the code was cool but unnecessarily complicated. Plus z2d lets
us have rounded caps on the undercurl which is neat.

Also make sure we won't draw off the canvas with our underlines-- the
canvas has padding but it's not infinite.
2025-11-20 12:48:39 -07:00
Jon Parise 2d0c0982f5
config: clarify `window-title-font-family` availability (#9651)
Address confusion discussed in #9650
2025-11-20 12:38:37 -05:00
Qwerasd 1fd7606db6 font: round cell height from line height instead of ceiling
This change should give more consistent results between high and low DPI
displays, and generally approximate the authorial intent of the metrics
a little better.

Also changed the cell height adjustment to prioritize the top or bottom
when adjusting by an odd number depending on whether the face is higher
or lower in the cell than it "should" be. This should make it easier for
users who have an issue with a glyph protruding from the cell to adjust
the height and resolve it.
2025-11-20 10:16:11 -07:00
Daniel Wennberg c937276976 Clarify window-title-font-family availability 2025-11-20 08:57:46 -08:00
Jeffrey C. Ollie 8386159764
nix vm tests: add test for ssh-terminfo shell integration feature 2025-11-20 08:30:09 -06:00
Jeffrey C. Ollie 516c416fa4
nix vm tests: fix ssh command 2025-11-20 08:30:09 -06:00
Jeffrey C. Ollie f26a6b949c
nix vm tests: sync ghostty user with other tests 2025-11-20 08:30:09 -06:00
Jeffrey C. Ollie debec946da
nix vm tests: refactor to make gnome vm node builder reusable 2025-11-20 08:30:08 -06:00
Jeffrey C. Ollie c77bbe6d7e
nix vms: make base vm more suitable for tests 2025-11-20 08:30:08 -06:00
Jeffrey C. Ollie f9d6a6d56f
nix vm tests: update contributors documentation 2025-11-20 08:30:08 -06:00
Jeffrey C. Ollie ca8313570c
nix: add vm-based integration tests 2025-11-20 08:30:08 -06:00
Jeffrey C. Ollie 10fcd9111c
nix: make 'nix flake check' happy 2025-11-20 08:30:08 -06:00
Jeffrey C. Ollie 7ba88a7178
synthetic: make bytes generation more flexible 2025-11-20 08:29:36 -06:00
Jeffrey C. Ollie f1ab3b20ae
gtk: support GTK 4.20 media queries in runtime & custom css 2025-11-20 08:28:26 -06:00
Jeffrey C. Ollie 701a2a1e05
gtk: update nixpkgs and zig-gobject for Gnome 49 2025-11-20 08:28:25 -06:00
Jon Parise a4e65f02b4
fish: add descriptions to fish shell completions (#9551)
Add descriptions to fish shell completions 

Claude Code used to understand the codebase and reason through the edge
cases (several iterations)

- Using first sentence from the Config to add description for each
config, even if sentence spans few lines
- Several options can share the same description, code doesn't duplicate
description, see screenshot in the posted issue thread below

Fixes [#9531](https://github.com/ghostty-org/ghostty/issues/9531)
2025-11-20 09:15:35 -05:00
Qwerasd a347406137 fix(font/CoreText): make system fallback fonts work again
The code that re-creates the font descriptor from scratch using the same
attributes also rubs off the magic dust that makes CoreText not throw a
fit at us for using a "hidden" system font (name prefixed with a dot) by
name when we use the descriptor. This means that a small subset of chars
that only have glyphs in these fallback system fonts like ".CJK Symbols
Fallback HK Regular" and ".DecoType Nastaleeq Urdu UI" would not be able
to be rendered, since when we requested the font with the non-magical
descriptor CoreText would complain in the console and give us Times New
Roman instead.

Using `CTFontDescriptorCreateCopyWithAttributes` to clear the charset
attribute instead of recreating from scratch makes the copy come out
magical, and CoreText lets us instantiate the font from it, yippee!
2025-11-19 22:03:37 -07:00
Qwerasd aa2f31179b
CoreText: Apply subpixel horizontal alignment also when cell width is less than advance (#9646)
Follow-up to #9432 to ensure that subpixel horizontal alignment is
consistent whether `cell_width = @round(face_width)` rounds up or down.
2025-11-19 21:51:15 -07:00
Leah Amelia Chen 81647692ba
build/blueprint: explicitly mention git vs tarballs (#9632) 2025-11-20 10:47:44 +08:00
Daniel Wennberg 42c1345238 CoreText: Apply subpixel halign also when cell width < advance 2025-11-19 15:32:29 -08:00
Mitchell Hashimoto 410d79b151
Assorted Performance Enhancements (#9645)
A whole bunch of optimizations in hot paths in the IO processing areas
of our code (well, one of them covers everything). I validated that each
commit either improved one or more of our vtebench results, or improved
the time it takes to process 2 years worth (2.4GB) of data from
asciinema.

## vtebench
<img width="1278" height="903" alt="image"
src="https://github.com/user-attachments/assets/bad46777-4606-4870-b7d7-8df0c4bb3b39"
/>

(I decided to patch vtebench to report in nanoseconds instead of
milliseconds since clearly it was not designed for a machine as fast as
mine. Nanoseconds gives much more useful results when the numbers are
this low.)

Do note the *slight* regression in the "unicode" test, this is probably
because I added a branch hint in `Terminal.print` in order to optimize
for printing narrow characters, since they make up the vast majority of
characters typically printed in the terminal, but the vtebench "unicode"
test is pretty much all wide characters.

This shouldn't have a negative effect on users of CJK languages since
it's a *very* slight reduction in speed and they will still be printing
many narrow characters, especially in TUIs; spaces, box drawing
characters, symbols, punctuation, etc.

## asciinema processing
I wrote a program that uses libghostty to push 2 years worth (2.4GB) of
data from publicly uploaded asciinema recordings in to the terminal as
fast as possible- since it's just libghostty, there's no renderer
overhead happening, it's just the core terminal emulation, effectively
everything that io-reader thread does if it didn't have wait for the
renderer ever.

On main, this took roughly 26.1–26.7 seconds to process, on this branch
it takes just 18.4–18.6 seconds, that's a ~30% improvement in raw IO
processing speed when processing real world data!

## Summary of changes
In order of commits:
- Fixed a bug that I hit when trying to have Ghostty process all that
asciinema data, in certain bad cases it was possible to accidentally
insert the `0` hyperlink ID in to a page, which would then cause a
lockup in ReleaseFast mode when trying to clone that page since the
string alloc would try to iterate `1..0` to allocate 0 chunks.
- I noticed in profiling Ghostty that `std.debug.assert` was showing up
in the profile, which it should not have been since its doc comment
promises that it will be optimized out in ReleaseFast- but evidently
something is wrong with Zig, or that comment's promise is based on an
expectation from LLVM that it fails to meet - but either way, by
replacing all uses of `assert` with a version that is explicitly marked
`inline`, that function call overhead in tight loops and hotpaths is
avoided. This change alone accounts for like a third of the IO
processing time improvement, though it had minimal impact on vtebench
scores.
- I optimized the SGR parser somewhat by adding branch hints and
removing the `.reset_underline` action, replacing it with `.{ .underline
= .none }`.
- Gated a somewhat expensive assert in RefCountedSet behind a runtime
safety check.
- Improved the performance of `Style.eql` and `Style.hash` since these
are hot functions, called extremely frequently since adding styles to
the style set is a very common operation. Achieved this by making `eql`
less generic - explicitly comparing each part of the style rather than
looping over fields - and ordering checks from most likely to differ to
least likely to differ so that differences can be found as soon as
possible; and changed the hash from xxhash to simply folding the packed
struct down to 64 bits and then using `std.hash.int`. Also manually
inlined the code from `std.meta.activeTag` in `Packed.fromStyle`, since
profiling showed it in the callstack and it's a single cast so it really
should not have the function call overhead.
- Explicitly marked some trivial functions as inline, the optimizer
would already have been doing this (probably) but doing it explicitly
gives the optimizer more time to spend on other things. Added cold
branch hints to "should be impossible" and error-returning paths that
should be very rare, and unlikely branch hints to a lot of "invalid"
paths- to optimize for receiving valid data.
- Removed a branch in the parser csi param action, just unconditionally
multiply by 10 before adding digit value, even if it's the first digit.
This codepath is rarely hit since we have a fast path for this in the
stream code, but the stream code already has this optimization so I just
copied it over.
- `CharsetState.charsets` used to be an `EnumArray`, but the
layout/access logic for that was less-than-ideal, and the access
functions were not inlining-- and these are very hot since we access
this for every single print, so I wrote a bespoke struct to hold that
info instead, gained a couple percent of IO perf with that.
- Added branch hints based on the data I derived from the asciinema
dump, which gave big boost to vtebench results, especially for the
cursor movement and dense cells tests (which makes sense, since cursor
movement and setting attributes both got `likely` hints :p) -- data at
https://github.com/qwerasd205/asciinema-stats
- This is probably the most invasive change in this PR: I removed the
dirty bitset from `Page` and replaced it with a dirty flag on each row,
for the majority of operations this is faster to write, since the row
being dirtied is probably already loaded and probably will be written to
for other changes as well. This gave a couple percent IO processing
improvement. The only exception is scrolling-type operations, which are
extremely efficient by just moving rows around with a single memmov, so
looping through the rows to mark each dirty slows them down, and indeed
after this change the scrolling benchmarks in vtebench regressed,
*however*...
- Added a "full page dirty" flag on `Page`, which is set when an
operation is performed that dirties most or all the rows in the page,
which is used for scrolling-type operations. This *does* make the dirty
tracking slightly less precise for these operations, but with the
caching and stuff we do in the renderer, I don't think `rebuildCells` is
a bottleneck, so rebuilding a few extra rows shouldn't hurt. After this
change, all the scrolling benchmarks in vtebench improved drastically.
- Tiny micro-improvements to RefCountedSet; streamlined the control flow
in `lookup`, added an unlikely branch hint in `insert` for the branch
that resurrects dead items since dead items aren't that common.
- Improve SGR parser performance again by using `@call(.always_inline`
to explicitly inline calls to `StaticBitSet.isSet` (for the separator
list), since I noticed they weren't being inlined, causing function call
overhead in a hotpath.
- I noticed that `clearGrapheme` and `clearHyperlink` would check every
cell in the row after they were done in order to update the
`grapheme`/`hyperlink` flag on the row if there were none left, which
isn't great since `clearCells` called these functions for multiple cells
in the same row back-to-back, which leads to a ton of excess work. I
separated the flag updating parts of these functions out and called them
only if necessary (if the cells being cleared were the full row then the
flag could unconditionally be set to false) and only after all the cells
were cleared. This gave a nice improvement to IO processing since
clearCells is evidently a very hot function.
- Removed inline annotations on `Page.clearGrapheme` and
`Page.clearHyperlink` in favor of inlining directly at the one callsite
that benefited from inlining, this improved IO processing speed.
- Inlined trivial function `Charset.table`.
- Inlined `size.getOffset` and `size.intFromBase` as they are both
trivial pointer math that often benefits from surrounding context.

---

If you'd like me to separate out the trivial improvements (branch hints,
inline annotations, 1-line changes) from the functionality-changing ones
(pretty much just the changes to dirty tracking), just let me know!
2025-11-19 12:53:48 -10:00
Qwerasd d2316ee718 perf: inline size.getOffset and intFromBase 2025-11-19 15:17:05 -07:00
Qwerasd e799023b89 perf: inline trivial charset lookup 2025-11-19 15:17:05 -07:00
Qwerasd 7d89aa764d perf: remove some overzealous inline annotations
These were actually hurting performance lol, except in the places where
I added the `.always_inline` calls- for some reason if these functions
aren't inlined there it really messes up the top region scrolling
benchmark in vtebench and I'm not entirely certain why...
2025-11-19 15:17:05 -07:00
Qwerasd 3b80f72dac
Fix horizontal glyph spacing on normal-DPI monitors (#9432)
This PR partially addresses #4504 with a one-liner, all feedback is very
welcome.

### AI disclaimer
I used Claude Code to help navigate the various layers of the rendering
stack, to instrument a ton of intermediate now-deleted log statements,
and ultimately to identify and fix this bug. I directed it
conversationally, gave it experiments to run, audited all of its work,
threw most of it out, and finally landed on this extremely small and
simple change that fixes the issue _for me_ but I think for a lot of
other cases as well. The fix ended up being small, so hopefully it's
easy to review and discuss.

Details:

#  Fix horizontal glyph spacing on non-Retina displays

On external monitors (1.0x scale, 72 DPI), text had excessive horizontal
spacing between glyphs. The issue was less noticeable on Retina displays
(2.0x scale, 144 DPI) due to higher pixel density, but the proportional
spacing error was identical.

## Before
Background is ghostty 1.2.3 from homebrew, foregreound is iTerm2:
<img width="862" height="938" alt="Screenshot 2025-10-31 at 3 04 47 PM"
src="https://github.com/user-attachments/assets/feff5279-05cc-4008-b2f5-8ea3b4d6d14b"
/>

## After
Background is ghostty tip + this change, foreground is iTerm2:
<img width="659" height="774" alt="Screenshot 2025-10-31 at 3 00 42 PM"
src="https://github.com/user-attachments/assets/702dc7f8-bb46-43ec-8156-f69d003e8a37"
/>

(my iTerm2 has some custom thickening / brightening you can see; that's
not a part of this change)

## Root Cause

The metrics calculation in Metrics.zig used `@ceil()` to round the cell
width from CoreText's glyph measurements, which created a mismatch
between cell width (which determines glyph positions) and the actual
glyph advances.

At 72 DPI with a 12pt font:
- CoreText returns glyph advance: 7.224609375 pixels
- Cell width was ceiled to: 8 pixels
- Gap per character: 0.78 pixels (~10.8% error)

At 144 DPI with the same font:
- CoreText returns glyph advance: 14.44921875 pixels (exactly 2x)
- Cell width was ceiled to: 15 pixels
- Gap per character: 0.55 pixels (~3.8% error)

The error at high DPI is much better than at low DPI, since the absolute
error is always no more than 1px.

##  Fix

Changed `@ceil(face_width)` to `@round(face_width)`. This makes cell
width match the glyph advances better, reducing the error to at most
0.5px:
- 72 DPI: round(7.22) = 7
- 144 DPI: round(14.45) = 14

Height continues using `@ceil()` since vertical space can be slightly
larger without visual issues, but... should it? I'm not sure; this is a
good topic for discussion.
2025-11-19 11:38:17 -07:00
Qwerasd 801a399f41 clarify comment 2025-11-19 11:10:24 -07:00
Charles Nicholson 45b8ce842e Cell width calculation from ceil to round, fix horizontal spacing 2025-11-19 10:56:29 -07:00
Mitchell Hashimoto 8d8798bc79
renderer: minor log update, all commented 2025-11-19 06:21:53 -10:00
LN Liberda 3e5c4590da Add system integration for highway 2025-11-19 14:25:35 +01:00
Qwerasd 0ce3d0bd07 remove useless code
the style ID is reset up above
2025-11-18 21:03:42 -07:00
Qwerasd f9e245ab7f perf: separate clearing graphemes/hyperlinks from updating row flag
This improves the `clearCells` function since it only has to update once
after clearing all of the individual cells, or not at all if the whole
row was cleared since then it knows for sure that it cleared them all.

This also makes it so that the row style flag is properly tracked when
cells are cleared but not the whole row.
2025-11-18 21:03:42 -07:00
Qwerasd 5ffa7f8f45 perf: inline calls to StaticBitSet.isSet in sgr parser 2025-11-18 20:46:00 -07:00
Qwerasd d14b4cf068 perf: streamline RefCountedSet lookup
+ add branch hint to insert
2025-11-18 20:46:00 -07:00
Qwerasd 81eda848cb perf: add full-page dirty flag
Avoids overhead of marking many rows dirty in functions that manipulate
row positions which dirties all or most of the page.
2025-11-18 20:46:00 -07:00
Qwerasd 30472c0077 perf: replace dirty bitset with a flag on each row
This is much faster for most operations since the row is often already
loaded when we have to mark it as dirty.
2025-11-18 20:46:00 -07:00
Qwerasd 212598ed66 perf: add branch hints based on real world data
+ move stream ESC state entry outside of `nextNonUtf8`
2025-11-18 20:43:31 -07:00
Qwerasd 5744fb042c perf: replace charset EnumArray with bespoke struct 2025-11-18 20:40:26 -07:00
Qwerasd 14771e5009 perf: avoid branch in parser csi param action 2025-11-18 20:40:26 -07:00
Qwerasd 3e8d94bb1c perf: misc inlines and branch hints
Inlined trivial functions, added cold branch hints to error paths, added
likely branch hints to common paths
2025-11-18 20:40:26 -07:00
Leah Amelia Chen 5a82e1b119
build/blueprint: explicitly mention git vs tarballs
I am so sick and tired of people complaining that the build instructions
on the website are wrong when they clearly haven't realized the difference
between Git-based and tarball-based builds, so here's the extra work to
make sure people actually realize that
2025-11-18 23:33:15 +08:00
Mitchell Hashimoto 1f1a5e9c3f
build(deps): bump actions/checkout from 5.0.0 to 5.0.1 (#9626)
Bumps [actions/checkout](https://github.com/actions/checkout) from 5.0.0
to 5.0.1.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/checkout/releases">actions/checkout's
releases</a>.</em></p>
<blockquote>
<h2>v5.0.1</h2>
<h2>What's Changed</h2>
<ul>
<li>Port v6 cleanup to v5 by <a
href="https://github.com/ericsciple"><code>@​ericsciple</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2301">actions/checkout#2301</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/checkout/compare/v5...v5.0.1">https://github.com/actions/checkout/compare/v5...v5.0.1</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="93cb6efe18"><code>93cb6ef</code></a>
Cleanup actions/checkout@v6 auth style (<a
href="https://redirect.github.com/actions/checkout/issues/2301">#2301</a>)</li>
<li>See full diff in <a
href="08c6903cd8...93cb6efe18">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=5.0.0&new-version=5.0.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-11-18 05:02:03 -10:00
Mitchell Hashimoto 949759f4b0
build(deps): bump cachix/install-nix-action from 31.8.3 to 31.8.4 (#9627)
Bumps
[cachix/install-nix-action](https://github.com/cachix/install-nix-action)
from 31.8.3 to 31.8.4.
<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.8.4</h2>
<h2>What's Changed</h2>
<ul>
<li>nix: 2.32.3 -&gt; 2.32.4 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/261">cachix/install-nix-action#261</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/cachix/install-nix-action/compare/v31.8.3...v31.8.4">https://github.com/cachix/install-nix-action/compare/v31.8.3...v31.8.4</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="0b0e072294"><code>0b0e072</code></a>
Merge pull request <a
href="https://redirect.github.com/cachix/install-nix-action/issues/261">#261</a>
from cachix/create-pull-request/patch</li>
<li><a
href="16d2e3294d"><code>16d2e32</code></a>
nix: 2.32.3 -&gt; 2.32.4</li>
<li>See full diff in <a
href="7ec16f2c06...0b0e072294">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.8.3&new-version=31.8.4)](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-11-18 05:01:50 -10:00
Qwerasd 58c26957b4 perf: improve style hash and eql fns 2025-11-17 21:32:48 -07:00
Qwerasd 9e754f9939 perf: fix accidental overhead in refcountedset 2025-11-17 21:31:40 -07:00
Denys Zhak e0007a66e7 feat: add sts.testing for comparison, test getDescription 2025-11-18 01:29:59 +01:00
dependabot[bot] 3264ff8291
build(deps): bump cachix/install-nix-action from 31.8.3 to 31.8.4
Bumps [cachix/install-nix-action](https://github.com/cachix/install-nix-action) from 31.8.3 to 31.8.4.
- [Release notes](https://github.com/cachix/install-nix-action/releases)
- [Changelog](https://github.com/cachix/install-nix-action/blob/master/RELEASE.md)
- [Commits](7ec16f2c06...0b0e072294)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-18 00:09:12 +00:00
dependabot[bot] 5c566fa32c
build(deps): bump actions/checkout from 5.0.0 to 5.0.1
Bumps [actions/checkout](https://github.com/actions/checkout) from 5.0.0 to 5.0.1.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](08c6903cd8...93cb6efe18)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 5.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-18 00:09:02 +00:00
Qwerasd 9ab9bc8e19 perf: small sgr parser improvements 2025-11-17 13:17:31 -07:00
Qwerasd 6d5b4a3426 perf: replace `std.debug.assert` with inlined version
See doc comment in `quirks.zig` for reasoning
2025-11-17 12:13:56 -07:00
Mitchell Hashimoto 9831709fca
macOS: match scroller’s appearance with surface’s background (#9619)
Currently, the scroller's appearance is the same as the window's.

So, with the light system appearance and the following config:

```
window-theme = system
macos-titlebar-style = native
```

It's hard to see where the scroller is. This pr changes the
scroller’s(ScrollView) appearance to match the surface's background
colour, so it's always easier to find.

> Changing `verticalScroller?.appearance` doesn't seem to work

<img width="601" height="630" alt="image"
src="https://github.com/user-attachments/assets/9dc18439-9dcb-479a-802a-de439b7dc9d8"
/>
2025-11-17 09:25:39 -08:00
Lukas 2f1427f529
macOS: match scroller’s appearance with surface’s background 2025-11-17 18:20:24 +01:00
Mitchell Hashimoto 3ff0cddee8
benchmark: add screen-clone for benchmarking the Screen.clone method (#9624)
This adds a benchmark and some test coverage for a `screen-clone`
benchmark. This benchmarks the screen cloning which is a hot spot for
lock contention for the renderer + IO threads. I wasn't able to
meaningfully speed this up, but still want to commit this benchmark.
2025-11-17 08:51:27 -08:00
Mitchell Hashimoto 2f49e0c902
remove screenclone test cause it leaks memory on purpose 2025-11-17 06:42:00 -10:00
Mitchell Hashimoto 09d41fd4af
terminal: page tests for full clone 2025-11-17 06:10:38 -10:00
Mitchell Hashimoto 9a46397b59
benchmark: screen clone 2025-11-17 05:08:19 -10:00
Mitchell Hashimoto b7be27b1f5
fix: ColorList.clone not cloning colors_c (#9613)
### Problem
Custom icon configuration (`macos-icon = custom-style` with
`macos-icon-screen-color`) stopped working, reverting to the default
icon.

### Root cause
The `ColorList.clone()` method only cloned the `colors` array but not
the `colors_c` array. The Swift code reads from `colors_c` via the C API
(`ghostty_config_get`), so when configs were cloned, the C-accessible
color list was empty.

### Why it broke
This bug was introduced in the original implementation in 29929a473 (Dec
2024), but remained dormant until commit f60bdb0fa (Sep 19, 2025), which
moved the icon-setting `switch` statement into `syncAppearance()`. Since
`syncAppearance()` is called with cloned configs from
`ghosttyConfigDidChange()` (which receives cloned configs from
`Ghostty.App.swift:1639`), the icon code now ran with cloned configs
that had empty `colors_c` arrays.

### Fix
Clone both arrays in `ColorList.clone()`:
```zig
.colors = try self.colors.clone(alloc),
.colors_c = try self.colors_c.clone(alloc),  // Added
```

### Testing
- Added ColorList.test.clone test case that verifies both colors and
colors_c arrays are properly cloned
- Verified test fails without the fix (expected 3 colors_c items, found
0)
- Verified test passes with the fix
- Confirmed custom icon now persists correctly with both initial config
load and subsequent config change notifications

### Discussion
I opened a discussion to report this
([9616](https://github.com/ghostty-org/ghostty/discussions/9616)) that
this PR will resolve.

> [!NOTE]
> **LLM Usage Disclosure** 
> This bug was investigated and debugged with assistance from Claude
Code. The root cause analysis and fix were developed through interactive
debugging.
2025-11-17 06:41:03 -08:00
Jake Nelson 243d32c82a fix: ColorList.clone not cloning colors_c 2025-11-17 15:59:53 +11:00
Qwerasd 995a7377c1 fix(terminal): avoid lockup caused by 0-length hyperlink
This could cause a 0-length hyperlink to be present in the screen,
which, in ReleaseFast, causes a lockup as the string alloc tries to
iterate `1..0` to allocate 0 chunks.
2025-11-16 19:38:46 -07:00
Denys Zhak c5ada505af feat: add test for getDescription 2025-11-17 01:22:33 +01:00
Mitchell Hashimoto bee5875351
Miscellaneous Bugfixes (#9609)
I encountered these bugs while trying to benchmark Ghostty for
performance work.

- Tmux control mode parsing would start accessing deallocated memory
after entering the "broken" state, and worse yet, would cause a
double-free once it was supposed to be deinited.
- Despite our best efforts, CoreText can still produce non-monotonic
(non-ltr) runs. Our renderer code relies on monotonic ltr ordering so in
the rare case where this happens we just sort the buffer before
returning it.
- C1 (8-bit) controls can be executed in certain parser states, so we
need to handle them in the stream's `execute` function. Luckily this was
pretty straightforward since all C1 controls are equivalent to `ESC`
followed by `C1 - 0x40`.
- `Terminal.Screen`'s `cursorScrollDown` function could cause memory
corruption because of `eraseRow` moving the cursor's tracked pin to a
different page. In fixing this, I actually reduced the complexity of
that codepath.
- **Bonus!** Added a nice helper function to `Offset.Slice` so that you
can just do `offset_slice.slice()` instead of
`offset_slice.offset.ptr(base)[0..offset_slice.len]`. Much more
readable.

### `vtebench` before/after
<img width="984" height="691" alt="image"
src="https://github.com/user-attachments/assets/ef20dcc5-d611-4763-9107-355d715a6c0b"
/>
Doesn't seem like any of these changes caused a performance regression.
2025-11-16 12:03:30 -08:00
Qwerasd 9e44c9c956 fix(terminal): avoid memory corruption in `cursorScrollDown`
It was previously possible for `eraseRow` to move the cursor pin to a
different page, and then the call to `cursorChangePin` would try to free
the cursor style from that page even though that's not the page it
belongs to, which creates memory corruption in release modes and
integrity violations or assertions in debug mode.

As a bonus, this should actually be faster this way than the old code,
since it avoids needless work that `cursorChangePin` otherwise does.
2025-11-16 12:39:10 -07:00
Qwerasd bb2455b3fc fix(terminal/stream): handle executing C1 controls
These can be unambiguously invoked in certain parser states, and as such
we need to handle them. In real world use they are extremely rare, hence
the branch hint. Without this, we get illegal behavior by trying to cast
the value to the 7-bit C0 enum.
2025-11-16 12:39:10 -07:00
Qwerasd 00c2216fe1 style: add Offset.Slice.slice helper fn
Makes code that interacts with these so much cleaner
2025-11-16 12:39:10 -07:00
Qwerasd 985e1a3cea test(shaper/coretext): test non-monotonic CoreText output 2025-11-16 12:39:10 -07:00
Qwerasd 712cc9e55c fix(shaper/coretext): handle non-monotonic runs by sorting 2025-11-16 12:39:10 -07:00
Qwerasd 0a7da32c71 fix: drop tmux control parsing immediately if broken 2025-11-16 11:28:04 -07:00
Mitchell Hashimoto 711e10d930
macOS: Fix dictation icon's position while speaking (#9605)
Fixes #8493.

There is still an "overflow" issue since preedit doesn't wrap right now,
but that's kind of off-topic.


https://github.com/user-attachments/assets/a7ae6018-76c7-4d16-9a9b-e0167072d910
2025-11-16 06:58:03 -08:00
Lukas 011fc77caa
macOS: Fix dictation icon's position while speaking 2025-11-16 12:17:31 +01:00
Mitchell Hashimoto b76203bbb9
Update iTerm2 colorschemes (#9603)
Upstream release:
https://github.com/mbadolato/iTerm2-Color-Schemes/releases/tag/release-20251110-150531-d5f3d53
2025-11-15 19:50:41 -08:00
Mitchell Hashimoto 4c0d7379db
Search Thread (#9602)
Progress towards #189 

## Search Thread

This completes an initial implementation of the search thread. This is a
separate thread that manages a terminal search operation, triggering
event callbacks for various scenarios. The performance goal of the
search thread is to minimize time spent within the critical area of the
terminal lock while making forward progress on search outside of that.

The search thread sends two messages back to the caller right now:

- Total matches: sent continuously as new matches are found, just a
number
- Viewport matches: a list of `Selection` structures spanning the
current viewport of matches within the visible viewport. Sent whenever
the viewport changes (location or content).

I think that's enough to build a rudimentary search UI.

For this initial implementation, the search also relies on a "refresh
timer" which trigger every 24ms (40 FPS) to grab the lock and look for
any reconciliation that needs to happen: viewport moved, active screen
changed, active area changed, etc. This is a total guess and is
arbitrary currently. The value should be tuned to balance responsiveness
and IO throughput (lock-holding). I actually suspect this may be too
frequent right now.

A TODO is noted for the future to pause the refresh timer when the
terminal being search isn't focused. We'll have to do that before
shipping search because the way its built right now we will definitely
consume unnecessary CPU while unfocused. But only while search is
active.

## `ViewportSearch`

I also determined the need for what is called the `ViewportSearch`
layer. This is similar to `ActiveSearch` in that it throws away and
re-searches an area, but is tuned towards efficiently detecting viewport
changes. I found its more efficient to continuously research the visible
viewport than to hunt for those matches within the cached ScreenSearch
results, which can be very large.

## Future

Next up we need to hook up the search thread to some keybindings to
start and stop the search so we can then trigger those from our apprts
(GUIs).

I highly suspect this is going to expose some major performance issues
(overly active message sending being the likely culprit) that we can fix
up in the search thread thereafter. Up until this point we can only run
this stuff in isolation in unit tests which is good for testing
correctness but difficult for testing resource usage.

There are some written TODOs in the Thread.zig file in this PR. I may
address some of them before merging, since I think a couple are pretty
obvious performance gotchas.
2025-11-15 19:50:28 -08:00
Mitchell Hashimoto 79af2378d2
terminal: unify all notification sending into the notify command 2025-11-15 19:48:09 -08:00
mitchellh ead01e8ffd deps: Update iTerm2 color schemes 2025-11-16 00:15:33 +00:00
Mitchell Hashimoto caf5040a6d
macOS: find correct tab bar when in fullscreen (#9596)
Fixes #9597
2025-11-15 14:13:30 -08:00
Mitchell Hashimoto 90a6ea7aa5
terminal: note some search thread TODOs we can address later 2025-11-15 14:03:27 -08:00
Mitchell Hashimoto f0af63db15
terminal: search thread refresh timer to reconcile state 2025-11-15 13:43:26 -08:00
Mitchell Hashimoto acab8c90a2
terminal: search.Thread searches viewport and notifies viewport results 2025-11-15 13:30:32 -08:00
Mitchell Hashimoto 99d47a4627
terminal: viewport search 2025-11-15 13:00:58 -08:00
Mitchell Hashimoto 05366485da
macOS: fix misplaced frame modifier (#9598)
As per #9504, this was supposed to be on `ZStack`, not on the overlay.
See also #9503. I cherry-picked it in the wrong place before.
2025-11-15 06:37:55 -08:00
Lukas 8d1dd332c6
macOS: fix misplaced frame modifier
As per #9504, this was supposed to be on `ZStack`, not on the overlay. See also #9503. I cherry-picked it in the wrong place before.
2025-11-15 10:14:43 +01:00
Lukas b124b78313
macOS: find correct tab bar when in fullscreen
Fixes #9593
2025-11-15 08:10:05 +01:00
Mitchell Hashimoto bfa397b196
terminal: search thread active screen reconciliation loop 2025-11-14 21:24:18 -08:00
Mitchell Hashimoto 1867928b84
terminal: search thread search ticking 2025-11-14 21:05:05 -08:00
Mitchell Hashimoto d1ad32eadd
terminal: search.Thread starting search loop 2025-11-14 17:04:34 -08:00
Mitchell Hashimoto 19dfc0aa98
terminal: search.Thread more boilerplate, test starting 2025-11-14 16:29:45 -08:00
Mitchell Hashimoto 466a004c39
lib-vt: export stream.Action for custom streams (#9595) 2025-11-14 16:06:59 -08:00
Mitchell Hashimoto de545eeae1
lib-vt: export stream.Action for custom streams 2025-11-14 16:01:57 -08:00
Mitchell Hashimoto 7cc8ea7efb
terminal: change primary/alt screens to use a ScreenSet, stable pointers (#9594)
This PR changes our primary/alt screen tracking from being by-value
fields that are copied during switch to heap-allocated pointers that are
stable. This is motivated now by #189 since our search thread needs a
stable screen pointer, but this will also help us in the future with our
future N-screens proposal I have.

Also, as a nice bonus, alt screen memory is now initialized on demand
when you first enter alt-screen, so this saves a few MB of memory for a
new terminal if you never use alt screen!

This is something I've wanted to do for a veryyyyyy long time, but the
annoyance of the task really held me back. I finally pushed through and
did this with the help of some AI agents for the rote tasks (renaming
stuff).
2025-11-14 16:00:47 -08:00
Mitchell Hashimoto 2452026ff3
terminal: kitty limits only if kitty graphics being built 2025-11-14 15:53:00 -08:00
Mitchell Hashimoto 4ba00dbe89
fix harfbuzz 2025-11-14 15:48:06 -08:00
Mitchell Hashimoto 580f9f057b
convert t.screen to t.screens.active 2025-11-14 15:40:31 -08:00
Mitchell Hashimoto 3aff5f0aff
ScreenSet 2025-11-14 15:08:10 -08:00
Mitchell Hashimoto 368f4f565a
terminal: Screen opts is a structure 2025-11-14 14:10:37 -08:00
Mitchell Hashimoto a5a914c2b8
Considerably more search internals (#9585)
Chugging along towards #189

This adds significantly more internal work for searching. A long time
ago, I added #2885 which had a hint of what I was thinking of. This
simultaneously builds on this and changes direction.

The change of direction is that instead of making PageList fully
concurrency safe and having a search thread access it concurrently, I'm
now making an architectural shift where our search thread will grab the
big lock (blocking all IO/rendering), but with the bet that we can make
our critical areas small enough and time them well enough that the
performance hit while actively searching will be minimal. **Results yet
to be seen, but the path to implement this is much, much simpler.**

## Rearchitecting Search

To that end, this PR builds on #2885 by making `src/terminal/search` and
entire package (rather than a single file).

```mermaid
graph TB
    subgraph Layer5 ["<b>Layer 5: Thread Orchestration</b>"]
        Thread["<b>Thread</b><br/>━━━━━━━━━━━━━━━━━━━━━<br/>• MPSC queue management<br/>• libxev event loop<br/>• Message handling<br/>• Surface mailbox communication<br/>• Forward progress coordination"]
    end
    
    subgraph Layer4 ["<b>Layer 4: Screen Coordination</b>"]
        ScreenSearch["<b>ScreenSearch</b><br/>━━━━━━━━━━━━━━━━━━━━━<br/>• State machine (tick + feed)<br/>• Result caching<br/>• Per-screen (alt/primary)<br/>• Composes Active + History search<br/>• Interrupt handling"]
    end
    
    subgraph Layer3 ["<b>Layer 3: Domain-Specific Search</b>"]
        ActiveSearch["<b>ActiveSearch</b><br/>━━━━━━━━━━━━━━━━━━━━━<br/>• Active area only<br/>• Invalidate & re-search<br/>• Small, volatile data"]
        
        PageListSearch["<b>PageListSearch</b><br/>━━━━━━━━━━━━━━━━━━━━━<br/>• History search (reverse order)<br/>• Separated tick/feed ops<br/>• Immutable PageList assumption<br/>• Garbage pin detection"]
    end
    
    subgraph Layer2 ["<b>Layer 1: Primitive Operations</b>"]
        SlidingWindow["<b>SlidingWindow</b><br/>━━━━━━━━━━━━━━━━━━━━━<br/>• Manual linked list node management<br/>• Circular buffer maintenance<br/>• Zero-allocation search<br/>• Match yielding<br/>• Page boundary handling"]
    end
    
    Thread --> ScreenSearch
    ScreenSearch --> ActiveSearch
    ScreenSearch --> PageListSearch
    ActiveSearch --> SlidingWindow
    PageListSearch --> SlidingWindow
    
    classDef layer5 fill:#0a0a0a,stroke:#ff0066,stroke-width:3px,color:#ffffff
    classDef layer4 fill:#0f0f0f,stroke:#ff6600,stroke-width:3px,color:#ffffff
    classDef layer3 fill:#141414,stroke:#ffaa00,stroke-width:3px,color:#ffffff
    classDef layer2 fill:#1a1a1a,stroke:#00ff00,stroke-width:3px,color:#ffffff
    
    class Thread layer5
    class ScreenSearch layer4
    class ActiveSearch,PageListSearch layer3
    class SlidingWindow layer2
    
    style Layer5 fill:#050505,stroke:#ff0066,stroke-width:2px,color:#ffffff
    style Layer4 fill:#080808,stroke:#ff6600,stroke-width:2px,color:#ffffff
    style Layer3 fill:#0c0c0c,stroke:#ffaa00,stroke-width:2px,color:#ffffff
    style Layer2 fill:#101010,stroke:#00ff00,stroke-width:2px,color:#ffffff
```

Within the package, we have composable layers that let us test each
point:

- `SlidingWindow`: The lowest layer, the caller manually adds linked
list page nodes and it maintains a sliding window we search over,
yielding results without allocation (besides the circular buffers to
maintain the sliding window).
- `PageListSearch`: Searches a PageList structure in reverse order
(assumption: more recent matches are more valuable than older), but
separates out the `tick` (search, but no PageList access) and `feed`
(PageList access, prep data for search but don't search) operations.
This lets us `feed` in a critical area and `tick` outside. **This
assumes an immutable PageList, so this is for history.**
- `ActiveSearch`: Searches only the active area of a PageList. The
expectation is that the active area changes much more regularly, but it
is also very small (relative to scrollback). Throws away and re-searches
the active area as necessary.
- `ScreenSearch`: Composes the previous three components to coordinate
searching an active terminal screen. You'd have one of these per screen
(alt vs primary). This also caches results unlike the other components,
with the expectation that the caller will revisit the results as screens
change (so if you switch from neovim back to your shell and vice versa
with a search active, it won't start over).
- `Thread`: A dedicated search thread that will receive messages via
MPSC queues while managing the forward progress of a `ScreenSearch` and
sending matches back to the surface mailbox for apprt rendering. **The
thread component is not functional, just boilerplate, in this PR.**

ScreenSearch is a state machine that moves in an iterative `tick` +
`feed` fashion. This will let us "interrupt" the search with updates on
the search thread (read our mailbox via libxev loops for example) and
will let us minimize critical areas with locks (only `feed`).

Each component is significantly unit tested, especially around page
boundary cases. Given the complexity, there is no way this is perfect,
but the architecture is such that we can easily add regression tests as
we find issues.

## Other Changes, Notes

The only change to actually used code is that tracked pins in a
`PageList` can now be flagged as "garbage." A garbage tracked pin is one
that had to be moved in a non-sensical way because the previous location
it tracked has been deleted. This is used by the searcher to detect that
our history was pruned.

**If my assumption about the big lock is wrong** and this ends up being
godawful for performance, then it should still be okay because more
granular locking and reference counting such as that down by @dave-fl in
#8850 can be pushed into these components and reused. So this work is
still valuable on its own.

## Future

This PR is still just a bunch of internals, split out into its own PR so
I don't make one huge 10K diff PR. There are a number of future tasks:

- Flesh out `ScreenSearch` and hook it up to `Thread`
- Pull search thread management into `Surface` (or possibly the render
thread or shared render state since active area changes can be
synchronized with renderer frame rebuilds. Not sure yet.)
- Send updates back to the surface thread so that apprts can update UI.
- Apprt actions, input bindings, etc. to hook this all up (the easy
part, really).

The next step is to continue to flesh out the `ScreenSearch` as required
and hook it up to `Thread`.

**AI disclosure:** AI reviewed the code and assisted with some tests,
but didn't write any of the logic or design. This is beyond its ability
(or my ability to spec it out clearly enough for AI to succeed).
2025-11-14 12:38:06 -08:00
Mitchell Hashimoto 89e23e9190
macOS: Use small scrollbar (#9589)
As per #9557. This PR includes both the style change and disabling
autohiding for legacy scrollbars, such that the scrollbar slot is always
visible in the right margin, albeit without a knob if there's no content
to scroll. Wasn't 100 % clear on whether to include the latter, let me
know if I should drop that part.

**Before**


https://github.com/user-attachments/assets/49617f1f-12dc-477d-9df9-93617296cea7

**After**


https://github.com/user-attachments/assets/2497f12d-b127-4004-9947-b8cd67b6b0eb
2025-11-14 08:27:25 -08:00
Daniel Wennberg 49bf73458b don't autohide scrollers 2025-11-14 07:40:51 -08:00
Daniel Wennberg d48f855a48 macOS: set scrollbar size to .small 2025-11-14 07:36:54 -08:00
Mitchell Hashimoto 5ab23e6493
macOS: restore visiblity state when hiding quick terminal (#9576)
Fixes #8414 and a case where `toggle_visibility` is not working after
hiding using `cmd+h`


https://github.com/user-attachments/assets/be28c2d9-b416-467f-9fe9-7b7c97278330
2025-11-14 07:29:46 -08:00
Mitchell Hashimoto 05b42919d5
macOS: add more cursor style and fixes #8409 (#9580)
Fixes #8409


https://github.com/user-attachments/assets/c9e7ad9b-c1eb-451b-a537-90f380f5f5f3
2025-11-14 07:28:20 -08:00
Mitchell Hashimoto 6ef850ba8e
wuffs: protect against crafted images that cause overflows (#9581)
Fixes #9579

Protect against panics caused by integer overflows by using functions
that allow integer overflows to be caught instead of causing a panic.

Also protect against DOS from images that might not cause an overflow
but do consume an absurd amount of memory by limiting images to a
maximum size of 4GiB.
2025-11-14 07:26:27 -08:00
Mitchell Hashimoto 6b805a318e
terminal: ScreenSearch can omit overlapped results in history tick 2025-11-14 07:24:22 -08:00
Mitchell Hashimoto d349cc8932
terminal: ScreenSearch to search a single terminal screen 2025-11-13 15:07:35 -08:00
Mitchell Hashimoto 7b26e6319e
terminal: Pin.garbage tracking 2025-11-13 13:16:38 -08:00
Jeffrey C. Ollie ec55cbc879
wuffs: protect against crafted images that cause overflows
Fixes #9579

Protect against panics caused by integer overflows by using functions
that allow integer overflows to be caught instead of causing a panic.

Also protect against DOS from images that might not cause an
overflow but do consume an absurd amount of memory by limiting
images to a maximum size of 4GiB (which is the maximum size of
`image-storage-limit`).
2025-11-13 14:20:19 -06:00
Mitchell Hashimoto 2b647ba4cb
terminal: PageListSearch updated to split next and feed 2025-11-13 10:14:12 -08:00
Mitchell Hashimoto 22496b8f0e
terminal: sliding window needs to handle hard-wraps properly (tested) 2025-11-13 10:07:32 -08:00
Lukas 1486be0cdf
macOS: add more cursor style and fixes #8409 2025-11-13 18:20:09 +01:00
Lukas bcb5112b24
macOS: restore visiblity state when hiding quick terminal 2025-11-13 11:30:43 +01:00
Mitchell Hashimoto 0ea350a8f2
terminal: ActiveSearch for searching the active area 2025-11-12 20:59:18 -08:00
Mitchell Hashimoto 0f64b9a8e8
apprt/gtk: remove explicit X11 clipboard atom (#9570)
Fixes #9532
Supersedes #9554

Turns out the explicit `UTF8_STRING` atom was not needed after all and
GTK adds it automatically when running under X11; just having the
explicit UTF-8 charset type is enough.

This corrects situations where it may not be necessary to include
(Wayland), in addition to removing a duplicate atom under X11.

Importantly, this also corrects issues under Wayland in some scenarios,
such as using Electron-based apps (e.g., VSCode/Codium under Ubuntu
24.04 LTS).
2025-11-12 13:41:39 -08:00
Chris Marchesi 4f6c5a8d4f
apprt/gtk: remove explicit X11 clipboard atom
Turns out this was not needed after all and GTK adds it automatically
when running under X11; just having the explicit UTF-8 charset type is
enough.

This corrects situations where it may not be necessary to include
(Wayland), in addition to removing a duplicate atom under X11.

Importantly, this also corrects issues under Wayland in some scenarios,
such as using Electron-based apps (e.g., VSCode/Codium under Ubuntu
24.04 LTS).
2025-11-12 13:12:42 -08:00
Mitchell Hashimoto 43835d1468
terminal: SlidingWindow supports forward/reverse directions 2025-11-12 11:46:52 -08:00
Mitchell Hashimoto 6439af0afc
terminal: SlidingWindow search to dedicated file 2025-11-12 11:03:29 -08:00
Mitchell Hashimoto 8848e98271
terminal: search thread boilerplate (does nothing) 2025-11-12 10:07:21 -08:00
Mitchell Hashimoto 188caf42a1
search: move PageListSearch to a dedicated file 2025-11-12 09:58:43 -08:00
Mitchell Hashimoto 682cb6c888
macOS: restore non native fullscreen styles (#9559)
Fixes #8435

> [!NOTE]
> Used AI to proofread my comments
2025-11-12 08:26:09 -08:00
Mitchell Hashimoto eff3619878
macos: Require fullScreenMode on fullscreenStyle 2025-11-11 09:21:15 -08:00
Lukas 2debeb0f13
macOS: save effective fullscreen styles 2025-11-11 18:16:40 +01:00
Lukas 8437be8ee1
macOS: 'restore' non native fullscreen styles 2025-11-11 18:11:15 +01:00
Mitchell Hashimoto 05b5809115
macos: add a "restart later" option to the installing state (#9562)
This fixes #9558 by providing a "restart later" option to the installing
state. This also adds a simulator case for autoupdating so we can test
UI easily for that.

<img width="884" height="726" alt="CleanShot 2025-11-11 at 07 10 23@2x"
src="https://github.com/user-attachments/assets/c5b3fa95-8416-47e1-8fd2-c50f70684032"
/>
2025-11-11 07:31:06 -08:00
Mitchell Hashimoto 791d8f8200
macos: add a "restart later" option to the installing state 2025-11-11 07:27:03 -08:00
Mitchell Hashimoto bed219c132
macOS: support `close_all_windows` action (#9552)
`close_all_windows` is marked supported, but missing actual
implementation currently
2025-11-10 13:41:03 -08:00
Lukas f5bddb346c
macOS: support `close_all_windows` action 2025-11-10 17:54:46 +01:00
Denys Zhak 2ee1f3191e feat: add descriptions to fish shell completions 2025-11-10 16:53:27 +01:00
Mitchell Hashimoto 848ee92169
macOS: move focus if command palette is not showing (#9548)
Fixes #9533
2025-11-10 07:29:28 -08:00
Mitchell Hashimoto a7f956e681
build(deps): bump softprops/action-gh-release from 2.4.1 to 2.4.2 (#9540)
Bumps
[softprops/action-gh-release](https://github.com/softprops/action-gh-release)
from 2.4.1 to 2.4.2.
<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.4.2</h2>
<h2>What's Changed</h2>
<h3>Exciting New Features 🎉</h3>
<ul>
<li>feat: Ensure generated release notes cannot be over 125000
characters by <a
href="https://github.com/BeryJu"><code>@​BeryJu</code></a> in <a
href="https://redirect.github.com/softprops/action-gh-release/pull/684">softprops/action-gh-release#684</a></li>
</ul>
<h3>Other Changes 🔄</h3>
<ul>
<li>dependency updates</li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/BeryJu"><code>@​BeryJu</code></a> made
their first contribution in <a
href="https://redirect.github.com/softprops/action-gh-release/pull/684">softprops/action-gh-release#684</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/softprops/action-gh-release/compare/v2.4.1...v2.4.2">https://github.com/softprops/action-gh-release/compare/v2.4.1...v2.4.2</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.4.2</h2>
<h2>What's Changed</h2>
<h3>Exciting New Features 🎉</h3>
<ul>
<li>feat: Ensure generated release notes cannot be over 125000
characters by <a
href="https://github.com/BeryJu"><code>@​BeryJu</code></a> in <a
href="https://redirect.github.com/softprops/action-gh-release/pull/684">softprops/action-gh-release#684</a></li>
</ul>
<h3>Other Changes 🔄</h3>
<ul>
<li>dependency updates</li>
</ul>
<h2>2.4.1</h2>
<h2>What's Changed</h2>
<h3>Other Changes 🔄</h3>
<ul>
<li>fix(util): support brace expansion globs containing commas in
parseInputFiles by <a
href="https://github.com/Copilot"><code>@​Copilot</code></a> in <a
href="https://redirect.github.com/softprops/action-gh-release/pull/672">softprops/action-gh-release#672</a></li>
<li>fix: gracefully fallback to body when body_path cannot be read by <a
href="https://github.com/Copilot"><code>@​Copilot</code></a> in <a
href="https://redirect.github.com/softprops/action-gh-release/pull/671">softprops/action-gh-release#671</a></li>
</ul>
<h2>2.4.0</h2>
<h2>What's Changed</h2>
<h3>Exciting New Features 🎉</h3>
<ul>
<li>feat(action): respect working_directory for files globs by <a
href="https://github.com/stephenway"><code>@​stephenway</code></a> in <a
href="https://redirect.github.com/softprops/action-gh-release/pull/667">softprops/action-gh-release#667</a></li>
</ul>
<h2>2.3.4</h2>
<h2>What's Changed</h2>
<h3>Bug fixes 🐛</h3>
<ul>
<li>fix(action): handle 422 already_exists race condition by <a
href="https://github.com/stephenway"><code>@​stephenway</code></a> in <a
href="https://redirect.github.com/softprops/action-gh-release/pull/665">softprops/action-gh-release#665</a></li>
</ul>
<h3>Other Changes 🔄</h3>
<ul>
<li>dependency updates</li>
</ul>
<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>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="5be0e66d93"><code>5be0e66</code></a>
release 2.4.2</li>
<li><a
href="af658b4d5d"><code>af658b4</code></a>
feat: Ensure generated release notes cannot be over 125000 characters
(<a
href="https://redirect.github.com/softprops/action-gh-release/issues/684">#684</a>)</li>
<li><a
href="237aaccf71"><code>237aacc</code></a>
chore: bump node to 24.11.0</li>
<li><a
href="00362bea6f"><code>00362be</code></a>
chore(deps): bump the npm group with 5 updates (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/687">#687</a>)</li>
<li><a
href="0adea5aa98"><code>0adea5a</code></a>
chore(deps): bump the npm group with 3 updates (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/686">#686</a>)</li>
<li><a
href="aa05f9d779"><code>aa05f9d</code></a>
chore(deps): bump actions/setup-node from 5.0.0 to 6.0.0 in the
github-action...</li>
<li><a
href="bbaccb3a0c"><code>bbaccb3</code></a>
chore(deps): bump <code>@​types/node</code> from 20.19.21 to 20.19.22 in
the npm group (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/682">#682</a>)</li>
<li><a
href="50fda3f773"><code>50fda3f</code></a>
chore(deps): bump vite from 7.1.5 to 7.1.11 (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/681">#681</a>)</li>
<li><a
href="5434409c2b"><code>5434409</code></a>
chore(deps): bump <code>@​types/node</code> from 20.19.19 to 20.19.21 in
the npm group (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/679">#679</a>)</li>
<li>See full diff in <a
href="6da8fa9354...5be0e66d93">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.4.1&new-version=2.4.2)](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-11-10 07:28:46 -08:00
Mitchell Hashimoto 69aa803725
build(deps): bump cachix/install-nix-action from 31.8.2 to 31.8.3 (#9541)
Bumps
[cachix/install-nix-action](https://github.com/cachix/install-nix-action)
from 31.8.2 to 31.8.3.
<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.8.3</h2>
<h2>What's Changed</h2>
<ul>
<li>nix: 2.32.2 -&gt; 2.32.3 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/260">cachix/install-nix-action#260</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/cachix/install-nix-action/compare/v31.8.2...v31.8.3">https://github.com/cachix/install-nix-action/compare/v31.8.2...v31.8.3</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="7ec16f2c06"><code>7ec16f2</code></a>
Merge pull request <a
href="https://redirect.github.com/cachix/install-nix-action/issues/260">#260</a>
from cachix/create-pull-request/patch</li>
<li><a
href="5afc2ac89d"><code>5afc2ac</code></a>
nix: 2.32.2 -&gt; 2.32.3</li>
<li>See full diff in <a
href="456688f15b...7ec16f2c06">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.8.2&new-version=31.8.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-11-10 07:28:39 -08:00
Lukas 7ca858d404
macOS: move focus if command palette is not showing 2025-11-10 10:11:34 +01:00
dependabot[bot] ded31cd931
build(deps): bump cachix/install-nix-action from 31.8.2 to 31.8.3
Bumps [cachix/install-nix-action](https://github.com/cachix/install-nix-action) from 31.8.2 to 31.8.3.
- [Release notes](https://github.com/cachix/install-nix-action/releases)
- [Changelog](https://github.com/cachix/install-nix-action/blob/master/RELEASE.md)
- [Commits](456688f15b...7ec16f2c06)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-10 00:10:17 +00:00
dependabot[bot] 687e62b907
build(deps): bump softprops/action-gh-release from 2.4.1 to 2.4.2
Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 2.4.1 to 2.4.2.
- [Release notes](https://github.com/softprops/action-gh-release/releases)
- [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md)
- [Commits](6da8fa9354...5be0e66d93)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-10 00:10:08 +00:00
Mitchell Hashimoto 1e7b8f6085
macOS: remove `readyToInstall` state in update capsule (#9529)
There is a sparkle-related 'issue' with the previous implementation.
When you download/install in the `updateAvailable` state, if you don't
install it, then check the updates again. Sparkle loses its downloaded
stage in the delegate (it's normal when I use the sparkle source code).
This time, when you click install in the `updateAvailable` state, it
just uses the previous downloaded package and starts to install, without
calling `showReady(toInstallAndRelaunch:)`.

I think removing `readyToInstall` in our customised ui makes sense,
since the current package is pretty small and only takes a few seconds
to download for a normal network. And most of users intend to install
this update.

Also, there is no way back once you reach "Install and Restart" stage in
`SPUStandardUserDriver`, unless you force quit ofc.

~~This pr also contains some further cleanup for #9170, since
`InstallingView` is no longer visible for users.~~

#### `auto-download`

When `auto-download = check`, Sparkle will call
`UpdateDriver/showUpdateFound(with:state:reply:)`.

When `auto-download = download`, previously no update ui was presented
to the user, neither Sparkle's nor Ghostty’s.
> I tried tick&untick auto download&install in Sparkle's alert, which
doesn't seem to make any difference.

With this pr, `auto-download = check` will behave the same,
**`auto-download = download` will now prompt the user with a capsule.**


https://github.com/user-attachments/assets/f994dd29-d348-4fea-8777-df3720d6e7af


> [!NOTE]
> I used AI to proofread my comments
2025-11-09 12:45:09 -08:00
Lukas 7e3aba7c99
macOS: remove `readyToInstall` state in update capsule
There is a sparkle-related 'issue' with the previous implementation. When you download/install in the `updateAvailable` state, if you don't install it, then check the updates again. Sparkle loses its downloaded stage in the delegate (it's normal when I use the sparkle source code). This time, when you click install in the `updateAvailable` state, it just uses the previous downloaded package and starts to install, without calling `showReady(toInstallAndRelaunch:)`.

I think removing `readyToInstall` in our customed ui, will reduce one step to install an update for most of the users out there, which makes sense, since the current package is pretty small, only takes a few seconds to download for a normal network, and they intended to install this update.
2025-11-09 20:24:24 +01:00
Jeffrey C. Ollie b5912006ca
fix typo in shaper (#9536) 2025-11-09 12:30:50 -06:00
Jeffrey C. Ollie c965afe066
fix typo in shaper 2025-11-09 12:11:03 -06:00
Mitchell Hashimoto 1509222cc9
Update iTerm2 colorschemes (#9521)
Upstream release:
https://github.com/mbadolato/iTerm2-Color-Schemes/releases/tag/release-20251103-150536-ae86c8c
2025-11-09 06:56:05 -08:00
Mitchell Hashimoto 3c123918af
macOS: use unobtrusive driver when quick terminal is visible (#9528)
Current:

<img width="1398" height="604" alt="image"
src="https://github.com/user-attachments/assets/63f7e05e-03b9-413f-9622-285158dae1f6"
/>
2025-11-09 06:55:13 -08:00
Lukas 52d3329f84
macOS: use unobtrusive when quick terminal is visible 2025-11-09 13:32:50 +01:00
Lukas 84082c2b96
macOS: equalize splits when double tapping on SplitView divider (#9524)
Resolves Issue #8357 

### Implementation

Following the existing `onResize` callback pattern in
`TerminalSplitTreeView`, I added an `onEqualize` callback to
`SplitView`. When a divider is double-tapped, the callback retrieves a
surface from that `TerminalView`'s `SplitTree` and calls `splitEqualize`
to equalize the entire tree.

### Context

There is an existing PR #8364 that implements this feature but uses
`focusedSurface`, which doesn't work for unfocused windows. Since that
PR has been inactive for a few months after requested changes, I've
implemented this alternative approach.

Credit to @liby for that initial implementation!

### AI Usage

I chatted with Claude Code in Plan mode to understand the relationship
between surfaces and the split tree/split views, but I wrote all the
code myself.

### Screenshot


https://github.com/user-attachments/assets/0efd70ef-c90e-4b50-b853-b05e2ca2be67
2025-11-09 09:07:09 +01:00
Lukas 0e42145027
macOS: Update core surface size when config changes (#9525)
More or less the same as #9523, but for config reloads. Matters if
`scrollbar = never` has been added or removed since the last config
reload.
2025-11-09 08:59:38 +01:00
Daniel Wennberg e3ff49e653 macOS: Update core surface size when config changes 2025-11-08 23:34:56 -08:00
Sean Kelly e298620828 macOS: equalize splits when double tapping on SplitView divider 2025-11-08 23:16:16 -08:00
Lukas 2592b96f6d
macOS: Update core surface size when scroller style changes (#9523)
Listen to changes to the OS preferred scroller style and use it to
trigger updates the core surface size such that the scrollbar margin
kept in sync. Otherwise, the margin update would be deferred until the
next window or surface resize/split event.

In the video I'm turning my external bluetooth mouse off and on again,
triggering these updates.


https://github.com/user-attachments/assets/15c0ee40-2c1a-419a-8b07-8270e9f7a12f
2025-11-09 08:11:02 +01:00
Daniel Wennberg 5845a7bd29 macOS: Update core surface size when scroller style changes 2025-11-08 22:41:59 -08:00
mitchellh 49abd901e4 deps: Update iTerm2 color schemes 2025-11-09 00:15:23 +00:00
Daniel Wennberg 9339ccf769 Decouple balanced top and left window paddings 2025-11-08 12:21:40 -08:00
Lukas 0d5ecc7713
macOS: Don't clip surfaceView to contentView, fix transparent scrollbar background (#9517)
Here's a much simpler approach to fixing #9248 that doesn't involve
changes to the core or libghostty (the apprt one) at all. No safe area
API needed. All that's needed is for the content view to not clip its
subviews, such that the surface view can draw behind the scrollbar even
though it's a subview of the content view.

I haven't looked at the details on the renderer side, but since this
works it must be that it always renders background all the way to the
edges of the framebuffer, regardless of what the terminal screen size
(including window padding) happens to be. (This was already evident in
that we were able to avoid a transparent slot when the scrollbar was
hidden.) So I guess we kind of already have a safe area API through this
ability to set a screen size that's different from the framebuffer size?
_EDIT:_ I guess what's missing is the ability to shift the origin of the
screen within the framebuffer.

Fixes #9248, supersedes #9291.
2025-11-08 19:29:28 +01:00
Daniel Wennberg 3142c5aa60 macOS: Don't clip surfaceView to contentView
Fixes #9248
2025-11-08 09:34:02 -08:00
Leah Amelia Chen 9894722051
core: check that file reader has capacity before priming (#9515) 2025-11-08 06:25:48 +01:00
Daniel Wennberg cf126baeb5 Check that file reader has capacity before priming 2025-11-07 20:29:16 -08:00
Mitchell Hashimoto 12c8b6c1aa
macOS: Refactor scrollview to preserve state across split tree changes (#9446)
Fixes #9444
2025-11-07 15:10:45 -08:00
Mitchell Hashimoto eb29274f6a
Feat/clipboard codepoint map (#9499)
Closes #8383
2025-11-07 15:01:41 -08:00
Mitchell Hashimoto 43d81600de
terminal: add codepoint mapping to the formatter itself 2025-11-07 14:58:23 -08:00
benodiwal 422fa8d304 refactor: remove unused hash methods from ClipboardCodepointMap 2025-11-07 14:30:22 -08:00
benodiwal 11274cd9e5 feat: integrate clipboard-codepoint-map with clipboard pipeline 2025-11-07 14:30:22 -08:00
benodiwal a162fa8f55 feat: add clipboard-codepoint-map configuration parsing 2025-11-07 14:30:22 -08:00
Mitchell Hashimoto 0d26bace25
macOS: attach close confirmation alert to the first window that actually needs it (#9509)
Currently, close confirmation is always attached to the first tab in the
window group.

**This pr will attach the alert to the window that actually needs that
confirmation, so upon close, the window with the running process will be
focused.**


https://github.com/user-attachments/assets/8fddd4ce-a3f9-4e18-a645-80c85b5ba995
2025-11-07 14:26:00 -08:00
Mitchell Hashimoto 04563a16b6
macos: simplify the code to a more understandable style 2025-11-07 14:24:56 -08:00
Lars 1eecd448e9 remove needsConfirm 2025-11-07 14:16:10 -08:00
Lars f94cb01ec8 macOS: attach close confirmation alert to the first window that actually needs it 2025-11-07 14:16:10 -08:00
Mitchell Hashimoto fbabafe8e3
macOS: fix undo new tab will cause a crash (#9512)
### Reproduce Steps on Tip (1.2.3 seems fine)

1. Open a new window.
2. Open a new tab.
3. **Wait for 2-3 seconds.**
4. Undo.
5. 💥

**RC is unclear for me, but dispatching it seems to fix it.**
2025-11-07 14:15:19 -08:00
Lars 3f20f153c5 macOS: fix undo new tab will cause a crash 2025-11-07 14:14:44 -08:00
Mitchell Hashimoto 7f0468f910
fix ucs-detect script 2025-11-06 12:56:43 -08:00
Mitchell Hashimoto 14bae9ed0a
nix: add ucs-detect (#9506)
This makes `ucs-detect` available in our Nix environment so that we can
run tests on our Unicode support. In the future, I'd like to modify our
CI to run this too.

This also adds a `./test/ucs-detect.sh` script that runs `ucs-detect`
with consistent options that match the upstream test styles.

Fwiw, I did try to write a simple libghostty-based Zig binary to run
this automatically for us in CI but while libghostty-vt is very good, we
don't yet have the proper APIs setup for actually setting up a Pty and
sub processing commands and hooking them up to a VT stream. So, I punt
that to the future.
2025-11-06 10:22:34 -07:00
Mitchell Hashimoto a315f8f32e
nix: add ucs-detect
This makes `ucs-detect` available in our Nix environment so that we can
run tests on our Unicode support. In the future, I'd like to modify our
CI to run this too.

This also adds a `./test/ucs-detect.sh` script that runs `ucs-detect`
with consistent options that match the upstream test styles.
2025-11-06 09:22:18 -08:00
Mitchell Hashimoto 5ca3b766be
core: handle utf-8 bom in config files (#9497)
If a UTF-8 byte order mark starts a config file, it should be ignored.
This also refactors config file loading a bit to reduce redundant code
and to make it possible to test loading config from a file.

Fixes #9490
2025-11-06 10:01:56 -07:00
Jeffrey C. Ollie df86e30877
drop utf-8 bom log message to info 2025-11-06 11:00:38 -06:00
Jeffrey C. Ollie c8e317b60f
core: handle utf-8 bom in config files
If a UTF-8 byte order mark starts a config file, it should be ignored.
This also refactors config file loading a bit to reduce redundant code
and to make it possible to test loading config from a file.

Fixes #9490
2025-11-06 10:59:26 -06:00
Mitchell Hashimoto f54c3d9209
macOS: set the macos-icon from a separate thread (#9485)
Closes #8793
2025-11-06 09:55:57 -07:00
Mitchell Hashimoto ec2ef5cf21
macOS: fix Dictation icon starting above the text, not below (#9488)
Partially fixes #8493.

After dictating some texts, the icon still appears above, but it will
return to its right position after resizing or `\n` (saying newline, not
hitting enter).

This behaviour is better than before, where the icon always appeared
above.

> Quicklook doesn't seem to call this on Tahoe, but it still works well
anyway.

### Reference:


9e905357bb/src/nsterm.m (L7426)



https://github.com/user-attachments/assets/6bf818c3-a0bb-412f-ae06-673f67cdeae4
2025-11-06 09:55:36 -07:00
Mitchell Hashimoto 4df50da207
macOS: fix funky resolution in quick terminal (#9504)
Same as #9503 but based on main
2025-11-06 09:52:11 -07:00
Mitchell Hashimoto 9786d0ea73
terminal: keypad variation sequences should respect VS16 (#9502)
This fixes the VS16 issues found in this test:
https://ucs-detect.readthedocs.io/sw_results/ghostty.html#ghostty This
is also a more robust way to handle VS15/16 in general.

This commit also changes our propeties to be a packed struct which
reduces its size from 4 bytes to 1 and likewise drops our unicode table
size 4x. This isn't as big as it seems, since this only affects stage3
of our LUT which goes from 108 bytes to 27 bytes.

## Before

<img width="1996" height="1740" alt="CleanShot 2025-11-06 at 07 08
20@2x"
src="https://github.com/user-attachments/assets/79850071-a2d5-4d6d-a76b-7ebf355b4480"
/>

## After

<img width="1996" height="1740" alt="CleanShot 2025-11-06 at 07 08
02@2x"
src="https://github.com/user-attachments/assets/44f809f2-93cd-4c97-8f42-46cd8f72ec8b"
/>
2025-11-06 08:20:28 -07:00
Lars c8c36a6035
macOS: fix funky resolution in quick terminal 2025-11-06 16:13:05 +01:00
Mitchell Hashimoto 3d58dc51c9
terminal: keypad variation sequences should respect VS16
This fixes the VS16 issues found in this test:
https://ucs-detect.readthedocs.io/sw_results/ghostty.html#ghostty
This is also a more robust way to handle VS15/16 in general. 

This commit also changes our propeties to be a packed struct which
reduces its size from 4 bytes to 1 and likewise drops our unicode table
size 4x.
2025-11-06 07:05:57 -08:00
Mitchell Hashimoto 923bde72d8
unicode: update uucode, force emoji modifiers width 2 as standalone (#9493)
This updates uucode. As part of this, the wcwidth implementation was
updated (in uucode) to make emoji modifiers width ZERO. But if they're
standalone, we want them as width 2.

So this also contains a change to force them as width 2 for our width
calculation. This only matters for standalone emoji modifiers, because
when they form a valid grapheme we don't use this width calculation.
2025-11-05 16:43:03 -07:00
Mitchell Hashimoto 631c58a302
unicode: update uucode, force emoji modifiers width 2 as standalone
This updates uucode. As part of this, the wcwidth implementation was
updated (in uucode) to make emoji modifiers width ZERO. But if they're
standalone, we want them as width 2.

So this also contains a change to force them as width 2 for our width
calculation. This only matters for standalone emoji modifiers, because
when they form a valid grapheme we don't use this width calculation.
2025-11-05 14:57:48 -08:00
Lars 98ae1dbd10
macOS: fix Dictation icon starting above the text, not below
Partially fixes #8493.

After dictating some texts, the icon still appears above, but it will return to its right position after resizing or `\n` (saying newline, not hitting enter).

This behaviour is better than before, where the icon always appeared above.

### Reference:

9e905357bb/src/nsterm.m (L7426)
2025-11-05 18:22:08 +01:00
Mitchell Hashimoto d43be63851
Add an example for `palette` configuration (#9473)
I found this syntax a bit confusing when I first read it, so I thought
it would be helpful for the next person to add a short example.
2025-11-05 06:34:34 -08:00
Lars 7472fb7732
macOS: set the macos-icon from a separate thread 2025-11-05 12:27:35 +01:00
Avery Mcnab 13d5f0c503 Add an example for `palette` configuration
I found this syntax a bit confusing when I first read it, so I thought it would be helpful for the next person to add a short example.
2025-11-04 15:02:03 +00:00
Daniel Wennberg afc64f6285 Refactor scrollview to preserve state across split tree changes 2025-11-04 00:02:21 -08:00
Daniel Wennberg 9002c5dbd2 Preserve surface content size across backing updates 2025-11-04 00:02:21 -08:00
Daniel Wennberg d678e2e305 Use notifications to deal with NSScrollPocket 2025-11-04 00:02:21 -08:00
Mitchell Hashimoto bbaee5e0a0
build(deps): bump namespacelabs/nscloud-cache-action from 1.2.20 to 1.2.21 (#9460)
Bumps
[namespacelabs/nscloud-cache-action](https://github.com/namespacelabs/nscloud-cache-action)
from 1.2.20 to 1.2.21.
<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.21</h2>
<h2>What's Changed</h2>
<ul>
<li>feat: <code>bun</code> &amp; <code>deno</code> cache mode by <a
href="https://github.com/rcrowe"><code>@​rcrowe</code></a> in <a
href="https://redirect.github.com/namespacelabs/nscloud-cache-action/pull/45">namespacelabs/nscloud-cache-action#45</a></li>
<li>Support <code>golangci-lint</code> caching by <a
href="https://github.com/rcrowe"><code>@​rcrowe</code></a> in <a
href="https://redirect.github.com/namespacelabs/nscloud-cache-action/pull/46">namespacelabs/nscloud-cache-action#46</a></li>
<li>Add Mise cache mode by <a
href="https://github.com/rcrowe"><code>@​rcrowe</code></a> in <a
href="https://redirect.github.com/namespacelabs/nscloud-cache-action/pull/47">namespacelabs/nscloud-cache-action#47</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/namespacelabs/nscloud-cache-action/compare/v1...v1.2.21">https://github.com/namespacelabs/nscloud-cache-action/compare/v1...v1.2.21</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="446d8f3905"><code>446d8f3</code></a>
Merge pull request <a
href="https://redirect.github.com/namespacelabs/nscloud-cache-action/issues/47">#47</a>
from rcrowe/mise-support</li>
<li><a
href="613cebb068"><code>613cebb</code></a>
Add Mise cache mode</li>
<li><a
href="7dddb61a4c"><code>7dddb61</code></a>
Merge pull request <a
href="https://redirect.github.com/namespacelabs/nscloud-cache-action/issues/46">#46</a>
from rcrowe/cache-mode-golangci-lint</li>
<li><a
href="2de3d9c86f"><code>2de3d9c</code></a>
Search for directory output</li>
<li><a
href="76fbc4cf47"><code>76fbc4c</code></a>
Build dist</li>
<li><a
href="74129e9b23"><code>74129e9</code></a>
Actions job</li>
<li><a
href="99c7dbff89"><code>99c7dbf</code></a>
Support golangci-lint caching</li>
<li><a
href="9ad1d3f484"><code>9ad1d3f</code></a>
Merge pull request <a
href="https://redirect.github.com/namespacelabs/nscloud-cache-action/issues/45">#45</a>
from rcrowe/cache-mode-deno</li>
<li><a
href="a1d88d2acc"><code>a1d88d2</code></a>
Support bun cache mode</li>
<li><a
href="93e08c88b5"><code>93e08c8</code></a>
Support deno cache mode</li>
<li>Additional commits viewable in <a
href="d93899d984...446d8f3905">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.20&new-version=1.2.21)](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-11-03 11:10:29 -08:00
dependabot[bot] 551c1e68e0
build(deps): bump namespacelabs/nscloud-cache-action
Bumps [namespacelabs/nscloud-cache-action](https://github.com/namespacelabs/nscloud-cache-action) from 1.2.20 to 1.2.21.
- [Release notes](https://github.com/namespacelabs/nscloud-cache-action/releases)
- [Commits](d93899d984...446d8f3905)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-03 00:07:29 +00:00
Mitchell Hashimoto 329aa7d334
nix: don't use deprecated pkgs.system (#9458)
'system' has been renamed to/replaced by 'stdenv.hostPlatform.system'

https://github.com/NixOS/nixpkgs/pull/456527
2025-11-02 14:29:37 -08:00
Mitchell Hashimoto 0eeae265aa
apprt/gtk: (clipboard) add X11 atoms and extra MIME types for text content (#9456)
This adds the `UTF8_STRING` atom and explicit UTF-8 character set MIME
type (`text/plain;charset=utf-8`) to text content when being sent to the
clipboard under the new multipart support.

This fixes clipboard support under X11 particularly, which generally
looks for the `UTF8_STRING` atom when looking for text content. This can
be verified with `xclip -out -verbose`, or trying to do things like
paste in Firefox.

I've noted that there's a number of other older atoms that exist, but
I've refrained from adding them for now. Kitty only seems to set
`UTF8_STRING` and I've had a hard time finding consensus on what exactly
is the correct set otherwise.
2025-11-02 13:51:10 -08:00
Caleb Norton d4f474bb35 nix: don't use deprecated pkgs.system
'system' has been renamed to/replaced by 'stdenv.hostPlatform.system'
https://github.com/NixOS/nixpkgs/pull/456527
2025-11-02 13:21:12 -06:00
Chris Marchesi e7c68142e3
apprt/gtk: (clipboard) add X11 atoms, extra MIME types for text content
This adds the UTF8_STRING atom and explicit UTF-8 character set MIME
type (text/plain;charset=utf-8) to text content when being sent to the
clipboard under the new multipart support.

This fixes clipboard support under X11 particularly, which generally
looks for the UTF8_STRING atom when looking for text content. This can be
verified with xclip -out -verbose, or trying to do things like paste in
Firefox.

I've noted that there's a number of other older atoms that exist, but
I've refrained from adding them for now. Kitty only seems to set
UTF8_STRING and I've had a hard time finding consensus on what exactly
is the correct set otherwise.
2025-11-02 11:19:10 -08:00
Mitchell Hashimoto 955087f5f2
i18n: prefer using ellipsis over three dots (#9455)
After skimming through the norwegian bokmål translation
(https://github.com/ghostty-org/ghostty/blob/main/po/nb_NO.UTF-8.po) I
noticed a inconsistent use of three dots/ellipses. On [line
93](https://github.com/ghostty-org/ghostty/blob/main/po/nb_NO.UTF-8.po#L93),
three dots (`...`) are present where the actual ellipsis sign (`…`)
should be used instead. As mentioned in [this discord
comment](https://discord.com/channels/1005603569187160125/1349894806180204625/1434515563496996988).

This is not a big "problem" by itself, but looking at the english
translation and the rest of norwegian ones, you'll see that they all use
the ellipsis sign. (e.g. `Execute a command…`, `Endre tittel…`)

This is just a simple one-liner replacing the three periods with an
ellipsis sign.

cc @uzaaft
2025-11-02 07:14:38 -08:00
Mitchell Hashimoto aa5ae095b0
Update iTerm2 colorschemes (#9450)
Upstream release:
https://github.com/mbadolato/iTerm2-Color-Schemes/releases/tag/release-20251027-150540-8f50c1d
2025-11-02 07:09:48 -08:00
realguse f6faf2a515
chore(i18n): prefer using ellipsis over three dots 2025-11-02 14:52:54 +01:00
mitchellh 9e2caedb7d deps: Update iTerm2 color schemes 2025-11-02 00:15:16 +00:00
Mitchell Hashimoto 765ee68429
apprt/gtk: set multiple content types for clipboard ops (#9431)
This supports the new `setClipboard` parameter that may provide data in
multiple formats, allowing us to copy rich text to/from the clipboard as
well as other types in the future.

This all fixes a memory leak on all clipboard ops that snuck through.
2025-10-31 10:58:12 -07:00
Mitchell Hashimoto 46db1cfd8f
apprt/gtk: set multiple content types for clipboard ops
This supports the new `setClipboard` parameter that may provide data in
multiple formats, allowing us to copy rich text to/from the clipboard as
well as other types in the future.
2025-10-31 10:53:10 -07:00
Mitchell Hashimoto 15bfdcb41e
input: write_*_file actions take an optional format (#9428)
Fixes #9398

This is fully backwards compatible. Example:
`write_screen_file:open,html`
2025-10-31 09:52:13 -07:00
Mitchell Hashimoto 901708e8da
input: write_*_file actions take an optional format
Fixes #9398
2025-10-31 09:49:59 -07:00
Mitchell Hashimoto 24b9778432
input: add more copy formatted options to the command palette 2025-10-31 08:21:16 -07:00
Mitchell Hashimoto 7d6cd12fb3
terminal: emit non-ASCII characters as Unicode codepoints for HTML (#9427)
Fixes #9426

Since we can't set the meta charset tag since we emit partial HTML, we
use codepoint entities like `&#123;` for non-ASCII characters to ensure
proper rendering.
2025-10-31 08:19:41 -07:00
Mitchell Hashimoto 05d2f881b6
terminal: emit non-ASCII characters as Unicode codepoints for HTML
Fixes #9426

Since we can't set the meta charset tag since we emit partial HTML, we
use codepoint entities like `&#123;` for non-ASCII characters to
ensure proper rendering.
2025-10-31 08:15:25 -07:00
Lukas b043623bb2
macos: Fix documentView padding calculations (#9423)
Fixes #9420 

The problem was ultimately that the padding calculations assumed that
the total vertical padding is always less than one cell height (just
doing `fmod(contentHeight, cellHeight)` instead of the more careful
`contentHeight - scrollbar.len * cellHeight`). This is not at all true,
and as a result, the calculated document height was often a cell height
short of what it should be.

For similar reasons, we shouldn't rely on `fmod`-based padding update
calculations during relayouting. This PR takes the proper approach of
saving and reusing the current scrollbar state to calculate the correct
document height on every layout. As a bonus, this removes the flickering
scrollbar during resize that I complained about in #9296.
2025-10-31 11:32:37 +01:00
Daniel Wennberg 951374cd1c Fix documentView padding calculations 2025-10-31 00:39:03 -07:00
Mitchell Hashimoto bc0f5e4d57
Copy formatted text to clipboard with plain, make it configurable (#9418)
Fixes #9397 

This makes `copy_to_clipboard` take an optional parameter with the
format to copy. **The default has changed to `mixed`,** which will set
multiple content types on the clipboard allowing the OS or target
application to choose what they prefer. In this case, we set both
`text/plain` and `text/html`.

This only includes the macOS implementation. The GTK side still needs to
be done, but is likely trivial to do.


https://github.com/user-attachments/assets/b1b2f5cd-d59a-496e-bb77-86a60571ed7f
2025-10-30 15:17:16 -07:00
Mitchell Hashimoto 5c1f036613
macos: assert only one text-plain gets written to clipboard 2025-10-30 15:16:15 -07:00
Mitchell Hashimoto 54fe54fe37
apprt/gtk: fix build errors 2025-10-30 14:43:31 -07:00
Mitchell Hashimoto f3352dd90b
core: copy the proper format to the clipboard as configured 2025-10-30 14:36:32 -07:00
Mitchell Hashimoto 9a198b47a0
apprt/gtk: support new set clipboard API 2025-10-30 14:11:00 -07:00
Mitchell Hashimoto 26bdb12f64
core: update Surface to use setClipboard 2025-10-30 14:08:29 -07:00
Mitchell Hashimoto 0f1c46e4a4
macos: support setting multiple clipboard content types 2025-10-30 14:01:58 -07:00
Mitchell Hashimoto df037d75a6
copy_to_clipboard format types 2025-10-30 13:40:32 -07:00
Mitchell Hashimoto 77b038dcb6
update README 2025-10-30 13:14:23 -07:00
Mitchell Hashimoto 038cdde334
terminal: formatters now emit background/foreground information (#9414)
This allows the full terminal style to be copied, except for the cursor:

<img width="1136" height="660" alt="image"
src="https://github.com/user-attachments/assets/448d7125-d4fd-477b-9a9b-96176d7fae56"
/>
2025-10-30 10:44:08 -07:00
Mitchell Hashimoto 83a4f32a14
terminal: formatter improvements for color handling 2025-10-30 10:39:46 -07:00
Mitchell Hashimoto 4c504560d4
terminal: move bg, fg, cursor color state into Terminal (#9412)
This moves the bg, fg, cursor color state into the `Terminal` struct,
including all default and override handling. I've rewritten our color
palette handling so that overrides, defaults, resets, etc are all
handled by the terminal package. I've added much more unit test
coverage.

This has various benefits:

* libghostty now handles OSC and Kitty color operations
* formatters can be aware of all of these colors (not implemented in
this PR)
* renderer has way less inter-thread messages
* renderer uses less memory 
* termio stream handler uses less memory and becomes simpler
* override logic, changing defaults can all be unit tested
* we have unit tests for kitty color operations end-to-end now (cc
@jcollie heyo!)

There's a ton of risk on this PR too. There's a lot of really tiny
conditionals EVERYWHERE and I'm sure I got at least one wrong. We'll let
this bake in tip to find those, I'm sure they're minor and will show up
as just the wrong color somewhere.

**AI disclosure:** Amp wrote many of the tests. I did all the
implementation.
2025-10-30 10:15:33 -07:00
Mitchell Hashimoto 799e4bca50
example/zig-formatter: fix build for new palette API 2025-10-30 10:07:44 -07:00
Mitchell Hashimoto 450155f150
zig fmt 2025-10-30 10:06:13 -07:00
Mitchell Hashimoto 27a98123a0
terminal: readonly stream can update more colors now 2025-10-30 09:58:56 -07:00
Mitchell Hashimoto 2daecd94a5
renderer: use terminal color state, remove color messages 2025-10-30 09:52:39 -07:00
Mitchell Hashimoto 77343bb06e
terminal: move color state fully into the terminal for fg/bg/cursor 2025-10-30 09:33:21 -07:00
Mitchell Hashimoto cabca0aca8
terminal: unify palette functionality into shared type DynamicPalette 2025-10-30 09:15:43 -07:00
Lukas c7d5d1b9fc
macOS: make text editor in clipboard confirmation non focusable (#9400)
With its being `focusable`(default), the first responder became the text
editor instead of the paste button.

This fixes the issue where one can't confirm with the keyboard.

This doesn't affect its selection.
2025-10-29 21:30:03 -07:00
Jon Parise 4818c2b896
cli: make the entire +ssh-cache cache path (#9403)
std.fs.makeDirAbsolute() only creates the last directory. We instead
need Dir.makePath() to make the entire path, including intermediate
directories.

This fixes the problem where a missing $XDG_STATE_HOME directory (e.g.
~/.local/state/) would prevent our ssh cache file from being created.

Fixes #9393
2025-10-29 21:29:40 -07:00
dependabot[bot] 5edf9aff50
build(deps): bump cachix/install-nix-action from 31.8.1 to 31.8.2 (#9405)
Bumps
[cachix/install-nix-action](https://github.com/cachix/install-nix-action)
from 31.8.1 to 31.8.2.
<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.8.2</h2>
<h2>What's Changed</h2>
<ul>
<li>nix: 2.32.1 -&gt; 2.32.2 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/259">cachix/install-nix-action#259</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/cachix/install-nix-action/compare/v31.8.1...v31.8.2">https://github.com/cachix/install-nix-action/compare/v31.8.1...v31.8.2</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="456688f15b"><code>456688f</code></a>
Merge pull request <a
href="https://redirect.github.com/cachix/install-nix-action/issues/259">#259</a>
from cachix/create-pull-request/patch</li>
<li><a
href="0cacfe0f2a"><code>0cacfe0</code></a>
nix: 2.32.1 -&gt; 2.32.2</li>
<li>See full diff in <a
href="fd24c48048...456688f15b">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.8.1&new-version=31.8.2)](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>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-29 21:29:05 -07:00
Mitchell Hashimoto 4a88976ef9
example/zig-formatter: show how to use formatters from libghostty (#9407) 2025-10-29 21:28:52 -07:00
Mitchell Hashimoto c0e483c49e
terminal: HTML formatting (#9402)
This adds HTML formatting capabilities to the formatter package. HTML is
emitted as inline styles. For palette indexes, direct RGB is emitted if
we have access to a palette; otherwise, we fall back to CSS variables.

This isn't exposed to end users yet, but will enable copy as html
features. This is available in libghostty.

Fixes #9395

**AI disclosure:** I used AI (Amp) to help me write tests, but the
implementation was done manually. I reviewed everything.
2025-10-29 20:55:52 -07:00
Daniel Wennberg e70ca0b9b5
Don't encode option as alt in modify other keys 2 (#9406)
There have been frequent reports of key encoding issues in vim and tmux
with version 1.2.3 on macOS: #9340, #9361, #9401,
https://discord.com/channels/1005603569187160125/1432413679806320772.

I think I found the culprit: the option modifier is always passed as alt
to the core, regardless of `macos-option-as-alt`. Since #9289, this
means that a key event where option was used (as option) for translation
is encoded as if it also has the alt modifier.

For example, consider the many European keyboard layouts where option+8
sends `[`. If `macos-option-as-alt = true`, Ghostty correctly intercepts
the option and encodes option+8 as alt+8 instead (that is,
`^[[27;3;56~`). But if `macos-option-as-alt = false`, Ghostty first
allows option to be used for translation, obtaining `[`, and then
encodes the key event as alt+[ (that is, `^[[27;3;91~`), rather than
just `[`.

Tweaking the test case from #9289, here's a quick way to see this: set
`macos-option-as-alt = left`, run
```
printf '\033[>4;2m'
cat
```
choose a European keyboard layout (e.g., Norwegian), and hit both
left-option+8 and right-option+8. The former inserts `^[[27;3;56~` in
all well-behaved terminals. The latter inserts `[` in other terminals,
but `^[[27;3;91~` in Ghostty.

Basically, while modify other keys 2 does require encoding consumed
modifiers, the option key is not one of the supported modifiers, and
should not be included (as alt or anything else) when
`macos-option-as-alt = false`.

This PR removes alts that were actually options when using modify other
keys 2.
2025-10-29 20:29:53 -07:00
Mitchell Hashimoto a4d54dca1c
terminal: remove all legacy encodeUtf8 functions, replace with formatter (#9392)
This removes all existing functionality that I know of that encodes a
terminal, screen, pagelist, or page as plaintext and unifies all logic
onto the formatter system.
2025-10-29 10:50:47 -07:00
Mitchell Hashimoto 028ce83d46
terminal: selectionString now uses ScreenFormatter (#9391)
This replaces the logic of Screen.selectionString with calls to
ScreenFormatter.

This means that all our various selection-based features like copying to
clipboards now uses the new formatter. The formatter code is now
user-facing.

This forced us to pass all selectionString tests which revealed some
edge cases that were not handled correctly before in the formatter! The
formatter now handles:

- Plain text now emits `\n` instead of `\r\n`. VT emits `\r\n`
 - Rectangular selections
 - Various wide character edge cases
 - Selection is now inclusive on the end, not exclusive
2025-10-29 10:16:38 -07:00
Mitchell Hashimoto d62235cb62
terminal: Add `pin_map/point_map` to formatter (#9379)
This adds the option `pin_map` or `point_map` (for pages) to formatter,
allowing callers to get a byte-by-byte mapping for where on the screen
each encoding maps to. This is used by search internals and hyperlinks.
I haven't hooked that all up yet. This diff was big enough I wanted this
as one.

Tests significantly cover the new feature.

Next up, we'll rip out `selectionString` and replace it with formatters!
2025-10-28 11:23:16 -07:00
Mitchell Hashimoto 17f2dc59fa
terminal: formatter that can emit VT sequences (#9374)
This adds a new formatter that can be used with standard Zig `{f}`
formatting that emits any portion of the terminal screen as VT
sequences. In addition to simply styling, this can emit the entire
terminal/screen state such as cursor positions, active style, terminal
modes, etc.

To do this, I've extracted all formatting to a dedicated `formatter`
package within `terminal`. This handles all formatting types (currently
plaintext and VT formatting, but can imagine things like HTML in the
future). Presently, we have "formatting" split out across a variety of
places in Terminal, Screen, PageList, and Page. I didn't remove this
code yet but I intend to unify it all on formatter in the future.

This also doesn't expose this functionality in any user-facing way yet.
This PR just adds it to the ghostty-vt Zig module and unit tests it.
Ghostty app changes will come later.

**This also improves the readonly stream** to handle OSC color
operations for _setting_ but it doesn't emit any responses of course,
since its readonly.
2025-10-28 07:23:00 -07:00
Lukas d40321a8d8
macOS: Adjust documentView padding on layout changes (#9296)
Fixes a bug described in #9291, where resizing an empty window causes
the scrollbar to appear even though the window remains larger than the
total content, because the relayouting fails to account for the change
in padding around the cell grid.

To reproduce the issue:
1. Enable legacy scrollbars (System Settings -> Appearance -> Show
scroll bars -> Always)
2. Open Ghostty
3. Vertically resize the window to make it smaller. The scrollbar will
pop up, and as you drag the window edge, it will cycle between a maximum
offset and zero depending on how far the resize is from an integer
multiple of the cell height.

With this PR you'll still see the scrollbar flicker while resizing, but
when you stop it will always disappear. Haven't figured out how to get
rid of the flickering yet. I tried to condition various updates on the
window not being in a live resize, but so far no luck.
2025-10-27 21:51:46 +01:00
Daniel Wennberg 88444d4bd7 macOS: Adjust documentView padding on layout changes 2025-10-27 10:43:47 -07:00
Jon Parise 86ec29237c
cli: make +ssh-cache contains() a read-only op (#9369)
contains() checks the cache for an existing entry. It's a read-only
operation, so we can drop the write bit and fixupPermissions() call.
This is also consistent with the list() operation.

fixupPermissions() is unnecessary in this code path. It provided minimal
additional security because all of our creation and update operations
enforce 0o600 (owner-only) permissions, so anyone tampering with this
file has already gotten around that. The contents of this (ssh host
cache) file are also not sensitive enough to warrant any additional
hardening on reads.
2025-10-27 09:06:55 -07:00
dependabot[bot] db75502fec
build(deps): bump actions/upload-artifact from 4.6.2 to 5.0.0 (#9364)
Bumps
[actions/upload-artifact](https://github.com/actions/upload-artifact)
from 4.6.2 to 5.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>v5.0.0</h2>
<h2>What's Changed</h2>
<p><strong>BREAKING CHANGE:</strong> this update supports Node
<code>v24.x</code>. This is not a breaking change per-se but we're
treating it as such.</p>
<ul>
<li>Update README.md by <a
href="https://github.com/GhadimiR"><code>@​GhadimiR</code></a> in <a
href="https://redirect.github.com/actions/upload-artifact/pull/681">actions/upload-artifact#681</a></li>
<li>Update README.md by <a
href="https://github.com/nebuk89"><code>@​nebuk89</code></a> in <a
href="https://redirect.github.com/actions/upload-artifact/pull/712">actions/upload-artifact#712</a></li>
<li>Readme: spell out the first use of GHES by <a
href="https://github.com/danwkennedy"><code>@​danwkennedy</code></a> in
<a
href="https://redirect.github.com/actions/upload-artifact/pull/727">actions/upload-artifact#727</a></li>
<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/upload-artifact/pull/725">actions/upload-artifact#725</a></li>
<li>Bump <code>@actions/artifact</code> to <code>v4.0.0</code></li>
<li>Prepare <code>v5.0.0</code> by <a
href="https://github.com/danwkennedy"><code>@​danwkennedy</code></a> in
<a
href="https://redirect.github.com/actions/upload-artifact/pull/734">actions/upload-artifact#734</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/GhadimiR"><code>@​GhadimiR</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/upload-artifact/pull/681">actions/upload-artifact#681</a></li>
<li><a href="https://github.com/nebuk89"><code>@​nebuk89</code></a> made
their first contribution in <a
href="https://redirect.github.com/actions/upload-artifact/pull/712">actions/upload-artifact#712</a></li>
<li><a
href="https://github.com/danwkennedy"><code>@​danwkennedy</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/upload-artifact/pull/727">actions/upload-artifact#727</a></li>
<li><a
href="https://github.com/patrikpolyak"><code>@​patrikpolyak</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/upload-artifact/pull/725">actions/upload-artifact#725</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/upload-artifact/compare/v4...v5.0.0">https://github.com/actions/upload-artifact/compare/v4...v5.0.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="330a01c490"><code>330a01c</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/upload-artifact/issues/734">#734</a>
from actions/danwkennedy/prepare-5.0.0</li>
<li><a
href="03f2824452"><code>03f2824</code></a>
Update <code>github.dep.yml</code></li>
<li><a
href="905a1ecb59"><code>905a1ec</code></a>
Prepare <code>v5.0.0</code></li>
<li><a
href="2d9f9cdfa9"><code>2d9f9cd</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/upload-artifact/issues/725">#725</a>
from patrikpolyak/patch-1</li>
<li><a
href="9687587dec"><code>9687587</code></a>
Merge branch 'main' into patch-1</li>
<li><a
href="2848b2cda0"><code>2848b2c</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/upload-artifact/issues/727">#727</a>
from danwkennedy/patch-1</li>
<li><a
href="9b511775fd"><code>9b51177</code></a>
Spell out the first use of GHES</li>
<li><a
href="cd231ca1ed"><code>cd231ca</code></a>
Update GHES guidance to include reference to Node 20 version</li>
<li><a
href="de65e23aa2"><code>de65e23</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/upload-artifact/issues/712">#712</a>
from actions/nebuk89-patch-1</li>
<li><a
href="8747d8cd76"><code>8747d8c</code></a>
Update README.md</li>
<li>Additional commits viewable in <a
href="ea165f8d65...330a01c490">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/upload-artifact&package-manager=github_actions&previous-version=4.6.2&new-version=5.0.0)](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>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-26 20:25:20 -07:00
dependabot[bot] 06966b42ad
build(deps): bump actions/download-artifact from 5.0.0 to 6.0.0 (#9365)
Bumps
[actions/download-artifact](https://github.com/actions/download-artifact)
from 5.0.0 to 6.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>v6.0.0</h2>
<h2>What's Changed</h2>
<p><strong>BREAKING CHANGE:</strong> this update supports Node
<code>v24.x</code>. This is not a breaking change per-se but we're
treating it as such.</p>
<ul>
<li>Update README for download-artifact v5 changes by <a
href="https://github.com/yacaovsnc"><code>@​yacaovsnc</code></a> in <a
href="https://redirect.github.com/actions/download-artifact/pull/417">actions/download-artifact#417</a></li>
<li>Update README with artifact extraction details by <a
href="https://github.com/yacaovsnc"><code>@​yacaovsnc</code></a> in <a
href="https://redirect.github.com/actions/download-artifact/pull/424">actions/download-artifact#424</a></li>
<li>Readme: spell out the first use of GHES by <a
href="https://github.com/danwkennedy"><code>@​danwkennedy</code></a> in
<a
href="https://redirect.github.com/actions/download-artifact/pull/431">actions/download-artifact#431</a></li>
<li>Bump <code>@actions/artifact</code> to <code>v4.0.0</code></li>
<li>Prepare <code>v6.0.0</code> by <a
href="https://github.com/danwkennedy"><code>@​danwkennedy</code></a> in
<a
href="https://redirect.github.com/actions/download-artifact/pull/438">actions/download-artifact#438</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/danwkennedy"><code>@​danwkennedy</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/download-artifact/pull/431">actions/download-artifact#431</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/download-artifact/compare/v5...v6.0.0">https://github.com/actions/download-artifact/compare/v5...v6.0.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="018cc2cf5b"><code>018cc2c</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/download-artifact/issues/438">#438</a>
from actions/danwkennedy/prepare-6.0.0</li>
<li><a
href="815651c680"><code>815651c</code></a>
Revert &quot;Remove <code>github.dep.yml</code>&quot;</li>
<li><a
href="bb3a066a8b"><code>bb3a066</code></a>
Remove <code>github.dep.yml</code></li>
<li><a
href="fa1ce46bbd"><code>fa1ce46</code></a>
Prepare <code>v6.0.0</code></li>
<li><a
href="4a24838f3d"><code>4a24838</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/download-artifact/issues/431">#431</a>
from danwkennedy/patch-1</li>
<li><a
href="5e3251c4ff"><code>5e3251c</code></a>
Readme: spell out the first use of GHES</li>
<li><a
href="abefc31eaf"><code>abefc31</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/download-artifact/issues/424">#424</a>
from actions/yacaovsnc/update_readme</li>
<li><a
href="ac43a6070a"><code>ac43a60</code></a>
Update README with artifact extraction details</li>
<li><a
href="de96f4613b"><code>de96f46</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/download-artifact/issues/417">#417</a>
from actions/yacaovsnc/update_readme</li>
<li><a
href="7993cb44e9"><code>7993cb4</code></a>
Remove migration guide for artifact download changes</li>
<li>Additional commits viewable in <a
href="634f93cb29...018cc2cf5b">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/download-artifact&package-manager=github_actions&previous-version=5.0.0&new-version=6.0.0)](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>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-26 20:25:13 -07:00
dependabot[bot] 929c0d1a9b
build(deps): bump namespacelabs/nscloud-cache-action from 1.2.19 to 1.2.20 (#9366)
Bumps
[namespacelabs/nscloud-cache-action](https://github.com/namespacelabs/nscloud-cache-action)
from 1.2.19 to 1.2.20.
<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.20</h2>
<h2>What's Changed</h2>
<ul>
<li>xcode mode: Enable Xcode compilation cache. by <a
href="https://github.com/nichtverstehen"><code>@​nichtverstehen</code></a>
in <a
href="https://redirect.github.com/namespacelabs/nscloud-cache-action/pull/41">namespacelabs/nscloud-cache-action#41</a></li>
<li>Add xcode and swiftpm to the list of documented cache modes. by <a
href="https://github.com/nichtverstehen"><code>@​nichtverstehen</code></a>
in <a
href="https://redirect.github.com/namespacelabs/nscloud-cache-action/pull/42">namespacelabs/nscloud-cache-action#42</a></li>
<li>mode=xcode: Only cache CompilationCache directory. by <a
href="https://github.com/nichtverstehen"><code>@​nichtverstehen</code></a>
in <a
href="https://redirect.github.com/namespacelabs/nscloud-cache-action/pull/43">namespacelabs/nscloud-cache-action#43</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/namespacelabs/nscloud-cache-action/compare/v1...v1.2.20">https://github.com/namespacelabs/nscloud-cache-action/compare/v1...v1.2.20</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="d93899d984"><code>d93899d</code></a>
Merge pull request <a
href="https://redirect.github.com/namespacelabs/nscloud-cache-action/issues/43">#43</a>
from namespacelabs/kirill/cc</li>
<li><a
href="6238c10f1c"><code>6238c10</code></a>
mode=xcode: Only cache CompilationCache directory.</li>
<li><a
href="5e5a55de39"><code>5e5a55d</code></a>
Merge pull request <a
href="https://redirect.github.com/namespacelabs/nscloud-cache-action/issues/42">#42</a>
from namespacelabs/kirill/xcode</li>
<li><a
href="7183752eb8"><code>7183752</code></a>
Add xcode, swiftpm and cocoapods to the list of documented cache
modes.</li>
<li><a
href="2ecee7545c"><code>2ecee75</code></a>
Merge pull request <a
href="https://redirect.github.com/namespacelabs/nscloud-cache-action/issues/41">#41</a>
from namespacelabs/kirill/xcode</li>
<li><a
href="23f725648c"><code>23f7256</code></a>
xcode mode: Enable Xcode compilation cache.</li>
<li>See full diff in <a
href="caff5c9dc5...d93899d984">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.19&new-version=1.2.20)](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>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-26 20:24:51 -07:00
Mitchell Hashimoto 7d7c0bf5cd
lib-vt: Wasm SGR helpers and example (#9362)
This adds some convenience functions for parsing SGR sequences
WebAssembly and adds an example demonstrating SGR parsing in the
browser.
2025-10-26 13:19:55 -07:00
Justin Ma 19d1377659
ci: Upgrade hustcer/milestone-action to v3 (#9357)
Upgrade `hustcer/milestone-action` to v3, try to fix set milestone error
2025-10-26 08:26:18 -07:00
Mitchell Hashimoto 2f5c09c1bf
ci: update milestone action (#9354)
Fixes our failing CI, hopefully!
2025-10-26 06:52:32 -07:00
Mitchell Hashimoto a82ad89ef3
lib-vt: C API for SGR parser (#9352)
This exposes the SGR parser to the C and Wasm APIs. An example is shown
in c-vt-sgr.

Compressed example:

```c
#include <assert.h>
#include <stdio.h>
#include <ghostty/vt.h>

int main() {
  // Create parser
  GhosttySgrParser parser;
  assert(ghostty_sgr_new(NULL, &parser) == GHOSTTY_SUCCESS);

  // Parse: ESC[1;31m (bold + red foreground)
  uint16_t params[] = {1, 31};
  assert(ghostty_sgr_set_params(parser, params, NULL, 2) == GHOSTTY_SUCCESS);

  printf("Parsing: ESC[1;31m\n\n");

  // Iterate through attributes
  GhosttySgrAttribute attr;
  while (ghostty_sgr_next(parser, &attr)) {
    switch (attr.tag) {
      case GHOSTTY_SGR_ATTR_BOLD:
        printf("✓ Bold enabled\n");
        break;
      case GHOSTTY_SGR_ATTR_FG_8:
        printf("✓ Foreground color: %d (red)\n", attr.value.fg_8);
        break;
      default:
        break;
    }
  }

  ghostty_sgr_free(parser);
  return 0;
}
```

**AI disclosure:** Amp wrote most of the C headers, but I verified it
all. https://ampcode.com/threads/T-d9f145cb-e6ef-48a8-ad63-e5fc85c0d43e
2025-10-25 21:26:06 -07:00
Dusk 27b0978cd5
macos: use system beep for bell (#9339)
This seems pretty straightforward. I've tested it and it does what I'd
expect it to do.

Fixes #9338
2025-10-26 03:24:52 +00:00
Lukas fd969b53a5
macOS: fix #8282 (#9343)
After `ghostty_app_update_config`, `ghostty_action_config_change_s` was
fired with the correct config. This happens synchronously, which will
update `App.config` in `App.configChange(_:target:v:)`.

Previously, after updating, `App.config` was set with the stale one,
which caused #8282.
2025-10-25 20:08:32 -07:00
github-actions[bot] 75b4e8b5a7
Update iTerm2 colorschemes (#9349)
Upstream release:
https://github.com/mbadolato/iTerm2-Color-Schemes/releases/tag/release-20251020-150521-589c0ea

Co-authored-by: mitchellh <1299+mitchellh@users.noreply.github.com>
2025-10-25 18:11:16 -07:00
Daniel Wennberg 973cfd98a5
Update Inspector to the new Stream/VTHandler APIs (#9350)
Fixes a double-free bug when closing the inspector.

Not sure if there's a good way to add a test to check that allocation
and deallocation are sound here? To instantiate an Inspector you need a
Surface, which in turn requires an entire App/apprt. Doesn't look like
the repo has any tests with that kind of scope at the moment?
2025-10-25 18:10:59 -07:00
Mitchell Hashimoto 580262c96f
terminal: add ReadonlyStream that updates terminal state (#9346)
This adds a new stream handler implementation that updates terminal
state in reaction to VT sequences, but doesn't perform any of the
actions that would require responses (e.g. queries).

This is exposed in two ways: first, as a standalone `ReadonlyStream` and
`ReadonlyHandler` type that contains all the implementation. Second, as
a convenience func on `Terminal` as `vtStream` and `vtHandler` which
return their respective types preconfigured to update the calling
terminal state.

This dramatically simplifies libghostty-vt usage from Zig (and will
eventually be exposed to C, too) since a Terminal on its own is ready to
go as a full VT parser and state machine without needing to build any
custom types!

There's a second big bonus here which is that our `stream_readonly.zig`
tests are true end-to-end tests for raw bytes to terminal state. This
will let us test a wider variety of situations more broadly. To start,
there are only a handful of tests implemented here.

**AI disclosure:** Amp wrote basically this whole thing, but I reviewed
it. https://ampcode.com/threads/T-3490efd2-1137-4112-96f6-4bf8a0141ff5
2025-10-25 14:52:33 -07:00
Mitchell Hashimoto 186b91ef84
ci: temporarily disable FreeBSD test since it is failing 2025-10-25 13:37:39 -07:00
Mitchell Hashimoto 9703d6cb6c
macOS: update window appearance based on `preferredBackgroundColor` (#9344)
### Background

> Reported from
https://discord.com/channels/1005603569187160125/1320882404717625374/1431258448439279709


Per current implementation, when `macos-titlebar-style` is `tabs` or
`transparent`, the titlebar's background is hidden to enable a blur
effect, but this could result in an incorrect appearance when the
window's appearance is different from the one based on the terminal's
background color. For instance, with the following configs:

```
window-theme = "light"
// theme will be default to Ghostty, which is dark
```

or

```
window-theme = "system"
// theme will be default to Ghostty, which is dark
// and system theme is set to light
```

### Changes

Update window theme based on the terminal's background color when using
`tabs` or `transparent`
2025-10-25 13:34:13 -07:00
Mitchell Hashimoto 83104ff27a
Convert terminal.Stream to use a tagged union, remove `hasDecl` (#9342)
This removes our `@hasDecl` usage from `terminal.Stream` and instead
uses a tagged union approach similar to what we already do for apprt
actions. The reasons to do this:

1. It is less magic. You don't get new functionality by magically
implementing a function.
2. It is safer. You can't typo a function name and Zig's exhaustive enum
handling will force you to handle all cases (even if most cases are
no-ops). This also helps you as at the implementor know when new
functionality pops up.
3. It is easier to integrate into C (for libghostty-vt). We can expose a
single tagged union type with a single callback rather than whatever the
previous mess was. This PR doesn't do this yet.

In addition, this PR adds in some helpers necessary to make it easier to
make C ABI compatible tagged unions. This lays the groundwork for our
libghostty-vt work but isn't exposed directly there yet. This PR has no
functional changes. Everything should behave identically as before.

I'm PRing this now because its already a huge diff, and I want to get
this in before I make more meaningful changes such as exposing some of
this to libghostty or adding a simpler Stream handler that maps to
terminal state for the Zig module and so on.

## Benchmarks

There's no meaningful impact on VT processing, I'd say all changes seen
below are noise:

<img width="2038" height="1392" alt="CleanShot 2025-10-25 at 07 10
04@2x"
src="https://github.com/user-attachments/assets/af6fa611-5b35-44d0-91ae-26955b1f980a"
/>

## One more `@hasDecl`

There is one more `hasDecl` remaining for `handleManually`. This is a
special case that's only used by our inspector. I think there is a
better way to do this but I didn't want to bloat this PR with anything
more! This doesn't impact our primary consumers of stream.

## AI Disclosure

I used AI considerably in handling the rote tasks in refactoring this. I
did the design myself manually but then prompted AI to help complete it
step by step. I did review each manually and understand it but I want to
take a careful review again...
2025-10-25 13:33:18 -07:00
Lars d39cc6d478
macOS: update window appearance based on `preferredBackgroundColor` 2025-10-25 19:35:34 +02:00
Mitchell Hashimoto 1d03451d4f
terminal: OSC color operations 2025-10-25 07:03:21 -07:00
Mitchell Hashimoto e13f9b9e8c
terminal: kitty color 2025-10-25 06:42:20 -07:00
Mitchell Hashimoto a85ad0e4f8
terminal: unused decls 2025-10-24 15:20:16 -07:00
Mitchell Hashimoto e49694439c
terminal: setAttribute 2025-10-24 11:53:25 -07:00
Mitchell Hashimoto 56376a8a38
sgr: make C compat 2025-10-24 11:48:01 -07:00
Mitchell Hashimoto 5ba451d073
terminal: configureCharset 2025-10-24 11:27:48 -07:00
Mitchell Hashimoto 4d028dac1f
terminal: some osc types 2025-10-24 11:17:31 -07:00
Jon Parise 3f75c66e83
cli: simplify +ssh-cache cache key validation (#9331)
Remove the semi-magic upper bound on the total cache key length. The
hostname and username validation routines will perform their own length
checks.

Also consolidate this function's tests. We previously had a few
redundant test cases.
2025-10-24 07:28:50 -07:00
Mitchell Hashimoto bce1164ae6
terminal: cursor style 2025-10-24 07:26:04 -07:00
Mitchell Hashimoto fd0f9bb843
terminal: device attributes 2025-10-24 07:17:44 -07:00
Mitchell Hashimoto a4a37534d7
terminal: missed some invoke charsets 2025-10-24 07:11:09 -07:00
Mitchell Hashimoto e347ab6915
terminal: device attributes 2025-10-24 07:08:34 -07:00
Mitchell Hashimoto 109376115b
terminal: convert dcs 2025-10-23 21:29:18 -07:00
Mitchell Hashimoto 6902d89d91
terminal: convert APC 2025-10-23 21:24:31 -07:00
Mitchell Hashimoto b91149f0fe
terminal: simple esc dispatch 2025-10-23 21:18:51 -07:00
Mitchell Hashimoto 9cd4594356
terminal: active status display 2025-10-23 21:14:21 -07:00
Mitchell Hashimoto f68ea7c907
terminal: many more conversions 2025-10-23 21:10:25 -07:00
Mitchell Hashimoto 2520e27aef
terminal: kitty keyboard actions 2025-10-23 20:55:08 -07:00
Mitchell Hashimoto b7ea979f38
terminal: zero-arg actions 2025-10-23 20:47:02 -07:00
Mitchell Hashimoto 0df4d5c5a4
terminal: margins 2025-10-23 20:37:34 -07:00
Mitchell Hashimoto c1e57dd330
terminal: setprotectedmode 2025-10-23 20:31:17 -07:00
Mitchell Hashimoto 25eee9379d
terminal: request mode 2025-10-23 20:26:14 -07:00
Mitchell Hashimoto b6ac4c764f
terminal: modify_other_keys 2025-10-23 20:26:11 -07:00
Mitchell Hashimoto 94a8fa05cb
terminal: convert modes 2025-10-23 20:07:45 -07:00
Mitchell Hashimoto dc5406781f
terminal: many more conversions 2025-10-23 19:56:13 -07:00
Mitchell Hashimoto 37016d8b89
terminal: erase/insert lines, characters, etc. 2025-10-23 16:44:49 -07:00
Mitchell Hashimoto b0fb3ef9a9
terminal: erase display conversion 2025-10-23 16:38:10 -07:00
Mitchell Hashimoto b5da54d925
terminal: horizontal tab 2025-10-23 16:28:38 -07:00
Mitchell Hashimoto ccd821a0ff
terminal: convert cursor movements 2025-10-23 16:22:43 -07:00
Mitchell Hashimoto 2ef89c153a
terminal: convert C0 2025-10-23 15:52:42 -07:00
Mitchell Hashimoto f7189d14b9
terminal: convert Stream to use Action tagged union 2025-10-23 15:50:56 -07:00
Mitchell Hashimoto 099dcbe04d
lib: add a `TaggedUnion` helper to create C ABI compatible tagged unions 2025-10-23 15:50:54 -07:00
Mitchell Hashimoto fb5b8d7968
input: command palette actions must use formatter, not tag (#9325)
Regression from our Zig 0.15 migration.
2025-10-23 12:49:55 -07:00
Mitchell Hashimoto 66486901f5
examples/wasm-key-encode: update README 2025-10-23 12:49:38 -07:00
Mitchell Hashimoto 5c574e7745
macos: use TextEditor instead of Text for clipboard confirmation (#9324)
Fixes #9322

SwiftUI `Text` has huge performance issues. On my maxed out MBP it hangs
for any text more than 100KB (it took ~8s to display it!). `TextEditor`
with a constant value works much better and handles scrolling for us,
too!
2025-10-23 09:22:35 -07:00
Daniel Wennberg e2fe0cf53a
macOS: remove scroll edge styling with hidden titlebar (#9317)
With `macos-titlebar-style = hidden`, creating splits or cycling
fullscreen sometimes produces a transparent overlay in the titlebar
area, clipping the top of the surfaces:

<img width="504" height="272" alt="Screenshot 2025-10-22 at 21 27 28"
src="https://github.com/user-attachments/assets/e28c5226-2e47-4c1d-8c14-b286fdb261f3"
/>

This is actually SwiftUI styling for scroll views, and the fact that it
pops up even though the titlebar is hidden is possibly a SwiftUI bug; at
least it's causing frustration for others too, see
https://developer.apple.com/forums/thread/798392 and
https://stackoverflow.com/questions/79776037/strange-nsscrollpocket-height-on-my-nstableview-in-fullscreen-mode-on-macos-taho.

I tried setting `.scrollEdgeEffectHidden()` on various nodes in the
SwiftUI hierarchy, but couldn't get it to work, so I ended up resorting
to an old-fashioned game of imperative whack-a-mole. Now:

<img width="504" height="272" alt="Screenshot 2025-10-22 at 21 28 47"
src="https://github.com/user-attachments/assets/e4499f16-5bd0-43cd-a7de-37fbc56eb1c4"
/>

AI disclosure (my first!): I consulted copilot trying to figure out of
the whole SwiftUI/AppKit situation and whether there might be a
declarative solution on the SwiftUI side. Just chatting in general terms
without showing real-world code. No dice.
2025-10-23 08:33:39 -07:00
Mitchell Hashimoto b764055c33
macos: window-position-x/y works with window-width/height (#9313)
Fixes #9132

We were processing our window size defaults separate from our window
position and the result was that you'd get some incorrect behavior.
Unify the logic more to fix the positioning.

Note there is room to improve this further, I think that all initial
positioning could go into the controller completely. But I wanted to
minimize the diff for a backport.
2025-10-22 16:14:28 -07:00
Mitchell Hashimoto bdbda2fd83
input: accidentally merged a loud log line 2025-10-22 15:36:21 -07:00
Mitchell Hashimoto c133fac7e7
lib-vt: wasm convenience functions and a simple example (#9309)
This adds a set of Wasm convenience functions to ease memory management.
These are all prefixed with `ghostty_wasm` and are documented as part of
the standard Doxygen docs.

I also added a very simple single-page HTML example that demonstrates
how to use the Wasm module for key encoding.

This also adds a bunch of safety checks to the C API to verify that
valid values are actually passed to the function. This is an easy to hit
bug.

**AI disclosure:** The example is AI-written with Amp. I read through
all the code and understand it but I can't claim there isn't a better
way, I'm far from a JS expert. It is simple and works currently though.
Happy to see improvements if anyone wants to contribute.
2025-10-22 14:25:52 -07:00
Mitchell Hashimoto 9dc2e5978f
lib-vt: enable freestanding wasm builds (#9301)
This makes `libghostty-vt` build for freestanding wasm targets (aka a
browser) and produce a `ghostty-vt.wasm` file. This exports the same C
API that libghostty-vt does.

This commit specifically makes the changes necessary for the build to
build properly and for us to run the build in CI. We don't yet actually
try using it...
2025-10-21 20:55:54 -07:00
Jared Gizersky 3548acfac6
os: handle nil languageCode/countryCode in setLangFromCocoa (#9290)
Fixes a crash when NSLocale returns nil for languageCode or countryCode
properties. This can happen when the app launches without locale
environment variables set.

The crash occurs at `src/os/locale.zig:87-88` when trying to call
`getProperty()` on a nil object. The fix adds a null check and falls
back to `en_US.UTF-8` instead of dereferencing null.

## Testing
Tested by running with locale variables unset:
```bash
unset LC_ALL && ./zig-out/Ghostty.app/Contents/MacOS/ghostty
```

Before: segmentation fault  
After: launches successfully with fallback locale
2025-10-20 20:27:04 -07:00
Mitchell Hashimoto da165fc3cf
input: modify other keys 2 should use all mods, ignore consumed mods (#9289)
Fixes #8900

Our xterm modify other keys state 2 encoding was stripped consumed mods
from the keyboard event. This doesn't match xterm or other popular
terminal emulators (but most importantly: xterm). Use the full set of
mods and add a test to verify this.

Reproduction:

```
printf '\033[>4;2m' 
cat
```

Then press `ctrl+shift+h` and compare across terminals.
2025-10-20 14:41:35 -07:00
Mitchell Hashimoto 0546606e05
build: add -Demit-themes option to emit/omit theme resources (#9288)
We'll backport this to 1.2.x for distros that would prefer this.
2025-10-20 13:14:42 -07:00
Matthew Hrehirchuk 2696d50ca4
feat: added mouse-reporting / toggle-mouse-reporting (#9282)
Closes #8430

A few questions:
* Should I set a default keybind for `toggle-mouse-reporting`? The issue
mentioned one, it's currently unset.
* Am I handling the `toggle-mouse-reporting` action properly in
`performAction` (gtk) / `action` (macos)?

Copilot was used to understand the codebase, but code was authored
manually.
2025-10-19 20:45:37 -07:00
Mitchell Hashimoto 1b86691896
termio: use a union to represent how a process is started (#9278)
This cleans up some of our termio exec code by unifying process launch
state into a single union type. This makes it easier to distinguish
between the current two mutually exclusive modes of launching a process:
fork/exec and flatpak dbus commands.

It also ensures everyplace we touch related to process launching is
forced to address every case (exhaustive switch handling). I did find
one resource cleanup bug based on this cleanup, which is also fixed
here. This just improves memory slightly so it's not a big deal.

If we add future ways to launch processes, we can add a new union case.
For example, I originally had a `posix_spawn` option while I was
experimenting with that before abandoning it (see #9274).
2025-10-19 20:43:28 -07:00
Mitchell Hashimoto 014de2992e
macos: goto_split direction is performable (#9284)
Fixes #9283

There was a comment here noting this deficiency. GTK implements this
properly.
2025-10-19 20:29:36 -07:00
Mitchell Hashimoto c65e837b22
cli: fix +ssh-cache IPv6 address validation (#9281)
The host validation code previously expected IPv6 addresses to be
enclosed in [brackets], but that's not how ssh(1) expects them.

This change removes that requirement and reimplements the host
validation routine to check for valid hostnames and IP addresses (IPv4
and IPv6) using standard routines rather than custom logic.

Fixes #9251
2025-10-19 19:47:41 -07:00
Mitchell Hashimoto 88ec71dd5a
build(deps): bump flatpak/flatpak-github-actions from 6.5 to 6.6 (#9279)
Bumps
[flatpak/flatpak-github-actions](https://github.com/flatpak/flatpak-github-actions)
from 6.5 to 6.6.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/flatpak/flatpak-github-actions/releases">flatpak/flatpak-github-actions's
releases</a>.</em></p>
<blockquote>
<h2>v6.6</h2>
<ul>
<li>Specify full URL policy when mirroring screenshots</li>
<li>Fix restore cache keys to actually include arch</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="92ae9851ad"><code>92ae985</code></a>
Fix restore cache keys to actually include arch</li>
<li><a
href="b8a638469e"><code>b8a6384</code></a>
Specify full URL policy when mirroring screenshots</li>
<li><a
href="6684584b07"><code>6684584</code></a>
Switch funding to flatpak instead</li>
<li><a
href="e5aa88fb51"><code>e5aa88f</code></a>
readme: Update flathub images list</li>
<li><a
href="b93832bada"><code>b93832b</code></a>
Sync readme from flathub's fork</li>
<li>See full diff in <a
href="10a3c29f01...92ae9851ad">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=flatpak/flatpak-github-actions&package-manager=github_actions&previous-version=6.5&new-version=6.6)](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-10-19 19:46:46 -07:00
Mitchell Hashimoto 58a1b60a4b
build(deps): bump namespacelabs/nscloud-cache-action from 1.2.18 to 1.2.19 (#9280)
Bumps
[namespacelabs/nscloud-cache-action](https://github.com/namespacelabs/nscloud-cache-action)
from 1.2.18 to 1.2.19.
<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.19</h2>
<h2>What's Changed</h2>
<ul>
<li>Add <code>Playwright</code> cache framework by <a
href="https://github.com/rcrowe"><code>@​rcrowe</code></a> in <a
href="https://redirect.github.com/namespacelabs/nscloud-cache-action/pull/40">namespacelabs/nscloud-cache-action#40</a></li>
<li>Add <code>apt</code> cache framework by <a
href="https://github.com/rcrowe"><code>@​rcrowe</code></a> in <a
href="https://redirect.github.com/namespacelabs/nscloud-cache-action/pull/39">namespacelabs/nscloud-cache-action#39</a></li>
<li>Bump GitHub action workflows by <a
href="https://github.com/deining"><code>@​deining</code></a> in <a
href="https://redirect.github.com/namespacelabs/nscloud-cache-action/pull/37">namespacelabs/nscloud-cache-action#37</a></li>
<li>Warn if mounted cache directory already exists by <a
href="https://github.com/rcrowe"><code>@​rcrowe</code></a> in <a
href="https://redirect.github.com/namespacelabs/nscloud-cache-action/pull/38">namespacelabs/nscloud-cache-action#38</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/rcrowe"><code>@​rcrowe</code></a> made
their first contribution in <a
href="https://redirect.github.com/namespacelabs/nscloud-cache-action/pull/40">namespacelabs/nscloud-cache-action#40</a></li>
<li><a href="https://github.com/deining"><code>@​deining</code></a> made
their first contribution in <a
href="https://redirect.github.com/namespacelabs/nscloud-cache-action/pull/37">namespacelabs/nscloud-cache-action#37</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/namespacelabs/nscloud-cache-action/compare/v1...v1.2.19">https://github.com/namespacelabs/nscloud-cache-action/compare/v1...v1.2.19</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="caff5c9dc5"><code>caff5c9</code></a>
Merge pull request <a
href="https://redirect.github.com/namespacelabs/nscloud-cache-action/issues/38">#38</a>
from rcrowe/mount-target-exists-error</li>
<li><a
href="4e2102fe86"><code>4e2102f</code></a>
Catch filesystem errors</li>
<li><a
href="e84601ffd1"><code>e84601f</code></a>
Handle case where mount target exists</li>
<li><a
href="4878cb2fed"><code>4878cb2</code></a>
Merge pull request <a
href="https://redirect.github.com/namespacelabs/nscloud-cache-action/issues/37">#37</a>
from deining/bump-workflows</li>
<li><a
href="818af18748"><code>818af18</code></a>
bump go versions</li>
<li><a
href="bf91808d15"><code>bf91808</code></a>
Merge pull request <a
href="https://redirect.github.com/namespacelabs/nscloud-cache-action/issues/39">#39</a>
from rcrowe/apt-framework</li>
<li><a
href="7245a34835"><code>7245a34</code></a>
Address feedback with clearer variable names</li>
<li><a
href="bf55a8733d"><code>bf55a87</code></a>
add actions workflow to test</li>
<li><a
href="856ef89a7a"><code>856ef89</code></a>
apt-config is noisy in the logs</li>
<li><a
href="fd911d7189"><code>fd911d7</code></a>
Remove docker-clean script</li>
<li>Additional commits viewable in <a
href="7baedde84b...caff5c9dc5">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.18&new-version=1.2.19)](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-10-19 19:46:39 -07:00
Jon Parise e522482710 cli: fix +ssh-cache IPv6 address validation
The host validation code previously expected IPv6 addresses to be
enclosed in [brackets], but that's not how ssh(1) expects them.

This change removes that requirement and reimplements the host
validation routine to check for valid hostnames and IP addresses (IPv4
and IPv6) using standard routines rather than custom logic.
2025-10-19 20:31:32 -04:00
dependabot[bot] d01697e7d5
build(deps): bump namespacelabs/nscloud-cache-action
Bumps [namespacelabs/nscloud-cache-action](https://github.com/namespacelabs/nscloud-cache-action) from 1.2.18 to 1.2.19.
- [Release notes](https://github.com/namespacelabs/nscloud-cache-action/releases)
- [Commits](7baedde84b...caff5c9dc5)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-20 00:10:08 +00:00
dependabot[bot] b2559e8d92
build(deps): bump flatpak/flatpak-github-actions from 6.5 to 6.6
Bumps [flatpak/flatpak-github-actions](https://github.com/flatpak/flatpak-github-actions) from 6.5 to 6.6.
- [Release notes](https://github.com/flatpak/flatpak-github-actions/releases)
- [Commits](10a3c29f01...92ae9851ad)

---
updated-dependencies:
- dependency-name: flatpak/flatpak-github-actions
  dependency-version: '6.6'
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-20 00:09:59 +00:00
Mitchell Hashimoto 40e558f953
os: remove unused UrlParsingError (#9275)
This is no longer used as of e5247f6d.
2025-10-19 15:16:45 -07:00
Mitchell Hashimoto 78621622e6
os: add RFC 1123-compliant hostname.isValid (#9276)
std.net.isValidHostname is currently too generous. It considers strings
like ".example.com", "exa..mple.com", and "-example.com" to be valid
hostnames, which is incorrect according to RFC 1123 (the currently
accepted standard).

Until the standard library function is improved, we can use this local
implementation that does follow the RFC 1123 standard.

I asked Claude to perform an audit of the code based on its understand
of the RFC. It suggested some additional test cases and considers the
overall implementation to be robust (its words) and standards compliant.

Ref: https://www.rfc-editor.org/rfc/rfc1123
2025-10-19 15:16:12 -07:00
Jon Parise 010cbce220 os: add RFC 1123-compliant hostname.isValid
std.net.isValidHostname is currently too generous. It considers strings
like ".example.com", "exa..mple.com", and "-example.com" to be valid
hostnames, which is incorrect according to RFC 1123 (the currently
accepted standard).

Until the standard library function is improved, we can use this local
implementation that does follow the RFC 1123 standard.

I asked Claude to perform an audit of the code based on its understand
of the RFC. It suggested some additional test cases and considers the
overall implementation to be robust (its words) and standards compliant.

Ref: https://www.rfc-editor.org/rfc/rfc1123
2025-10-19 14:36:02 -04:00
Jon Parise 73da748390 os: remove unused UrlParsingError
This is no longer used as of e5247f6d.
2025-10-19 13:12:32 -04:00
Mitchell Hashimoto 94c5572029
fix: fish shell integration should not update the universal `fish_user_paths` variable (#9273)
`fish_add_path` by default updates the `fish_user_paths` universal
variable which makes the modification persist across shell sessions.

The integration also tries to update the `fish_user_paths` when the
desired path already appears in the `PATH` environment variable but not
in `fish_user_paths`. Because `fish_user_paths` will always be inserted
before the inherited `PATH` env. This makes the added path
unintentionally has a higher priority.

This patch fixes the above issues by adding `--global` and `--path`
options to `fish_user_paths` which limits the modification scope and
ensures that the path won't be added if it already exists in `PATH`.

Ref: https://fishshell.com/docs/current/cmds/fish_add_path.html
2025-10-19 08:19:01 -07:00
Sola c6788dd178
fix: fish shell integration should not modify universal path variable
`fish_add_path` by default updates the `fish_user_paths` universal
variable which makes the modification persist across shell sessions.

The integration also tries to update the `fish_user_paths` when the
desired path already appears in the `PATH` environment variable but
not in `fish_user_paths`. Because `fish_user_paths` will always be
inserted before the inherited `PATH` env. This makes the added path
unintentionally has a higher priority.

This patch makes the above issues by adding `--global` and `--path`
options to `fish_user_paths` which limits the modification scope and
ensures that the path won't be added if it already exists in `PATH`.
2025-10-19 20:46:48 +08:00
Mitchell Hashimoto f74bfdaa2a
Update iTerm2 colorschemes (#9269)
Upstream release:
https://github.com/mbadolato/iTerm2-Color-Schemes/releases/tag/release-20251013-150525-147b9d3
2025-10-18 21:34:50 -07:00
Mitchell Hashimoto be608ea2d1
renderer: don't allow the scrollbar state to block the renderer (#9270)
This fixes the source of a deadlock that some tip users have hit. If our
surface mailbox is full and there is a dirty scrollbar state, then
drawFrame would block forever trying to queue to the surface mailbox.

We now fail instantly if the queue is full and keep the scrollbar state
dirty. We can try again on the next frame, it's not a critical thing to
get updated.
2025-10-18 21:34:27 -07:00
Mitchell Hashimoto 3a9eedcd15
renderer: don't allow the scrollbar state to block the renderer
This fixes the source of a deadlock that some tip users have hit. If our 
surface mailbox is full and there is a dirty scrollbar state, then
drawFrame would block forever trying to queue to the surface mailbox.

We now fail instantly if the queue is full and keep the scrollbar state
dirty. We can try again on the next frame, it's not a critical thing to
get updated.
2025-10-18 21:30:11 -07:00
mitchellh 92c9ba67d5 deps: Update iTerm2 color schemes 2025-10-19 00:15:26 +00:00
tdslot be0da4845c
🌐 i18n(locale): add lithuanian language support (#8711)
Co-authored-by: Andrius Budvytis <154380884+abudvytis@users.noreply.github.com>
2025-10-18 19:27:39 +02:00
Mitchell Hashimoto dffa4f4fc7
macos: use stable display UUID for quick terminal screen tracking (#9256)
NSScreen instances can be garbage collected at any time, even for
screens that remain connected, making NSMapTable with weak keys
unreliable for tracking per-screen state.

This changes the quick terminal to use CGDisplay UUIDs as stable
identifiers, keyed in a strong dictionary. Each entry stores the window
frame along with screen dimensions, scale factor, and last-seen
timestamp.

**This should make quick terminal size restore more stable than 1.2.2.**

Rules for pruning:
- Entries are invalidated when screens shrink or change scale
- Entries persist and update when screens grow (allowing cached state to
work with larger resolutions)
- Stale entries for disconnected screens expire after 14 days.
- Maximum of 10 screen entries to prevent unbounded growth
2025-10-17 21:14:56 -07:00
Mitchell Hashimoto ea505ec51d
macos: use stable display UUID for quick terminal screen tracking
NSScreen instances can be garbage collected at any time, even for
screens that remain connected, making NSMapTable with weak keys
unreliable for tracking per-screen state.

This changes the quick terminal to use CGDisplay UUIDs as stable
identifiers, keyed in a strong dictionary. Each entry stores the
window frame along with screen dimensions, scale factor, and last-seen
timestamp.

Rules for pruning:
- Entries are invalidated when screens shrink or change scale
- Entries persist and update when screens grow (allowing cached state
  to work with larger resolutions)
- Stale entries for disconnected screens expire after 14 days.
- Maximum of 10 screen entries to prevent unbounded growth
2025-10-17 21:04:23 -07:00
Mitchell Hashimoto 3e6bda1fff
ci: run release-tip even if prior step failed 2025-10-17 21:03:23 -07:00
Mitchell Hashimoto 5bf05dfe31
macos: make terminal smaller to account for legacy scrollbar (#9255)
https://github.com/ghostty-org/ghostty/discussions/9254

When the preferred scrollbar style is "legacy", the scrollbar takes up
space that offsets the actual terminal. To prevent reflow, we detect
this before the scrollbar becomes visible and shrink our terminal width
to prepare for it.

This doesn't account for the style changing at runtime, yet.

## Demo

Notice even before scrollbars, the `gh` output doesn't wrap.


https://github.com/user-attachments/assets/8716ff4d-0660-48b1-aadb-0d31e0b70fcd
2025-10-17 20:18:10 -07:00
Mitchell Hashimoto 5b7f145640
macos: make terminal smaller to account for legacy scrollbar
When the preferred scrollbar style is "legacy", the scrollbar takes up
space that offsets the actual terminal. To prevent reflow, we detect
this before the scrollbar becomes visible and shrink our terminal width
to prepare for it.

This doesn't account for the style changing at runtime, yet.
2025-10-17 20:08:03 -07:00
Mitchell Hashimoto e4db7f5487
font: Default to light hinting in FreeType (#9253)
This changes the default FreeType load target to `FT_LOAD_TARGET_LIGHT`,
giving the hinter a lighter touch in line with the default behavior in
most other GTK apps, and adds a load flag such that the old hinting
behavior can be restored via config.

As discussed in
https://github.com/ghostty-org/ghostty/issues/8674#issuecomment-3417082534.
However, this doesn't close that issue, as it still doesn't respect
custom Fontconfig settings. It's just a stopgap solution bringing
Ghostty's defaults more in line with the typical results of not
customizing Fontconfig.
2025-10-17 17:14:57 -07:00
Daniel Wennberg ad9f9dc11e font: Default to light hinting in FreeType 2025-10-17 15:04:04 -07:00
Mitchell Hashimoto 3b8e683d96
renderer: force a full rebuild on any font grid change (#9252)
Fixes #2731 (again)

This regressed in 1.2 due to the renderer rework missing porting this. I
believe this issue is still valid even with the rework since the font
grid changes the atlas and if there are still cached cells that
reference the old atlas coordinates it will produce garbage.
2025-10-17 14:51:30 -07:00
Mitchell Hashimoto 1cc22f93ca
renderer: force a full rebuild on any font grid change
Fixes #2731 (again)

This regressed in 1.2 due to the renderer rework missing porting this. I
believe this issue is still valid even with the rework since the font
grid changes the atlas and if there are still cached cells that
reference the old atlas coordinates it will produce garbage.
2025-10-17 14:46:58 -07:00
Mitchell Hashimoto 063070915f
gtk: Scrollbars (#9245)
Fixes #111 

This builds on the prior work and adds scrollbars to the GTK
application. After this PR, both the macOS and GTK applications support
scrollbars and #111 can be closed.

## TODO

- [x] Verify that with text coming out if we manually scroll to the
bottom we bind to the bottom
- [x] Valgrind checks
2025-10-17 09:21:57 -07:00
Mitchell Hashimoto ed443bc6ed
gtk: Scrollbars 2025-10-17 09:19:02 -07:00
Mitchell Hashimoto a2e95ce7b5
macOS: Remove hidden titlebar safe area and pad document height in SurfaceScrollView (#9241)
Fixes #9233. The issue was that the content view was effectively
truncated by `SurfaceScrollView`s safe area insets covering the titlebar
(I suppose the scroll view doesn't inherit the `ignoresSafeArea`
modifier on `TerminalSplitTreeView` because it's not actually a node in
that tree, it just contains a subview that is). I think it's OK to zero
these insets unconditionally, as I don't think the frame size passed
down from `SurfaceWrapper` will ever overlap with a visible titlebar.

This PR also fixes a somewhat related issue I discovered along the way.
In many cases, the mouse wouldn't work on the first row of text, whether
trying to select text or interact with TUI elements like neovim
bufferlines/tablines. When looking at the inspector while moving the
mouse around, you'd see the mouse position jump discontinuously from a
y-coordinate of 10-20 pixels to -3, i.e., no longer within the surface.

The problem turned out to be that the height of the document view only
included the text lines, not the window padding, while the content view
is sized to the surface including padding. If you imagine the
metaphorical sliding of the viewport up and down the document, and you
require the text to snap to a fixed grid on the viewport, it's clear
that the document must have the same top and bottom padding as the
viewport, otherwise the math breaks at the ends. Sure enough, adding
this padding fixed the problem.

To properly reproduce these issues and see the effect of the fixes, it's
helpful to change the system settings to always show scroll bars
(Appearance -> Show scroll bars -> Always). That's what connecting an
external mouse was all about. You should also remove the debug banner or
use a release build, otherwise the banner takes the place of the hidden
titlebar and conceals the issue.
2025-10-17 06:34:25 -07:00
Daniel Wennberg 51b2374616 Add window padding to scrollView document height 2025-10-17 00:14:21 -07:00
Daniel Wennberg ffead466c7 Remove hidden titlebar safe area for SurfaceScrollView 2025-10-17 00:06:00 -07:00
Mitchell Hashimoto 58699c7992
macOS: remove background from SurfaceScrollView (#9234)
<img width="1157" height="126" alt="image"
src="https://github.com/user-attachments/assets/07f67e6c-76b3-4d7d-ba44-37e85b8660cc"
/>
2025-10-16 14:56:47 -07:00
Lars cc91e2ad16
macOS: remove background from SurfaceScrollView 2025-10-16 23:52:07 +02:00
Mitchell Hashimoto 0e0bbfaa61
macOS: Scrollbars (#9232)
Completes #111 for macOS

This builds on #9225 and adds the native, macOS GUI scrollbars for
terminals.

This doesn't do GTK, but all the groundwork is there to make this easy
on GTK, depending on how scrollviews work there. I have to look into
that still. But in theory all the information and controls we provide
out of core are generic to _any_ scrollbar drawing.

## Demo


https://github.com/user-attachments/assets/85683bf9-1117-4f32-aaec-d926edd68c39

## Details

- The scrollbars respect your macOS system settings on style, color,
visibility.
- A new configuration `scrollbar` controls whether scrollbars are
visible (defaults to `system` allowing the system to choose).
- There is a new keybind action `scroll_to_row:N` that lets you jump to
an absolute row number N. This is implemented efficiently. This is how
grabbing the knob and scrolling works.
2025-10-16 14:09:33 -07:00
Mitchell Hashimoto 4b34b2389a
config: add `scrollbar` config to control when scrollbars appear 2025-10-16 14:06:48 -07:00
Mitchell Hashimoto 7207ff08d5
macos: SurfaceScrollView 2025-10-16 14:06:46 -07:00
Mitchell Hashimoto 2937aff513
gtk: mark scrollbar as unimplemented 2025-10-16 09:36:47 -07:00
Mitchell Hashimoto c86266cd90
input: scroll_to_row action 2025-10-16 09:11:03 -07:00
Mitchell Hashimoto 135136f733
terminal: PageList scroll to absolute row function 2025-10-16 09:11:03 -07:00
Mitchell Hashimoto da7736cd44
renderer: emit scrollbar apprt event when scrollbar changes 2025-10-15 21:45:01 -07:00
Mitchell Hashimoto 5a9bd0e49e
snap: update to Zig 0.15.2 2025-10-15 20:04:37 -07:00
dependabot[bot] 3ffbd87a0f
build(deps): bump cachix/install-nix-action from 31.8.0 to 31.8.1 (#9226)
Bumps
[cachix/install-nix-action](https://github.com/cachix/install-nix-action)
from 31.8.0 to 31.8.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.8.1</h2>
<h2>What's Changed</h2>
<ul>
<li>nix: 2.32.0 -&gt; 2.32.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/258">cachix/install-nix-action#258</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/cachix/install-nix-action/compare/v31...v31.8.1">https://github.com/cachix/install-nix-action/compare/v31...v31.8.1</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="fd24c48048"><code>fd24c48</code></a>
Merge pull request <a
href="https://redirect.github.com/cachix/install-nix-action/issues/258">#258</a>
from cachix/create-pull-request/patch</li>
<li><a
href="a55fd2d847"><code>a55fd2d</code></a>
nix: 2.32.0 -&gt; 2.32.1</li>
<li>See full diff in <a
href="7ab6e7fd29...fd24c48048">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.8.0&new-version=31.8.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>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-15 19:43:35 -07:00
dependabot[bot] 123d23682a
build(deps): bump namespacelabs/nscloud-setup-buildx-action from 0.0.19 to 0.0.20 (#9227)
Bumps
[namespacelabs/nscloud-setup-buildx-action](https://github.com/namespacelabs/nscloud-setup-buildx-action)
from 0.0.19 to 0.0.20.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/namespacelabs/nscloud-setup-buildx-action/releases">namespacelabs/nscloud-setup-buildx-action's
releases</a>.</em></p>
<blockquote>
<h2>v0.0.20</h2>
<h2>What's Changed</h2>
<ul>
<li>Add wait-for-builder input to eagerly start build clusters and wait
for them by <a
href="https://github.com/annervisser"><code>@​annervisser</code></a> in
<a
href="https://redirect.github.com/namespacelabs/nscloud-setup-buildx-action/pull/11">namespacelabs/nscloud-setup-buildx-action#11</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/annervisser"><code>@​annervisser</code></a>
made their first contribution in <a
href="https://redirect.github.com/namespacelabs/nscloud-setup-buildx-action/pull/11">namespacelabs/nscloud-setup-buildx-action#11</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/namespacelabs/nscloud-setup-buildx-action/compare/v0...v0.0.20">https://github.com/namespacelabs/nscloud-setup-buildx-action/compare/v0...v0.0.20</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="91c2e65377"><code>91c2e65</code></a>
Merge pull request <a
href="https://redirect.github.com/namespacelabs/nscloud-setup-buildx-action/issues/11">#11</a>
from namespacelabs/add-wait-for-builder-input-to-eager...</li>
<li><a
href="459dd43ae1"><code>459dd43</code></a>
Add wait-for-builder input to eagerly start build clusters and wait for
them</li>
<li>See full diff in <a
href="7020d7d8e6...91c2e65377">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=namespacelabs/nscloud-setup-buildx-action&package-manager=github_actions&previous-version=0.0.19&new-version=0.0.20)](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>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-15 19:43:22 -07:00
Mitchell Hashimoto e1b527fb9a
core: PageList tracks minimum metadata for rendering a scrollbar (#9225)
Related to #111

This adds the necessary logic and data for the `PageList` data structure
to keep track of **total length** of the screen, **offset** into the
viewport, and **length** of the viewport. These three values are
necessary to _render_ a scrollbar. This PR updates the renderer to grab
this information but stops short of actually drawing a scrollbar (which
we'll do with native UI), in the interest of having a PR that doesn't
contain too many changes.

**This doesn't yet draw a scrollbar, these are just the internal changes
necessary to support it.**

## Background

The `PageList` structure is very core to how we represent terminal
state. It maintains a doubly linked list of "pages" (not literally
virtual memory pages, but close). Each page stores cell information,
styles, hyperlinks, etc fully self-contained in a contiguous sets of VM
pages using offset addresses rather than full pointers. **Pages are not
guaranteed to be equal sizes.** (This is where scrollbars get difficult)

Because it is a linked list structure of non-equal sized nodes, it isn't
amenable to typical scrollbar behavior. A scrollbar needs to know: full
size, offset, and length in order to draw the scrollbar properly.
Getting these values naively is `O(N)` within the data structure that is
on the hottest IO performance path in all of Ghostty.

## Implementation

### PageList

We now maintain two cached values for **total length** and **viewport
offset**.

The total length is relatively straightforward, we just have to be
careful to update it in every operation that could add or remove rows.
I've done this and ensured that every place we update it is covered with
unit test coverage.

The viewport offset is nasty, but I came up with what I believe is a
good solution. The viewport when arbitrarily scrolled is defined as a
direct pointer to the linked list node plus a row offset into that node.
The only way to calculate offset from the top is `O(N)`.

But we have a couple shortcuts:

1. If the viewport is at the bottom (most common) or top, calculating
the offset is `O(1)`: bottom is `total_rows - active_rows`, both readily
available. And top is `0` by definition.

2. Operations on the PageList typically add or remove rows. We don't do
arbitrary linked list surgery. If we instrument those areas with delta
updates to our cache, we can avoid the `O(N)` cost for most operations,
including scrolling a scrollbar. The only expensive operation is a full,
arbitrary jump (new node pointer).

Point 1 was quick to implement, so I focused all the complexity on point
2. Whenever we have an operation that adds or removes rows (for example
pruning the scroll back, adding more, erase rows within the active area,
etc.) then I do the math to calculate the delta change required for the
offset if we've already calculated it, and apply that directly.

### Renderer

The other issue was how to notify the apprts of scrollbar state. Sending
messages on any terminal change within the IO thread is a non-option
because (1) sending messages is slow (2) the terminal changes a lot and
(3) any slowness in the IO thread slows down overall terminal
throughput.

The solution was to **trigger scrollbar notifications with the renderer
vsync**. We read the scrollbar information when we render a frame,
compare it to renderer previous state, and if the scrollbar changed,
send a message to the apprt _after the frame is GPU-renderer_.

The renderer spends _most_ of its time sleeping compared to the IO
thread, and has more opportunities for optimizing its awake time.
Additionally, there's no reason to update the scrollbar information if
the renderer hasn't rendered the new frames because the user can't even
see the stuff the scrollbar wants to scroll to. We're talking about
millisecond scale stuff here at worst but it adds up.

## Performance

No noticeable performance impact for the additional metrics:

<img width="1012" height="738" alt="image"
src="https://github.com/user-attachments/assets/4ed0a3e8-6d76-40c1-b249-e34041c2f6fd"
/>

## AI Usage

I used Amp to help audit the codebase and write tests. I wrote all the
main implementation code manually. I came up with the main design
myself. Relevant threads:

-
https://ampcode.com/threads/T-95fff686-75bb-4553-a2fb-e41fe4cd4b77#message-0-block-0
-
https://ampcode.com/threads/T-48e9a288-b280-4eec-83b7-ca73d029b4ef#message-91-block-0

## Future

This is just the internal changes necessary to _draw_ a scrollbar. There
will be other changes we'll need to add to handle grabbing and actually
jumping the scrollbar. I have a good idea of how to implement those
performantly as well.
2025-10-15 19:42:49 -07:00
Mitchell Hashimoto 014a2e0042
termio: color change operations must gracefully handle renderer mailbox full (#9224)
Fixes #9191

This changes our color change operations from writing to the renderer
mailbox directly to using our `rendererMailboxWriter` function which
handles the scenario where the mailbox is full by yielding the lock,
waking up the renderer, and retrying later.

This is a known deadlock scenario we've worked around since the private
beta days, but unfortunately this slipped through and I didn't catch it
in review.

What happens here is it's possible with certain escape sequences for the
IO thread to saturate other mailboxes with messages while holding the
terminal state lock. This can happen to any thread. This ultimately
leads to starvation and all threads deadlock.

Our IO thread is the only thread that produces this kind of massive
stream of events while holding the lock, so we have helpers in it to
attempt to queue (cheap, fast) and if that fails then to yield the lock,
wakeup the target thread, requeue, and grab the lock again (expensive,
slow).
2025-10-15 16:01:26 -07:00
Mitchell Hashimoto 3665040b59
Selection dragging should not process when terminal screen changes (#9223)
This hasn't caused any known bugs but leads to selection memory
corruption and assertion failures in runtime safe modes. When the
terminal screen changes (primary to secondary) and we have an active
dragging mode going either by moving the mouse or our selection tick
timer, we should halt.

We still keep the mouse state active which lets selection continue once
the screen switches back.
2025-10-15 15:47:08 -07:00
Mitchell Hashimoto d460800a17
chore: typos should ignore build artifacts (#9222) 2025-10-15 15:44:51 -07:00
Jeffrey C. Ollie 1caab0c208
nix: make sure zon2nix uses Zig 0.15 in generated files (#9220) 2025-10-15 11:56:07 -07:00
Jeffrey C. Ollie c91bfb9dd5
bump version for development (#9218) 2025-10-15 11:55:30 -07:00
Jeffrey C. Ollie bdd2e4d734
build: more Zig 0.15.2 updates (#9217)
- update nixpkgs now that Zig 0.15.2 is available in nixpkgs
- drop hack that worked around compile failures on systems with more
than 32 cores
- enforce patch version of Zig
2025-10-15 11:55:11 -07:00
Jon Parise e5247f6d10
termio: reimplement OSC 7 URI handling (#9193)
This reimplements the MAC address-aware URI parsing logic used by the
OSC 7 handler and adds an additional .raw_path option that returns the
full, unencoded path string (including query and fragment values), which
is needed for compliant kitty-shell-cwd:// handling.

Notably, this implementation takes an options-based approach that allows
these additional behaviors to be enabled at runtime. It also leverages
two std.Uri.parse guarantees:

1. Return slices point into the original text string.
2. .raw components don't require unescaping (.percent_encoded does).

The implementation is in a new 'os.uri' module because its now generic
enough to not be hostname-oriented.

We use os.uri.parseUri and its parsing options to reimplement our OSC 7
file-style URI handling. This has two advantages:

First, it fixes kitty-shell-cwd scheme handling. This scheme expects the
full, unencoded path string, whereas the file scheme expects normal URI
percent encoding. This was preventing paths containing "special" URI
characters (like "path?") from working correctly in our bash, zsh, and
elvish shell integrations, which report working directories using the
kitty-shell-cwd scheme. (fish uses file URIs, which work as expected.)

Second, we can greatly simplify our hostname and path string handling
because we can now rely on the "raw" std.Uri component form to always
provide the correct representation.

Lastly, this lets us remove the previous URI-related code from the
os.hostname module, restoring its focus to hostname-related functions.

See: #5289
2025-10-14 12:12:45 -07:00
Jeffrey C. Ollie 54b021f6d6
core: update zf to remove zg transitive dep (#9208) 2025-10-14 12:04:42 -07:00
Mitchell Hashimoto 3d837cbbce
macos: "Check for updates" cancels whatever the current update state is (#9203)
This mainly allows users who have a pending update but didn't install it
for some time to re-check to see if there is something newer in the mean
time.
2025-10-14 07:31:31 -07:00
Mitchell Hashimoto 9f726492ac
macOS: release builds from source using `zig build` uses ReleaseLocal (#9201)
This fixes codesign issues that are common. The official release process
does not use this, but it is useful for local builds.
2025-10-14 07:13:05 -07:00
Mitchell Hashimoto 06ad3b77b7
Zig 0.15.2 (#9200) 2025-10-14 07:11:10 -07:00
Mitchell Hashimoto 6eb26da3b7
macos: fix failing xcode tests 2025-10-14 06:55:10 -07:00
Peter Guy 41bb8d7af0
fix make clean: change dir name from zig-cache to .zig-cache (#9192)
`make clean` was not removing the `.zig-cache` directory. Instead it was
removing the `zig-cache` directory.
2025-10-14 06:46:24 -07:00
Mitchell Hashimoto 75734a4d07
macos: clarify the "ready to install update" state
- The copy is updated to better explain what the user should do next.
- The symbol is updated to make it clear the update isn't yet installed.
2025-10-13 21:06:01 -07:00
Mitchell Hashimoto 17a20e5b1c
termio: don't start scroll timer if its already active (#9195)
This might fix #9191, but since I don't have a reproduction I can't be
sure. In any case, this is a bad bug that should be fixed.

The issue is that we weren't checking our scroll timer completion state.
This meant that if `start_scroll_timer` was called multiple times within
a single loop tick, we'd enqueue our completion multiple times, leading
to various undefined behaviors.

If we don't enqueue anything else in the interim, this is safe by
chance. But if we enqueue something else, then we'd hit a queue
assertion failure and honestly I'm not totally sure what would happen.

I wasn't able to trigger the "bad" case, but I was able to trigger the
benign case very easily. Our other timers such as the renderer cursor
timer already have this protection.

Let's fix this and continue looking...
2025-10-13 20:44:32 -07:00
Mitchell Hashimoto 5462553741
config: only create template file is prior was not found 2025-10-13 14:27:40 -07:00
Daniel Wennberg 14b441be1e
renderer: Include arrows block in constrained symbols (#9189)
Fixes #8693 

**Before**
<img width="164" height="47" alt="Screenshot 2025-10-13 at 14 00 28"
src="https://github.com/user-attachments/assets/df42df51-7706-4285-8c91-d79e227999ed"
/>

**After**
<img width="164" height="47" alt="Screenshot 2025-10-13 at 14 01 14"
src="https://github.com/user-attachments/assets/c1ca314e-a2ad-47b2-9bcf-d4200db173f5"
/>

The effect is somewhat subtle with my combination of fonts. See #8693
for the more egregious examples that this fixes.
2025-10-13 14:10:29 -07:00
Jeffrey C. Ollie 5f287774a6
osc: simplify parser init (#9184) 2025-10-13 13:47:58 -07:00
Xiangbao Meng dafb9e89a3
macOS: use default app for `*.ghostty` files first (#9180)
A small improvement for #8885, tested `config` and `config.ghostty`

<img width="526" height="267" alt="image"
src="https://github.com/user-attachments/assets/d09305ab-4a87-4393-b09c-804e618968f3"
/>
2025-10-13 06:52:00 -07:00
dependabot[bot] f5af3d4585
build(deps): bump namespacelabs/nscloud-setup-buildx-action from 0.0.18 to 0.0.19 (#9173)
Bumps
[namespacelabs/nscloud-setup-buildx-action](https://github.com/namespacelabs/nscloud-setup-buildx-action)
from 0.0.18 to 0.0.19.
<details>
<summary>Commits</summary>
<ul>
<li><a
href="7020d7d8e6"><code>7020d7d</code></a>
support experimental flags in setup-buildx action. (<a
href="https://redirect.github.com/namespacelabs/nscloud-setup-buildx-action/issues/10">#10</a>)</li>
<li><a
href="361d7cbc2b"><code>361d7cb</code></a>
Fix error parsing.</li>
<li><a
href="4271c3f47a"><code>4271c3f</code></a>
Robust status checking.</li>
<li><a
href="77ccfe1b7f"><code>77ccfe1</code></a>
Print exec outputs.</li>
<li><a
href="5b194a9c8d"><code>5b194a9</code></a>
Update README</li>
<li><a
href="4db0d391b6"><code>4db0d39</code></a>
Merge pull request <a
href="https://redirect.github.com/namespacelabs/nscloud-setup-buildx-action/issues/9">#9</a>
from namespacelabs/n-g-patch-1</li>
<li><a
href="feb137b9d0"><code>feb137b</code></a>
Update README.md</li>
<li><a
href="f57c281382"><code>f57c281</code></a>
Merge pull request <a
href="https://redirect.github.com/namespacelabs/nscloud-setup-buildx-action/issues/8">#8</a>
from namespacelabs/pavol/docker_buildx_ls</li>
<li><a
href="4177f4c963"><code>4177f4c</code></a>
e2e: run docker buildx ls</li>
<li>See full diff in <a
href="01628ae51e...7020d7d8e6">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=namespacelabs/nscloud-setup-buildx-action&package-manager=github_actions&previous-version=0.0.18&new-version=0.0.19)](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>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-13 06:46:03 -07:00
dependabot[bot] 1835a86a6a
build(deps): bump softprops/action-gh-release from 2.4.0 to 2.4.1 (#9174)
Bumps
[softprops/action-gh-release](https://github.com/softprops/action-gh-release)
from 2.4.0 to 2.4.1.
<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.4.1</h2>
<!-- raw HTML omitted -->
<h2>What's Changed</h2>
<h3>Other Changes 🔄</h3>
<ul>
<li>fix(util): support brace expansion globs containing commas in
parseInputFiles by <a
href="https://github.com/Copilot"><code>@​Copilot</code></a> in <a
href="https://redirect.github.com/softprops/action-gh-release/pull/672">softprops/action-gh-release#672</a></li>
<li>fix: gracefully fallback to body when body_path cannot be read by <a
href="https://github.com/Copilot"><code>@​Copilot</code></a> in <a
href="https://redirect.github.com/softprops/action-gh-release/pull/671">softprops/action-gh-release#671</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/softprops/action-gh-release/compare/v2...v2.4.1">https://github.com/softprops/action-gh-release/compare/v2...v2.4.1</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.4.1</h2>
<h2>What's Changed</h2>
<h3>Other Changes 🔄</h3>
<ul>
<li>fix(util): support brace expansion globs containing commas in
parseInputFiles by <a
href="https://github.com/Copilot"><code>@​Copilot</code></a> in <a
href="https://redirect.github.com/softprops/action-gh-release/pull/672">softprops/action-gh-release#672</a></li>
<li>fix: gracefully fallback to body when body_path cannot be read by <a
href="https://github.com/Copilot"><code>@​Copilot</code></a> in <a
href="https://redirect.github.com/softprops/action-gh-release/pull/671">softprops/action-gh-release#671</a></li>
</ul>
<h2>2.4.0</h2>
<h2>What's Changed</h2>
<h3>Exciting New Features 🎉</h3>
<ul>
<li>feat(action): respect working_directory for files globs by <a
href="https://github.com/stephenway"><code>@​stephenway</code></a> in <a
href="https://redirect.github.com/softprops/action-gh-release/pull/667">softprops/action-gh-release#667</a></li>
</ul>
<h2>2.3.4</h2>
<h2>What's Changed</h2>
<h3>Bug fixes 🐛</h3>
<ul>
<li>fix(action): handle 422 already_exists race condition by <a
href="https://github.com/stephenway"><code>@​stephenway</code></a> in <a
href="https://redirect.github.com/softprops/action-gh-release/pull/665">softprops/action-gh-release#665</a></li>
</ul>
<h3>Other Changes 🔄</h3>
<ul>
<li>dependency updates</li>
</ul>
<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>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="6da8fa9354"><code>6da8fa9</code></a>
release 2.4.1</li>
<li><a
href="f38efdea4c"><code>f38efde</code></a>
fix: gracefully fallback to body when body_path cannot be read (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/671">#671</a>)</li>
<li><a
href="cec1a1113b"><code>cec1a11</code></a>
fix(util): support brace expansion globs containing commas in
parseInputFiles...</li>
<li>See full diff in <a
href="aec2ec56f9...6da8fa9354">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.4.0&new-version=2.4.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>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-13 06:45:55 -07:00
dependabot[bot] e805a98722
build(deps): bump cachix/install-nix-action from 31.7.0 to 31.8.0 (#9175)
Bumps
[cachix/install-nix-action](https://github.com/cachix/install-nix-action)
from 31.7.0 to 31.8.0.
<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.8.0</h2>
<h2>What's Changed</h2>
<ul>
<li>nix: 2.31.2 -&gt; 2.32.0 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/257">cachix/install-nix-action#257</a>
Release notes: <a
href="https://discourse.nixos.org/t/nix-2-32-0-released/70528">https://discourse.nixos.org/t/nix-2-32-0-released/70528</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/cachix/install-nix-action/compare/v31.7.0...v31.8.0">https://github.com/cachix/install-nix-action/compare/v31.7.0...v31.8.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="7ab6e7fd29"><code>7ab6e7f</code></a>
Merge pull request <a
href="https://redirect.github.com/cachix/install-nix-action/issues/257">#257</a>
from cachix/create-pull-request/patch</li>
<li><a
href="a851831538"><code>a851831</code></a>
nix: 2.31.2 -&gt; 2.32.0</li>
<li><a
href="0b2de19be5"><code>0b2de19</code></a>
docs: update the ci badge</li>
<li><a
href="b8a94d3614"><code>b8a94d3</code></a>
ci: pass correct args to the act test</li>
<li><a
href="0ef05056da"><code>0ef0505</code></a>
ci: adjust oldest supported version for macos-15</li>
<li><a
href="0b43574e96"><code>0b43574</code></a>
ci: add macos-15-intel runner</li>
<li>See full diff in <a
href="9280e7aca8...7ab6e7fd29">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.7.0&new-version=31.8.0)](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>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-13 06:45:46 -07:00
Tim Culverhouse 797c54a2d7
deps: update libvaxis (#9177)
Update libvaxis. The latest commit of libvaxis includes `uucode` as the
unicode
library. `uucode` has a much cleaner API and is actively developed by a
Ghostty
maintainer (@jacobsandlund). This also has the advantage of removing the
last
transitive dependency Ghostty has that is hosted on codeberg, which
separates us
from the frequent outages.


Disclosures: I used AI to debug the import issue in `boo.zig`

---------

Co-authored-by: Mitchell Hashimoto <m@mitchellh.com>
2025-10-13 06:45:21 -07:00
Mitchell Hashimoto 97a5a59cc3
macos: update to Sparkle 2.8 (#9171)
Most of the changes seem to be Tahoe UI related and now that we have a
custom UI I don't think there is anything important here but we should
update nonetheless.
2025-10-12 15:30:34 -07:00
Mitchell Hashimoto 8f1a014afd
macos: clean up the "installing" update state (#9170)
This includes multiple changes to clean up the "installing" state:

- Ghostty will not confirm quit, since the user has already confirmed
they want to restart to install the update.
- If termination fails for any reason, the popover has a button to retry
restarting.
- The copy and badge symbol have been updated to better match the
reality of the "installing" state.

<img width="1756" height="890" alt="CleanShot 2025-10-12 at 15 04 08@2x"
src="https://github.com/user-attachments/assets/1b769518-e15f-4758-be3b-c45163fa2603"
/>

AI written:
https://ampcode.com/threads/T-623d1030-419f-413f-a285-e79c86a4246b fully
understood.
2025-10-12 15:20:26 -07:00
Joshie cbeb6890c9
Add `.ghostty` extension to `config` (#8885)
Resolves #8689

For various reason, ghostty wants to have a unique file extension for
the config files. The name was settled on `config.ghostty`. This will
help with tooling. See #8438 (original discussion) for more details.

This PR introduces the preferred default of `.ghostty` while still
supporting the previous `config` file. If both files exist, a warning
log is sent.

The docs / website will need to be updated to reflect this change. 

> [!NOTE]
> Only tested on macOS 26.0.

---------

Co-authored-by: Mitchell Hashimoto <m@mitchellh.com>
2025-10-12 13:48:06 -07:00
Jeffrey C. Ollie 37b3c27020
synthetic: use std.Io.Writer for more of the interface (#9038) 2025-10-12 13:11:52 -07:00
Xiangbao Meng 03e71e86a4
macOS: distinguish between Debug and Release(Stable/Tip) (#9149)
### Background

Been running Ghostty locally for a while now, and I use the Finder
service a lot. It often confuses me which one is the official one, until
I actually open it.

### Changes

- Use blueprint to distinguish from release app, if no custom icon
specified
- Change BundleDisplayName to Ghostty[Debug]
- Enable Info.plist preprocessing for reading
`$(INFOPLIST_KEY_CFBundleDisplayName)` for providing different services
with different configurations
> (Preprocessing was once reverted
before](https://github.com/ghostty-org/ghostty/commit/6508fec), so I'm
not sure whether this follows the 'rules' here, but for now, there are
no links in the plist file, so I think it’s
[safe](https://developer.apple.com/library/archive/technotes/tn2175/_index.html#:~:text=can%20pass%20the-,%2Dtraditional,-flag%20to%20the)
to enable it
2025-10-12 13:07:29 -07:00
Xiangbao Meng 8d8821004e
macOS: fix title misalignment in tabs (#9168)
While I was testing #9166, noticed another edge case🤯. 

This appears both in Tahoe and Sequoia👇🏻


https://github.com/user-attachments/assets/9cecea35-1241-4f31-9c15-0f2a7a6f342a
2025-10-12 13:04:18 -07:00
Alan Wu 5efb915771
Fix fish shell cursor integration in fish vi mode (#9157)
Previously, the fish shell integration interfered with fish's builtin vi
mode cursor switching configurations such as `$fish_cursor_default` and
`$fish_cursor_insert`.

```console
$ ghostty --config-default-files=false -e fish --no-config --init-command 'source "$GHOSTTY_RESOURCES_DIR"/shell-integration/fish/vendor_conf.d/ghostty-shell-integration.fish; fish_vi_key_bindings'
```

The above command starts fish in vi mode with Ghostty shell
integrations. Manually loading the integration is necessary due to
`--no-config` blocking auto injection.

1. At the prompt, fish is in insert mode, and the cursor is a blinking
beam. However, press escape and then "i" to exit then re-enter insert
mode, and the cursor will be a solid beam due to the
`$fish_cursor_unknown` setting. Without the shell integration, insert
mode always uses a solid beam cursor.

2. A similar problem shows if we start fish with `fish_vi_key_bindings
default`. The cursor ends up as a blinking beam in normal mode only due
to the shell integration interfering. This glitch can also be reset away
by entering then exiting insert mode.

3. Also, `$fish_cursor_external` has no effect when used with shell
integration. After `fish_vi_key_bindings`, set it to `line`, run cat(1),
and shell integration will give you a blinking block, not the asked for
line/beam.

I verified that this patch makes the shell integration stop interfering
in three scenarios above, and it still changes the cursor when not using
fish's vi mode.

Note that `$fish_cursor_*` variables can be set when fish isn't in vi
mode, so they're not great signals for the shell integration hooks.
2025-10-12 10:55:21 -07:00
Daniel Wennberg 65f73f5d20
font: Apply `adjust-icon-height` to both large and small icons (#9160)
As pointed out in #9156, an unintended consequence of all the work to
get icon sizing right is that `adjust-icon-height` now only applies to
the small icons you get when the next cell is not whitespace. Large
icons are unaffected.

With this PR, `adjust-icon-height` affects the maximum height of every
symbol specifying the `.icon` constraint height, regardless of
constraint width. This includes most Nerd Font icons, but excludes emoji
and other unicode symbols, and also excludes terminal graphics-oriented
Nerd Font symbols such as Powerline symbols.

In the following screenshots, **Baseline** is without
`adjust-icon-height`, while **Before** and **After** are with
`adjust-icon-height = -25%`.

**Baseline**
<img width="711" height="95" alt="Screenshot 2025-10-11 at 23 28 20"
src="https://github.com/user-attachments/assets/7499db4d-75a4-4dbd-b107-8cb5849e31a3"
/>

**Before** (only small icons affected)
<img width="711" height="95" alt="Screenshot 2025-10-11 at 23 20 12"
src="https://github.com/user-attachments/assets/9afd9fbf-ef25-44cc-9d8e-c39a69875163"
/>


**After** (both small and large icons affected, but not emoji)
<img width="711" height="95" alt="Screenshot 2025-10-11 at 23 21 05"
src="https://github.com/user-attachments/assets/90999f59-3b43-4684-9c8e-2c3c1edd6d18"
/>
2025-10-12 07:31:54 -07:00
Xiangbao Meng 47a8f8083d
macOS: Fix more `macos-titlebar-style` related issues (#9163)
### This PR depends on #9162 

#1691 doesn't seem to be an issue anymore, but changing appearance while
Ghosty is active will result in similar nastiness.



https://github.com/user-attachments/assets/fcd7761e-a521-4382-8d7a-9d93dc0806bc



### Changes

- [Sequoia/Ventura] Fix flickering new tab icon, and it also didn't
respond to window's key status change correctly
- [Sequoia/Ventura] Fix after changing appearance, tab bar may disappear
or have inconsistent background colour
- Fix initial tint of reset zoom button on Sequoia/Ventura with
`macos-titlebar-style=tabs` and all `native/transparent` titlebars
- Fix title alignment with custom font with `native/transparent`
titlebar
2025-10-12 07:31:42 -07:00
Xiangbao Meng cbc06a0abc
macOS: Support building with Xcode 16 (#9162)
With this you can test most of the old tab bar behaviour without using a
virtual machine
2025-10-12 07:25:18 -07:00
Rohan Alexander 6faf7fcac3
Add missing word to README.md (#9165) 2025-10-12 07:21:49 -07:00
Daniel Wennberg 2e34f4e0e5
fix(font): Additional scale group tweaks (#9152)
Of course #9142 would require a minor follow-up!

* Scale groups can cut across patch sets, but not across fonts. We had
some scale group mixing between Font Awesome and the weather symbols,
which is removed by this PR.[^cp_table_full]
* There's one case where a scale group includes a glyph that's not part
of any patch sets, just for padding out the group bounding box.
Previously, an unrelated glyph from a different font would be pulled in.
Now we use an appropriate stand-in. (See code comment for details.)
* I noticed overlaps weren't being split between each side of the
bounding box, they were added to both sides, resulting in twice as much
padding as specified.

Screenshots showing the extra vertical padding for progress bar elements
due to the second bullet point:

**Before**
<img width="191" height="42" alt="Screenshot 2025-10-11 at 15 33 54"
src="https://github.com/user-attachments/assets/cf288cce-86d3-46fd-ae86-18e5c274b0e4"
/>

**After**
<img width="191" height="42" alt="Screenshot 2025-10-11 at 15 33 20"
src="https://github.com/user-attachments/assets/7ac799c7-bf50-4e65-a74a-f8a2c42d2441"
/>

[^cp_table_full]: Forming and using the merged `cp_table_full` table
should have been a red flag. Such a table doesn't make sense, it would
be a one-to-many map. You need the names of the original fonts to
disambiguate.
2025-10-11 19:48:08 -07:00
github-actions[bot] aa0c68ee5e
Update iTerm2 colorschemes (#9155)
Upstream release:
https://github.com/mbadolato/iTerm2-Color-Schemes/releases/tag/release-20251006-150522-c07f0e8

Co-authored-by: mitchellh <1299+mitchellh@users.noreply.github.com>
2025-10-11 19:44:59 -07:00
Mitchell Hashimoto d3ee3c5b8a
macos: update permission request response should move state back to idle (#9151)
Previously, the permission request response would not move the state so
it'd stay in the titlebar.
2025-10-11 14:49:31 -07:00
Daniel Wennberg 4af93975ed
font(fix): Extract and apply Nerd Font codepoint mapping table (#9142)
Fixes #9076

**Before** 
<img width="128" height="57" alt="Screenshot 2025-10-11 at 00 07 09"
src="https://github.com/user-attachments/assets/a6b416d5-dae1-4cea-a836-00640ceaf39b"
/>

**After**
<img width="128" height="57" alt="Screenshot 2025-10-11 at 00 07 31"
src="https://github.com/user-attachments/assets/7d2df7b1-4767-4e2d-84d2-8301da5c6602"
/>

These screenshots show the chevrons mentioned in
https://github.com/ghostty-org/ghostty/discussions/7820#discussioncomment-14617170,
which should be scaled as a group but were not until this PR.

The added code downloads each individual symbol font file from the Nerd
Fonts github repo (making sure to get the version corresponding to the
vendored `font-patcher.py`) and iterates over all of them to build the
correct and complete codepoint mapping table. The table is saved to
`nerd_font_codepoint_tables.py`, which `nerd_font_codegen.py` will reuse
if possible instead of downloading the font files again.

I'm not going to utter any famous last words or anything, but... after
this, I don't think the number of remaining issues with icon
scaling/alignment is _large._
2025-10-11 13:12:13 -07:00
Mitchell Hashimoto 7087eea1e2
chore: add nerd font attributes as generated too 2025-10-11 13:08:11 -07:00
Mitchell Hashimoto 6ab416376a
chore: mark the nerd font tables as a generated file. 2025-10-11 12:54:25 -07:00
Brice c7058143c7
GTK fix quick terminal autohide (#9139)
This is pretty much a direct port of the previous GTK app. still inside
of the `isActive` handler for a window


7e429d73d6/src/apprt/gtk/Window.zig (L822-L837)

Fixes: https://github.com/ghostty-org/ghostty/discussions/9137
2025-10-11 12:52:35 -07:00
Jeffrey C. Ollie 81c982df96
gtk: fix clicking on desktop notifications (#9146)
Clicking on desktop notifications sent by Ghostty _should_ cause the
window that sent the notification to come to the top. However, because
the notification that was sent targeted the wrong surface (apprt surface
vs core surface) and the window did not call `present()` on itself the
window would never be brought to the surface, the correct tab would not
be selected, etc.

Fixes #9145
2025-10-11 12:51:52 -07:00
Jeffrey C. Ollie c5ad7563f9
gtk: better reporting for CSS parsing problems (#9129)
Log messages will include the problematic CSS, simplifying debugging.
Especially helpful since some of our CSS is generated at runtime so it
could be difficult to examine the CSS "source".

```
info(gtk_ghostty_application): loading gtk-custom-css path=/home/ghostty/dev/ghostty/x.css
warning(gtk_ghostty_application): css parsing failed at <data>:2:3-14: gtk-css-parser-error-quark 4 No property named "border-poop"
* {
  border-poop: 0;

warning(gtk_ghostty_application): css parsing failed at <data>:1:3-3:1: gtk-css-parser-warning-quark 1 Unterminated block at end of document
* {
  border-poop: 0;
```

vs:

```
info(gtk_ghostty_application): loading gtk-custom-css path=/home/ghostty/dev/ghostty/x.css
warning(glib): WARNING: Gtk: Theme parser error: <data>:2:3-14: No property named "border-poop"
warning(glib): WARNING: Gtk: Theme parser warning: <data>:1:3-3:1: Unterminated block at end of document
```
2025-10-10 13:41:58 -07:00
Bruno BELANYI 854c8e6975
Set title as argv[0] for commands specified with `-e` (#9121)
I want to see #7932 get merged, so applied the latest proposed patch.

Will close if the original PR gets some traction, as I do _not_ know Zig
nor this project.

Co-authored-by: rhodes-b <59537185+rhodes-b@users.noreply.github.com>
2025-10-10 13:41:38 -07:00
Mitchell Hashimoto ac2f040b31
macos: Show "Update and Restart" in the Command Palette (#9131)
If an update is available, you can now trigger the full download,
install, and restart from a single command palette action. This allows
for a fully keyboard-driven update process.

While an update is being installed, an option to cancel or skip the
current update is also shown as an option, so that can also be
keyboard-driven.

This currently can't be bound to a keyboard action, but that may be
added in the future if there's demand for it.

**AI Disclosure:** Amp was used considerably. I reviewed all the code
and understand it.

## Demo



https://github.com/user-attachments/assets/df6307f8-9967-40d4-9a62-04feddf00ac2
2025-10-10 13:40:35 -07:00
Mitchell Hashimoto cd7621167f
macos: update accessory in the titlebar should not move the window
This is annoyingly easy to trigger, just disable this.
2025-10-10 10:20:35 -07:00
Jeffrey C. Ollie c28104e62f
gtk: properly check for amount of time elapsed before notifying about command finish (#9128) 2025-10-10 10:01:06 -07:00
Jeffrey C. Ollie 7767a45779
osc: do inplace decoding of cmdline passed in OSC 133;C (#9127) 2025-10-10 10:00:50 -07:00
Mitchell Hashimoto bac2419343
macos: fix unit tests for notFound change 2025-10-10 09:45:34 -07:00
Xiangbao Meng c8ea42b894
macOS: Fix New Tab behaviours (#9124)
- Fix `macos-dock-drop-behavior = new-tab` not working, which also
affects `open /path/to/directory -a Ghostty.app`
- Fix 'New Tab' in dock icon not working **when Ghostty's not active**

### Issue preview with `1.2.2(12187)`


https://github.com/user-attachments/assets/18068cc2-c25d-4360-97ab-cec22d5d3ff4
2025-10-10 09:31:55 -07:00
Mitchell Hashimoto 207eccffda
macos: Sparkle notFound acknowledgement should only be called on dismiss (#9126)
This was causing the "no update found" message to never really appear in
the real world.
2025-10-10 09:30:12 -07:00
Xiangbao Meng 2bf9c777d7
Fix `macos-titlebar-tabs` related issues (#9090)
### This pr fixes multiple issues related to `macos-titlebar-tabs`

- [Window title clipping **on
Tahoe**](https://github.com/ghostty-org/ghostty/discussions/9027#discussion-8981483)
- Clipped tab bar **on Tahoe** when creating new ones in fullscreen
> Sequoia doesn't seem to have this issue (at least I didn't reproduce
myself)
- [Title missing **on Tahoe** after dragging a tab into a separate
window](https://github.com/ghostty-org/ghostty/discussions/9027#discussioncomment-14617088)
- [Clipped tab bar **on Tahoe** after dragging from one tab group to
another](https://github.com/ghostty-org/ghostty/discussions/9027#discussioncomment-14626078)
- [Stretched tab bar after switching system
appearance](https://github.com/ghostty-org/ghostty/discussions/9027#discussioncomment-14626918)


### Related issues
I checked all of the open sub-issues in #2349 , most of them should be
fixed in latest main branch (I didn't reproduce)

- [#1692](https://github.com/ghostty-org/ghostty/issues/1692)
@peteschaffner
- [#1945](https://github.com/ghostty-org/ghostty/issues/1945) this one I
reproduce only on Tahoe, and fixed in this pr, @injust
- [#1813](https://github.com/ghostty-org/ghostty/issues/1813) @jacakira
- [#1787](https://github.com/ghostty-org/ghostty/issues/1787)
@roguesherlock
- [#1691](https://github.com/ghostty-org/ghostty/issues/1691) ~**haven't
found a solution yet**(building zig on VM is a pain**)~
> Tried commenting out `isOpaque` check in
`TitlebarTabsVenturaTerminalWindow`, which would fix the issue, but I
see the note there about transparency issue.
  >
> After commenting it out, it worked fine for me with blur and opacity
config, so **I might need some more background on this**. Didn't include
this change yet.
  > 
> [See screenshot
here](https://github.com/user-attachments/assets/eb17642d-b0de-46b2-b42a-19fb38a2c7f0)



### Minor improvements

- Match window title style with `window-title-font-family` and focus
state
  
<img width="843" height="198" alt="image"
src="https://github.com/user-attachments/assets/0138c4fa-1a4b-4bab-a415-b32695899ccf"
/>

---------

Co-authored-by: Mitchell Hashimoto <m@mitchellh.com>
2025-10-10 09:21:29 -07:00
Mitchell Hashimoto cbbcf06e6e
terminal: add semi-colon character to word boundary list for easier selection (#9069)
Sorry, I'm living dangerously here and haven't started a discussion.

New ghostty user. When working interactively with SQL clients you're
often writing semi-colons at the end of statements, e.g. `select * from
table;`

It's super annoying when you double-click to select the word `table` it
actually selects `table;` Anecdotally, this behaviour disagrees with
other terminals I've tried (tho not exhaustive).

Disclosure: Claude wrote this code but, ironically, I "assisted it" by
pointing to the file and function after uncovering issue #30 and
relevant PR.
2025-10-10 09:04:22 -07:00
Mitchell Hashimoto 989acacbf9
macOS: Unobtrusive Updates (a.k.a. OpenAI Demogate Fix) (#9116)
Fixes #2638
Fixes #9056 

This changes our update check and notification system to be fully
unobtrusive if a terminal window is open. If a terminal window is open,
update system notifications now appear in the titlebar or the bottom
right corner of the window (if the titlebar is unavailable for any
reason). Importantly, this means no more window popups!

If a terminal window is not open, then explicit update checks will open
the existing, standard, dedicated window that currently exists. This
only triggers for manual update checks while the window is not open,
though. Or at least, that is the intention, I'm not sure if I got all
the logic there 100% correct.

**AI disclosure:** I used Amp considerably on the path to this fix.
Sorry, I wanted to use Codex due to the source, but I wanted to get this
fix out quickly and used a tool I was more familiar with. I manually
modified most of the code and understand it all.

## Demo

Update flows are complex and can do many things, so I built a simulator
to test the various states. This section will show videos of this.

### Happy Path (Full Update Check and Install)


https://github.com/user-attachments/assets/0d9c3396-cad1-4f13-b247-0fcc7382b47e

### Happy Path (No titlebar)


https://github.com/user-attachments/assets/839ffc20-b2d2-459b-9558-29f0f233d7a2

### No Update Available


https://github.com/user-attachments/assets/44650a98-c39b-4119-a8d0-64c21e06b79f

### Error


https://github.com/user-attachments/assets/ab27fe8c-4dd9-48f2-ad4f-23928d6a6829

### First Launch Permission Check

Note: This would show up automatically, not manually triggered.


https://github.com/user-attachments/assets/0add869e-eea8-4600-b119-4a236e77c4bf

## TODO

- [x] Fix progress percentage causing width wiggling
- [x] Fix padding from edges to be aligned on top/bottom and right
2025-10-10 08:52:59 -07:00
Mitchell Hashimoto 2a58aaf837
apprt/gtk: set the correct window title from the start (#9120)
Previous PR: #8535 (merged but problem persists)
Issues: #5934

The Ghostty window will always start with the title "Ghostty" at
startup, and then immediately change to the correct window title. This
is a problem when using compositors like Hyprland and Niri if you want
to create rules for floating windows and similar, as the window title
isn't detected at startup.

This fixes the bad behaviour both for title configured in the config
file, and for processes started with the --title argument.

In this fix I've updated the `tags.zig` `closureComputedTitle()`
function to get the title from the passed in config, and use that as a
fallback before the default `Ghostty` fallback.

Previous behaviour as logged by `niri msg event-stream`:

> Window opened or changed: Window { id: 19, title: Some("Ghostty"),
app_id: Some("com.mitchellh.ghostty-debug"), pid: Some(802495),
workspace_id: Some(1), is_focused: true, is_floating: false, is_urgent:
false, layout: WindowLayout { pos_in_scrolling_layout: Some((3, 1)),
tile_size: (2266.0, 1365.0), window_size: (2266, 1365),
tile_pos_in_workspace_view: None, window_offset_in_tile: (0.0, 0.0) } }
Window layouts changed: [(6, WindowLayout { pos_in_scrolling_layout:
Some((4, 1)), tile_size: (2266.0, 1365.0), window_size: (2266, 1365),
tile_pos_in_workspace_view: None, window_offset_in_tile: (0.0, 0.0) })]
Window opened or changed: Window { id: 19, title:
Some("pr-test-title-fix"), app_id: Some("com.mitchellh.ghostty-debug"),
pid: Some(802495), workspace_id: Some(1), is_focused: true, is_floating:
false, is_urgent: false, layout: WindowLayout { pos_in_scrolling_layout:
Some((3, 1)), tile_size: (2266.0, 1365.0), window_size: (2266, 1365),
tile_pos_in_workspace_view: None, window_offset_in_tile: (0.0, 0.0) } }

New behaviour:

> Window opened or changed: Window { id: 20, title:
Some("pr-test-title-fix"), app_id: Some("com.mitchellh.ghostty-debug"),
pid: Some(804534), workspace_id: Some(1), is_focused: true, is_floating:
false, is_urgent: false, layout: WindowLayout { pos_in_scrolling_layout:
Some((3, 1)), tile_size: (2266.0, 1365.0), window_size: (2266, 1365),
tile_pos_in_workspace_view: None, window_offset_in_tile: (0.0, 0.0) } }
Window layouts changed: [(6, WindowLayout { pos_in_scrolling_layout:
Some((4, 1)), tile_size: (2266.0, 1365.0), window_size: (2266, 1365),
tile_pos_in_workspace_view: None, window_offset_in_tile: (0.0, 0.0) })]

This fixes the problem as shown in the output. I have only tested this
on Linux (Arch with Niri).
2025-10-10 08:51:05 -07:00
tlj f0da093bdc apprt/gtk: use configured title as fallback for closureComputedTitle 2025-10-10 08:49:59 -07:00
Mitchell Hashimoto 029bcf2d39
gtk4-layer-shell: version from build.zig.zon, reenable ubsan (#9122)
added version read from build.zig.zon
didn't get any ubsan error locally with zig 0.15.1 (related to
https://github.com/ghostty-org/ghostty/issues/5744#issuecomment-2719313984)
2025-10-10 08:45:32 -07:00
Mitchell Hashimoto e0ee10e902
macos: re-enable real update check 2025-10-10 08:44:25 -07:00
Mitchell Hashimoto 9dac88248f
macos: ax for update info 2025-10-10 08:38:50 -07:00
Mitchell Hashimoto 47f3c94640
macos: many more unit tests for update work 2025-10-10 08:34:45 -07:00
Mitchell Hashimoto 6993947a3a
macOS: Make a lot of things more robust 2025-10-10 08:27:30 -07:00
Mitchell Hashimoto ba8eae027e
macos: fixed width for downloading/extracting, better padding 2025-10-10 07:19:25 -07:00
Ēriks Remess 82a5c177fe gtk4-layer-shell: reenable ubsan 2025-10-10 14:40:56 +03:00
Ēriks Remess ce47a85bf7 gtk4-layer-shell: version from build.zig.zon 2025-10-10 14:40:42 +03:00
Mitchell Hashimoto dbe42d9353
deps: update z2d to v0.9.0 (#9110)
Release notes at:
 https://github.com/vancluever/z2d/blob/v0.9.0/CHANGELOG.md

This release brings our Zig 0.15.x branch into main, now that Ghostty is
on it too.

Additionally, this adds major speedups to the default path (filling with
a solid color using the default operator).
2025-10-09 17:39:07 -07:00
Mitchell Hashimoto f124bb4975
macos: Fallback to standard driver when no unobtrusive targets exist 2025-10-09 17:38:24 -07:00
Chris Marchesi 36b3c1fa47
deps: update z2d to v0.9.0
Release notes at:
 https://github.com/vancluever/z2d/blob/v0.9.0/CHANGELOG.md

This release brings our Zig 0.15.x branch into main, now that Ghostty is
on it too.

Additionally, this adds major speedups to the default path (filling with a
solid color using the default operator).
2025-10-09 12:48:52 -07:00
Mitchell Hashimoto f2c7f4ec0f
Get app_version from build.zig.zon .version (#9101)
Reads .version from build.zig.zon and passes it to Config.
2025-10-09 11:11:18 -07:00
Mitchell Hashimoto d0f800c5fb
docs: Update build requirements for macOS (#9095)
Adds the Metal Toolchain as a required Xcode component for building
Ghostty. Also updates the notes about Xcode 26 now that it and Tahoe are
out of Beta.
2025-10-09 11:08:19 -07:00
Mitchell Hashimoto 6e5e726bc2
ci: fix typo (#9097) 2025-10-09 11:08:01 -07:00
Mitchell Hashimoto f2e5b8fb2d
macos: setup the standard sparkle driver for no-window scenario
If there are no windows, we use the standard sparkle driver to drive
the standard window-based update UI.
2025-10-09 08:57:48 -07:00
Mitchell Hashimoto bbf875216f
macos: fix driver for retry to trigger update check again 2025-10-09 08:51:33 -07:00
Ēriks Remess 402c492d94 set minimum required zig version from build.zig.zon in tests and dockerfile 2025-10-09 17:07:58 +03:00
Ēriks Remess ea5ea5f98e set minimum required zig version from build.zig.zon 2025-10-09 16:47:27 +03:00
Ēriks Remess f4b051a84c use app_version from build.zig.zon 2025-10-09 16:02:40 +03:00
Mitchell Hashimoto a2fbaec613
macos: do not build updaters into iOS 2025-10-08 22:18:36 -07:00
Mitchell Hashimoto 49eb65df77
macos: show release notes link 2025-10-08 22:05:03 -07:00
Mitchell Hashimoto abab6899f9
macos: better update descriptions 2025-10-08 21:45:48 -07:00
Mitchell Hashimoto bce49a0843
macos: hook up our new update controller 2025-10-08 21:41:18 -07:00
Mitchell Hashimoto b4ab1cc1ed
macos: clean up the permission request 2025-10-08 21:21:27 -07:00
Mitchell Hashimoto 9e17255ca9
macos: "OK" should dismiss error 2025-10-08 21:16:07 -07:00
Mitchell Hashimoto 95a9e63401
macos: not found state dismisses on click, after 5s 2025-10-08 21:13:34 -07:00
Mitchell Hashimoto a55de09944
macos: update simulator to test various scenarios in UI 2025-10-08 21:09:06 -07:00
Mitchell Hashimoto 59829f5359
Sparkle user driver, drives updates to the view model. 2025-10-08 21:03:04 -07:00
Mitchell Hashimoto 3b2ef4c216
build(deps): bump softprops/action-gh-release from 2.3.4 to 2.4.0 (#9079)
Bumps
[softprops/action-gh-release](https://github.com/softprops/action-gh-release)
from 2.3.4 to 2.4.0.
<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.4.0</h2>
<!-- raw HTML omitted -->
<h2>What's Changed</h2>
<h3>Exciting New Features 🎉</h3>
<ul>
<li>feat(action): respect working_directory for files globs by <a
href="https://github.com/stephenway"><code>@​stephenway</code></a> in <a
href="https://redirect.github.com/softprops/action-gh-release/pull/667">softprops/action-gh-release#667</a></li>
</ul>
<h3>Other Changes 🔄</h3>
<ul>
<li>chore(deps): bump the npm group with 2 updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/softprops/action-gh-release/pull/668">softprops/action-gh-release#668</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/softprops/action-gh-release/compare/v2.3.4...v2.4.0">https://github.com/softprops/action-gh-release/compare/v2.3.4...v2.4.0</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.4.0</h2>
<h2>What's Changed</h2>
<h3>Exciting New Features 🎉</h3>
<ul>
<li>feat(action): respect working_directory for files globs by <a
href="https://github.com/stephenway"><code>@​stephenway</code></a> in <a
href="https://redirect.github.com/softprops/action-gh-release/pull/667">softprops/action-gh-release#667</a></li>
</ul>
<h2>2.3.4</h2>
<h2>What's Changed</h2>
<h3>Bug fixes 🐛</h3>
<ul>
<li>fix(action): handle 422 already_exists race condition by <a
href="https://github.com/stephenway"><code>@​stephenway</code></a> in <a
href="https://redirect.github.com/softprops/action-gh-release/pull/665">softprops/action-gh-release#665</a></li>
</ul>
<h3>Other Changes 🔄</h3>
<ul>
<li>dependency updates</li>
</ul>
<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>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="aec2ec56f9"><code>aec2ec5</code></a>
release 2.4.0</li>
<li><a
href="4db716b167"><code>4db716b</code></a>
feat: respect working_directory for files globs; add input and tests (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/667">#667</a>)</li>
<li><a
href="14820f2cee"><code>14820f2</code></a>
chore(deps): bump the npm group with 2 updates (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/668">#668</a>)</li>
<li>See full diff in <a
href="62c96d0c4e...aec2ec56f9">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.4&new-version=2.4.0)](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-10-08 20:17:50 -07:00
Mitchell Hashimoto beaac8db8b
build(deps): bump hustcer/milestone-action from 2.9 to 2.11 (#9094)
Bumps
[hustcer/milestone-action](https://github.com/hustcer/milestone-action)
from 2.9 to 2.11.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/hustcer/milestone-action/releases">hustcer/milestone-action's
releases</a>.</em></p>
<blockquote>
<h2>v2.11</h2>
<h2>[2.11] - 2025-10-08</h2>
<h3>Bug Fixes</h3>
<ul>
<li>Fall back to the earliest-created milestone if no due_on set for
milestones (<a
href="https://redirect.github.com/hustcer/milestone-action/issues/145">#145</a>)</li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/hustcer/milestone-action/compare/v2.10...v2.11">https://github.com/hustcer/milestone-action/compare/v2.10...v2.11</a></p>
<h2>v2.10</h2>
<h2>[2.10] - 2025-10-07</h2>
<h3>Features</h3>
<ul>
<li>Try to inherit milestone from closing issues (<a
href="https://redirect.github.com/hustcer/milestone-action/issues/129">#129</a>)</li>
</ul>
<h3>Miscellaneous Tasks</h3>
<ul>
<li>Export guess-milestone-for-pr custom command (<a
href="https://redirect.github.com/hustcer/milestone-action/issues/124">#124</a>)</li>
</ul>
<h3>Deps</h3>
<ul>
<li>Upgrade Nu to v0.107 (<a
href="https://redirect.github.com/hustcer/milestone-action/issues/120">#120</a>)</li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/hustcer/milestone-action/compare/v2.9...v2.10">https://github.com/hustcer/milestone-action/compare/v2.9...v2.10</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/hustcer/milestone-action/blob/main/CHANGELOG.md">hustcer/milestone-action's
changelog</a>.</em></p>
<blockquote>
<h1>Changelog</h1>
<p>All notable changes to this project will be documented in this
file.</p>
<h2>[2.11] - 2025-10-08</h2>
<h3>Bug Fixes</h3>
<ul>
<li>Fall back to the earliest-created milestone if no due_on set for
milestones (<a
href="https://redirect.github.com/hustcer/milestone-action/issues/145">#145</a>)</li>
</ul>
<h2>[2.10] - 2025-10-07</h2>
<h3>Features</h3>
<ul>
<li>Try to inherit milestone from closing issues (<a
href="https://redirect.github.com/hustcer/milestone-action/issues/129">#129</a>)</li>
</ul>
<h3>Miscellaneous Tasks</h3>
<ul>
<li>Export <code>guess-milestone-for-pr</code> custom command (<a
href="https://redirect.github.com/hustcer/milestone-action/issues/124">#124</a>)</li>
</ul>
<h3>Deps</h3>
<ul>
<li>Upgrade Nu to v0.107 (<a
href="https://redirect.github.com/hustcer/milestone-action/issues/120">#120</a>)</li>
</ul>
<h2>[2.9] - 2025-07-26</h2>
<h3>Bug Fixes</h3>
<ul>
<li>Fix getting Nu binary path for Nushell 0.106</li>
</ul>
<h3>Deps</h3>
<ul>
<li>Upgrade Nu to 0.106 and pin <code>hustcer/setup-nu</code> to v3.20
(<a
href="https://redirect.github.com/hustcer/milestone-action/issues/118">#118</a>)</li>
</ul>
<h2>[2.8] - 2025-06-11</h2>
<h3>Miscellaneous Tasks</h3>
<ul>
<li>Upgrade <code>Nu</code> to 0.105 and pin
<code>hustcer/setup-nu</code> to v3.19 (<a
href="https://redirect.github.com/hustcer/milestone-action/issues/117">#117</a>)</li>
</ul>
<h2>[2.7] - 2025-03-22</h2>
<h3>Features</h3>
<ul>
<li>Add DeepSeek Code review support by
<code>hustcer/deepseek-review</code></li>
</ul>
<h3>Deps</h3>
<ul>
<li>Upgrade <code>Nu</code> to <strong>v0.103</strong> (<a
href="https://redirect.github.com/hustcer/milestone-action/issues/114">#114</a>)</li>
<li>Upgrade <code>Nu</code> to v0.102 (<a
href="https://redirect.github.com/hustcer/milestone-action/issues/113">#113</a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="bff2091b54"><code>bff2091</code></a>
ci skip</li>
<li><a
href="2c7baeca62"><code>2c7baec</code></a>
fix: Improve int number checking</li>
<li><a
href="efffe97cbe"><code>efffe97</code></a>
Bump to 2.11</li>
<li><a
href="837250188c"><code>8372501</code></a>
fix: Fall back to the earliest-created milestone if no due_on set for
milesto...</li>
<li><a
href="dc568606da"><code>dc56860</code></a>
chore: Code formatting by prettier</li>
<li><a
href="92e0e50802"><code>92e0e50</code></a>
ci skip</li>
<li><a
href="69cb97509e"><code>69cb975</code></a>
Bump to v2.10 (<a
href="https://redirect.github.com/hustcer/milestone-action/issues/142">#142</a>)</li>
<li><a
href="ddb9b7cb59"><code>ddb9b7c</code></a>
fix: Fix query-pr-closing-issues command execution error</li>
<li><a
href="76d2b550e8"><code>76d2b55</code></a>
feat: Try to inherit milestone from closing issues (<a
href="https://redirect.github.com/hustcer/milestone-action/issues/128">#128</a>)
(<a
href="https://redirect.github.com/hustcer/milestone-action/issues/129">#129</a>)</li>
<li><a
href="78368de40a"><code>78368de</code></a>
chore: Export guess-milestone-for-pr custom command (<a
href="https://redirect.github.com/hustcer/milestone-action/issues/124">#124</a>)</li>
<li>Additional commits viewable in <a
href="b57a7e52e9...bff2091b54">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=hustcer/milestone-action&package-manager=github_actions&previous-version=2.9&new-version=2.11)](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-10-08 20:17:35 -07:00
Zhizhen He dfb32022d4
ci: fix typo 2025-10-09 10:52:52 +08:00
Mike Akers e8ebc6f405 docs: Update build requirements for macOS
Adds the Metal Toolchain as a required Xcode component for building
Ghostty. Also updates the notes about Xcode 26 now that it and Tahoe are
out of Beta.
2025-10-08 21:05:04 -04:00
dependabot[bot] 5bebd10b7f
build(deps): bump hustcer/milestone-action from 2.9 to 2.11
Bumps [hustcer/milestone-action](https://github.com/hustcer/milestone-action) from 2.9 to 2.11.
- [Release notes](https://github.com/hustcer/milestone-action/releases)
- [Changelog](https://github.com/hustcer/milestone-action/blob/main/CHANGELOG.md)
- [Commits](b57a7e52e9...bff2091b54)

---
updated-dependencies:
- dependency-name: hustcer/milestone-action
  dependency-version: '2.11'
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-09 00:06:42 +00:00
Mitchell Hashimoto f975ac8019
macOS: only show the update overlay if window doesn't support it 2025-10-08 15:39:56 -07:00
Mitchell Hashimoto 81e3ff90a3
macOS: Show update information as an overlay 2025-10-08 13:29:39 -07:00
Mitchell Hashimoto fc347a6040
macOS: Move update view model over to App scope 2025-10-08 12:50:09 -07:00
Mitchell Hashimoto 09ba5a27a2
macOS: Unobtrusive update views 2025-10-08 12:50:09 -07:00
dependabot[bot] b56808f138
build(deps): bump softprops/action-gh-release from 2.3.4 to 2.4.0
Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 2.3.4 to 2.4.0.
- [Release notes](https://github.com/softprops/action-gh-release/releases)
- [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md)
- [Commits](62c96d0c4e...aec2ec56f9)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-08 00:07:23 +00:00
Ravi Chandra e70ae28fa3 terminal: add semi-colon character to word boundary list 2025-10-07 18:16:06 +13:00
Mitchell Hashimoto 67ece53423
lib-vt: begin paste utilities exports starting with safe paste (#9068) 2025-10-06 21:13:54 -07:00
Mitchell Hashimoto bf9f025aec
lib-vt: begin paste utilities exports starting with safe paste 2025-10-06 21:09:28 -07:00
Mitchell Hashimoto 5ece02fa76
lib-vt: split header to be more consumable (#9067)
No functionality changes. This just splits our header up.

Mostly driven by AI, hand reviewed:
https://ampcode.com/threads/T-c3f3e668-448b-4aec-9bac-a230b1d2b3c0
2025-10-06 21:06:27 -07:00
Mitchell Hashimoto 725203d494
lib-vt: split header to be more consumable 2025-10-06 20:48:49 -07:00
Jeffrey C. Ollie 3d1977ca43
osc: parse additional OSC 133 options (#9059)
OSC 133;A can have:

- special_key
- click_events

OSC 133;C can have:

- cmdline
- cmdline_url

Notably, they are in use by `fish`. Not sure what other shells currently
use these options.

Note that the options are only parsed. Nothing further is done with them
at this point.
2025-10-06 16:01:34 -05:00
Jeffrey C. Ollie 323dc54d46
fix custom-shader writergate breakage (#9061)
Fixes: #9060
2025-10-06 15:17:45 -05:00
Jeffrey C. Ollie f72bbb5038
fix custom-shader writergate breakage
Fixes: #9060
2025-10-06 15:03:25 -05:00
Jeffrey C. Ollie debdf6bf03
osc: parse additional OSC 133 options
OSC 133;A can have:

- special_key
- click_events

OSC 133;C can have:

- cmdline
- cmdline_url

Notably, they are in use by `fish`. Not sure what other shells currently
use these options.

Note that the options are only parsed. Nothing further is done with them
at this point.
2025-10-06 14:52:09 -05:00
Mitchell Hashimoto 39d3af469e
update to the latest zf (#9051) 2025-10-06 11:42:13 -07:00
Mitchell Hashimoto 16026f3023
apprt/gtk: only close with no windows active if close delay is off (#9053)
Fixes #9052
2025-10-06 09:19:33 -07:00
Mitchell Hashimoto e1e5bfc096
apprt/gtk: only close with no windows active if close delay is off
Fixes #9052
2025-10-06 09:17:16 -07:00
Mitchell Hashimoto e4f0c366ff
lib-vt docs: add etags to the pages 2025-10-06 08:48:57 -07:00
Mitchell Hashimoto d7b9ce76a6
typos 2025-10-06 08:47:02 -07:00
Mitchell Hashimoto ffbdfbd1e6
prettier 2025-10-06 08:45:25 -07:00
Mitchell Hashimoto 9194d6c496
doxygen: integrate examples into documentation 2025-10-06 08:44:47 -07:00
Mitchell Hashimoto 972dc94386
gtk: use std.Io.Writer to generate runtime CSS (#9050) 2025-10-06 08:30:23 -07:00
Mitchell Hashimoto 48d5fc925f
doxygen: better scrollbar styling 2025-10-06 08:28:24 -07:00
Mitchell Hashimoto 992e9e2a6e
doxygen: mobile styling 2025-10-06 08:25:44 -07:00
Jeffrey C. Ollie 76d9d731f0
update to the latest zf 2025-10-06 09:53:42 -05:00
Jeffrey C. Ollie d2ee80bc49
gtk: use std.Io.Writer to generate runtime CSS 2025-10-06 09:39:50 -05:00
Mitchell Hashimoto 86421c9e09
lib-vt: trying to fix up hosted docs 2025-10-05 20:36:22 -07:00
Mitchell Hashimoto 21d545c3b4
doxygen prettier 2025-10-05 20:28:37 -07:00
Mitchell Hashimoto 6ef0be7580
libghostty website: update to use arch for doxygen for latest 2025-10-05 20:26:18 -07:00
Mitchell Hashimoto f3c1357337
lib-vt: fix dockerfile to include assets for web 2025-10-05 20:18:48 -07:00
Mitchell Hashimoto a73a67d252
doxygen improvements 2025-10-05 20:16:42 -07:00
Mitchell Hashimoto ed65401bf8
osc: reorder osc tests and name them consistently (#9042)
No changes in the tests were made, but reordering them and naming them
consistently will makes finding tests easier (there are a LOT).
2025-10-05 19:51:07 -07:00
Mitchell Hashimoto 3fe1828e5e
freebsd: fix CI for Zig 0.15 and enable FreeBSD 15.0 (#9039) 2025-10-05 19:50:47 -07:00
Mitchell Hashimoto 0425e5492e
build(deps): bump softprops/action-gh-release from 2.3.3 to 2.3.4 (#9041)
Bumps
[softprops/action-gh-release](https://github.com/softprops/action-gh-release)
from 2.3.3 to 2.3.4.
<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.4</h2>
<!-- raw HTML omitted -->
<h2>What's Changed</h2>
<h3>Bug fixes 🐛</h3>
<ul>
<li>fix(action): handle 422 already_exists race condition by <a
href="https://github.com/stephenway"><code>@​stephenway</code></a> in <a
href="https://redirect.github.com/softprops/action-gh-release/pull/665">softprops/action-gh-release#665</a></li>
</ul>
<h3>Other Changes 🔄</h3>
<ul>
<li>chore(deps): bump actions/setup-node from 4.4.0 to 5.0.0 in the
github-actions group by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/softprops/action-gh-release/pull/656">softprops/action-gh-release#656</a></li>
<li>chore(deps): bump <code>@​types/node</code> from 20.19.11 to
20.19.13 in the npm group by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/softprops/action-gh-release/pull/655">softprops/action-gh-release#655</a></li>
<li>chore(deps): bump vite from 7.0.0 to 7.1.5 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/softprops/action-gh-release/pull/657">softprops/action-gh-release#657</a></li>
<li>chore(deps): bump the npm group across 1 directory with 2 updates by
<a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/softprops/action-gh-release/pull/662">softprops/action-gh-release#662</a></li>
<li>chore(deps): bump the npm group with 3 updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/softprops/action-gh-release/pull/666">softprops/action-gh-release#666</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/softprops/action-gh-release/compare/v2...v2.3.4">https://github.com/softprops/action-gh-release/compare/v2...v2.3.4</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.4</h2>
<h2>What's Changed</h2>
<h3>Bug fixes 🐛</h3>
<ul>
<li>fix(action): handle 422 already_exists race condition by <a
href="https://github.com/stephenway"><code>@​stephenway</code></a> in <a
href="https://redirect.github.com/softprops/action-gh-release/pull/665">softprops/action-gh-release#665</a></li>
</ul>
<h3>Other Changes 🔄</h3>
<ul>
<li>dependency updates</li>
</ul>
<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>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="62c96d0c4e"><code>62c96d0</code></a>
release 2.3.4</li>
<li><a
href="7dc9b8ac0f"><code>7dc9b8a</code></a>
fix(action): handle 422 already_exists race condition (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/665">#665</a>)</li>
<li><a
href="0f0e0b98e9"><code>0f0e0b9</code></a>
chore(deps): bump the npm group with 3 updates (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/666">#666</a>)</li>
<li><a
href="97d42c1b50"><code>97d42c1</code></a>
chore(deps): bump the npm group across 1 directory with 2 updates (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/662">#662</a>)</li>
<li><a
href="19cd0bcd2b"><code>19cd0bc</code></a>
chore(deps): bump vite from 7.0.0 to 7.1.5 (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/657">#657</a>)</li>
<li><a
href="5d1b0b1164"><code>5d1b0b1</code></a>
chore(deps): bump <code>@​types/node</code> from 20.19.11 to 20.19.13 in
the npm group (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/655">#655</a>)</li>
<li><a
href="f6021cf9a4"><code>f6021cf</code></a>
chore(deps): bump actions/setup-node in the github-actions group (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/656">#656</a>)</li>
<li>See full diff in <a
href="6cbd405e2c...62c96d0c4e">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.3&new-version=2.3.4)](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-10-05 19:50:05 -07:00
Mitchell Hashimoto b5661cc887
linux cgroup: fix initialization (#9043)
`std.Io.Reader.readAlloc` will fail if it can't read all of the bytes
asked for, so use `File.readToEndAlloc` instead.
2025-10-05 19:49:50 -07:00
Jeffrey C. Ollie d9de5909d9
linux cgroup: also fix controllers()
This fix was found by Claude Code, but I manually reviewed this change
and removed extraneous changes made by the AI tool.

Co-authored-by: moderation <michael@sooper.org>
2025-10-05 21:03:14 -05:00
Jeffrey C. Ollie a249b3da3a
linux cgroup: fix initialization 2025-10-05 20:46:48 -05:00
Jeffrey C. Ollie f03344b1c6
osc: reorder osc tests and name them consistently 2025-10-05 19:49:21 -05:00
dependabot[bot] 34cb77c9f2
build(deps): bump softprops/action-gh-release from 2.3.3 to 2.3.4
Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 2.3.3 to 2.3.4.
- [Release notes](https://github.com/softprops/action-gh-release/releases)
- [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md)
- [Commits](6cbd405e2c...62c96d0c4e)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-06 00:10:09 +00:00
Jeffrey C. Ollie 67357c663d
freebsd: add a timeout to the freebsd job 2025-10-05 19:08:20 -05:00
Jeffrey C. Ollie d6ef048cd7
freebsd: fix CI for Zig 0.15 and enable FreeBSD 15.0 2025-10-05 18:47:54 -05:00
Mitchell Hashimoto c5ea4a8079
libghostty: use Arch for docs container to get later Doxygen 2025-10-05 15:19:20 -07:00
Mitchell Hashimoto aeb6647aa6
libghostty docs: use latest Doxygen 2025-10-05 15:04:51 -07:00
Mitchell Hashimoto fd0851bae7
lib-vt: update documentation with more examples 2025-10-05 14:54:58 -07:00
Mitchell Hashimoto 48f5e4a16d
lib-vt: expose key encoding as a C API (#9040)
Example in `example/c-vt-key-encode`, but here is an abridged version:

```c
#include <assert.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <ghostty/vt.h>

int main() {
  GhosttyKeyEncoder encoder;
  GhosttyResult result = ghostty_key_encoder_new(NULL, &encoder);
  assert(result == GHOSTTY_SUCCESS);

  ghostty_key_encoder_setopt(encoder, GHOSTTY_KEY_ENCODER_OPT_KITTY_FLAGS, &(uint8_t){GHOSTTY_KITTY_KEY_ALL});

  GhosttyKeyEvent event;
  result = ghostty_key_event_new(NULL, &event);
  assert(result == GHOSTTY_SUCCESS);
  ghostty_key_event_set_action(event, GHOSTTY_KEY_ACTION_RELEASE);
  ghostty_key_event_set_key(event, GHOSTTY_KEY_CONTROL_LEFT);
  ghostty_key_event_set_mods(event, GHOSTTY_MODS_CTRL);

  char buf[128];
  size_t written = 0;
  result = ghostty_key_encoder_encode(encoder, event, buf, sizeof(buf), &written);
  assert(result == GHOSTTY_SUCCESS);

  ghostty_key_event_free(event);
  ghostty_key_encoder_free(encoder);
  return 0;
}
```
2025-10-05 14:44:55 -07:00
Mitchell Hashimoto 61fe78c1d3
lib-vt: expose key encoding as a C API 2025-10-05 14:40:20 -07:00
Mitchell Hashimoto fa3bc416ab
fix:use builtin memmove (#9033) 2025-10-05 08:18:08 -07:00
NikoMalik ff3a6d0650 fix: do not remove libc memmove until performance comparisons have been conducted 2025-10-05 17:35:58 +03:00
NikoMalik 1c0282d658 fix:use builtin memmove 2025-10-05 12:30:51 +03:00
Mitchell Hashimoto 31ba6534cf
input: use std.Io.Writer for key encoder, new API, expose via libghostty (#9030)
This modernizes `KeyEncoder` to a new `std.Io.Writer`-based API.
Additionally, instead of a single struct, it is now an `encode` function
that takes a series of more focused options. This is more idiomatic Zig
while also making it easier to expose via libghostty-vt.

libghostty-vt Zig module also gains access to key encoding APIs. The C
APIs will follow another time.

Converting the KeyEncoder tests was done using AI:
https://ampcode.com/threads/T-9731bbdc-e0a9-41ad-9404-2b781a66ee39
Reviewed and understood.
2025-10-04 20:24:42 -07:00
Mitchell Hashimoto 44496df899
input: use std.Io.Writer for key encoder, new API, expose via libghostty
This modernizes `KeyEncoder` to a new `std.Io.Writer`-based API.
Additionally, instead of a single struct, it is now an `encode` function
that takes a series of more focused options. This is more idiomatic Zig
while also making it easier to expose via libghostty-vt.

libghostty-vt also gains access to key encoding APIs.
2025-10-04 20:19:39 -07:00
Mitchell Hashimoto abae5422bf
Update iTerm2 colorschemes (#9029)
Upstream release:
https://github.com/mbadolato/iTerm2-Color-Schemes/releases/tag/release-20251002-142451-4a5043e
2025-10-04 17:17:27 -07:00
mitchellh cef99250a7 deps: Update iTerm2 color schemes 2025-10-05 00:16:06 +00:00
Mitchell Hashimoto 503a25653f
build: framegen can use self-hosted (#9021)
This was a red herring when I was doing the 0.15 port. It works with
self-hosted just fine.
2025-10-04 14:08:42 -07:00
Mitchell Hashimoto e1568118ee
Move paste encoding to the input package, test, optimize away one alloc (#9028)
This moves our paste logic to `src/input` in preparation for exposing
this as part of libghostty-vt. This yields an immediate benefit of unit
tests for paste encoding.

Additionally, we were able to remove one allocation on every unbracketed
paste path unless the input specifically contains a newline. Unlikely to
be noticable, but nice.

NOTE: This also includes one change in behavior: we no longer encode
`\r\n` and a single `\r`, but as a duplicate `\r\r`. This matches xterm
behavior and I don't think will result in any issues since duplicate
carriage returns should do nothing in well-behaved terminals.
2025-10-04 14:08:26 -07:00
Mitchell Hashimoto d4dcecb071
Move paste encoding to the input package, test, optimize away one alloc
This moves our paste logic to `src/input` in preparation for exposing
this as part of libghostty-vt. This yields an immediate benefit of
unit tests for paste encoding. 

Additionally, we were able to remove one allocation on every unbracketed
paste path unless the input specifically contains a newline. Unlikely to
be noticable, but nice.

NOTE: This also includes one change in behavior: we no longer encode
`\r\n` and a single `\r`, but as a duplicate `\r\r`. This matches xterm
behavior and I don't think will result in any issues since duplicate
carriage returns should do nothing in well-behaved terminals.
2025-10-04 14:05:32 -07:00
Mitchell Hashimoto 18eee610bc
Expand `~` in `macos-custom-icon` (#9024)
Since #8999, `macos-custom-icon` works when its a fully expanded
absolute path like `/Users/username/dir/icon.icns`, but not when it's
abbreviated as `~/dir/icon.icns`. Users were understandably surprised
and confused by this. This PR adds tilde expansion using `NSString`s
built-in property for this.

Also removed a line from the config docs that seemed erroneous. Given
that the option has a functional default, it seems incorrect to say that
it's required.
2025-10-04 07:18:50 -07:00
Mitchell Hashimoto 271024c982
font: Add comprehensive constraint tests (#9023)
As promised in #8990.

I opted for hardcoded metrics and bounding boxes rather than actually
loading fonts and glyphs, both to avoid backend dependence and limit the
focus to the constraint calculations themselves, and because I wanted to
test a case that isn't exhibited by any of the fonts available in the
repo.

This also fixes an error from #8990, probably due to a botched
cherry-pick or rebase.
2025-10-04 06:17:28 -07:00
greathongtu 906dac3145 io as interface 2025-10-04 21:17:04 +08:00
greathongtu fe52eb9494 Adding keybind 'w' to the +list-themes TUI that would write out a file that contained themes 2025-10-04 19:49:34 +08:00
Daniel Wennberg 3620132dfc Remove incorrect note from config docs 2025-10-04 00:13:23 -07:00
Daniel Wennberg 0b14026696 Expand `~` in `macos-custom-icon` 2025-10-04 00:13:23 -07:00
Daniel Wennberg 6bc60b6c64 Add comprehensive constraint tests 2025-10-03 22:30:52 -07:00
Daniel Wennberg 5360aeb8aa Fix botched cherry-pick from #8990 2025-10-03 22:20:45 -07:00
Mitchell Hashimoto e07415a2e2
build: framegen can use self-hosted
This was a red herring when I was doing the 0.15 port. It works with
self-hosted just fine.
2025-10-03 14:41:05 -07:00
Mitchell Hashimoto 42a38ff672
snap: fix Zig 0.15 install 2025-10-03 14:12:04 -07:00
Mitchell Hashimoto f052eb435e
fix(font): Final font patcher fixes (#8847)
This is my final set of fixes to the font patcher/icon scaling code. It
builds on #8563 and there's not much reason to pay attention here until
that one has been reviewed (the unique changes in this PR only touch the
two `nerd_font_*` files; the other 8 files in the diff are just #8563).
However, I wanted to make sure the full set of changes/fixes I propose
are out in the open, such that any substantial edits by maintainers
(like in #7953) can take into account the full context.

I think this and the related patches should be considered fixes, not
features, so I hope they can be considered for a 1.2.x release.

This PR fixes some bugs in the extraction of scale and alignment rules
from the `font_patcher` script. Roughly in order of importance:

* Nerd fonts apply an offset to some codepoint ranges when extracting
glyphs from their original font (e.g., Font Awesome) and placing them in
a Nerd Font. Rules are specified in terms of the former codepoints, but
must be applied to the latter. This offset was previously not taken into
account, so rules were applied to the wrong glyphs, and some glyphs that
should have rules didn't get any.
* Previously, the rules from every single patch set was included, but
the embedded Symbols Only font doesn't contain all of them. Most
importantly, there's a legacy patch set that only exists for historical
reasons and is never used anymore, which was overwriting some other
rules because of overlapping codepoint ranges. Also, the Symbols Only
font contains no box drawing characters, so those rules should not be
included. With this PR, irrelevant patch sets are filtered out.
* Some patch sets specify overlapping codepoint ranges, though in
reality the original fonts don't actually cover the full ranges and the
overlaps just imply that they're filling each other's gaps. During font
patching, the presence/absence of a glyph at each codepoint in the
original font takes care of the ambiguity. Since we don't have that
information, we need to hardcode which patch set "wins" for each case
(it's not always the latest set in the list). Luckily, there are only
two cases.
* Many glyphs belong to scale groups that should be scaled and aligned
as a unit. However, in `font_patcher`, the scale group is _not_ used for
_horizontal_ alignment, _unless_ the entire scale group has a single
advance width (remember, the original symbol fonts are not monospace).
This PR implements this rule by only setting `relative_width` and
`relative_x` if the group is monospace.

There are some additional tweaks to ensure that each codepoint actually
gets the rule it's supposed to when it belongs to multiple scale groups
or patch sets, and to avoid setting rules for codepoints that don't
exist in the embedded font.
2025-10-03 13:53:04 -07:00
Mitchell Hashimoto afa3d5e087
macos: avoid any zero-sized content size increments (#9020)
Fixes #9016
2025-10-03 13:52:42 -07:00
Daniel Wennberg 78f1bf1807 Handle font_patcher codepoint range overlaps 2025-10-03 13:50:11 -07:00
Daniel Wennberg 44951d9b1c Handle font_patcher codepoint offsets 2025-10-03 13:50:11 -07:00
Daniel Wennberg d07237fff5 Skip patchsets and codepoints not in SymbolsNF 2025-10-03 13:50:11 -07:00
Daniel Wennberg a1b7ea2e71 Add font_patcher's grouped vs individual alignment 2025-10-03 13:50:11 -07:00
Mitchell Hashimoto 21aa70dc8b
fix(font): Fix positioning of scaled glyphs that don’t specify alignment (#8990)
Follow-up to #8563, which broke scaling without alignment. This change
recovers the behavior from before #8563, such that a scaled group is
clamped to the constraint width and height if necessary, and otherwise,
scaling does not shift the center of the group bounding box.

As a part of this change, horizontal alignment was rewritten to assume
the face is flush with the left edge of the cell. The cell-to-face
offset in the rendering code is then applied regardless of the value of
`align_horizontal`. This both simplifies the code and improves
consistency, as it ensures that the offset is the same for all
non-bitmap glyphs (rounded in FreeType, not rounded in CoreText). It's
the right thing to do following the align-to-face changes in #8563.
2025-10-03 13:49:48 -07:00
Daniel Wennberg 50bdd3bac6 Align stretched glyphs to cell, not face 2025-10-03 13:46:36 -07:00
Daniel Wennberg 32f8c71be3 Always clamp scaled glyph to cell
Also take padding into account for centered alignment, necessary since
our constraint type allows asymmetric padding.
2025-10-03 13:44:22 -07:00
Daniel Wennberg 7acf617763 fix(font): Anchor scaling at bounding box center 2025-10-03 13:44:22 -07:00
Mitchell Hashimoto 77114d7927
macos: avoid any zero-sized content size increments
Fixes #9016
2025-10-03 13:35:40 -07:00
Mitchell Hashimoto b99ca6ad97
flush output for our builddata executable (#9019)
Fixes #9018

We were truncated our terminfo causing tmux to not respect some
features.
2025-10-03 13:33:59 -07:00
Mitchell Hashimoto 93c634c866
flush output for our builddata executable
Fixes #9018

We were truncated our terminfo causing tmux to not respect some
features.
2025-10-03 13:32:15 -07:00
Mitchell Hashimoto fd64b833a4
fix(font): Apply glyph constraints before thickening and centering before quantizing (#8580)
In CoreText, when thickening (font smoothing) is enabled or Ghostty is
synthesizing a bold face, the glyph bounding box is padded to make sure
the thicker glyph can fit. Currently, this happens before applying
constraints (scaling and alignment), which makes the size and position
of constrained glyphs dependent on font size, font thickening strength,
and display DPI.

With this PR, constraints are applied before any other adjustments, and
padding is applied directly to the rasterization canvas without
modifying any metrics.

For consistency, I also moved constraint application above emboldening
in the FreeType code, although under that API, the two operations are
orthogonal as far as I can tell.

Secondly, this PR moves glyph centering above bitmap quantization, as
centering is generally fractional and will therefore undo the quantizing
if done after.

Supersedes #8552.
2025-10-03 12:55:23 -07:00
Daniel Wennberg f245574087 Fix comment 2025-10-03 12:53:46 -07:00
Daniel Wennberg 5c129205a5 Use correct and consistent pre-constraint glyph rect
In Freetype, measure rect after emboldening, so constraints apply to the
true glyph size like in CoreText.

In CoreText, don't let font smoothing affect the rect (only the canvas).
2025-10-03 12:53:46 -07:00
Daniel Wennberg 96fbff681b Center before quantizing bitmap glyphs 2025-10-03 12:53:46 -07:00
Mitchell Hashimoto 071621a8c2
Fix typos (#9013)
This PR fixes typos I spotted in the project.
2025-10-03 10:04:35 -07:00
Andreas Deininger a667b740ee Fix typos 2025-10-03 18:52:26 +02:00
Mitchell Hashimoto f99a6846bc
Add update-mirror Nu script to ease mirror updating for deps (#9010)
This adds a new script we can manually run that downloads all the files
that need to be uploaded to the mirror and updates our build.zig.zon.
The upload still happens manually [by me] but this simplifies the task
greatly.
2025-10-03 08:13:45 -07:00
Mitchell Hashimoto f0eb46ea26
Add update-mirror Nu script to ease mirror updating for deps
This adds a new script we can manually run that downloads all the files
that need to be uploaded to the mirror and updates our build.zig.zon.
The upload still happens manually [by me] but this simplifies the task
greatly.
2025-10-03 07:39:41 -07:00
Mitchell Hashimoto 1c1a56394d
apprt/gtk: Zig 0.15 whack a mole 2025-10-03 07:33:58 -07:00
Mitchell Hashimoto 4d97186643
apprt/gtk: fix Zig 0.15 2025-10-03 07:17:35 -07:00
Mitchell Hashimoto e0cf528576
Zig 0.15 (#9004)
Replaces #8372 

Before merge I'm going to squash this and give @pluiedev coauthor, since
I took a lot of her work. I just have to go through this myself to make
sure I learn all the changes in Zig 0.15, but as I got things, I copy
and pasted her work in. My work is probably less thorough and there are
places we can convert deprecated things, probably, but this results in
green CI.

## Benchmarks

It looks like there are some speed regressions in isolated places. I'm
not sure if this is noise or not, I'm going to keep running some tests.
If someone can check macOS that'd be helpful (my vtebench is down on
macOS atm), cc @qwerasd205 if interested.

On an x86_64 system:


![output](https://github.com/user-attachments/assets/25395c18-2560-45c8-9fd3-d524bc5cbfb8)
2025-10-03 07:12:12 -07:00
Mitchell Hashimoto 569fe92389
fix up merge conflicts 2025-10-03 07:11:48 -07:00
Mitchell Hashimoto bb98bc744d
ci: disable freebsd for now 2025-10-03 07:10:44 -07:00
Mitchell Hashimoto 22caf60263
update a bunch of required Zig versions to 0.15 2025-10-03 07:10:44 -07:00
Mitchell Hashimoto a41f59837e
nix: update to unstable for Zig 0.15 in package 2025-10-03 07:10:44 -07:00
Mitchell Hashimoto ba100dddff
update deps 2025-10-03 07:10:44 -07:00
Mitchell Hashimoto 87b77e1980
ci: cleanup 2025-10-03 07:10:43 -07:00
Mitchell Hashimoto 4e3e0ed056
Zig 0.15: Flatpak 2025-10-03 07:10:43 -07:00
Mitchell Hashimoto e1b5464bab
Zig 0.15: build snap 2025-10-03 07:10:43 -07:00
Mitchell Hashimoto 2af424268a
Zig 0.15: emit bench 2025-10-03 07:10:43 -07:00
Mitchell Hashimoto 9ec3b1b152
Zig 0.15: webdata 2025-10-03 07:10:43 -07:00
Mitchell Hashimoto f0cfaa9580
zig 0.15: build on macOS 2025-10-03 07:10:43 -07:00
Mitchell Hashimoto 0112607532
Zig 0.15: zig build test macOS 2025-10-03 07:10:43 -07:00
Mitchell Hashimoto d59d754e29
Zig 0.15: zig build GTK exe 2025-10-03 07:10:43 -07:00
Mitchell Hashimoto cb295b84a0
Zig 0.15: zig build test 2025-10-03 07:10:43 -07:00
Mitchell Hashimoto 3770f97608
terminal: Zig 0.15, lib-vt and test-lib-vt work 2025-10-03 07:10:43 -07:00
Mitchell Hashimoto 913d2dfb23
unicode: fix lookup table generation 2025-10-03 07:10:43 -07:00
Mitchell Hashimoto 7ec57aeebd
Zig 0.15: zig fmt 2025-10-03 07:10:43 -07:00
Mitchell Hashimoto d02770d292
zig-15: build binary builds 2025-10-03 07:10:41 -07:00
Mitchell Hashimoto dfa2354fec
Implement and use generic approx equality tester (#8979)
Seems like there needs to be a general, easy-to-use solution for
approximate equality testing of containers holding floats (see, e.g.,
https://github.com/ghostty-org/ghostty/pull/8563#pullrequestreview-3281357931).
How's this?
2025-10-03 07:10:16 -07:00
Mitchell Hashimoto f8ef51fc61
core: add 'command finished' notifications (#8992)
Fixes #8991

Uses OSC 133 esc sequences to keep track of how long commands take to
execute. If the user chooses, commands that take longer than a user
specified limit will trigger a notification. The user can choose between
a bell notification or a desktop notification.
2025-10-03 06:58:29 -07:00
Mitchell Hashimoto 7ac9de7d83
gtk: fix duplicate signal handlers (#9001)
Signal handlers are connected to surface objects in two spots - when a
tab is added to a page and when the split tree changes. This resulted in
duplicate signal handlers being added for each surface. This was most
noticeable when copying the selection to the clipboard - you would see
two "Copied to clipboard" toasts. Ensure that there is only one signal
handler by removing any old ones before adding the new ones.
2025-10-03 06:53:29 -07:00
Mitchell Hashimoto 8ed3a98db2
Fix Weird Behavior in CoreText Shaper (#9002)
You can pretty simply reproduce a crash on `main` in `Debug` mode by
running `printf "مرحبًا \n"` with your primary font set to one that
supports Arabic such as Cascadia Code/Mono or Kawkab Mono, which will
cause CoreText to output the shaped glyphs non-monotonically which hits
the assert we have in the renderer.

In `ReleaseFast` this assert is skipped and because we already moved
ahead to the space glyph (which belongs at the end but is emitted first)
all of the glyphs up to that point are lost. I believe this is probably
the cause of #8280, I tested and this change seems to fix it at least.

Included in this PR is a little optimization: we were allocating buffers
to copy glyphs etc. from runs to every time, even though CoreText
provides `CTRunGet*Ptr` functions which get *pointers* to the internal
storage of these values- these aren't guaranteed to return a usable
pointer but in that case we can always fall back to allocating again.
Also avoided allocation while processing glyphs by ensuring capacity
beforehand immediately after creating the `CTLine`.

The performance impact of this PR is negligible on my machine and
actually seems to be positive, probably due to avoiding allocations if I
had to guess.
2025-10-02 15:36:02 -07:00
Jeffrey C. Ollie c8ed3031bc
gtk: improve signal handler management
Instead of making two separate passes over the surfaces in a split tree
to manage signal handlers, do it in one pass.
2025-10-02 17:22:52 -05:00
Jeffrey C. Ollie 10adef3092
gtk: fix duplicate signal handlers 2025-10-02 17:22:52 -05:00
Qwerasd efc6e0d673 fix(font/coretext): always prevent shaper from emitting rtl
The solution we had before worked in most cases but there were some
which caused problems still. This is what HarfBuzz's CoreText shaper
backend does, it uses a CTTypesetter with the forced embedding level
attribute. This fixes the failure case I found that was causing non-
monotonic outputs which can have all sorts of unexpected results, and
causes a crash in Debug modes because we assert the monotonicity while
rendering.
2025-10-02 15:32:21 -06:00
Qwerasd d6063428bd font/coretext: tiny shaper improvements
Reduce potential allocation while processing glyphs by ensuring capacity
in the buffer ahead of time and also using CTRunGet*Ptr functions first
and only allocating for those if that didn't work (it should almost
always work in practice.)
2025-10-02 14:06:58 -06:00
Mitchell Hashimoto 052857b58b
fix(config): Make `macos-custom-icon` null-terminated (#8999)
The config option `macos-custom-icon` wasn't working because, to pass
successfully through the C API to Swift, the string must be
null-terminated.

Fixes
https://discord.com/channels/1005603569187160125/1423192859112116224
2025-10-02 11:44:43 -07:00
Mitchell Hashimoto 16dab3b8dc
crash: remove minidump parser (#9000)
We never used it because our minidump files on Linux didn't contain
meaningful information. With Zig's Writergate, let's drop this and
rewrite it later, we can always resurrect it from the git history.

Rejoice @pluiedev
2025-10-02 11:23:45 -07:00
Mitchell Hashimoto f76dd96c7e
crash: remove minidump parser
We never used it because our minidump files on Linux didn't contain
meaningful information. With Zig's Writergate, let's drop this and
rewrite it later, we can always resurrect it from the git history.
2025-10-02 11:09:51 -07:00
Jeffrey C. Ollie 1c23ebc6f1
address review comments 2025-10-02 12:57:53 -05:00
Jeffrey C. Ollie 07124dba64
core: add 'command finished' notifications
Fixes #8991

Uses OSC 133 esc sequences to keep track of how long commands take to
execute. If the user chooses, commands that take longer than a user
specified limit will trigger a notification. The user can choose between
a bell notification or a desktop notification.
2025-10-02 12:40:40 -05:00
Daniel Wennberg e615b11b2c fix(config): Make macos-custom-icon null-terminated 2025-10-02 10:28:18 -07:00
Mitchell Hashimoto 9c8d2e577e
fix(font): Let powerline glyphs be wide (#8994)
#8829 fixed the interaction of Powerline glyphs with other symbols, but
regressed in the handling of the Powerline glyphs themselves by letting
them get caught in an early exit that imposes a constraint width of 1.
This PR fixes the regression and adds corresponding tests. Tried to be
somewhat principled about why the special treatment is warranted, hence
the new helper function `isGraphicsElement`.

**Before**
<img width="270" height="44" alt="Screenshot 2025-10-02 at 00 16 54"
src="https://github.com/user-attachments/assets/9e975434-114c-44d5-a4ed-ac6a954b9d00"
/>

**After**
<img width="270" height="44" alt="Screenshot 2025-10-02 at 00 16 11"
src="https://github.com/user-attachments/assets/20545e74-c9f9-4a6b-9bf0-a7cf1d38c3a0"
/>
2025-10-02 10:08:24 -07:00
Mitchell Hashimoto f11a4f7a68
Convert framegen to C, add compressed data to source tarball (#8989)
Zig 0.15 removed the ability to compress from the stdlib, which makes
porting our framegen tool to Zig 0.15+ more work than it's worth. We
already depend on and have the ability to build zlib, and Zig is a full
blown C compiler, so let's just use C.

The framegen C program doesn't free any memory, because it is meant to
exit quickly. It otherwise behaves pretty much the same as the old Zig
codebase.

The build scripts were modified to build the C program and run it, but
also to include the framedata in the generated source tarball so that
downstream packagers don't have to do this (although they'll have all
the deps anyways).

**AI disclosure:** The Zig to C conversion was done by Amp. I know C and
reviewed the code. The build system improvements are partially done by
Amp as well but I finished it all out. I've reviewed everything. Full
thread:
https://ampcode.com/threads/T-4e0a80af-3d2a-48d6-bf59-3e2f05eb7673
2025-10-02 06:57:50 -07:00
Daniel Wennberg 85c879f112 fix(font): Let powerline glyphs be wide 2025-10-02 00:12:00 -07:00
Mitchell Hashimoto 1ec74f8e39
Convert framegen to C, add compressed data to source tarball
Zig 0.15 removed the ability to compress from the stdlib, which makes
porting our framegen tool to Zig 0.15+ more work than it's worth. We
already depend on and have the ability to build zlib, and Zig is a full
blown C compiler, so let's just use C.

The framegen C program doesn't free any memory, because it is meant to
exit quickly. It otherwise behaves pretty much the same as the old Zig
codebase.

The build scripts were modified to build the C program and run it, but
also to include the framedata in the generated source tarball so that
downstream packagers don't have to do this (although they'll have all
the deps anyways).
2025-10-01 14:03:49 -07:00
Mitchell Hashimoto a5aff0e347
feat: add GHOSTTY_BIN_DIR to path via shell integration (#8976)
Closes #8956

Elvish written by Copilot, the rest was written by me with AI
documentation.
2025-10-01 07:52:12 -07:00
Jon Parise 6f596ee7c3 shell-integration: append $GHOSTTY_BIN_DIR to $PATH
For consistency with the termio/Exec.zig implementation, we always
append to the PATH (lowest priority).
2025-10-01 10:42:33 -04:00
Jon Parise 4989f92c71 shell-integration: remove redundant comments
I think the conditions are sufficiently self-descriptive.
2025-10-01 10:27:42 -04:00
Mitchell Hashimoto d7cfc51a4e
build: isolate XCFramework.Target so runtime code doesn't depend on it (#8983)
This fixes the lazyImport importing outside of the build root. The build
root for the build binary is always the root `build.zig` (which we
want), but our `src/build_config.zig` transitively imported SharedDeps
which led to issues with Zig 0.15.

This back ports to main early (outside our Zig 0.15 PR) because its
compatible and will simplify that one.
2025-10-01 07:18:05 -07:00
Mitchell Hashimoto 09e4c1e6f2
build: isolate XCFramework.Target so runtime code doesn't depend on it
This fixes the lazyImport importing outside of the build root. The build
root for the build binary is always the root `build.zig` (which we
want), but our `src/build_config.zig` transitively imported SharedDeps
which led to issues.
2025-10-01 07:04:54 -07:00
Matthew Hrehirchuk 9407e0fd0d fix: cleaned up elvish and fish integrations for bin_dir 2025-09-30 22:26:07 -06:00
Daniel Wennberg 3feff75c99 Add proper Zig stdlib attribution 2025-09-30 13:58:41 -07:00
Daniel Wennberg 26b70e3125 Implement and use generic approx equality tester 2025-09-30 12:38:29 -07:00
Mitchell Hashimoto f41e61cd31
nuke ziglyph from orbit (#8978)
Since we now use uucode, we don't need ziglyph anymore. Ziglyph was kept
around as a test-only dep so we can verify matching but this is
complicating our Zig 0.15 upgrade because ziglyph doesn't support Zig
0.15. Let's just drop it.

cc @jacobsandlund
2025-09-30 12:22:10 -07:00
Mitchell Hashimoto 16deea2761
nuke ziglyph from orbit
Since we now use uucode, we don't need ziglyph anymore. Ziglyph was kept
around as a test-only dep so we can verify matching but this is
complicating our Zig 0.15 upgrade because ziglyph doesn't support Zig
0.15. Let's just drop it.
2025-09-30 12:17:10 -07: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
himura467 7ab0a7814b docs(BaseTerminalController) 2025-09-29 01:56:00 +09:00
himura467 337ecdd0b3 refactor(focusSurface): check app status in advance 2025-09-29 00:02:43 +09:00
himura467 8151f4bbf5 feat: focusSurface for quick terminal 2025-09-29 00:00:41 +09:00
Mitchell Hashimoto a76297058f
example/c-vt: parse a full OSC command 2025-09-28 07:24:09 -07:00
Mitchell Hashimoto cfe9f19454
lib-vt: expose command type enum 2025-09-28 07:21:46 -07:00
himura467 9d33545a55 feat: focus terminal in basic cases 2025-09-28 19:20:00 +09:00
mitchellh 89fc7139ae deps: Update iTerm2 color schemes 2025-09-28 00:15:36 +00:00
Mitchell Hashimoto f564ffa30b
lib-vt: expose ghostty_osc_end 2025-09-27 15:15:51 -07:00
Mitchell Hashimoto cc0f2e79cd
terminal: osc parser end returns a pointer 2025-09-27 15:07:56 -07:00
Mitchell Hashimoto 6b1f4088dd
lib-vt: add the C functions for command inspection 2025-09-27 15:03:38 -07:00
Mitchell Hashimoto 6a0a94c827
lib: fix holes handling for C 2025-09-27 14:43:01 -07:00
Mitchell Hashimoto 397e47c274
terminal: use LibEnum for the command keys 2025-09-27 14:32:49 -07:00
Mitchell Hashimoto a79e68ace1
lib: enum func 2025-09-27 14:25:06 -07:00
Mitchell Hashimoto b3d1802c89
lib_vt: osc_next/reset 2025-09-27 13:25:56 -07:00
Mitchell Hashimoto 8a1dc5bd97
terminal: shuffle some C APIs to make it more long term maintainable 2025-09-27 13:20:54 -07:00
Mitchell Hashimoto e4e8a61e0c
build: limit cpu affinity to 32 cpus on Linux (#8925)
Related to #8924

Zig currenly has a bug where it crashes when compiling Ghostty on
systems with more than 32 cpus (See the linked issue for the gory
details). As a temporary hack, use `sched_setaffinity` on Linux systems
to limit the compile to the first 32 cores. Note that this affects the
build only. The resulting Ghostty executable is not limited in any way.

This is a more general fix than wrapping the Zig compiler with
`taskset`. First of all, it requires no action from the user or
packagers. Second, it will be easier for us to remove once the upstream
Zig bug is fixed.
2025-09-27 12:34:57 -07:00
Jeffrey C. Ollie 311f8ec70b build: limit cpu affinity to 32 cpus on Linux
Related to #8924

Zig currenly has a bug where it crashes when compiling Ghostty on
systems with more than 32 cpus (See the linked issue for the gory
details). As a temporary hack, use `sched_setaffinity` on Linux systems
to limit the compile to the first 32 cores. Note that this affects the
build only. The resulting Ghostty executable is not limited in any way.

This is a more general fix than wrapping the Zig compiler with
`taskset`. First of all, it requires no action from the user or
packagers. Second, it will be easier for us to remove once the upstream
Zig bug is fixed.
2025-09-27 12:29:39 -07:00
Mitchell Hashimoto 7749b46463
chore: pin zig 0.14 in build.zig.zon (#8871)
Hi!

I'm a full Zig noob but [Mitchell's recent
post](https://mitchellh.com/writing/libghostty-is-coming) made me want
to clone the repo and take a look at the tooling.

My first attempt at running examples though VSCode failed because the
latest version of Zig is 0.15.1, but Ghostty requires Zig 0.14*. When
configuring the extension to use a compatible version if Zig, it
suggested pinning the version in a .zigversion file. I'm not familiar
with the pattern, but if it can help someone else's onboarding, I
figured I'd open a PR to suggest the change.

Cheers

*edit: I had a hard time figuring that out
2025-09-26 06:58:44 -07:00
Mitchell Hashimoto 6995fd7f10
fix: alloc free off by one (#8886)
Fix provided by @jcollie 

The swift `open_config` action was triggering an allocation error
`error(gpa): Allocation size 41 bytes does not match free size 40.`.

> A string that was created as a `[:0]const u8` was cast to `[]const u8`
and then freed. The sentinel is the off-by-one.

@jcollie 

For full context, see
https://discord.com/channels/1005603569187160125/1420367156071239820

Co-authored-by: Jeffrey C. Ollie <jcollie@dmacc.edu>
2025-09-26 06:58:10 -07:00
Mitchell Hashimoto 7975316ceb
vim: use :setf to set the filetype (#8914)
This is nicer because it only sets the filetype if it hasn't already
been set. :setf[iletype] has been available since vim version 6.

See: https://vimhelp.org/options.txt.html#%3Asetf
2025-09-26 06:57:28 -07:00
Mitchell Hashimoto d9080cd83c
build(deps): bump namespacelabs/nscloud-cache-action from 1.2.17 to 1.2.18 (#8916)
Bumps
[namespacelabs/nscloud-cache-action](https://github.com/namespacelabs/nscloud-cache-action)
from 1.2.17 to 1.2.18.
<details>
<summary>Commits</summary>
<ul>
<li><a
href="7baedde84b"><code>7baedde</code></a>
Merge pull request <a
href="https://redirect.github.com/namespacelabs/nscloud-cache-action/issues/36">#36</a>
from namespacelabs/niklas-docs</li>
<li><a
href="72a48b9085"><code>72a48b9</code></a>
fix docs links</li>
<li><a
href="f5a0d9e059"><code>f5a0d9e</code></a>
Merge pull request <a
href="https://redirect.github.com/namespacelabs/nscloud-cache-action/issues/35">#35</a>
from namespacelabs/niklas-workflow</li>
<li><a
href="7bb48a0f26"><code>7bb48a0</code></a>
skip bundle exec</li>
<li><a
href="32d69b87dc"><code>32d69b8</code></a>
Merge pull request <a
href="https://redirect.github.com/namespacelabs/nscloud-cache-action/issues/34">#34</a>
from namespacelabs/niklas-apple-caches</li>
<li><a
href="a49d9d84e9"><code>a49d9d8</code></a>
Add experimental cache modes for Xcode, Swift, Ruby and CocoaPods</li>
<li>See full diff in <a
href="a289cf5d2f...7baedde84b">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.17&new-version=1.2.18)](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-25 17:12:19 -07:00
dependabot[bot] fdbf0c6242
build(deps): bump namespacelabs/nscloud-cache-action
Bumps [namespacelabs/nscloud-cache-action](https://github.com/namespacelabs/nscloud-cache-action) from 1.2.17 to 1.2.18.
- [Release notes](https://github.com/namespacelabs/nscloud-cache-action/releases)
- [Commits](a289cf5d2f...7baedde84b)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-26 00:06:22 +00:00
Jon Parise 79a5902ef2 vim: use :setf to set the filetype
This is nicer because it only sets the filetype if it hasn't already
been set. :setf[iletype] has been available since vim version 6.

See: https://vimhelp.org/options.txt.html#%3Asetf
2025-09-25 16:39:11 -04:00
CoderJoshDK d79441edd1
test: valid string slices for ghostty_string_s 2025-09-25 12:26:52 -04:00
Jacob Sandlund 1d89a63f29 Use commit pointed to by signed tag `v0.1.0-zig-0.14` 2025-09-25 10:00:03 -04:00
Jacob Sandlund beda36a3ca Merge remote-tracking branch 'upstream/main' into jacob/uucode 2025-09-25 09:59:51 -04:00
Mitchell Hashimoto 230014a536
cli: use sh to launch editor (#8901)
Fixes #8898
2025-09-25 06:52:58 -07:00
Jacob Sandlund 76cafeb957 move ziglyph dep to SharedDeps with .@"test" condition 2025-09-25 08:48:19 -04:00
Jacob Sandlund 4f2d80b08f Merge remote-tracking branch 'upstream/main' into jacob/uucode 2025-09-25 08:43:18 -04:00
Filip Milković f8fa812932
i18n: add Croatian hr_HR translation (#8668) 2025-09-25 09:45:41 +00:00
Gautier Ben Aïm 22cf46aefc
use 0.14.1 2025-09-25 09:08:57 +02:00
Mitchell Hashimoto dbbff53af7
build(deps): bump cachix/install-nix-action from 31.6.2 to 31.7.0 (#8904)
Bumps
[cachix/install-nix-action](https://github.com/cachix/install-nix-action)
from 31.6.2 to 31.7.0.
<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.7.0</h2>
<h2>What's Changed</h2>
<ul>
<li>
<p>feat: set up the environment based on the installer shell scripts by
<a href="https://github.com/sandydoo"><code>@​sandydoo</code></a> in <a
href="https://redirect.github.com/cachix/install-nix-action/pull/251">cachix/install-nix-action#251</a></p>
<p>Configures the following environment variables:</p>
<ul>
<li><code>NIX_PROFILES</code></li>
<li><code>NIX_SSL_CERT_FILE</code> (if not set)</li>
</ul>
<p>Adds the bin directory from the user's profile to
<code>$PATH</code>.</p>
</li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/cachix/install-nix-action/compare/v31.6.2...v31.7.0">https://github.com/cachix/install-nix-action/compare/v31.6.2...v31.7.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="9280e7aca8"><code>9280e7a</code></a>
fix: use -e to check for certs</li>
<li><a
href="effa594a17"><code>effa594</code></a>
fix: simplify setting the user profile</li>
<li><a
href="eb0f6c7357"><code>eb0f6c7</code></a>
ci: document where to find available images to test against</li>
<li><a
href="6676c23a71"><code>6676c23</code></a>
ci: add ubuntu-22.04-arm</li>
<li><a
href="cbf4b16d11"><code>cbf4b16</code></a>
Merge pull request <a
href="https://redirect.github.com/cachix/install-nix-action/issues/251">#251</a>
from cachix/fix-env</li>
<li><a
href="29a4dac2fa"><code>29a4dac</code></a>
tests: refactor tests to run under a single matrix</li>
<li><a
href="7449e8905b"><code>7449e89</code></a>
tests: improve env tests and move to tests dir</li>
<li><a
href="d487f94a7a"><code>d487f94</code></a>
lint</li>
<li><a
href="581a134122"><code>581a134</code></a>
refactor: document ssl-cert-file vs NIX_SSL_CERT_FILE</li>
<li><a
href="d914f6d9e8"><code>d914f6d</code></a>
refactor: drop ssl handling for unsupported platforms</li>
<li>Additional commits viewable in <a
href="a809471b5c...9280e7aca8">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.2&new-version=31.7.0)](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-24 20:24:38 -07:00
dependabot[bot] 74419b2fcf
build(deps): bump cachix/install-nix-action from 31.6.2 to 31.7.0
Bumps [cachix/install-nix-action](https://github.com/cachix/install-nix-action) from 31.6.2 to 31.7.0.
- [Release notes](https://github.com/cachix/install-nix-action/releases)
- [Changelog](https://github.com/cachix/install-nix-action/blob/master/RELEASE.md)
- [Commits](a809471b5c...9280e7aca8)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-25 00:08:57 +00:00
Jeffrey C. Ollie bff758f03b
cli: use sh to launch editor 2025-09-24 17:47:29 -05:00
CoderJoshDK dc03a47558
chore: sync changes with ghostty_string_s 2025-09-24 17:47:24 -04:00
Jeffrey C. Ollie 79685f87c4
use comptime to make C String interface nicer 2025-09-24 16:33:18 -05:00
CoderJoshDK c5786c5d38
fix: alloc free off by one 2025-09-24 16:58:39 -04:00
Mitchell Hashimoto fc0a37f9e0
GTK: Fix split-divider-color (#8853)
The `loadRuntimeCss416` overrode a color option for the split divider
color

https://github.com/ghostty-org/ghostty/blob/main/src/apprt/gtk/class/application.zig#L959-L965

I moved the user config options until the other runtime css is loaded so
they will always take priority
2025-09-24 12:58:25 -07:00
Mitchell Hashimoto 103e7abad5
config: smarter parsing in autoParseStruct (#8873)
Fixes #8849

Previously, the `parseAutoStruct` function that was used to parse
generic structs for the config simply split the input value on commas
without taking into account quoting or escapes. This led to problems
because it was impossible to include a comma in the value of config
entries that were parsed by `parseAutoStruct`. This is particularly
problematic because `ghostty +show-config --default` would produce
output like the following:

```
command-palette-entry = title:Focus Split: Next,description:Focus the next split, if any.,action:goto_split:next
```

Because the `description` contains a comma, Ghostty is unable to parse
this correctly. The value would be split into four parts:

```
title:Focus Split: Next
description:Focus the next split
 if any.
action:goto_split:next
```

Instead of three parts:

```
title:Focus Split: Next
description:Focus the next split, if any.
action:goto_split:next
```

Because `parseAutoStruct` simply looked for commas to split on, no
amount of quoting or escaping would allow that to be parsed correctly.

This is fixed by (1) introducing a parser that will split the input to
`parseAutoStruct` into fields while taking into account quotes and
escaping. And (2) changing the `ghostty +show-config` output to put the
values in `command-palette-entry` into quotes so that Ghostty can parse
it's own output.

`parseAutoStruct` will also now parse double quoted values as a Zig
string literal. This makes it easier to embed control codes, whitespace,
and commas in values.
2025-09-24 12:54:27 -07:00
Mitchell Hashimoto 64800d94ba
fix: file creation when directory already exists (#8892)
Resolves #8890 

If you try to create the config file when the directory already exists,
you (I) get an error that the _file_ path already exists.
```
warning(config): error creating template config file err=error.PathAlreadyExists
```
Even though the file does not exist. By changing the API entry point,
this error goes away.

I have no solid explanation for why this change works.


| State | Old Behavior | New Behavior |
|--------|--------|--------|
| A config file exists | N/A | N/A |
| No config file, no directory | create directory and config file | N/A
|
| No config file, yes directory | fail to create on config file | create
config file |

This behavior is confirmed on my macOS 26 machine. It is the least
intrusive change I could make, and in all other situations should be a
no-op.
2025-09-24 12:51:09 -07:00
Mitchell Hashimoto 232b1898fa
lib-vt: update header comments 2025-09-24 12:50:25 -07:00
Mitchell Hashimoto 390f72accc
libghostty-vt C shared library boilerplate, custom allocators API (#8895)
This adds the boilerplate necessary for `libghostty-vt` the C library.

> [!IMPORTANT]
>
> This _does not expose almost any APIs_. The point of this PR is to
setup our boilerplate, build system, docs system, etc. for the
libghostty-vt C lib.

- Adds a `zig build lib-vt` target to _only_ build `libghostty-vt`
- Adds the beginning of `include/ghostty-vt.h` for the C API 
- Adds a full custom allocator interface to the C API mimicking Zig
custom allocators
- Adds an example in `example/c-vt` that builds a pure C program and
links to our shared library and calls functions
- Adds the `osc_parser_new/free` C APIs just as a proof of concept that
things work
- Adds a basic Doxygen config so we have _something_ (I'm not at all
committed to Doxygen, but want us to doc from the beginning)
- Updates CI to test building the shared library for macOS, Windows, and
Linux (yes, it builds for Windows!)

**Note:** To use the `dep.artifact` function provided by Zig, we must
install the artifact. But this means that every `zig build` now includes
`libghostty-vt`. That... could be completely fine, but it's something to
consider for packagers.

## Bikeshed

We're at a pivotal point where we must define the general _style_ of our
C API.

This includes the very bike shed things such as capitalization styling,
but also general API form.

ABI compatibility will eventually be important.

I'm very much open and would love to receive feedback form more
experience C programmers on what they feel would constitute a good API.
I've consumed _many_ C APIs but I haven't provided many directly.

cc @gpanders
2025-09-24 12:45:34 -07:00
Mitchell Hashimoto 37372fa50b
more docs 2025-09-24 12:45:21 -07:00
Mitchell Hashimoto 37e238c2f6
remove vt prefixes 2025-09-24 12:36:50 -07:00
Mitchell Hashimoto 96e9053862
move header into subdirectory 2025-09-24 12:30:37 -07:00
Mitchell Hashimoto 48827b21d8
some PR feedback 2025-09-24 12:25:43 -07:00
Mitchell Hashimoto 513cdf667b
build: add pkg-config for libghostty-vt 2025-09-24 12:22:09 -07:00
Mitchell Hashimoto 0944f051aa
terminal: simplify opaque type 2025-09-24 11:09:19 -07:00
Mitchell Hashimoto 4d165fbaaa
remove unused items 2025-09-24 11:06:23 -07:00
Mitchell Hashimoto 43089a01f1
lib: c allocator can use fromZig 2025-09-24 11:00:48 -07:00
Mitchell Hashimoto fba953feeb
ci: run the c-vt example 2025-09-24 10:46:43 -07:00
Mitchell Hashimoto e7a0198103
lib-vt: docs 2025-09-24 10:46:24 -07:00
Mitchell Hashimoto 2c78ad8889
lib-vt: setup a default allocator if null 2025-09-24 10:30:13 -07:00
Mitchell Hashimoto de013148d3
build: install the ghostty-vt artifact 2025-09-24 10:17:50 -07:00
Mitchell Hashimoto e1429dabae
example/c-vt 2025-09-24 09:54:08 -07:00
Mitchell Hashimoto 969fcfaec3
lib: allocator interface based on Zig allocators 2025-09-24 09:27:17 -07:00
CoderJoshDK 315b54822a
fix: file creation when directory already exists 2025-09-24 12:08:12 -04:00
Jacob Sandlund 8bcab93c21 separate out runtime and buildtime uucode tables 2025-09-24 08:34:21 -04:00
Jacob Sandlund 444b40bc4a Merge remote-tracking branch 'upstream/main' into jacob/uucode 2025-09-24 08:05:29 -04:00
Jeffrey C. Ollie 5f3fd9742f
rename Splitter-CommaSplitter 2025-09-23 21:53:52 -05:00
Jeffrey C. Ollie 5265414a36
config: smarter parsing in autoParseStruct
Fixes #8849

Previously, the `parseAutoStruct` function that was used to parse
generic structs for the config simply split the input value on commas
without taking into account quoting or escapes. This led to problems
because it was impossible to include a comma in the value of config
entries that were parsed by `parseAutoStruct`. This is particularly
problematic because `ghostty +show-config --default` would produce
output like the following:

```
command-palette-entry = title:Focus Split: Next,description:Focus the next split, if any.,action:goto_split:next
```

Because the `description` contains a comma, Ghostty is unable to
parse this correctly. The value would be split into four parts:

```
title:Focus Split: Next
description:Focus the next split
 if any.
action:goto_split:next
```

Instead of three parts:

```
title:Focus Split: Next
description:Focus the next split, if any.
action:goto_split:next
```

Because `parseAutoStruct` simply looked for commas to split on, no
amount of quoting or escaping would allow that to be parsed correctly.

This is fixed by (1) introducing a parser that will split the input
to `parseAutoStruct` into fields while taking into account quotes and
escaping. And (2) changing the `ghostty +show-config` output to put the
values in `command-palette-entry` into quotes so that Ghostty can parse
it's own output.

`parseAutoStruct` will also now parse double quoted values as a Zig
string literal. This makes it easier to embed control codes, whitespace,
and commas in values.
2025-09-23 20:44:49 -05:00
Mitchell Hashimoto 32bf37e5e4
setup basic doxygen for docs
We may not stick with Doxygen, but it gives us something to start with.
2025-09-23 15:51:27 -07:00
Mitchell Hashimoto def4969aff
build: shared object is a dylib on macOS 2025-09-23 15:15:16 -07:00
Mitchell Hashimoto 3d04fbb451
ci: build lib-vt for a variety of targets
We don't run our tests on all these targets so its not sure they all
will function correctly, but at least we can be sure they build.
2025-09-23 15:04:24 -07:00
Mitchell Hashimoto 85345c31cf
build: don't add deps when cross compiling to darwin 2025-09-23 15:03:55 -07:00
Brice 35095fddda
comment to load standard css options before some of the user configured styles 2025-09-23 15:15:04 -05:00
Mitchell Hashimoto b006101ddd
lib-vt: boilerplate to build a shared object 2025-09-23 12:35:39 -07:00
Gautier Ben Aïm b0e85d900e
use build.zig.zon instead 2025-09-23 21:14:09 +02:00
Mitchell Hashimoto f97518cc10
example/zig-vt: add comment explaining how to get zero-dep build 2025-09-23 11:55:44 -07:00
Gautier Ben Aïm a96cb9ab57
chore: pin zig 0.14.1 in .zigversion 2025-09-23 20:42:57 +02:00
Mitchell Hashimoto 31af87e021
macOS: Convert `Sources` to folder references (#8856)
https://github.com/ghostty-org/ghostty/discussions/8855
2025-09-23 11:29:32 -07:00
Leah Amelia Chen 2a24918eec
deps: removing utf8proc (#8866) 2025-09-23 20:05:03 +02:00
Paal Øye-Strømme bd9bc5f1b9 deps: removing utf8proc
utf8proc is no longer being used

Per #808, it should be removed.

Link: https://github.com/ghostty-org/ghostty/discussions/6931
Link: https://github.com/ghostty-org/ghostty/discussions/2563
2025-09-23 17:38:03 +02:00
Lars 9072bab6b8
Update iOS membership exceptions 2025-09-23 16:50:13 +02:00
Jacob Sandlund c7ad29ca91 move tests over to _uucode.zig files to avoid needing deps for vt tests 2025-09-23 10:49:59 -04:00
Jacob Sandlund b5c6c044a7 Fix merge 2025-09-23 10:01:23 -04:00
Jacob Sandlund c2a9c5ee5b fix comment 2025-09-23 09:48:09 -04:00
Mitchell Hashimoto f8472cb32b
feat: list-themes cursor and selection colors (#8848)
Closes #8446

Adds the remaining theme colors: cursor-color, cursor-text,
selection-background, and selection-foreground.

## Before
<img width="1840" height="1195" alt="image"
src="https://github.com/user-attachments/assets/f39f0cf1-f1c4-468c-a706-a39e3efe2883"
/>

## After
<img width="1840" height="1195" alt="image"
src="https://github.com/user-attachments/assets/a6995c35-070d-4971-9caf-ebae994deba5"
/>
2025-09-23 06:47:49 -07:00
Mitchell Hashimoto 0bbe39fb0a
ci: fix missing var name 2025-09-23 06:45:03 -07:00
Jacob Sandlund 7386dae079 use unicode.graphemeBreak in src/font/shaper/web_canvas.zig 2025-09-23 09:43:28 -04:00
Mitchell Hashimoto 52c0afcc93
ci: Add test for building with i18n on and off (#8858)
Closes #8360
2025-09-23 06:42:12 -07:00
Mitchell Hashimoto 862e19cbab
deps: Allow dynamic-linking of spirv-cross (#8859)
- Use the pkg-config name of 'spirv-cross-c-shared' exported by the
upstream SPIRV-Cross build
https://github.com/KhronosGroup/SPIRV-Cross/blob/main/pkg-config/spirv-cross-c-shared.pc.in
2025-09-23 06:38:43 -07:00
Jacob Sandlund b01770c21c Merge remote-tracking branch 'upstream/main' into jacob/uucode 2025-09-23 09:36:41 -04:00
azhn a9c5a05e5b deps: Allow dynamic-linking of spirv-cross
- Use the pkg-config name of 'spirv-cross-c-shared' exported by the upstream SPIRV-Cross build
2025-09-23 20:49:22 +10:00
azhn aa52e11c34 ci: Add test for building with i18n on and off 2025-09-23 20:03:26 +10:00
Kat 3eb646ea6b
Add zh_TW Traditional Chinese locale (#6773)
🎉
2025-09-23 08:33:46 +00:00
Lars 131f4fb8b1
Convert `Sources` to folder references 2025-09-23 09:30:49 +02:00
rhodes-b a584163306 load runtime css before user options 2025-09-22 23:14:05 -05:00
Mitchell Hashimoto e951dedc66
GTK Fix unfocused-split-fill (#8813)
Attempts a resolution for
https://github.com/ghostty-org/ghostty/discussions/8572

This matches the behavior of the old GTK apprt where
unfocused-split-fill /opacity doesn't apply when there is only one
active surface.
2025-09-22 19:58:50 -07:00
rhodes-b 36e09cdbe1 remove debug print from helping something with graphics issues 2025-09-22 21:30:03 -05:00
rhodes-b f36ccc4866 remove is_split properity in priv since it has a getter method 2025-09-22 21:22:53 -05:00
CoderJoshDK 2aad450d2e
feat: list-themes cursor and selection colors 2025-09-22 21:18:37 -04:00
Mitchell Hashimoto 8cb52323e5
ghostty-vt Zig Module (#8840)
This makes a `ghostty-vt` Zig module available from our `build.zig` that
contains a reusable Zig API version of our core terminal emulation layer
including escape sequence parsing, terminal state, and screen state.
This is the groundwork for phase one of my "libghostty" vision.

With SIMD disabled, `ghostty-vt` has no dependencies -- not even on libc
-- and can produce fully static standalone binaries. With SIMD enabled,
`ghostty-vt` only depends on libc.

The point of this PR is primarily to get the bug fixes I found in and to
get this running in CI on every commit so that we don't regress it. In
the future we'll do more (see the future section below).

> [!WARNING]
> **The API is extremely not stable and will definitely change in the
future.** The _functionality/logic_ is very stable, because it's the
same core logic used by Ghostty, but the API itself is not at all. For
this PR, we mostly just expose everything and we'll reshape the API
later.

## What is `libghostty-vt`? 

I've stated my vision for a `libghostty` for some time. You can find
background on that. Recently, I've realized that the _scope_ of
`libghostty` is way too large to ship as a single unit. To that end,
`libghostty` will be split into smaller scoped sub-libraries (that may
depend on each other for higher level functionality). The exact mapping
is being worked out.

**The first library I'm extracting is `libghostty-vt` (both Zig and C,
this PR starts with Zig).** This will be a library focused only on core
terminal emulation, terminal state, and screen state. It lacks rendering
support and input handling.

**But why?** The core terminal emulation is the primary source of both
missing functionality and bugs within terminal emulators. Look at this
[simple bug in jediterm](https://github.com/JetBrains/jediterm/pull/311)
that fails to parse a trivially common sequence resulting in horrendous
misrenders. Jediterm is used by every JetBrains IDE! Literally the core
terminal in a many-millions-of-dollars business!

`libghostty-vt` is a _zero dependency_ terminal emulation layer that
exposes a C API which will let any popular language build bindings so
that we can stop reinventing the terminal emulation layer and get best
in class (or near it) terminal emulation capabilities everywhere.

## In This PR

- `ghostty-vt` Zig module
- Example usage of it in `example/zig-vt`
- CI to run Zig module tests, test that our examples build, and test
SIMD on/off
- New feature build flag `-Dsimd` (default on) that turns SIMD on or off
- Unexposed feature flag that allows building the core terminal logic
without regex support (default on right now jus for the ghostty-vt
module as I figure out what our future regex story is in a post-oni
world).
- Fixes for non-SIMD builds

## Future

There's a lot to do in the future outside of this PR:

- Define a more stable Zig API
- Define a C API at all
- Figure out our regex engine story
- Documentation improvements
2025-09-22 10:06:36 -07:00
Mitchell Hashimoto c177716ac6
build: some docs 2025-09-22 09:53:22 -07:00
Mitchell Hashimoto 8477b6a21a
simd: scalar base64 ignores invalid padding 2025-09-22 09:44:58 -07:00
Mitchell Hashimoto 530633b9e9
simd: fix scalar utf8 decoding 2025-09-22 09:29:08 -07:00
Mitchell Hashimoto 5a29dd3ef5
build: make build_options generally available 2025-09-22 08:35:44 -07:00
Mitchell Hashimoto 6893024c51
simd: add scalar fallbacks to all for build_options.simd false 2025-09-22 08:26:53 -07:00
Mitchell Hashimoto 8aa4373aaf
ci: add simd on/off test 2025-09-22 06:48:07 -07:00
Lars 8beeebc21d
Force Ghostty to be active if not 2025-09-22 15:27:27 +02:00
Lars 8600954526
Workaround for #8669 2025-09-22 14:52:10 +02:00
rhodes-b fd9014952f use getter to notify is-split property 2025-09-21 22:59:42 -05:00
Mitchell Hashimoto 9c92c3bb81
fastmem non-libc needs to use copyBackwards if dest > src
This fixes test failures when Ghostty's core is run without libc. 
Ghostty in the real world (all built executables) require libc so this
bug has never been hit before, but I'm working on a libc-less core and
this caused real test failures (so its already tested, as well).
2025-09-21 20:48:18 -07:00
Mitchell Hashimoto dfda3ac280
ci: fix example build 2025-09-21 20:39:43 -07:00
Mitchell Hashimoto 3e1ba35843
terminal: fix mistaken gtk logic 2025-09-21 20:29:18 -07:00
Mitchell Hashimoto 14eb8aa4e4
Add simd flag for disabling SIMD functionality 2025-09-21 20:27:34 -07:00
Mitchell Hashimoto f42656b0ac
lib-vt: require libc for now 2025-09-21 19:59:23 -07:00
Mitchell Hashimoto 645520b502
ci: build examples in CI 2025-09-21 19:54:11 -07:00
Mitchell Hashimoto 3e34009492
lib-vt: expose all of terminal for now 2025-09-21 19:50:42 -07:00
Mitchell Hashimoto 64f26c14d3
example/zig-vt 2025-09-21 19:41:58 -07:00
Mitchell Hashimoto 1758f962f6
remove stale example wasm app 2025-09-21 19:40:00 -07:00
Mitchell Hashimoto 4f974f4278
terminal: don't build StringMap.searchIterator without regex support 2025-09-21 19:40:00 -07:00
Mitchell Hashimoto 811f9f05d0
terminal: support disabling kitty graphics protocol 2025-09-21 19:40:00 -07:00
Mitchell Hashimoto 1b46884e72
terminal: add build option for oniguruma, which controls tmux cc mode 2025-09-21 19:39:59 -07:00
Mitchell Hashimoto a42193b997
start extracting core terminal zig module 2025-09-21 19:39:58 -07:00
Mitchell Hashimoto 485b6b73bf
build(deps): bump vmactions/freebsd-vm from 1.2.3 to 1.2.4 (#8827)
Bumps [vmactions/freebsd-vm](https://github.com/vmactions/freebsd-vm)
from 1.2.3 to 1.2.4.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/vmactions/freebsd-vm/releases">vmactions/freebsd-vm's
releases</a>.</em></p>
<blockquote>
<p>add 15.0</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="487ce35b96"><code>487ce35</code></a>
Update from base vm</li>
<li><a
href="81b0e85cca"><code>81b0e85</code></a>
Generated from base-vm</li>
<li><a
href="4f22df8b8d"><code>4f22df8</code></a>
add 15</li>
<li><a
href="11ecb20fda"><code>11ecb20</code></a>
Update from base vm</li>
<li><a
href="ec67fecd18"><code>ec67fec</code></a>
Generated from base-vm</li>
<li><a
href="709b36f060"><code>709b36f</code></a>
Update version to</li>
<li>See full diff in <a
href="05856381fa...487ce35b96">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=vmactions/freebsd-vm&package-manager=github_actions&previous-version=1.2.3&new-version=1.2.4)](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-21 19:38:54 -07:00
Mitchell Hashimoto 6c160844b9
build(deps): bump cachix/install-nix-action from 31.6.1 to 31.6.2 (#8828)
Bumps
[cachix/install-nix-action](https://github.com/cachix/install-nix-action)
from 31.6.1 to 31.6.2.
<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.2</h2>
<h2>What's Changed</h2>
<ul>
<li>nix: 2.31.1 -&gt; 2.31.2 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/256">cachix/install-nix-action#256</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/cachix/install-nix-action/compare/v31...v31.6.2">https://github.com/cachix/install-nix-action/compare/v31...v31.6.2</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="a809471b5c"><code>a809471</code></a>
Merge pull request <a
href="https://redirect.github.com/cachix/install-nix-action/issues/256">#256</a>
from cachix/create-pull-request/patch</li>
<li><a
href="d5f1c043d0"><code>d5f1c04</code></a>
nix: 2.31.1 -&gt; 2.31.2</li>
<li>See full diff in <a
href="7be5dee142...a809471b5c">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.1&new-version=31.6.2)](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-21 19:38:25 -07:00
Mitchell Hashimoto 1de584f32c
xdg: treat empty env vars as not existing (#8830)
Replaces #8786 

The author of the original PR used AI agents to create that PR. To the
extent that this PR borrows code from that PR (mostly in the tests) AI
was used in the creation of this PR.
2025-09-21 19:38:14 -07:00
Daniel Wennberg f2fcbd6e5e Add missing codepoints to isPowerline predicate
e0d6 and e0d7 were left out.

Also collapsed everything to a single range; unlikely that the unused
gaps (e0c9, e0cb, e0d3, e0d5) would be used for something else in any
font that ships Powerline glyphs.
2025-09-21 19:00:35 -07:00
Jeffrey C. Ollie e9c18ff6db
xdg: treat empty env vars as not existing 2025-09-21 20:57:00 -05:00
rhodes-b 4e7f847d03 remove setIsSplit in surface class 2025-09-21 20:37:47 -05:00
rhodes-b fdcaeebb99 bind is-split property between split_tree class and surface class 2025-09-21 20:35:20 -05:00
dependabot[bot] a63864d8df
build(deps): bump cachix/install-nix-action from 31.6.1 to 31.6.2
Bumps [cachix/install-nix-action](https://github.com/cachix/install-nix-action) from 31.6.1 to 31.6.2.
- [Release notes](https://github.com/cachix/install-nix-action/releases)
- [Changelog](https://github.com/cachix/install-nix-action/blob/master/RELEASE.md)
- [Commits](7be5dee142...a809471b5c)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-22 00:07:00 +00:00
dependabot[bot] 3a4f7b3d0f
build(deps): bump vmactions/freebsd-vm from 1.2.3 to 1.2.4
Bumps [vmactions/freebsd-vm](https://github.com/vmactions/freebsd-vm) from 1.2.3 to 1.2.4.
- [Release notes](https://github.com/vmactions/freebsd-vm/releases)
- [Commits](05856381fa...487ce35b96)

---
updated-dependencies:
- dependency-name: vmactions/freebsd-vm
  dependency-version: 1.2.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-22 00:06:51 +00:00
Daniel Wennberg d1db596039 Add box drawing characters to the min contrast exclusion 2025-09-21 17:01:58 -07:00
Daniel Wennberg 2f19d6bb73 Treat Powerline glyphs like normal characters
...not whitespace. Powerline glyphs can be considered an extension of
the Block Elements unicode block, which is neither whitespace nor
symbols (icons).

This ensures that characters immediately followed by a powerline glyph
are constrained to a single cell (unlike the current behavior where a PL
glyph is considered whitespace), while symbols (icons) immediately
preceded by a powerline glyph are not (unlike if a PL glyph were
considered a symbol). This resolves
https://discord.com/channels/1005603569187160125/1417236683266592798
2025-09-21 17:01:58 -07:00
Daniel Wennberg 13d44129bf Add constraint width tests 2025-09-21 16:39:17 -07:00
Mitchell Hashimoto bc95317ba4
build: many more lazy dependencies, defer deps add unless needed (#8826)
This makes more dependencies lazy. This has a practical effect of
reducing the number of dependencies that need to be downloaded when
running certain zig build steps.

This is all limited because we're blocked on an upstream Zig issue:
https://github.com/ziglang/zig/issues/21525 This prevents us from fully
avoiding downloading many dependencies, but at least they're relatively
small.

One major improvement here is the usage of `lazyImport` for
`zig-wayland` that prevents downloading `zig_wayland` unconditionally on
all platforms. On macOS, we don't download this at all anymore.

Another, weirder change is that all our transitive dependencies are now
marked lazy (e.g. glslang's upstream source) even if the glslang build
always requires it. This was necessary because without this, even if we
simply referenced glslang in the root build.zig, it would force the
source package to download unconditionally. This no longer happens.

cc @pluiedev Minor improvements here, doesn't change the long term plan,
but improves things in the interim.
2025-09-21 13:43:31 -07:00
Mitchell Hashimoto 17498ce122
build: many more lazy dependencies, defer deps add unless needed
This makes more dependencies lazy. This has a practical effect of
reducing the number of dependencies that need to be downloaded when
running certain zig build steps.

This is all limited because we're blocked on an upstream Zig issue:
https://github.com/ziglang/zig/issues/21525 This prevents us from
fully avoiding downloading many dependencies, but at least they're
relatively small.

One major improvement here is the usage of `lazyImport` for
`zig-wayland` that prevents downloading `zig_wayland` unconditionally on
all platforms. On macOS, we don't download this at all anymore.

Another, weirder change is that all our transitive dependencies are now
marked lazy (e.g. glslang's upstream source) even if the glslang build
always requires it. This was necessary because without this, even if we
simply referenced glslang in the root build.zig, it would force the
source package to download unconditionally. This no longer happens.
2025-09-21 13:26:09 -07:00
Mitchell Hashimoto 09b37e3b24
flatpak: update GNOME runtime to 49 (#8825)
Notable dependencies changes:

- blueprint-compiler is dropped as it has been bundled in the SDK
- GTK 4.18.6 -> 4.20.1
- libadwaita 1.7.7 -> 1.8.0
2025-09-21 13:07:36 -07:00
Leorize 4ff74fdfae
flatpak: update GNOME runtime to 49
Notable dependencies changes:

- blueprint-compiler is dropped as it has been bundled in the SDK
- GTK 4.18.6 -> 4.20.1
- libadwaita 1.7.7 -> 1.8.0
2025-09-21 14:17:48 -05:00
Daniel Wennberg 52ef17d4e0 Hoist `GlyphSize` out of nested scopes 2025-09-21 11:32:41 -07:00
Peter Dave Hello 1a189787ae Add zh_TW Traditional Chinese locale 2025-09-22 00:13:15 +08:00
Mitchell Hashimoto 25aaca5a6f
Update iTerm2 colorschemes (#8812)
Upstream release:
https://github.com/mbadolato/iTerm2-Color-Schemes/releases/tag/release-20250916-134637-76894f0
2025-09-21 07:25:05 -07:00
Mitchell Hashimoto 1a6af17041
gtk: restore flatpak-aware resource directory support (#8816)
This was not ported to gtk-ng before old runtime was removed, breaking
shell integration on Flatpak.

This implementation is copied verbatim from old runtime.
2025-09-21 07:02:47 -07:00
Kat b52553de24
Update README_TRANSLATORS to reflect the new i18n locales struct path (#8819)
It was moved in 9feaec9c9c (#8798), but
the documentation seems to have been forgotten.
2025-09-21 11:57:56 +00:00
Kat f6c1653dee
Update README_TRANSLATORS to reflect the new i18n locales struct path.
It was moved in 9feaec9c9c, but the documentation
seems to have been forgotten.
2025-09-21 11:42:32 +00:00
Leah Amelia Chen 055a007926
Default config template be explicit that you do not copy the default values (#8701) 2025-09-21 10:59:45 +02:00
Leorize cf0557a093
gtk: restore flatpak-aware resource directory support
This was not ported to gtk-ng before old runtime was removed, breaking
shell integration on Flatpak.
2025-09-21 02:11:41 -05:00
Mitchell Hashimoto fcd0f88024
unicode: delete props.zig and clean up symbols deps too (#8814)
Follow up to #8810

Same reasoning.
2025-09-20 21:07:23 -07:00
rhodes-b 3254bb41d5 fix typo 2025-09-20 22:49:35 -05:00
rhodes-b 1c59ed5d60 comment for the n_siblings surface member 2025-09-20 22:47:50 -05:00
rhodes-b 3d3551d1ed add n_siblings member, and when splits are created / removed update the number of siblings for the remaining nodes 2025-09-20 22:45:17 -05:00
Mitchell Hashimoto 10dc9353b7
unicode: delete props.zig and clean up symbols deps too
Follow up to #8810

Same reasoning.
2025-09-20 20:28:25 -07:00
rhodes-b 42fc42de2d fix surface blueprint formatting 2025-09-20 21:45:01 -05:00
rhodes-b 180cc31d87 fix comments to specific the config option 2025-09-20 21:41:15 -05:00
rhodes-b fa5a44e591 apply unfocused-split with surface blueprint 2025-09-20 21:37:59 -05:00
rhodes-b cfcd11863e rename setUnfocused to setUnfocusedFill 2025-09-20 20:24:51 -05:00
rhodes-b 52c2f02fa4 use focus signal in split_tree to determine if we apply unfocused-split-fill 2025-09-20 20:18:28 -05:00
mitchellh 6e1eb67d94 deps: Update iTerm2 color schemes 2025-09-21 00:15:05 +00:00
Mitchell Hashimoto 511314e1a1
unicode: isolate properties, tables, and ziglyph into separate files (#8810)
This makes it cleaner visually where the separation of concerns is.
There is now the generic `Properties.zig`, and then the
implementation-specific `props_<impl>.zig` files. Despite Zig's lazy
analysis, I find this is much easier to understand as a human.

Doing this resulted in finding one part in `src/terminal` where we were
still inadvertently using ziglyph directly instead of our LUTs! I
switched this out.

After this PR, `src/terminal` as a standalone module no longer depends
on `ziglyph` at all.[^1]

cc @jacobsandlund this is going to cause conflicts in your PR. I'm sorry
about that. But it should make it cleaner to bring in the uucode work by
adding a dedicated `props_uucode.zig` file!

[^1]: Why would I be talking about `src/terminal` as a standalone
module? That's interesting.
2025-09-20 15:15:15 -07:00
Mitchell Hashimoto a96b2abf7c
update to the latest zon2nix (#8808) 2025-09-20 15:11:34 -07:00
Jeffrey C. Ollie d4bc73a9d6
update to the latest zon2nix 2025-09-20 17:02:24 -05:00
Mitchell Hashimoto bf1278deff
unicode: isolate properties, tables, and ziglyph into separate files
This makes it cleaner to add new sources of table generation and also
avoids inadvertently depending on different modules (despite Zig's lazy
analysis). 

This also fixes up terminal to only use our look up tables which avoids
bringing ziglyph in for the terminal module.
2025-09-20 15:00:55 -07:00
Mitchell Hashimoto c277ef8d82
gtk: use zig-gobject generated from ghostty-org/zig-gobject (#8802) 2025-09-20 12:38:54 -07:00
rhodes-b 6ee9a3767b worse way but its at least split aware, doesn't seem like the path forward 2025-09-20 04:32:09 -05:00
rhodes-b b34e22053d unfocused-split-fill working again though it can't detect when its actually a split yet 2025-09-20 03:55:05 -05:00
rhodes-b f0e407de85 nicer comment on why you shouldn't copy the defaults into your config specifically that some options will conflict with each other 2025-09-20 02:28:07 -05:00
Jeffrey C. Ollie fbaacc235b
gtk: use zig-gobject generated from ghostty-org/zig-gobject 2025-09-20 01:39:59 -05:00
Mitchell Hashimoto f6e4a2888a
Snap: Do not leak snap variables or snap paths into children (#8771)
Avoid leaking snap environment values and in particular the `$SNAP*`
values to the children that we run from the terminal.

Do this programmatically instead of the launcher, since ghostty needs
know the environment it runs in, while it must not leak the info to the
children.

We've also another leak on snap, that creates a more visible problem
(wrong matching of children applications) that is the apparmor security
profile.

I've handled it at
cc3b46f600
but that requires some love in order to fully decouple the snap option
to the build, to avoid including it in non-snap builds, so an help would
be appreciated there.

> This PR was contains code (in `filterSnapPaths`) that was improved by
DeepSeek.
2025-09-19 16:12:30 -07:00
Mitchell Hashimoto 270891eee1
ci: add -Dsnap test 2025-09-19 16:07:55 -07:00
Mitchell Hashimoto 7b8be344fc
stylistic changes 2025-09-19 16:03:49 -07:00
Marco Trevisan (Treviño) bf3a607db6 build: Add a new snap option and use it to build the snap
So we can limit the snap operations even at build time
2025-09-19 15:55:14 -07:00
Marco Trevisan (Treviño) d55f3e5c41 gtk/surface: Filter out the SNAP variables by their contents
When running in a snap context we need to filtering out all the SNAP_*
variables out there, but this is not enough, because it's also needed
to sanitize them by ensuring that no variable containing a path pointing
to a $SNAP folder is leaked there.

Otherwise we might have (for example) XDG_RUNTIME_DIRS containing a
"private" snap path, and that will be exposed to all the applications
that will be started from ghostty
2025-09-19 15:54:52 -07:00
Marco Trevisan (Treviño) 2de105e035 snap: Do not leak the launcher into the ghostty $PATH
Otherwise when launching the snap we'll get a "launcher" binary that is
provided by the own snap
2025-09-19 15:54:52 -07:00
Mitchell Hashimoto 944f206b76
build: lower build.zig dependencies to improve caching (#8798)
This is stomping towards minimizing our build.zig dependencies so that
it can be cached more often. Right now, touching almost any file in the
project forces the build.zig to rebuild which is destroying my
productivity.

The first set of work is to move all our completion and syntax file
generation into a data generator exe, e.g. vim, zsh, fish, etc. This
might seem like just shuffling bits but it results in a real tangible
improvement: when you run `zig build test`, we no longer have to rebuild
our `build.zig` when you for example... modify a CLI action.

This is just a small improvement. Our build.zig depends on way too much
stuff, so this PR will be draft while I continue to use commits to
separate out scopes of change.
2025-09-19 15:46:02 -07:00
Mitchell Hashimoto da2a3e2510
very slightly improve helpgen dependencies 2025-09-19 15:41:14 -07:00
Mitchell Hashimoto 9feaec9c9c
build: move locales out into dedicated file 2025-09-19 15:28:25 -07:00
Mitchell Hashimoto d65466362d
build: Command.expandPath can go in its own dedicated os/path.zig file 2025-09-19 15:22:10 -07:00
Mitchell Hashimoto 800fa99ff2
build: move apprt, font, renderer enums to dedicated files
This reduces the surface area of files we depend on for builds.
2025-09-19 15:17:41 -07:00
Mitchell Hashimoto bf047032b5
build: generate various resources at build run, not build graph
This is stomping towards minimizing our build.zig dependencies so that
it can be cached more often. Right now, touching almost any file in the
project forces the build.zig to rebuild which is destroying my
productivity.
2025-09-19 14:50:33 -07:00
Mitchell Hashimoto 999b605145
macos: quick terminal stores the last closed size by screen (#8796)
Fixes #8713

This stores the last closed state of the quick terminal by screen
pointer. We use a weak mapping so if a screen is unplugged we'll clear
the memory. We will not remember the size if you unplug and replug in a
monitor.
2025-09-19 13:14:14 -07:00
Mitchell Hashimoto 4d761c96e5
macos: quick terminal stores the last closed size by screen
Fixes #8713

This stores the last closed state of the quick terminal by screen
pointer. We use a weak mapping so if a screen is unplugged we'll clear
the memory. We will not remember the size if you unplug and replug in a
monitor.
2025-09-19 13:01:29 -07:00
Mitchell Hashimoto 3ce1239460
ci: put a 10 minute timeout on the Debian build (#8795)
This usually takes around 2 minutes. I just saw a runaway one spending
30+ minutes.
2025-09-19 12:32:49 -07:00
Mitchell Hashimoto 36ef1169f6
ci: put a 10 minute timeout on the Debian build
This usually takes around 2 minutes. I just saw a runaway one spending
30+ minutes.
2025-09-19 12:29:20 -07:00
Mitchell Hashimoto 66a2da13d4
macos: set the app icon in syncAppearance to delay the icon update (#8792)
Fixes #8734

This forces the app icon to be set on another event loop tick from the
main startup.

In the future, we should load and set the icon completely in another
thread. It appears that all the logic we have is totally thread-safe.
2025-09-19 12:16:59 -07:00
Mitchell Hashimoto f60bdb0faa
macos: set the app icon in syncAppearance to delay the icon update
Fixes #8734

This forces the app icon to be set on another event loop tick from
the main startup. 

In the future, we should load and set the icon completely in another
thread. It appears that all the logic we have is totally thread-safe.
2025-09-19 12:07:28 -07:00
Mitchell Hashimoto 55153937c6
macos: correct SurfaceView supported send/receive types for services (#8790)
Fixes #8785

This is the callback AppKit sends when it wants to know if our
application can handle sending and receiving certain types of data.

The prior implementaiton was incorrect and would erroneously claim
support over combinations that we couldn't handle (at least, at the
SurfaceView layer).

This corrects the implementation. The services we expect still show up
and the error in 8785 goes away.
2025-09-19 12:01:31 -07:00
Mitchell Hashimoto d27bc69f2e
macos: correct SurfaceView supported send/receive types for services
Fixes #8785

This is the callback AppKit sends when it wants to know if our
application can handle sending and receiving certain types of data.

The prior implementaiton was incorrect and would erroneously claim
support over combinations that we couldn't handle (at least, at the
SurfaceView layer). 

This corrects the implementation. The services we expect still show up
and the error in 8785 goes away.
2025-09-19 11:44:46 -07:00
Mitchell Hashimoto 1b6cda2b10
macos: "new tab" service should set preferred parent to ensure tab (#8784)
Fixes #8783

Our new tab flow will never have a previously focused window because its
triggered by a service so we need to use the "preferred parent" logic we
have to open this in the last focused window.
2025-09-19 10:15:04 -07:00
Mitchell Hashimoto 950d3755ff
renderer/opengl: minimum contrast for black sets proper color (#8782)
Fixes #8745

When rendering black for minimum contrast we were setting opacity to 0
making it invisible.
2025-09-19 09:58:50 -07:00
Mitchell Hashimoto 6143aa8ce0
macos: "new tab" service should set preferred parent to ensure tab
Fixes #8783

Our new tab flow will never have a previously focused window because its
triggered by a service so we need to use the "preferred parent" logic we
have to open this in the last focused window.
2025-09-19 09:58:27 -07:00
Mitchell Hashimoto d30f1537ec
gtk: add glib log writer function (#8779)
This will funnel GLib/GObject/GTK logging messages through Zig's logging
system rather than just dumping them directly to stderr.
2025-09-19 09:47:06 -07:00
Mitchell Hashimoto c42ed70758
renderer/opengl: minimum contrast for black sets proper color
Fixes #8745

When rendering black for minimum contrast we were setting opacity to 0
making it invisible.
2025-09-19 09:45:08 -07:00
Jeffrey C. Ollie f375ec7c65
gtk: add glib log writer function
This will funnel GLib/GObject/GTK logging messages through Zig's logging
system rather than just dumping them directly to stderr.
2025-09-19 09:35:35 -05:00
Mitchell Hashimoto 122731c6e8
Optimize PNG images losslessly: 73 → 51 KiB (−30%) (#8776) 2025-09-19 07:07:57 -07:00
maximal 38c0de3aa4 Revert `src/font/sprite/testdata` 2025-09-19 15:00:04 +03:00
maximal 6d40da1e1c Optimize PNG images losslessly: 73 → 51 KiB (−30%) 2025-09-19 12:55:19 +03:00
Jacob Sandlund 7b0722bf16 Remove comment above test. it's not too slow 2025-09-19 01:26:17 -04:00
Jacob Sandlund cf3b514efc pr feedback: `get`, remove todos for case_folding_simple 2025-09-19 01:24:13 -04:00
Mitchell Hashimoto b9a5cad562
build: explicitly suffix Zig files 2: Electric Boogaloo (#8769)
Of *course* I missed one
2025-09-18 16:58:50 -07:00
Leah Amelia Chen 6d2576abee
build: explicitly suffix Zig files 2: Electric Boogaloo
Of *course* I missed one
2025-09-19 01:23:06 +02:00
Mitchell Hashimoto 77b39c45a6
slightly improve logs (#8767)
Hello

This is a small thing I noticed when building Ghostty. The logs for
SetTitle and Pwd are unreadable due to them being shown as an array of
integers, so I added a custom formatter for them to be shows as text.
2025-09-18 15:28:24 -07:00
عبد الرحمن صباهي d6e58ef1fc slightly improve logs 2025-09-19 01:00:17 +03:00
Mitchell Hashimoto 7875efbcb8
macos: implement bell-features=border on macOS (#8768)
https://github.com/user-attachments/assets/ac58ff8e-9ef6-4cb2-8e40-9f588aaaca4e
2025-09-18 14:51:26 -07:00
Mitchell Hashimoto fe55d90ec5
macos: implement bell-features=border on macOS 2025-09-18 14:43:09 -07:00
Mitchell Hashimoto 2ebef2650c
build: explicitly suffix generated Zig source files (#8765)
Previously we're just feeding the compiler source files generated via
capturing stdout, which all by default have the filename `stdout`. Under
some particular yet uncertain circumstances in Zig 0.14 (only factor
we've found so far is a large amount of cores/compilation shards) the
compiler will actually crash on an unreachable code path that assumes
all source files either end in .zig or .zon, causing crashes for
packagers for distros like Nixpkgs and Gentoo.

Given this has been explicitly made illegal in Zig 0.15 (see
ziglang/zig#24957) I don't really see why we shouldn't fix this for 1.2
too. We have to do this at some point no matter what anyways.
2025-09-18 14:11:32 -07:00
Mitchell Hashimoto 050188fc12
macos: bell-features=title works again (#8766)
This was a regression we didn't fix before 1.2.
2025-09-18 14:11:22 -07:00
Daniel Wennberg 333a32208e Factor out glyph rect function 2025-09-18 14:05:12 -07:00
Mitchell Hashimoto ad92bf7ab5
macos: bell-features=title works again
This was a regression we didn't fix before 1.2.
2025-09-18 14:02:32 -07:00
Leah Amelia Chen 9b40e03c40
build: explicitly suffix generated Zig source files
Previously we're just feeding the compiler source files generated via
capturing stdout, which all by default have the filename `stdout`.
Under some particular yet uncertain circumstances in Zig 0.14 (only
factor we've found so far is a large amount of cores/compilation shards)
the compiler will actually crash on an unreachable code path that assumes
all source files either end in .zig or .zon, causing crashes for packagers
for distros like Nixpkgs and Gentoo.

Given this has been explicitly made illegal in Zig 0.15
(see ziglang/zig#24957) I don't really see why we shouldn't fix this for
1.2 too. We have to do this at some point no matter what anyways.
2025-09-18 23:02:03 +02:00
Mitchell Hashimoto da9334dce5
macos: opening filepaths should make proper file URLs (#8764)
Fixes #8763
2025-09-18 13:37:02 -07:00
Mitchell Hashimoto 4fa8b8f285
macos: opening filepaths should make proper file URLs
Fixes #8763
2025-09-18 13:28:27 -07:00
Mitchell Hashimoto 834fe17abb
macos: set initial window in TerminalWindow awakeFromNib (#8762)
Maybe fixes #8736

I thought `windowDidLoad` was early on because its before the window is
shown but apparently not. Let's try `awakeFromNib` which is called just
after the window is loaded from the nib. It is hard to get any earlier
than that.
2025-09-18 13:10:28 -07:00
Mitchell Hashimoto 734d1a13b3
macos: set initial window in TerminalWindow awakeFromNib
Maybe fixes #8736

I thought `windowDidLoad` was early on because its before the window is
shown but apparently not. Let's try `awakeFromNib` which is called
just after the window is loaded from the nib. It is hard to get any
earlier than that.
2025-09-18 13:05:57 -07:00
Mitchell Hashimoto 92effb37db
documentation: fix MacOSDockDropBehavior valid values (#8752)
The documentation shows that the enum values should be "new-window" and
"new-tab",
However, "new-window" currently fails, but "window" is still accepted.
2025-09-18 12:46:54 -07:00
Daniel Wennberg 8fe9c579ef Drop the nan sentinel; just fall through instead 2025-09-18 12:39:19 -07:00
Daniel Wennberg 4af4e18725 Use approximate equality for float comparisons 2025-09-18 12:34:32 -07:00
Mitchell Hashimoto 38dcf0ab59
macos: window-position-x/y are from top-left corner (#8760)
Fixes #8672

Almost fully written by AI:
https://ampcode.com/threads/T-86df68a3-578c-4a1c-91f3-788f8b8f0aae

I reviewed all the code.
2025-09-18 12:27:35 -07:00
Mitchell Hashimoto 773990ada3
macos: window-position-x/y are from top-left corner
Fixes #8672

Almost fully written by AI: https://ampcode.com/threads/T-86df68a3-578c-4a1c-91f3-788f8b8f0aae

I reviewed all the code.
2025-09-18 12:18:13 -07:00
Jacob Sandlund 4fc8faa01e Merge remote-tracking branch 'upstream/main' into jacob/uucode 2025-09-18 14:27:33 -04:00
Jacob Sandlund b83315cb81 set max for unicode grapheme executable 2025-09-18 14:26:04 -04:00
Jacob Sandlund 6bd5da7354 update commented out test 2025-09-18 14:24:24 -04:00
Jacob Sandlund 83f387d735 default log level 2025-09-18 14:21:39 -04:00
Jacob Sandlund 18e9989f63 forgot to align buf 2025-09-18 14:20:41 -04:00
Mitchell Hashimoto 354b62d5ce
macos: add progress bar to iOS target 2025-09-18 10:48:29 -07:00
Mitchell Hashimoto 9f6991f9db
macos: custom progress bar to workaround macOS 26 ProgressView bugs (#8753)
Fixes #8731

The progress view in macOS 26 is broken in ways we can't work around
directly. Instead, we must create our own custom progress bar. Luckily,
our usage of the progress view is very simple.



https://github.com/user-attachments/assets/fb3dd271-0830-49fa-97ce-48eb5514e781

This was written mostly by Amp. I made my own modifications and fully
understand the code. Threads below.

Amp threads:
https://ampcode.com/threads/T-88b550b7-5e0d-4ab9-97d9-36fb63d18f21
https://ampcode.com/threads/T-721d6085-21d5-497d-b6ac-9f203aae0b94
2025-09-18 10:31:48 -07:00
Mitchell Hashimoto 058d6808c1
macos: custom progress bar to workaround macOS 26 ProgressView bugs
Fixes #8731

The progress view in macOS 26 is broken in ways we can't work around
directly. Instead, we must create our own custom progress bar. Luckily,
our usage of the progress view is very simple.

Amp threads:
https://ampcode.com/threads/T-88b550b7-5e0d-4ab9-97d9-36fb63d18f21
https://ampcode.com/threads/T-721d6085-21d5-497d-b6ac-9f203aae0b94
2025-09-18 10:22:54 -07:00
Mitchell Hashimoto 6ed00b1217
renderer: create explicit sampler state for custom shaders (#8751)
The GLSL to MSL conversion process uses a passed-in sampler state for
the `iChannel0` parameter and we weren't providing it. This magically
worked on Apple Silicon for unknown reasons but failed on Intel GPUs.

In normal, hand-written MSL, we'd explicitly create the sampler state as
a normal variable (we do this in `shaders.metal` already!), but the
Shadertoy conversion stuff doesn't do this, probably because the exact
sampler parameters can't be safely known.

This fixes a Metal validation error when using custom shaders:

```
-[MTLDebugRenderCommandEncoder validateCommonDrawErrors:]:5970: failed 
assertion `Draw Errors Validation Fragment Function(main0): missing Sampler 
binding at index 0 for iChannel0Smplr[0].
```

This wasn't a simple error message, the assertion would cause Xcode 26
to halt the program at that point.
2025-09-18 09:31:17 -07:00
Mitchell Hashimoto a453681615
renderer: create explicit sampler state for custom shaders
The GLSL to MSL conversion process uses a passed-in sampler state for
the `iChannel0` parameter and we weren't providing it. This magically
worked on Apple Silicon for unknown reasons but failed on Intel GPUs.

In normal, hand-written MSL, we'd explicitly create the sampler state as
a normal variable (we do this in `shaders.metal` already!), but the
Shadertoy conversion stuff doesn't do this, probably because the exact
sampler parameters can't be safely known.

This fixes a Metal validation error when using custom shaders:

```
-[MTLDebugRenderCommandEncoder validateCommonDrawErrors:]:5970: failed 
assertion `Draw Errors Validation Fragment Function(main0): missing Sampler 
binding at index 0 for iChannel0Smplr[0].
```
2025-09-18 09:25:37 -07:00
Daniel Wennberg bb607e0999 Refactor load flags into a function 2025-09-18 09:16:32 -07:00
Matthias von Arx a22a1771b5
documentation: fix MacOSDockDropBehavior valid values 2025-09-18 18:09:10 +02:00
Jacob Sandlund 69594119c3 fix up diff from benchmarks, and add tests against ziglyph 2025-09-18 11:46:05 -04:00
Mitchell Hashimoto a3643f8f52
renderer/metal: provide MTLTextureUsage render target for custom shaders (#8749)
This fixes a Metal validation error in Xcode when using custom shaders.
I suspect this is one part of custom shaders not working properly on
Intel macs (probably anything with a discrete GPU).

This happens to work on Apple Silicon but this is undefined behavior and
we're just getting lucky.

There is one more issue I'm chasing down that I think is also still
blocking custom shaders working on Intel macs.
2025-09-18 07:51:12 -07:00
Mitchell Hashimoto cb0e60c3e5
renderer/metal: provide MTLTextureUsage render target for custom shaders
This fixes a Metal validation error in Xcode when using custom shaders. 
I suspect this is one part of custom shaders not working properly on
Intel macs (probably anything with a discrete GPU).

This happens to work on Apple Silicon but this is undefined behavior and
we're just getting lucky.

There is one more issue I'm chasing down that I think is also still
blocking custom shaders working on Intel macs.
2025-09-18 07:29:26 -07:00
Jacob Sandlund 285a33fbc0 nix update and remove extra benchmark files 2025-09-18 09:29:22 -04:00
Jacob Sandlund 3275903611 update uucode and cleanups 2025-09-18 09:26:09 -04:00
Jacob Sandlund ec5e1e504d Merge remote-tracking branch 'upstream/main' into jacob/uucode 2025-09-18 08:46:08 -04:00
Daniel Wennberg 03a707b2c0 Add tests for font metrics and their estimators 2025-09-17 23:04:59 -07:00
Daniel Wennberg e1b2f6f021 Use same hinting flags for measurement and rendering 2025-09-17 23:04:59 -07:00
Daniel Wennberg cc165990ec Use outline bbox for ascii_height measurement 2025-09-17 22:51:12 -07:00
Daniel Wennberg 3a7e7f905b Give the autoformatter what it wants 2025-09-17 22:03:00 -07:00
Mitchell Hashimoto 1efde5caba
font: Measure ascii height and use to upper bound ic_width (#8720)
Measure the ~actual height between the ascender and descender lines as
the height of the~ overall bounding box of the font's ASCII
characters[^1], and use this to upper bound the IC width estimate. This
ensures that the scaling of fallback CJK fonts to a wide-aspect primary
font doesn't result in oversized CJK glyphs.

Fixes #8709.

I'd appreciate feedback from Chinese speakers on the suitability of this
metric across a variety of primary fonts.

Screenshots using an empty Ghostty config on macOS and the test file
from #8651. The font loaded as fallback for CJK is PingFang SC.

**1.2.0**
<img width="592" height="301" alt="Screenshot 2025-09-17 at 09 51 43"
src="https://github.com/user-attachments/assets/e553885d-009a-4205-88c9-24747b195211"
/>

**This PR**
<img width="592" height="301" alt="Screenshot 2025-09-17 at 09 51 25"
src="https://github.com/user-attachments/assets/3a8e8d95-ec0a-4d23-a5f0-85b2f47253e3"
/>

[^1]: Note that this may be different from the difference between the
nominal ascent - descent, as non-letter ASCII characters often exceed
the ascender and descnder lines, and fonts often bake the line gap into
the ascent/descent and set `line_gap` to zero, as per official
recommendations like those from Google Fonts:
https://simoncozens.github.io/gf-docs/metrics.html
2025-09-17 14:19:04 -07:00
Daniel Wennberg 6781fbda93 Measure ascii height and use to upper bound ic_width 2025-09-17 12:44:42 -07:00
rhodes-b 55ac946fff more info on do NOT copy default config 2025-09-17 02:41:20 -05:00
Jacob Sandlund ae21e2c8cf Merge remote-tracking branch 'upstream/main' into jacob/uucode 2025-09-17 02:34:06 -04:00
Mitchell Hashimoto 0f0a61c38d
selection scrolling should only depend on y value (#8686)
Fixes #8683

The selection scrolling logic should only depend on the y value of the
cursor position, not the x value. This presents unwanted scroll
behaviors, such as reversing the scroll direction which was just a side
effect of attempting to scroll tick to begin with.
2025-09-16 16:37:31 -07:00
Mitchell Hashimoto 4f47138ea3
selection scrolling should only depend on y value
Fixes #8683

The selection scrolling logic should only depend on the y value of the
cursor position, not the x value. This presents unwanted scroll
behaviors, such as reversing the scroll direction which was just a side
effect of attempting to scroll tick to begin with.
2025-09-16 16:33:49 -07:00
Mitchell Hashimoto a098816709
font-size reloads at runtime if the font wasn't manually set (#8680)
This was a very common pitfall for users. The new logic will reload the
font-size at runtime, but only if the font wasn't manually set by the
user using actions such as `increase_font_size`, `decrease_font_size`,
or `set_font_size`. The `reset_font_size` action will reset our state to
assume the font-size wasn't manually set.

This was requested by the Omarchy project since their themes also can
adjust font size. It makes sense to me.

I also updated a comment about `font-family` not reloading at runtime;
this wasn't true even prior to this commit.
2025-09-16 15:45:23 -07:00
Mitchell Hashimoto 67992fde91
font-size reloads at runtime if the font wasn't manually set
This was a very common pitfall for users. The new logic will reload the
font-size at runtime, but only if the font wasn't manually set by the
user using actions such as `increase_font_size`, `decrease_font_size`,
or `set_font_size`. The `reset_font_size` action will reset our state
to assume the font-size wasn't manually set.

I also updated a comment about `font-family` not reloading at runtime;
this wasn't true even prior to this commit.
2025-09-16 15:39:34 -07:00
Mitchell Hashimoto abec922d91
config: fix binding parsing to allow values containing `=` (#8675)
Fixes #8667

The binding `a=text:=` didn't parse properly.

This is a band-aid solution. It works and we have test coverage for it
thankfully. Longer term we should move the parser to a fully
state-machine based parser that parses the trigger first then the
action, to avoid these kind of things.
2025-09-16 13:57:22 -07:00
Mitchell Hashimoto f7e622e8af
config: fix binding parsing to allow values containing `=`
Fixes #8667

The binding `a=text:=` didn't parse properly.

This is a band-aid solution. It works and we have test coverage for it
thankfully. Longer term we should move the parser to a fully
state-machine based parser that parses the trigger first then the
action, to avoid these kind of things.
2025-09-16 13:53:16 -07:00
Mitchell Hashimoto a32d4988f7
config: update theme names in docs (#8655)
They were renamed, see:
https://github.com/mbadolato/iTerm2-Color-Schemes/commits/master/ghostty/Rose%20Pine
2025-09-16 07:01:43 -07:00
Mitchell Hashimoto b5b4b1be72
ci: no dmg to notarize for debug builds 2025-09-16 06:50:40 -07:00
Mitchell Hashimoto 07243789be
docs: add lacking version information (#8653)
According to the release note
(https://ghostty.org/docs/install/release-notes/1-2-0#quick-terminal-size),
`quick-terminal-size` option is available since 1.2.0.
At first, I opened a PR in ghostty-org/website
(https://github.com/ghostty-org/website/pull/370). Then the bot
commented that the part was auto-generated content, so I created this
PR.
2025-09-16 06:05:19 -07:00
Jon Parise ed0d1b8371
Bash shell-integration mark ssh wrapper as a function (#8647) 2025-09-16 07:55:49 -04:00
Simon Olofsson fd03a146ba
config: update theme names in docs
They were renamed, see: https://github.com/mbadolato/iTerm2-Color-Schemes/commits/master/ghostty/Rose%20Pine
2025-09-16 10:37:24 +02:00
カワリミ人形 a92a237b80
docs: add lacking version information
`quick-terminal-size` option is available since 1.2.0
2025-09-16 16:13:56 +09:00
Nilton Perim Neto 79f8ea07a1
Some portuguese translation updates (#8633)
Added some prepositions not previously added and
changed a word to be more accurate to the portuguese meaning

---------

Signed-off-by: Nilton Perim Neto <niltonperimneto@gmail.com>
2025-09-16 04:13:12 +00:00
rhodes-b 1397c76243 mark ssh shell-integration wrapper as a function this matches other features + fixes a case where users alias to some other command 2025-09-15 21:49:48 -05:00
Mitchell Hashimoto 0646cf8c1e
Docs: add undo-timeout configuration setting name (#8639)
The action to undo commands had the configuration option missing

Related to: https://github.com/ghostty-org/website/pull/367
2025-09-15 14:02:14 -07:00
dmunozv04 c6143a1539
Docs: add undo-timeout configuration setting name 2025-09-15 22:55:01 +02:00
Mitchell Hashimoto 0e9d052e68
Pass config to splits in NewTerminalConfig (#8638)
Config contains the command, working directory, and environment
variables intended to be passed to the new split, but it looks like we
forgot to include it as an argument in this branch.

Discussion: https://github.com/ghostty-org/ghostty/discussions/8637
2025-09-15 13:18:40 -07:00
Caleb Hearth ac9f3b88aa
Pass config to splits in NewTerminalConfig
Config contains the command, working directory, and environment
variables intended to be passed to the new split, but it looks like we
forgot to include it as an argument in this branch.

Discussion: https://github.com/ghostty-org/ghostty/discussions/8637
2025-09-15 13:16:18 -06:00
Mitchell Hashimoto 8b00bd430d
bump the version for development (#8635) 2025-09-15 11:04:57 -07:00
Mitchell Hashimoto 1201bc27d2
bump the version for development 2025-09-15 11:01:14 -07:00
Mitchell Hashimoto 3e38e284ca
pin iTerm2 themes dependency (#8632)
There is an upstream bug where subsequent releases will nuke prior
released packages, resulting in 404s. Not good!
2025-09-15 09:33:51 -07:00
Mitchell Hashimoto 693d64b5f8
pin iTerm2 themes dependency
There is an upstream bug where subsequent releases will nuke prior
released packages, resulting in 404s. Not good!
2025-09-15 09:31:09 -07:00
Mitchell Hashimoto d4e62cb6d9
ci: source tarball needs to be uploaded to staged artifacts 2025-09-15 09:24:54 -07:00
Mitchell Hashimoto 6634afc358
ci: fix source tarball copy for release-tag 2025-09-15 09:12:37 -07:00
Mitchell Hashimoto 60aa53d5e2
Update iTerm2 colorschemes (#8631)
Upstream release:
https://github.com/mbadolato/iTerm2-Color-Schemes/releases/tag/release-20250915-154825-b4500fc
2025-09-15 08:57:55 -07:00
mitchellh 5e52659d51 deps: Update iTerm2 color schemes 2025-09-15 15:57:37 +00:00
Mitchell Hashimoto 895fb5f5db
ci: release tip should also staple the dmg 2025-09-15 08:49:47 -07:00
Mitchell Hashimoto d205e65c4d
ci: update tag release to Xcode 26, sparkle to 2.7.3 (#8630)
Our built sparkle was always 2.7.3 recently, this just updates our CI
jobs for the auxiliary binaries.
2025-09-15 08:36:27 -07:00
Mitchell Hashimoto c195cb054d
ci: update tag release to Xcode 26, sparkle to 2.7.3 2025-09-15 08:33:17 -07:00
Mitchell Hashimoto a426e22cb2
Set version to 1.2.0 (#8629) 2025-09-15 08:28:58 -07:00
Mitchell Hashimoto 510f4e474c
Set version to 1.2.0 2025-09-15 08:25:54 -07:00
Mitchell Hashimoto b58a761aba
macos: disable NSAutoFillHeuristicController on macOS 26 (#8625)
Fixes #8616

macOS 26 (as of RC1) has some pathological performance bug where the
terminal becomes unusably slow after some period of time. We aren't 100%
sure what triggers the slowdown, but it is app-wide (new tabs or windows
don't resolve it) and Instruments traces point directly to
NSAutoFillHeuristicController. Specifically, to the `debounceTextUpdate`
selector.

This is all not documented as far as I can find and also not open
source, so I have no idea what's going on.

The best I can tell is that the NSAutoFillHeuristicController has
something to do with enabling heuristic-based autofill such as SMS auth
codes in text input fields. I don't know what is causing it to go
haywire.

SMS autofill is not desirable in a terminal app, nor is any of the other
automatic autofill in macOS I know of (contact info, passwords, etc.).
So, we can just disable it.

This default isn't documented but I found it via a strings dump of the
AppKit binary blob and comparing it to the disassembly to see how it is
used. In my limited testing, this seems to work around the problem.
2025-09-14 13:22:54 -07:00
Mitchell Hashimoto 431364cf16
macos: disable NSAutoFillHeuristicController on macOS 26
Fixes #8616

macOS 26 (as of RC1) has some pathological performance bug where the
terminal becomes unusably slow after some period of time. We aren't 100%
sure what triggers the slowdown, but it is app-wide (new tabs or windows
don't resolve it) and Instruments traces point directly to
NSAutoFillHeuristicController. Specifically, to the `debounceTextUpdate`
selector.

This is all not documented as far as I can find and also not open
source, so I have no idea what's going on.

The best I can tell is that the NSAutoFillHeuristicController has
something to do with enabling heuristic-based autofill such as SMS auth
codes in text input fields. I don't know what is causing it to go
haywire.

SMS autofill is not desirable in a terminal app, nor is any of the other
automatic autofill in macOS I know of (contact info, passwords, etc.).
So, we can just disable it.

This default isn't documented but I found it via a strings dump of the
AppKit binary blob and comparing it to the disassembly to see how it is
used. In my limited testing, this seems to work around the problem.
2025-09-14 13:05:01 -07:00
Mitchell Hashimoto ab5cd0b709
ci: update-colorschemes sets GH token for gh 2025-09-14 07:07:27 -07:00
Mitchell Hashimoto 0c63946bdb
termio: don't send extra OSC terminator for color reports (#8615)
Fixes #8613

I reiterate my comment in my own PR that this needs to be extracted so
we can unit test this. :)
2025-09-12 21:20:52 -07:00
Mitchell Hashimoto d7c2a829bb
termio: don't send extra OSC terminator for color reports
Fixes #8613

I reiterate my comment in my own PR that this needs to be extracted so
we can unit test this. :)
2025-09-12 21:19:16 -07:00
Mitchell Hashimoto a387d6cc08
terminal: OSC 104 with no semicolon should parse as reset palette (#8614)
https://github.com/ghostty-org/ghostty/pull/8590#issuecomment-3287418867
2025-09-12 21:12:11 -07:00
Mitchell Hashimoto a19aa0a398
terminal: OSC 104 with no semicolon should parse as reset palette
https://github.com/ghostty-org/ghostty/pull/8590#issuecomment-3287418867
2025-09-12 21:10:07 -07:00
Mitchell Hashimoto b5c8c83468
macOS 26: Always set titlebarview background color for transparent title (#8611)
This fixes an issue where new tabs would not have the proper transparent
background set whilst in native fullscreen. This is because in native
fullscreen, the NSTitlebarView always is visible, so our guard was
preventing us from setting it before.
2025-09-12 20:49:30 -07:00
Mitchell Hashimoto d813d82da1
macOS 26: Always set titlebarview background color for transparent title
This fixes an issue where new tabs would not have the proper transparent
background set whilst in native fullscreen. This is because in native
fullscreen, the NSTitlebarView always is visible, so our guard was
preventing us from setting it before.
2025-09-12 20:41:02 -07:00
Mitchell Hashimoto bbf03cfa07
macOS 26: always reset titlebar tab constraints on frame change (#8610)
Fixes #8595

Whenever the titlebar frame changes, we should set up our constraints
again to force it to re-render properly.
2025-09-12 20:40:53 -07:00
Mitchell Hashimoto eaaf5aa8cf
macos: always reset titlebar tab constraints on frame change
Fixes #8595

Whenever the titlebar frame changes, we should set up our constraints
again to force it to re-render properly.
2025-09-12 20:14:31 -07:00
Mitchell Hashimoto da7e3d1882
deps/ci: Use Ghostty-specific themes release (#8609)
Closes #8608 
iterm2_themes now provides terminal-specific releases, this reduces the
size of the dependency from 55MB->53kB.
- Update the `.github/workflows/update-colorschemes.yml` to track the
latest release and fetch the ghostty-specific theme archive.
2025-09-12 14:45:02 -07:00
azhn ffa54dceea Update ` .github/workflows/update-colorschemes.yml` to track the latest release and update the ghostty-specific download 2025-09-13 07:17:00 +10:00
azhn 928f5492dc Fix name of `check-zig-cache.sh` in documentation for updating the zig cache hash 2025-09-13 06:54:56 +10:00
azhn e0350aa13f nix: update build.zig.zon.nix build.zig.zon.txt build.zig.zon.json flatpak/zig-packages.json 2025-09-13 06:53:18 +10:00
azhn ac07cf5270 Use ghostty-specific themes release 2025-09-13 06:52:44 +10:00
Mitchell Hashimoto 74b204b6ce
ci: disable trigger-snap for PRs (#8601)
Fixes #8568

This will hide snap issues from PRs which is not ideal but we can
address that in the future. We still run snap CI for main.

This more importantly ensures that CI can be green for maintainers to
merge.
2025-09-12 07:34:59 -07:00
Mitchell Hashimoto dc7bf7e71f
ci: disable trigger-snap for PRs
Fixes #8568

This will hide snap issues from PRs which is not ideal but we can
address that in the future. We still run snap CI for main.
2025-09-12 07:29:44 -07:00
Mitchell Hashimoto db24f9715b
Position-independent font shaper caching (#8555)
Use relative cluster positioning to allow identical texts runs in
different row positions to share the same cache entry.

I am opening this PR clean w/o the cache size change. There could be
some benefit to a larger 256->512 shaper cache, but this still performs
amazingly well and I don't know the full memory impacts of moving the
cache size up.


https://github.com/ghostty-org/ghostty/discussions/8547#discussioncomment-14329590
2025-09-12 07:27:21 -07:00
Mitchell Hashimoto a8c3186658
macos 26: fix visual glitches with moving tabs and titlebar tabs (#8594)
This is a hacky fix to fix some visual glitches when titlebar tabs is on
and we're using the `move_tab` keybinding action (I test via the command
palette).

There is probably a more graceful way to fix this but this might be good
enough for a 1.2 to fix a very obviously nasty UI render.
2025-09-11 14:57:07 -07:00
Mitchell Hashimoto 09246780bb
macos 26: fix visual glitches with moving tabs and titlebar tabs
This is a hacky fix to fix some visual glitches when titlebar tabs is on
and we're using the `move_tab` keybinding action (I test via the command
palette).

There is probably a more graceful way to fix this but this might be good
enough for a 1.2 to fix a very obviously nasty UI render.
2025-09-11 14:51:01 -07:00
Mitchell Hashimoto 7f3ee19225
macos: run change title dialog in a sheet modal (#8592)
This fixes a macOS 26 issue where the OK button would not be visible. 

This MUST be an AppKit bug, but I'm trying to find workarounds.
2025-09-11 14:49:15 -07:00
Mitchell Hashimoto 22ec755e75
macos: run change title dialog in a sheet modal
This fixes a macOS 26 issue where the OK button would not be visible. 

This MUST be an AppKit bug, but I'm trying to find workarounds.
2025-09-11 14:40:25 -07:00
Mitchell Hashimoto 5936987e71
macOS: grab text field focus of command palette after tick (#8591)
Fixes #8497

This works on every other supported version of macOS but doesn't work on
macOS tahoe. Putting it on the next event loop tick works at least on
Sequoia and Tahoe so let's just do that.
2025-09-11 14:24:41 -07:00
Mitchell Hashimoto c9574ed0c7
macOS: grab text field focus of command palette after tick
Fixes #8497

This works on every other supported version of macOS but doesn't work on
macOS tahoe. Putting it on the next event loop tick works at least on
Sequoia and Tahoe so let's just do that.
2025-09-11 14:14:14 -07:00
Mitchell Hashimoto 3d6207e88c
deps: update z2d to v0.8.1 (#8588)
Release notes at:
  https://github.com/vancluever/z2d/blob/v0.8.1/CHANGELOG.md

Small release again, just keeping up to date with releases in
anticipation of the Ghostty 1.2.0 release.
2025-09-11 12:41:45 -07:00
Mitchell Hashimoto 2b24ac53f1
xterm color operations compatibility and rewrite (#8590)
Replaces #7952
Fixes #7951 

This reimplements our color operation parsing completely to make it
fully compatible (as far as I can tell) with xterm. Our previous
implementation had numerous problems, I think because we kept addressing
singular compatibility issues as they were experienced in the field
rather than doing a proper thoughtful audit compared to the xterm
implementation. This PR does that audit.

**Specifically, this updates/adds: OSC 4, 5, 10-19, 104, 105, 110-119.**

To ease maintenance, understanding, and testing, I've pulled color
operation parsing out into a separate file and function that operates on
the full buffered OSC command. This is similar to Kitty protocols
previously. This hurts performance but that's acceptable to me for now
while we get compatibility down and test coverage added.

We can address more performance later if it becomes a bottleneck, but
these color operations are pretty rare.

I've associated each test with a `printf` command you can run in xterm
to compare.

## Xterm Divergence

We purposely diverge from xterm in some scenarios:

- Whitespace is allowed around x11 color names. Kitty allows this.
- Invalid index values for 104/105 are ignored. xterm typically halts
processing. Kitty allows this.

## TODO

- [x] Update our parser to use the new color parsing functions
- [x] Update the stream handler to use the new types
- [x] Fix our stream handler to emit on response per query
2025-09-11 12:38:52 -07:00
Mitchell Hashimoto 3afc8019d5
terminal: update parser to use new color parser and stream handler 2025-09-11 12:32:31 -07:00
Mitchell Hashimoto 67b7a5f267
terminal: osc 104/105 are more flexible on invalid index 2025-09-11 11:38:45 -07:00
Mitchell Hashimoto 03e2a8049e
terminal: remove old color tests 2025-09-11 11:34:17 -07:00
Mitchell Hashimoto 4350804f0a
terminal: osc 10-19 should use next function 2025-09-11 11:27:26 -07:00
Mitchell Hashimoto 83dd578cc5
terminal: osc 104/105 2025-09-11 11:20:54 -07:00
Mitchell Hashimoto d7523e3e37
terminal: OSC 10-19 2025-09-11 11:12:03 -07:00
Mitchell Hashimoto b4fdefc2c0
terminal: OSC 4/5 matches xterm 2025-09-11 10:58:55 -07:00
Chris Marchesi 8b56f80e56
deps: update z2d to v0.8.1
Release notes at:
  https://github.com/vancluever/z2d/blob/v0.8.1/CHANGELOG.md

Small release again, just keeping up to date with releases in
anticipation of the Ghostty 1.2.0 release.
2025-09-11 10:16:52 -07:00
Mitchell Hashimoto aba8981d28
terminal: make dedicated OSC parsing, do dynamic resets 2025-09-11 10:08:43 -07:00
Mitchell Hashimoto 4717f8d22b
terminal: special/dynamic color enums 2025-09-11 07:35:32 -07:00
Mitchell Hashimoto dccefc288f
Add default bindings for the "copy" and "paste" keyboard keys. (#8586)
These keys are present in some old unix keyboards, but more importantly,
their keycodes can be mapped to physical keys in modern programmable
keyboards.
Using them in Linux is a way to be able to have the same keys for
copy/pasting in GUI apps and in terminal apps instead of switching
between ctrl-c/ctrl-v and ctrl-shift-c/ctrl-shift-v.
2025-09-11 07:33:27 -07:00
Jacob Sandlund 4d37853f6c benchmark sources 2025-09-11 10:30:01 -04:00
Yaacov Akiba Slama b4ecadf2e9 Add default bindings for the "copy" and "paste" keyboard keys.
These keys are present in some old unix keyboards, but more importantly,
their keycodes can be mapped to physical keys in modern programmable
keyboards.
Using them in Linux is a way to be able to have the same keys for
copy/pasting in GUI apps and in terminal apps instead of switching between
ctrl-c/ctrl-v and ctrl-shift-c/ctrl-shift-v.
2025-09-11 12:17:49 +03:00
Kat eb8767bb3b
i18n: update ja_JP translations (#8479)
Update Japanese translation for Ghostty 1.2. Part of #8344
2025-09-11 06:10:56 +00:00
Mitchell Hashimoto d83a4dc82d
macos: update Sparkle to 2.7.3 (#8584)
Fixes some critical issues.
2025-09-10 20:13:57 -07:00
Mitchell Hashimoto 83024e08bc
macos: update Sparkle to 2.7.3
Fixes some critical issues.
2025-09-10 20:04:24 -07:00
Misairuzame 5aac5a764b
i18n: add Italian translation (#7074) 2025-09-10 18:17:48 +00:00
Jacob Sandlund 8a40c1f59f Merge remote-tracking branch 'upstream/main' into jacob/uucode 2025-09-10 10:01:06 -04:00
Mitchell Hashimoto 0dc324607d
terminal: fix test w/ freed config (#8576)
this test previously didn't fail when accessing freed members of config
because deiniting `command_arena` was a no-op; `command_arena` was
derived from `arena`, which allocated memory after `command_arena` was
created/used
2025-09-09 14:07:03 -07:00
Cheru Berhanu be6cb0f6ce terminal: fix test w/ freed config
this test previously didn't fail when accessing freed members of config
because deiniting `command_arena` was a no-op; `command_arena` was derived
from `arena`, which allocated memory after `command_arena` was created/used
2025-09-09 12:31:49 -05:00
Lon Sagisawa 85b149a2aa
Update po/ja_JP.UTF-8.po
Co-authored-by: Takayuki Nagatomi <tnagatomi@okweird.net>
2025-09-10 02:02:26 +09:00
Jacob Sandlund cffa52e658 changes after benchmarking 2025-09-09 11:38:10 -04:00
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 7a1865080f Merge remote-tracking branch 'upstream/main' into jacob/uucode 2025-09-09 08:19:53 -04: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
Jacob Sandlund 2a3629fe21 Merge remote-tracking branch 'upstream/main' into jacob/uucode 2025-09-08 08:31:34 -04: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
Jacob Sandlund 0af7dc703d Merge remote-tracking branch 'upstream/main' into jacob/uucode 2025-09-06 15:53:07 -04:00
Jacob Sandlund 9ed2385b48 Merge `main` 2025-09-06 15:52:35 -04: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
Jacob Sandlund b0db51c45e fast getX(.is_symbol) 2025-09-06 15:01:29 -04:00
Jacob Sandlund c3994347c0 doNotOptimizeAway 2025-09-06 14:55:21 -04:00
Jacob Sandlund f86a3a9b50 Merge remote-tracking branch 'upstream/main' into jacob/uucode 2025-09-06 14:31:41 -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
Jacob Sandlund 2af08bdbe3 trying a bunch of things to get performance to match 2025-09-06 10:42:02 -04: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
Jeffrey C. Ollie d10e474860
gtk-ng: deprecate detection of launch source
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 09:54:24 -05:00
Mitchell Hashimoto 4552ea9104
devshell: add poop (#8529) 2025-09-05 07:24:02 -07:00
Mitchell Hashimoto 19b76df80e
gtk: the Future is Now (#8531) 2025-09-05 07:23:37 -07:00
Jeffrey C. Ollie e024b77ad5
drop the new LUT type as no performance advantage detected 2025-09-05 07:58:05 -05:00
Jeffrey C. Ollie a7da96faee
add two LUT-based implementations of isSymbol 2025-09-05 07:58:01 -05:00
Leah Amelia Chen 93debc439c
gtk: the Future is Now 2025-09-05 10:10:52 +02:00
Jeffrey C. Ollie bb78adbd93
devshell: add poop 2025-09-04 23:44:23 -05:00
Mitchell Hashimoto 968b9d536d
gtk: nuke the legacy apprt from orbit (#8520)
We don't really have any large outstanding regressions on -ng to warrant
keeping this alive anymore. ¡Adiós!
2025-09-04 20:15:06 -07:00
Leah Amelia Chen ac52af27d3
gtk: nuke the legacy apprt from orbit
We don't really have any large outstanding regressions on -ng to warrant
keeping this alive anymore. ¡Adiós!
2025-09-05 00:21:41 +02:00
Mitchell Hashimoto 8a2ab8ff21
ai: add `gh-issue` command to help diagnose GitHub issues (#8526)
This enables agents (namely Amp) to use `/gh-issue <number/url>` to
begin diagnosing a GitHub issue, explaining the problem, and suggesting
a plan of action. This action explicitly prompts the AI to not write
code.

**You can run this manually too,** for testing or curiosity or for
pasting into another LLM. Execute it like any other script:
`.agents/command/gh-issue <issue>`

I've used this manually for months with good results, so now I'm
formalizing it in the repo for other contributors.

Example diagnosing #8523:

https://ampcode.com/threads/T-3e26e8cc-83d1-4e3c-9b5e-02d9111909a7

**I'm going to be highly selective about integrating repository-level
commands.** I think guiding AI contributors in the right direction is
going to result in less AI slop being sent to us. But I want to only add
commands that maintainers use and also can vouch for. The best way to
vouch is to share something like an Amp thread link that shows it
working on real data.

Ironically, no AI was used to write this PR. I did consult Claude Chat
for help on some Nu syntax, but verified it manually with the Nu manual.
2025-09-04 14:02:26 -07:00
Mitchell Hashimoto ee573ebd36
ai: add `gh-issue` command to help diagnose GitHub issues
This enables agents (namely Amp) to use `/gh-issue <number/url>` to 
begin diagnosing a GitHub issue, explaining the problem, and suggesting
a plan of action. This action explicitly prompts the AI to not write
code.

I've used this manually for months with good results, so now I'm
formalizing it in the repo for other contributors.

Example diagnosing #8523:

https://ampcode.com/threads/T-3e26e8cc-83d1-4e3c-9b5e-02d9111909a7
2025-09-04 13:56:50 -07:00
Mitchell Hashimoto e2504d9cbf
Fix font handling for bitmap and non-sfnt fonts (#8512)
Fixes #8483, fixes #2991

With this change, `font.face.getMetrics` is now infallible, and real
bitmap fonts are properly handled and can be configured as the primary
font (or used as fallbacks), as long as the backend (FreeType or
CoreText) knows how to interpret them, since we now fall back on the
backend for any metrics we can't extract from sfnt tables (which means
we don't need any to be present in the first place).

Also, doing this uncovered a double-free issue in our FreeType
`renderGlyph` code, which thankfully wasn't too hard to track down and
fix.

> [!NOTE]
> We should vendor a true bitmap font in each of the native formats
supported by each backend and add tests for the metrics being computed
right and the glyphs being rendered correctly. Idk if we wanna block
this PR on that or not.
2025-09-04 12:20:49 -07:00
Mitchell Hashimoto 93744a4002
update zig-gobject to Zig 0.15 version (but still builds on Zig 0.14) (#8522) 2025-09-04 11:10:23 -07:00
Qwerasd a590194cd7 reduce nesting 2025-09-04 12:04:12 -06:00
Qwerasd 3ac2da99f4
Constrain dingbats + add some more symbol-like blocks to isSymbol (#8510)
This is a very minimal change to fix a regression from when the
constraints were reworked (moved off the GPU and on to the CPU), where
we weren't constraining dingbats anymore. This fixes that and also adds
several other Unicode blocks to also treat as symbols.

In the future (post-1.2) I'll make a more comprehensive set of custom
constraints that differ depending on a hand-rolled list of character
attributes.

|Before|After|
|-|-|
|<img width="1708" height="2096" alt="image"
src="https://github.com/user-attachments/assets/8ce593ac-f032-4c75-80e1-030dd301115d"
/>|<img width="1708" height="2096" alt="image"
src="https://github.com/user-attachments/assets/06dc2307-342d-4ea2-959d-7416eee6ddc2"
/>|

You'll notice that with spaces in between (so each glyph can be up to 2
cells wide), there's very little change with a font with wider cells,
there would be more of a change for people with narrower fonts. The real
star of the show is when they're all shoved together and need to be
constrained to 1 cell; it's utter chaos without constraints, but with
constraints it's nice and orderly (some glyphs get too small to read
well, but there's nothing we can really do about that, users should
really have a font like Iosevka Fixed installed on their system if they
want a good source for terminal-compatible symbol glyphs)
2025-09-04 11:54:23 -06:00
Jeffrey C. Ollie 43ee3cc8c6
update zig-gobject to Zig 0.15 version (but still builds on Zig 0.14) 2025-09-04 11:58:06 -05:00
Qwerasd aeae54072c fix(font/freetype): mark glyph bitmap as owned if modifying
This caused a malloc fault due to a double free when deiniting the face
if we didn't do this, which makes sense- making it possible to actually
load bitmap fonts revealed this bug which was sitting dormant the whole
time before that ever since I refactored the freetype rasterization.
2025-09-03 21:33:38 -06:00
Qwerasd 5c1d87fda6 fix(font): make `face.getMetrics()` infallible
Before we had a bad day if we tried to get the metrics of a bitmap font,
which would happen if we ever used one as fallback because we started
doing it for all fonts when we added fallback font scaling. This is a
pretty easy fix and finally allows users to configure true bitmap fonts
as their primary font as long as FreeType/CoreText can handle it.
2025-09-03 21:13:39 -06:00
Qwerasd 7c4b45ecee font: expand set of characters considered symbols
Low hanging fruit of some Unicode blocks that are full of very symbol-y
characters.
2025-09-03 18:06:05 -06:00
Qwerasd 2464728851 font: constrain dingbats
This was a regression, we were giving dingbats an extra cell of
constraint width but not actually applying constraints to them.
2025-09-03 18:01:40 -06:00
Mitchell Hashimoto c3e7857a2c
gtk-ng: pull in latest zig-gobject changes (#8468) 2025-09-03 15:53:35 -07:00
Jeffrey C. Ollie e67db2a01c gtk-ng: pull in latest zig-gobject changes 2025-09-03 15:49:34 -07:00
Mitchell Hashimoto befee07f16
macOS: prevent focus loss in hidden titlebar + non-native fullscreen (#8508)
Fixes #8415

When using hidden titlebar with non-native fullscreen, the window would
lose focus after entering the first command. This occurred because:

1. Shell commands update the window title
2. Title changes trigger reapplyHiddenStyle() 
3. reapplyHiddenStyle() re-adds .titled to the style mask
4. Style mask changes during fullscreen confuse AppKit, causing focus
loss

Fixed by adding a guard to skip titlebar restyling while fullscreen is
active, using terminalController.fullscreenStyle.isFullscreen for proper
detection of both native and non-native fullscreen modes.

AI disclaimer:
https://ampcode.com/threads/T-c4ef59cc-1232-4fa5-8f09-c65724ee84d3 But I
hand-modified the end.
2025-09-03 10:19:19 -07:00
Mitchell Hashimoto c8243ffd99
macOS: prevent focus loss in hidden titlebar + non-native fullscreen
When using hidden titlebar with non-native fullscreen, the window would
lose focus after entering the first command. This occurred because:

1. Shell commands update the window title
2. Title changes trigger reapplyHiddenStyle() 
3. reapplyHiddenStyle() re-adds .titled to the style mask
4. Style mask changes during fullscreen confuse AppKit, causing focus loss

Fixed by adding a guard to skip titlebar restyling while fullscreen is
active, using terminalController.fullscreenStyle.isFullscreen for
proper detection of both native and non-native fullscreen modes.

https://ampcode.com/threads/T-c4ef59cc-1232-4fa5-8f09-c65724ee84d3
2025-09-03 10:01:28 -07:00
Mitchell Hashimoto 084ff2de67
Initial AGENTS.md (#8507)
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.

**Changes should not be made to `AGENTS.md` unless it demonstrably
improves agent behavior.** To demonstrate agent behavior, I'd prefer
sharing an amp thread before and after the change with the same prompt
and model to show an improvement.
2025-09-03 09:28:40 -07:00
Mitchell Hashimoto e1f3f52686
macOS: SurfaceView should implement Identifiable (#8506)
This has no meaningful functionality yet, it was one of the paths I was
looking at for #8505 but didn't pursue further. But I still think that
this makes more sense in general for the macOS app and will likely be
more useful later.
2025-09-03 09:28:01 -07:00
Mitchell Hashimoto fe3dab9467
macOS: SurfaceView should implement Identifiable
This has no meaningful functionality yet, it was one of the paths I was
looking at for #8505 but didn't pursue further. But I still think that
this makes more sense in general for the macOS app and will likely be
more useful later.
2025-09-03 09:17:37 -07:00
Mitchell Hashimoto b90c72aea6
Initial AGENTS.md
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.
2025-09-03 09:16:35 -07:00
Mitchell Hashimoto e6d60dee07
macOS: split tree zoom state should encode as path, not full node (#8505)
Fixes #8356

Zoom state should encode as a path so that it can be mapped to a
reference to the node in `root`. Previously, we were encoding a full
node which was instantiating an extra terminal on restore.

AI disclaimer: Claude code did the Codable implementation.
2025-09-03 09:08:45 -07:00
Mitchell Hashimoto 508e36bc03
macOS: split tree zoom state should encode as path, not full node
Fixes #8356

Zoom state should encode as a path so that it can be mapped to a
reference to the node in `root`. Previously, we were encoding a full
node which was instantiating an extra terminal on restore.
2025-09-03 08:51:37 -07:00
Mitchell Hashimoto 6a9b8b70cc
config: make default copy_to_clipboard binds performable (#8504)
Make the default keybind for copy_to_clipboard performable. This allows
TUIs to receive events when keybinds aren't used, for example cmd+c on
macos for copy, or ctrl+shift+c elsewhere.

Disclosure: This commit was made with the assistance of AI (ampcode.com)
2025-09-03 07:58:47 -07:00
Tim Culverhouse 1dee9e7cb2
config: make default copy_to_clipboard binds performable
Make the default keybind for copy_to_clipboard performable. This allows
TUIs to receive events when keybinds aren't used, for example cmd+c on
macos for copy, or ctrl+shift+c elsewhere.

Disclosure: This commit was made with the assistance of AI (ampcode.com)
2025-09-03 09:35:08 -05:00
Mitchell Hashimoto 291d4ed423
gtk-ng/wayland: allow more quick terminal configs (#8484)
We should at least be on par with what Kitty's panels could do in terms
of customization
2025-09-03 07:01:23 -07:00
Leah Amelia Chen 5eb69b405d
gtk-ng/wayland: allow more quick terminal configs 2025-09-03 15:44:23 +08:00
Kat 7d5be8e960
i18n: update Russian translation (#8473)
Part of #8344
2025-09-03 04:12:21 +00:00
Mitchell Hashimoto d05ec81b86
apprt/gtk-ng: must quit scenarios should quit immediately (#8500)
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.
2025-09-02 20:46:35 -07:00
Mitchell Hashimoto f016b79f22
apprt/gtk-ng: must quit scenarios should quit immediately
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.
2025-09-02 20:42:01 -07:00
Ivan Bastrakov 52f5ab1a36
i18n: update Russian translation 2025-09-03 01:57:25 +03:00
Mitchell Hashimoto 8d11c08db3
feat: add `selection-clear-on-copy` configuration option (#8462)
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.
2025-09-02 14:55:46 -07:00
Toufiq Shishir 90c0fc2590 feat: add `selection-clear-on-copy` configuration 2025-09-02 14:48:47 -07:00
Mitchell Hashimoto e909e28876
Compare fields directly instead of PackedStyle (#8489)
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%
2025-09-02 14:37:30 -07:00
Jesse Miller cf0390bab5 Use comptime for eql() to ensure Style struct coverage. 2025-09-02 15:14:42 -06:00
Jesse Miller 4614e5fdad Zig 0.14+ can directly compare packed structs. 2025-09-02 14:58:21 -06:00
Mitchell Hashimoto ce94bb9f6a
macOS: firstRect should return full rect width/height (#8492)
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
2025-09-02 13:28:08 -07:00
Jesse Miller ac104a3dfc zig fmt 2025-09-02 14:14:06 -06:00
Mitchell Hashimoto 16e47e7586
fix(font): detect and reject improper advance for icwidth (#8491)
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.
2025-09-02 13:09:07 -07:00
Mitchell Hashimoto e8217aa007
macOS: firstRect should return full rect width/height
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.
2025-09-02 13:08:46 -07:00
Qwerasd 9aa1698e5a font: log warning when rejecting ic_width 2025-09-02 13:47:59 -06:00
Mitchell Hashimoto 3664ee9f87
macOS: Notify macOS of cell width/height for firstRect (#8490)
Related to #2473

This fixes an issue where the dictation icon didn't show the language
picker.
2025-09-02 12:38:50 -07:00
Qwerasd a72995590b fix(font): detect and reject improper advance for icwidth 2025-09-02 13:33:33 -06:00
Mitchell Hashimoto 2bf0d3f4c7
macOS: Notify macOS of cell width/height for firstRect
Related to #2473

This fixes an issue where the dictation icon didn't show the language 
picker.
2025-09-02 12:26:52 -07:00
Mitchell Hashimoto 4af290d5f0
fix(renderer): kitty images should all be processed (#8488)
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
2025-09-02 12:14:11 -07:00
Qwerasd ef7857f9be fix(renderer): kitty images should all be processed
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.
2025-09-02 12:42:34 -06:00
Jesse Miller 7dcf2c9b62 Compare fields directly instead of PackedStyle
Comparing the fields directly is actually faster than PackedStyle
2025-09-02 12:05:30 -06:00
Mitchell Hashimoto d316449ebf
config: bind both physical digit plus unicode digit for `goto_tab` (#8486)
Fixes #8478

The comments explain this.
2025-09-02 09:12:08 -07:00
Mitchell Hashimoto 650028fa9f
config: bind both physical digit plus unicode digit for `goto_tab`
Fixes #8478

The comments explain this.
2025-09-02 09:00:58 -07:00
Lon Sagisawa 987a759f17 i18n: update ja_JP translations 2025-09-01 14:44:57 +09:00
Jacob Sandlund c67f51f3ee Merge remote-tracking branch 'upstream/main' into jacob/uucode 2025-09-01 01:34:03 -04:00
Mitchell Hashimoto 5ef6412823
macOS: Progress bar for OSC9 progress reports (#8477)
#7975 but for macOS. The behavior and even the look is almost identical:


https://github.com/user-attachments/assets/b7e0b370-3a30-443d-89ae-08209d2c9b89

Similar to GTK, it'll remove the progress bar state after 15 seconds. 

AI disclaimer: Claude code produced most of this code. I reviewed all
the lines and understand them completely.
2025-08-31 20:51:54 -07:00
Mitchell Hashimoto 0b58830882
macOS: Progress bar for OSC9 progress reports 2025-08-31 20:42:34 -07:00
Mitchell Hashimoto a41ec17b61
build(deps): bump actions/checkout from 4.3.0 to 5.0.0 (#8476)
Bumps [actions/checkout](https://github.com/actions/checkout) from 4.3.0
to 5.0.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/checkout/releases">actions/checkout's
releases</a>.</em></p>
<blockquote>
<h2>v5.0.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Update actions checkout to use node 24 by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2226">actions/checkout#2226</a></li>
<li>Prepare v5.0.0 release by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2238">actions/checkout#2238</a></li>
</ul>
<h2>⚠️ Minimum Compatible Runner Version</h2>
<p><strong>v2.327.1</strong><br />
<a
href="https://github.com/actions/runner/releases/tag/v2.327.1">Release
Notes</a></p>
<p>Make sure your runner is updated to this version or newer to use this
release.</p>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/checkout/compare/v4...v5.0.0">https://github.com/actions/checkout/compare/v4...v5.0.0</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/actions/checkout/blob/main/CHANGELOG.md">actions/checkout's
changelog</a>.</em></p>
<blockquote>
<h1>Changelog</h1>
<h2>V5.0.0</h2>
<ul>
<li>Update actions checkout to use node 24 by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2226">actions/checkout#2226</a></li>
</ul>
<h2>V4.3.0</h2>
<ul>
<li>docs: update README.md by <a
href="https://github.com/motss"><code>@​motss</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1971">actions/checkout#1971</a></li>
<li>Add internal repos for checking out multiple repositories by <a
href="https://github.com/mouismail"><code>@​mouismail</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1977">actions/checkout#1977</a></li>
<li>Documentation update - add recommended permissions to Readme by <a
href="https://github.com/benwells"><code>@​benwells</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2043">actions/checkout#2043</a></li>
<li>Adjust positioning of user email note and permissions heading by <a
href="https://github.com/joshmgross"><code>@​joshmgross</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2044">actions/checkout#2044</a></li>
<li>Update README.md by <a
href="https://github.com/nebuk89"><code>@​nebuk89</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2194">actions/checkout#2194</a></li>
<li>Update CODEOWNERS for actions by <a
href="https://github.com/TingluoHuang"><code>@​TingluoHuang</code></a>
in <a
href="https://redirect.github.com/actions/checkout/pull/2224">actions/checkout#2224</a></li>
<li>Update package dependencies by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2236">actions/checkout#2236</a></li>
</ul>
<h2>v4.2.2</h2>
<ul>
<li><code>url-helper.ts</code> now leverages well-known environment
variables by <a href="https://github.com/jww3"><code>@​jww3</code></a>
in <a
href="https://redirect.github.com/actions/checkout/pull/1941">actions/checkout#1941</a></li>
<li>Expand unit test coverage for <code>isGhes</code> by <a
href="https://github.com/jww3"><code>@​jww3</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1946">actions/checkout#1946</a></li>
</ul>
<h2>v4.2.1</h2>
<ul>
<li>Check out other refs/* by commit if provided, fall back to ref by <a
href="https://github.com/orhantoy"><code>@​orhantoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1924">actions/checkout#1924</a></li>
</ul>
<h2>v4.2.0</h2>
<ul>
<li>Add Ref and Commit outputs by <a
href="https://github.com/lucacome"><code>@​lucacome</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1180">actions/checkout#1180</a></li>
<li>Dependency updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>- <a
href="https://redirect.github.com/actions/checkout/pull/1777">actions/checkout#1777</a>,
<a
href="https://redirect.github.com/actions/checkout/pull/1872">actions/checkout#1872</a></li>
</ul>
<h2>v4.1.7</h2>
<ul>
<li>Bump the minor-npm-dependencies group across 1 directory with 4
updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1739">actions/checkout#1739</a></li>
<li>Bump actions/checkout from 3 to 4 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1697">actions/checkout#1697</a></li>
<li>Check out other refs/* by commit by <a
href="https://github.com/orhantoy"><code>@​orhantoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1774">actions/checkout#1774</a></li>
<li>Pin actions/checkout's own workflows to a known, good, stable
version. by <a href="https://github.com/jww3"><code>@​jww3</code></a> in
<a
href="https://redirect.github.com/actions/checkout/pull/1776">actions/checkout#1776</a></li>
</ul>
<h2>v4.1.6</h2>
<ul>
<li>Check platform to set archive extension appropriately by <a
href="https://github.com/cory-miller"><code>@​cory-miller</code></a> in
<a
href="https://redirect.github.com/actions/checkout/pull/1732">actions/checkout#1732</a></li>
</ul>
<h2>v4.1.5</h2>
<ul>
<li>Update NPM dependencies by <a
href="https://github.com/cory-miller"><code>@​cory-miller</code></a> in
<a
href="https://redirect.github.com/actions/checkout/pull/1703">actions/checkout#1703</a></li>
<li>Bump github/codeql-action from 2 to 3 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1694">actions/checkout#1694</a></li>
<li>Bump actions/setup-node from 1 to 4 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1696">actions/checkout#1696</a></li>
<li>Bump actions/upload-artifact from 2 to 4 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1695">actions/checkout#1695</a></li>
<li>README: Suggest <code>user.email</code> to be
<code>41898282+github-actions[bot]@users.noreply.github.com</code> by <a
href="https://github.com/cory-miller"><code>@​cory-miller</code></a> in
<a
href="https://redirect.github.com/actions/checkout/pull/1707">actions/checkout#1707</a></li>
</ul>
<h2>v4.1.4</h2>
<ul>
<li>Disable <code>extensions.worktreeConfig</code> when disabling
<code>sparse-checkout</code> by <a
href="https://github.com/jww3"><code>@​jww3</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1692">actions/checkout#1692</a></li>
<li>Add dependabot config by <a
href="https://github.com/cory-miller"><code>@​cory-miller</code></a> in
<a
href="https://redirect.github.com/actions/checkout/pull/1688">actions/checkout#1688</a></li>
<li>Bump the minor-actions-dependencies group with 2 updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1693">actions/checkout#1693</a></li>
<li>Bump word-wrap from 1.2.3 to 1.2.5 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1643">actions/checkout#1643</a></li>
</ul>
<h2>v4.1.3</h2>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="08c6903cd8"><code>08c6903</code></a>
Prepare v5.0.0 release (<a
href="https://redirect.github.com/actions/checkout/issues/2238">#2238</a>)</li>
<li><a
href="9f265659d3"><code>9f26565</code></a>
Update actions checkout to use node 24 (<a
href="https://redirect.github.com/actions/checkout/issues/2226">#2226</a>)</li>
<li>See full diff in <a
href="https://github.com/actions/checkout/compare/v4.3.0...08c6903cd8c0fde910a37f88322edcfb5dd907a8">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4.3.0&new-version=5.0.0)](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-08-31 19:50:03 -07:00
dependabot[bot] c535d0a664
build(deps): bump actions/checkout from 4.3.0 to 5.0.0
Bumps [actions/checkout](https://github.com/actions/checkout) from 4.3.0 to 5.0.0.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4.3.0...08c6903cd8c0fde910a37f88322edcfb5dd907a8)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 5.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-01 00:47:33 +00:00
Mitchell Hashimoto 2009ea511d
feat: added faint-opacity option (#8472)
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.
2025-08-31 13:45:26 -07:00
Mitchell Hashimoto d8578a9ee2
fix: correct the cursor Y position value exposed to shader uniforms (#8122)
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
2025-08-31 11:32:59 -07:00
Qwerasd 0d30f859bd renderer: clarify and correct custom shader cursor position math
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.
2025-08-31 11:44:10 -06:00
Pavel Ivanov 650095e7e9
fix: changed default faint-opacity value to 0.5 2025-08-31 17:21:00 +02:00
Pavel Ivanov 6319464cfb
refactor: move faint-opacity clamping to config finalization 2025-08-31 17:19:51 +02:00
Pavel Ivanov fc6266133f
feat: added faint-opacity option 2025-08-31 15:00:29 +02:00
Mitchell Hashimoto a51a956bdb
Update iTerm2 colorschemes (#8470)
Upstream revision:
6cdbc8501d
2025-08-30 21:01:10 -07:00
mitchellh c94805f0aa deps: Update iTerm2 color schemes 2025-08-31 00:16:30 +00:00
Jacob Sandlund 6d02da0317 nix and flatpak 2025-08-30 18:20:06 -04:00
Mitchell Hashimoto 937d17cc35
ci: add freebsd tests (#8466) 2025-08-30 12:59:01 -07:00
Jeffrey C. Ollie 0bc90b2a20
ci: build on freebsd 2025-08-30 13:58:25 -05:00
Jeffrey C. Ollie 75e3835a9e
gtk-ng: ensure CSS works on both 4.14 and 4.16+ (#8459)
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.
2025-08-30 10:41:59 -05:00
Jeffrey C. Ollie d1e01ec5c3
gtk-ng: ensure CSS works on both 4.14 and 4.16+
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.
2025-08-30 09:54:40 -05:00
Mitchell Hashimoto b0d9b0dee0
build(deps): bump namespacelabs/nscloud-cache-action from 1.2.16 to 1.2.17 (#8449)
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 />


[![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-08-29 07:08:26 -07:00
Mitchell Hashimoto e6b019b197
build(deps): bump cachix/install-nix-action from 31.5.2 to 31.6.0 (#8450)
Bumps
[cachix/install-nix-action](https://github.com/cachix/install-nix-action)
from 31.5.2 to 31.6.0.
<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.0</h2>
<h2>What's Changed</h2>
<ul>
<li>chore(deps): bump actions/checkout from 4 to 5 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/cachix/install-nix-action/pull/249">cachix/install-nix-action#249</a></li>
<li>docs: add example for <code>nix develop</code> by <a
href="https://github.com/jennydaman"><code>@​jennydaman</code></a> in <a
href="https://redirect.github.com/cachix/install-nix-action/pull/248">cachix/install-nix-action#248</a></li>
<li>nix: 2.30.2 -&gt; 2.31.0 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/250">cachix/install-nix-action#250</a>
Release notes: <a
href="https://discourse.nixos.org/t/nix-2-31-0-released/68465">https://discourse.nixos.org/t/nix-2-31-0-released/68465</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/jennydaman"><code>@​jennydaman</code></a> made
their first contribution in <a
href="https://redirect.github.com/cachix/install-nix-action/pull/248">cachix/install-nix-action#248</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/cachix/install-nix-action/compare/v31.5.2...v31.6.0">https://github.com/cachix/install-nix-action/compare/v31.5.2...v31.6.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="56a7bb7b56"><code>56a7bb7</code></a>
Merge pull request <a
href="https://redirect.github.com/cachix/install-nix-action/issues/250">#250</a>
from cachix/create-pull-request/patch</li>
<li><a
href="c04e864467"><code>c04e864</code></a>
nix: 2.30.2 -&gt; 2.31.0</li>
<li><a
href="9aaadd8b85"><code>9aaadd8</code></a>
Merge pull request <a
href="https://redirect.github.com/cachix/install-nix-action/issues/248">#248</a>
from jennydaman/patch-1</li>
<li><a
href="a23271bac0"><code>a23271b</code></a>
Reword README.md section on <code>nix develop</code></li>
<li><a
href="f02d365678"><code>f02d365</code></a>
Merge pull request <a
href="https://redirect.github.com/cachix/install-nix-action/issues/249">#249</a>
from cachix/dependabot/github_actions/actions/checkout-5</li>
<li><a
href="b4dc112147"><code>b4dc112</code></a>
chore(deps): bump actions/checkout from 4 to 5</li>
<li><a
href="ca6a0fa535"><code>ca6a0fa</code></a>
Add example for <code>nix develop</code></li>
<li><a
href="96bd9f39e4"><code>96bd9f3</code></a>
ci: update nixpkgs channel used in tests</li>
<li><a
href="92ffed7f0d"><code>92ffed7</code></a>
ci: make test workflow dispatchable</li>
<li>See full diff in <a
href="fc6e360bed...56a7bb7b56">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.5.2&new-version=31.6.0)](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-08-29 07:08:09 -07:00
Guilherme Nandi Tiscoski 5761f66f35
i18n: update pt_BR translations (#8391)
relative to https://github.com/ghostty-org/ghostty/issues/8344
2025-08-29 13:26:37 +00:00
trag1c a5eef1d227
i18n: Updating Irish translation for Ghostty 1.2 (#8349)
This Pull Request updates 5 translation strings for Ghostty 1.2 as per
#8344
2025-08-29 11:01:00 +02:00
dependabot[bot] 85e642097a
build(deps): bump cachix/install-nix-action from 31.5.2 to 31.6.0
Bumps [cachix/install-nix-action](https://github.com/cachix/install-nix-action) from 31.5.2 to 31.6.0.
- [Release notes](https://github.com/cachix/install-nix-action/releases)
- [Changelog](https://github.com/cachix/install-nix-action/blob/master/RELEASE.md)
- [Commits](fc6e360bed...56a7bb7b56)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-29 00:08:00 +00:00
dependabot[bot] bed350f0be
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](305bfa7ea9...a289cf5d2f)

---
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-08-29 00:07:51 +00:00
Mitchell Hashimoto 460fcc1344
docs: reorganize and separate out HACKING.md for technical instructions (#8445)
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...?)
2025-08-28 15:20:23 -07:00
Leah Amelia Chen f91e6f1764
docs: better integrate CONTRIBUTING into the README 2025-08-29 06:14:41 +08:00
Leah Amelia Chen f802d33652
docs: divide content more evenly between CONTRIBUTING and HACKING
CONTRIBUTING should now solely be about the contribution *process*
while HACKING goes into the technical details
2025-08-29 06:14:41 +08:00
Leah Amelia Chen 2701932475
docs: separate out HACKING.md from README.md
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...?)
2025-08-29 06:14:36 +08:00
Mitchell Hashimoto 6cfd89e248
macOS: Always require confirmation when executing a script via `open` (Finder, etc.) (#8442)
Right now, passing a file path to Ghostty will always execute it
unconditionally. This has various risks associated with it. I think we
can mitigate a lot of risks in the future by inspecting what is being
executed, but to be safe now we should always ask for confirmation.
2025-08-28 13:12:48 -07:00
Mitchell Hashimoto 9962e523a8
some typos 2025-08-28 12:58:07 -07:00
Mitchell Hashimoto 04956f3dc1
macos: require confirmation to run any script 2025-08-28 12:34:04 -07:00
Mitchell Hashimoto f1ea30dcf1
macos: when executing a script directly, always wait after command 2025-08-28 11:26:33 -07:00
trag1c d3cadf2495
i18n: update bg_BG translations (#8345)
Part of https://github.com/ghostty-org/ghostty/issues/8344
2025-08-27 23:16:15 +02:00
Mitchell Hashimoto 7106d71a42
apprt/gtk-ng: "cancel" should be default close response for dialog (#8427)
Fixes #8424

This is the response that will be sent when "escape" is pressed.

This also fixes a null ptr deref that was possible when this fix wasn't
in.
2025-08-27 09:48:19 -07:00
Mitchell Hashimoto f54f2dc7f3
apprt/gtk-ng: "cancel" should be default close response for dialog
Fixes #8424

This is the response that will be sent when "escape" is pressed.

This also fixes a null ptr deref that was possible when this fix wasn't
in.
2025-08-27 09:42:35 -07:00
Mitchell Hashimoto 5013d028a3
terminal: fix csi parsing (#8417)
Make `MAX_PARAMS` public and increase CSI parameter limit from 16 to 24.
Fix potential out-of-bounds read in SGR partial sequence extraction.

Related discussion:
https://github.com/ghostty-org/ghostty/discussions/5198

DISCLAIMER: the tests were written with Claude Code's help.
2025-08-27 07:20:16 -07:00
Mitchell Hashimoto adfc93047c
terminal: fix up some tests to be more robust 2025-08-27 07:15:42 -07:00
Adrià Arrufat a3f4997fbc fix(terminal): handle CSI/SGR with many parameters
Adds tests to ensure CSI and SGR sequences with 17 or more parameters are correctly parsed, fixing a bug where later parameters were previously dropped.
2025-08-27 07:10:17 -07:00
Adrià Arrufat 56d3fd872e fix(terminal): improve CSI parameter parsing
Make `MAX_PARAMS` public and increase CSI parameter limit from 16 to 24.
Fix potential out-of-bounds read in SGR partial sequence extraction.
2025-08-27 07:10:17 -07:00
Mitchell Hashimoto 58e85bf133
macos: use visible frame for quick terminal sizing calculation (#8423)
Fixes #8418

This fixes issues where left/right positions would be cut off from the
menu bar. And makes it so that size 100%,100% doesn't overflow into the
non-visible space of the edge of the screen.

I didn't just copy and paste, I tested each of these code paths.
2025-08-27 07:06:55 -07:00
Mitchell Hashimoto 19a27383f8
macos: use visible frame for quick terminal sizing calculation
Fixes #8418

This fixes issues where left/right positions would be cut off from the
menu bar. And makes it so that size 100%,100% doesn't overflow into the
non-visible space of the edge of the screen.
2025-08-27 06:59:02 -07:00
reo101 8fa065512f
i18n: update bg_BG translations 2025-08-27 16:39:58 +03:00
Jeffrey C. Ollie 6530107e3b
config: add entry for scroll-to-bottom (#8412)
Related #8408

(EDIT @mitchellh: Removed "Fixes" to avoid closing)
2025-08-26 22:26:03 -05:00
Jeffrey C. Ollie 87056a2600
surface: store entire scroll-to-bottom struct 2025-08-26 22:04:23 -05:00
Jeffrey C. Ollie 6a128189e3
osc: conemu cleanup (#8413)
- Add more comments, and make existing ones more consistent.
- Rename commands so they consitently have a `conemu_` prefix.
- Ensure that OSC 9 desktop notifications can be sent in the maximum
number of circumstances. There are still many notifications that can't
be sent because of our support for the ConEmu OSCs but that's the
tradeoff we have chosen. We recommend that you switch to OSC 777 to
ensure desktop notifications can be sent in all circumstances.
- Make sure that the tests that exercise the ConEmu OSCs have a
consistent naming structure. That will make them easier to find through
searching as well as make it easier to filter only the ConEmu OSC tests.
- Add more tests to make sure that desktop notifications are sent
properly.
2025-08-26 22:03:42 -05:00
Jeffrey C. Ollie 2490171304
surface: implement scroll-to-bottom=keystroke 2025-08-26 21:48:18 -05:00
Jeffrey C. Ollie 31c96d906a
config: add entry for scroll-to-bottom
Fixes #8408
2025-08-26 21:48:18 -05:00
Jeffrey C. Ollie 64d8492836
osc: conemu cleanup
- Add more comments, and make existing ones more consistent.
- Rename commands so they consitently have a `conemu_` prefix.
- Ensure that OSC 9 desktop notifications can be sent in the maximum
  number of circumstances. There are still many notifications that can't
  be sent because of our support for the ConEmu OSCs but that's the
  tradeoff we have chosen. We recommend that you switch to OSC 777 to
  ensure desktop notifications can be sent in all circumstances.
- Make sure that the tests that exercise the ConEmu OSCs have a
  consistent naming structure. That will make them easier to find
  through searching as well as make it easier to filter only the ConEmu
  OSC tests.
- Add more tests to make sure that desktop notifications are sent
  properly.
2025-08-26 21:28:50 -05:00
Mitchell Hashimoto c1ab41afac
osc: parse OSC 9;6 gui macros (#8410) 2025-08-26 14:56:42 -07:00
Jeffrey C. Ollie f047db6a3b
osc: parse OSC 9;6 gui macros 2025-08-26 16:28:25 -05:00
Mitchell Hashimoto cd8455c24b
apprt/gtk-ng: show error widget if GLArea fails to initialize (#8390)
If GTK can't acquire an OpenGL context, this shows a message.
Previously, we would only log a warning which was difficult to find. The
GUI previously was the default GTK view which showed "Failed to acquire
EGL display" which was equally confusing.

This is a draft. There are TODOs (listed below).

## TODO

- [x] Disable context menu in error state
- [x] Use property to bind to unhealthy state instead of directly
setting stack child
- [x] Create a web page and put that in the error description
- [x] Set non-transparent background in error state
- [x] Bug where closing the window isn't exiting Ghostty
2025-08-26 12:07:42 -07:00
Mitchell Hashimoto 4d6269a859
apprt/gtk-ng: show error widget if GLArea fails to initialize
If GTK can't acquire an OpenGL context, this shows a message.
Previously, we would only log a warning which was difficult to find. The
GUI previously was the default GTK view which showed "Failed to acquire
EGL display" which was equally confusing.
2025-08-26 12:03:02 -07:00
Mitchell Hashimoto 3fb17dc802
scroll: round up fractional mouse scroll ticks (#7185)
Scrolling with a mouse on macos doesn't work very well when doing small,
single tick scrolls. macos attempts to mimic precision scrolling by
changing the magnitude of the scroll deltas based on scrolling speed.
Slow scrolls only send deltas with a magnitude of 0.1, which isn't
enough to send a single scroll event with the default scroll multiplier
of 3. Changing the scroll multiplier to 10 as a workaround (so even
single small scroll ticks are enough to register a scroll event) cause
scrolling to be way too fast if the scroll speed is ramped up.

This commit causes the yoffset delta to be rounded out to at least a
magnitude of 1 in the appropriate direction. Single scroll ticks now
register as a single vertical cell scroll event, but as scroll speed is
ramped up, the true delta reported to the surface is used again. Setting
a scroll multiplier of 1 with the changes here makes mouse scrolling
feel just as good as trackpad precision scrolling.
2025-08-26 11:07:12 -07:00
John Drouhard 6cf636b1ad scroll: round up fractional mouse scroll ticks
Scrolling with a mouse on macos doesn't work very well when doing small,
single tick scrolls. macos attempts to mimic precision scrolling by
changing the magnitude of the scroll deltas based on scrolling speed.
Slow scrolls only send deltas with a magnitude of 0.1, which isn't
enough to send a single scroll event with the default scroll multiplier
of 3. Changing the scroll multiplier to 10 as a workaround (so even
single small scroll ticks are enough to register a scroll event) cause
scrolling to be way too fast if the scroll speed is ramped up.

This commit causes the yoffset delta to be rounded out to at least a
magnitude of 1 in the appropriate direction. For small single scroll
ticks, it's enough to register a scroll event, but as scroll speed is
ramped up, the true delta reported to the surface is used again. Setting
a scroll multiplier of 1 with the changes here makes mouse scrolling
feel just as good as trackpad precision scrolling.
2025-08-26 11:02:36 -07:00
Mitchell Hashimoto 673afd193b
macos: fix quick terminal fullscreen crash bug (#8093)
Fullscreen on quick terminal was failing with a crash, when it tried
to save the state of a non-existent toolbar and its accessory view
controllers.

See #7980
2025-08-26 10:51:31 -07:00
Mitchell Hashimoto ff61cad1e2
gtk-ng: implement close_tab:other keybind (#8403) 2025-08-26 10:48:55 -07:00
Mitchell Hashimoto 520eaec61c
macos: fix quick terminal issue where closing while fullscreen 2025-08-26 10:40:41 -07:00
Alexander Lais e676eae640 macos: fix quick terminal fullscreen
Fullscreen on quick terminal was failing with a crash, when it tried
to save the state of a non-existent toolbar and its accessory view
controllers.
2025-08-26 10:36:06 -07:00
Mitchell Hashimoto 830194d436
Quick Terminal Sizing on macOS (#8402)
Fixes #8398
Fixes #2384 

This is just #7576 rebased with some style changes. For some reason I
couldn't update that PR.
2025-08-26 10:31:02 -07:00
Jeffrey C. Ollie 6f630a27be
gtk-ng: implement close_tab:other keybind 2025-08-26 12:22:45 -05:00
Mitchell Hashimoto ae48f323d7
macos: style changes for quick terminal sizing 2025-08-26 10:20:16 -07:00
Mitchell Hashimoto a90bf58080
config: change quick terminal size C layout to tagged union 2025-08-26 09:52:26 -07:00
Friedrich Stoltzfus 6a78f9c0c0 Merge branch 'ghostty-org:main' into quick-term-initial-size 2025-08-26 09:47:31 -07:00
Friedrich Stoltzfus 466fdfffe6 macOS: rename c struct, relocate QuickTerminalSize file
Renamed the ghostty_quick_terminal_size_u to
ghostty_quick_terminal_size_s and moved the QuickTerminalSize file to
the Ghostty folder as requested.
2025-08-26 09:47:31 -07:00
Friedrich Stoltzfus 58e7400ea5 macOS: Round quick terminal window position coordinates
This resolves an issue where the right side of the quick terminal would
not resize equally to the left side if adjusting the width from the left
side.
2025-08-26 09:47:31 -07:00
Friedrich Stoltzfus 0afadeea5f use decl literals as suggested
Applied from the code review

Co-authored-by: Leah Amelia Chen <github@acc.pluie.me>
2025-08-26 09:47:31 -07:00
Friedrich Stoltzfus e5ad6603f4 Merge branch 'main' into quick-term-initial-size 2025-08-26 09:47:31 -07:00
Friedrich Stoltzfus 7cc0728fe5 macOS: enable quick terminal manual resizing
You can now resize the quick terminal both vertically and horizontally. To incorporate adjusting the custom secondary size on the quick terminal we needed to have the ability to resize the width (if from top, bottom, or center), and height (if from right, left, or center). The quick terminal will retain the user's manually adjusted size while the app is open. A new feature with this is that when the secondary size is adjusted (or primary if the quick terminal is center), the size will increase or decrease on both sides of the terminal.
2025-08-26 09:47:31 -07:00
Friedrich Stoltzfus 17f7f204e1 macOS: update zig and c structs for quick terminal size
Applying the feedback given by @pluiedev to use an enum to specify the
type of quick terminal size configuration given (pixels or percentage).
Updated the Swift code to work with the enum as well.
2025-08-26 09:47:31 -07:00
Friedrich Stoltzfus 63cd424678 macOS: Add support for quick terminal sizing configuration
Added C bindings for the already existing quick-terminal-size
configuration. Created a new QuickTerminalSize struct to hold these
values in Swift. Updated the QuickTerminal implementation to use the
user's configuration if supplied. Retains defaults. Also adds support to
customize the width of the quick terminal (height if quick terminal is
set to right or left).
2025-08-26 09:47:31 -07:00
Mitchell Hashimoto 5c464e855d
parameterize close_tab (#8389)
- Add mode (`this`/`other`) parameter to `close_tab` keybind/apprt
action.
- Keybinds will default to `this` if not specified, eliminating backward
compatibility issues (`keybind=x=close_tab` ===
`keybind=x=close_tab:this`).
- Remove `close_other_tabs` keybind and apprt action.

Replaces #8380
2025-08-26 09:28:16 -07:00
Aindriú Mac Giolla Eoin 9c725187e1 Updating two strings 2025-08-26 15:47:16 +01:00
trag1c 4630369f87
i18n: update Ukrainian translation (#8379) 2025-08-26 10:44:58 +02:00
Mitchell Hashimoto 5b0801cbc9
osc 9: allow single character notifications (#8396) 2025-08-25 19:35:51 -07:00
Jeffrey C. Ollie 3320a081b4
osc 9: allow single character notifications 2025-08-25 19:27:27 -05:00
trag1c 9a56e77937
i18n: add new translations in fr_FR (#8378)
relative to #8344
2025-08-26 00:32:56 +02:00
Marija Gjorgjieva Gjondeva a471bac782
Update macedonian translation strings (#8392)
Updated new translation strings for version 1.2.

#8344
2025-08-25 21:03:43 +00:00
Jeffrey C. Ollie 14a3765916
cli: show colors in +list-colors if possible (#8393)
Fixes #8386

This is a fairly simple implementaion, there's no interactivity or
searching. It will adapt the number of columns to the available width of
the display though.

Will fallback to a plain text dump if there's no tty or the `--plain`
argument is specified on the CLI.

<img width="2112" height="1278" alt="image"
src="https://github.com/user-attachments/assets/0dbeec72-2092-4ed5-b1ed-0df43e5c64a3"
/>
2025-08-25 15:51:03 -05:00
Jeffrey C. Ollie ca06b95f65
cli: show colors in +list-colors if possible
Fixes #8386

This is a fairly simple implementaion, there's no interactivity or
searching. It will adapt the number of columns to the available width of
the display though.

Will fallback to a plain text dump if there's no tty or the `--plain`
argument is specified on the CLI.
2025-08-25 15:00:32 -05:00
trag1c d659bdcfdd
i18n: add missing de_DE translations (#8351)
Part of #8344.
2025-08-25 21:37:46 +02:00
Volodymyr Chernetskyi 754bb4011a i18n: add missing coma 2025-08-25 19:59:46 +02:00
Volodymyr Chernetskyi 11d845ce17 i18n: shorten Ukrainian translations 2025-08-25 19:57:08 +02:00
Robin c629ea674c
i18n: add missing de_DE translations 2025-08-25 19:38:54 +02:00
Volodymyr Chernetskyi f8d69e5baf i18n: use native Ukrainian word for "config" 2025-08-25 19:33:19 +02:00
Volodymyr Chernetskyi c396c25898 i18n: shorten Ukrainian translation for "split" 2025-08-25 19:23:26 +02:00
Jeffrey C. Ollie e98e868265
close-tab: style-fixes 2025-08-25 11:56:17 -05:00
Jeffrey C. Ollie 52a25e9c69
parameterize close_tab
- Add mode (`this`/`other`) parameter to `close_tab` keybind/apprt action.
- Keybinds will default to `this` if not specified, eliminating backward
  compatibility issues (`keybind=x=close_tab` === `keybind=x=close_tab:this`).
- Remove `close_other_tabs` keybind and apprt action.
2025-08-25 11:00:26 -05:00
Mitchell Hashimoto 8aa0b4c92a
gtk-ng: fix setting/unsetting of urgency (#8376)
- Don't set urgency on windows that are the topmost window.
- Turn off urgency on windows that become the topmost window.

Fixes #8373
2025-08-25 07:20:15 -07:00
Jeffrey C. Ollie 8a14f21325
gtk-ng: fix setting/unsetting of urgency
- Don't set urgency on windows that are the topmost window.
- Turn off urgency on windows that become the topmost window.

Fixes #8373
2025-08-25 09:06:29 -05:00
Volodymyr Chernetskyi 5c03ff8165 i18n: update Ukrainian translation 2025-08-24 22:58:10 +02:00
trag1c 400576f0b0
i18n: Add missing ca_ES translations (#8371)
Part of #8344
2025-08-24 19:52:08 +02:00
KristoferSoler c9199f2ba2
i18n: Add missing ca_ES translations
Part of #8344
2025-08-24 19:32:59 +02:00
trag1c 48120f8b6c
fix: update Spanish translations and revision date in es_BO.UTF-8.po (#8374)
8 new strings added
2025-08-24 17:05:13 +02:00
Mitchell Hashimoto 27ed58252d
Close other tabs feature on Mac. (#8363)
Supporting command line, file menu and keybindings. Default mac shortcut
of `super + alt + o` (other)

Not able to test on Linux so excluding `close_other_tabs` from `gtk` for
now
2025-08-24 08:00:11 -07:00
jamylak c26323d697 Close other tabs feature on Mac.
Supporting command line, file menu and keybindings.
Default mac shortcut of `super + alt + o` (other)

Not able to test on Linux so excluding `close_other_tabs` from `gtk` for now
make a default short cut for close other tabs
2025-08-24 07:55:08 -07:00
Mitchell Hashimoto 13425b4881
Update iTerm2 colorschemes (#8368)
Upstream revision:
e4c0090a65
2025-08-24 07:02:50 -07:00
Mitchell Hashimoto 9ff716642e
nix: update zon2nix (#8370)
- Builds with Zig 0.15 now (but still works just fine with Zig 0.14
projects).
- Fixes a double-free if nix-prefetch-git can't be found or errors out
- Adds support for generating Flatpak package metadata natively.
2025-08-24 07:02:38 -07:00
MiguelElGallo c57a84a6de fix: update Spanish translations for window split terminology 2025-08-24 16:26:41 +03:00
MiguelElGallo 42b1ff70d1 fix: update Spanish translations and revision date in es_BO.UTF-8.po 2025-08-24 15:52:13 +03:00
Balázs Szücs 95bc181c98
Add hu_HU for Hungarian locale (#7560)
## Description of changes

Added Hungarian locale files, and corresponding translation

For the translation I mainly relied on my native skills, double checked
my work using LLMs.

Copilot generated summary:

This pull request introduces Hungarian language support to the
application by adding translations and updating the locale
configurations. The most important changes include the addition of
Hungarian translations in the `.po` file and registering the new locale
in the application's supported locales.

### Hungarian Language Support:

* Added Hungarian translations for various UI elements and messages in
the `po/hu_HU.UTF-8.po` file. This includes translations for prompts,
dialogs, menus, and other interface components.
* Updated the supported locales list in `src/os/i18n.zig` to include
`hu_HU.UTF-8`, enabling Hungarian as an available language option.

## Picture(s) of the translation


![image](https://github.com/user-attachments/assets/60f47f11-d55e-4408-889b-5b44ecaffc23)
2025-08-24 09:10:21 +00:00
Jeffrey C. Ollie a18332828a
nix: update zon2nix
- Builds with Zig 0.15 now (but still works just fine with Zig
  0.14 projects).
- Fixes a double-free if nix-prefetch-git can't be found or errors out
- Adds support for generating Flatpak package metadata natively.
2025-08-23 21:31:00 -05:00
mitchellh 00e4a90699 deps: Update iTerm2 color schemes 2025-08-24 00:14:50 +00:00
Mitchell Hashimoto 7622d2662d
feat: add option to disable the "Reloaded the configuration" notification (#8366)
Redo of #8085 since I can't push that branch.
2025-08-23 12:59:09 -07:00
Mitchell Hashimoto e1d4c37996
apprt/gtk-ng: some style changes for toast 2025-08-23 12:51:52 -07:00
dy0gu 1b8dd234b0 Merge branch 'main' of https://github.com/Elyptica/ghostty 2025-08-23 12:50:53 -07:00
dy0gu 43e010bf47 feat: add option to disable the "Reloaded the configuration" notification 2025-08-23 12:50:53 -07:00
Mitchell Hashimoto 062d596c0a
terminal: fix use-after-free in exec (#8358)
This was only an issue on Linux, as MacOS' command is reallocated and
rewritten. We hit this using embedded Ghostty w/o a login shell :p
2025-08-23 12:45:44 -07:00
Kirwiisp a3be474d28 add new translations 2025-08-23 21:03:25 +02:00
Jacob Sandlund c7fa1d8381 using uucode for the graphemeBreak in shaper/web_canvas.zig 2025-08-23 14:33:11 -04:00
trag1c b347585e27
i18n: update norwegian translations (#8365)
Updated the norwegian translation file to include the new translations
(cc @Uzaaft).
2025-08-23 19:37:15 +02:00
hanna 1aa59cf63d
i18n: update choice selection prompt text 2025-08-23 13:19:13 -04:00
hanna bd4e9b96bf
i18n: update translation metadata 2025-08-23 12:53:05 -04:00
trag1c 59fd366264
i18n: Update Turkish translations (#8350)
Part of #8344
2025-08-23 18:48:35 +02:00
hanna 78f05ec96c
i18n: adjust wording in translation 2025-08-23 12:48:32 -04:00
trag1c 0d536d447c
i18n: Update Hebrew translation (#8362)
issue: #8344
2025-08-23 18:47:56 +02:00
hanna 4f4c06967a
i18n: update norwegian translations 2025-08-23 12:43:02 -04:00
Emir SARI f6f2a85256
i18n: Update Turkish translations
Signed-off-by: Emir SARI <emir_sari@icloud.com>
2025-08-23 19:27:19 +03:00
Jacob Sandlund 39ecfe9211 Merge remote-tracking branch 'upstream/main' into jacob/uucode 2025-08-23 09:16:11 -04:00
Jacob Sandlund 3c61aaca2a attempting to use uucode from uucode.x 2025-08-23 09:16:01 -04:00
Gal c181fc4fbf i18n: Update Hebrew translation
issue: #8344
2025-08-23 13:53:29 +03:00
Cheru Berhanu d854ecd374 terminal: test execCommand w/ freed config 2025-08-22 15:55:08 -07:00
Cheru Berhanu 652f6f1deb terminal: fix use-after-free in exec
This was only an issue on Linux, as MacOS' command is reallocated and
rewritten. We hit this using embedded Ghostty w/o a login shell :p
2025-08-22 15:22:54 -07:00
Mitchell Hashimoto c014dd79f6
terminal: fix build with -Di18n=false (#8359)
canonicalizeLocale should return a null-terminated string, and didn't
previously.

Compiler output:
```
src/os/i18n.zig:139:45: error: expected type 'error{NoSpaceLeft}![:0]const u8', found '[]const u8'
    if (comptime !build_config.i18n) return locale;
                                            ^~~~~~
src/os/i18n.zig:139:45: note: destination pointer requires '0' sentinel
src/os/i18n.zig:138:21: note: function return type declared here
) error{NoSpaceLeft}![:0]const u8 {
  ~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~
```
2025-08-22 14:54:11 -07:00
Cheru Berhanu 292efec669 terminal: fix build with -Di18n=false
canonicalizeLocale should return a null-terminated string, and didn't previously.

Compiler output:
```
src/os/i18n.zig:139:45: error: expected type 'error{NoSpaceLeft}![:0]const u8', found '[]const u8'
    if (comptime !build_config.i18n) return locale;
                                            ^~~~~~
src/os/i18n.zig:139:45: note: destination pointer requires '0' sentinel
src/os/i18n.zig:138:21: note: function return type declared here
) error{NoSpaceLeft}![:0]const u8 {
  ~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~
```
2025-08-22 14:47:04 -07:00
Mitchell Hashimoto 0c722b0e3d
macos: if parent window is fullscreen, new window is fullscreen too (#8355)
Fixes #8229

This was a regression. 

The discussion noted in #8229 requests we create a new window on the
non-fullscreen desktop but that isn't how Ghostty has behaved
historically. I bisected back and tried 1.1.3 as well and we always
created a new fullscreen window when the parent was fullscreen.

This behavior matches iTerm2. Its noteworthy that native tabbing and
Apple apps such as Terminal.app and Safari do NOT do this. For both of
these, new window creates a _tab_ when in fullscreen. I don't think
that's particularly desirable, though.
2025-08-22 14:41:00 -07:00
Mitchell Hashimoto 54f8dff308
macos: if parent window is fullscreen, new window is fullscreen too
Fixes #8229

This was a regression. 

The discussion noted in #8229 requests we create a new window on the 
non-fullscreen desktop but that isn't how Ghostty has behaved
historically. I bisected back and tried 1.1.3 as well and we always
created a new fullscreen window when the parent was fullscreen.

This behavior matches iTerm2. Its noteworthy that native tabbing and
Apple apps such as Terminal.app and Safari do NOT do this. For both of
these, new window creates a _tab_ when in fullscreen. I don't think
that's particularly desirable, though.
2025-08-22 14:31:50 -07:00
Mitchell Hashimoto 60e077b651
deps: update z2d to v0.7.2 (#8354)
Release notes at:
  https://github.com/vancluever/z2d/blob/v0.7.2/CHANGELOG.md

This is mostly a bugfix release for text rendering, including a fix for
an invalid free flagged as:

https://github.com/vancluever/z2d/security/advisories/GHSA-v7f4-f3hm-282w

Note that the invalid free affects the new in-library text rendering
only and as such is likely not in use in Ghostty.

I'm anticipating *maybe* one more release after this ahead of Ghostty
1.2.0, depending on if I find any more bugs, but close to around the
release I am planning a freeze to ensure a clean versioned release
continues to be set.
2025-08-22 10:51:26 -07:00
Chris Marchesi 50fe12e85c
deps: update z2d to v0.7.2
Release notes at:
  https://github.com/vancluever/z2d/blob/v0.7.2/CHANGELOG.md

This is mostly a bugfix release for text rendering, including a fix for
an invalid free flagged as:
  https://github.com/vancluever/z2d/security/advisories/GHSA-v7f4-f3hm-282w

Note that the invalid free affects the new in-library text rendering
only and as such is likely not in use in Ghostty.

I'm anticipating *maybe* one more release after this ahead of Ghostty
1.2.0, depending on if I find any more bugs, but close to around the
release I am planning a freeze to ensure a clean versioned release
continues to be set.
2025-08-22 10:30:01 -07:00
Mitchell Hashimoto f4abecefe4
core: avoid possible deadlock in right-click-action paste actions (#8352)
Fixes #8313

The clipboard request flow can result in the apprt immediately
completing the request which itself grabs a lock. For pastes, we should
yield the lock during the clipboard request.

GTK is always async so this worked there, but we want to be resilient to
any apprt behavior here.
2025-08-22 09:52:51 -07:00
Mitchell Hashimoto db60e981d1
core: avoid possible deadlock in right-click-action paste actions
Fixes #8313

The clipboard request flow can result in the apprt immediately
completing the request which itself grabs a lock. For pastes, we should
yield the lock during the clipboard request.

GTK is always async so this worked there, but we want to be resilient to
any apprt behavior here.
2025-08-22 09:49:18 -07:00
Mitchell Hashimoto 3859f50b88
Work around strange SwiftUI behavior in "older" macOSen. (might fix #7690) (#8026)
The Quick Terminal would not appear anymore, as somewhere in the
framework the Quick Terminal Window's geometry gets corrupted when the
window is added to the UI.

This works around by caching the windows geometry and reusing it
afterwards

This might fix #7690
2025-08-22 09:31:11 -07:00
Tobias Pape 4fdf0b687e typo found typos, typo may keep them 2025-08-22 09:19:25 -07:00
Tobias Pape 85cba70c2e Work around strange SwiftUI behavior in "older" macOSen.
The Quick Terminal would not appear anymore, as somewhere
in the framework the Quick Terminal Window's geometry
gets corrupted when the window is added to the UI.

This works around by caching the windows geometry and
reusing it afterwards
2025-08-22 09:17:49 -07:00
Mitchell Hashimoto 5bff354e96
fix: copy_url_to_clipboard copies full OSC8 URL instead of single cha… (#7551)
fix: copy_url_to_clipboard for OSC8 hyperlinks

OSC8 links were only detected when exact platform-specific modifiers
were held (Cmd on macOS, Ctrl on Linux), but copy_url_to_clipboard
should work with either. Additionally, OSC8 links were using
selectionString() which gets visible text instead of the actual URI. Now
we use osc8URI() for OSC8 links and fall back to selectionString() for
regex-detected links.

Fixes #7499
2025-08-22 09:14:36 -07:00
Mitchell Hashimoto 6d9cac5ffc
macOS: order out alert sheets to avoid Stage Manager focus loss (#8348)
On macOS, when using stage manager, ghostty loses focus when a running
process is terminated.

This aims to fix #8336 which has reappeared since the previously fixed
#5108.

Opened a new pr following the closure of the previous #8343
2025-08-22 09:12:01 -07:00
Alex 6248030426 removed boolean logic, reverted back to ctrlOrSuper call 2025-08-22 09:10:53 -07:00
Alex 6708229a7e Removed boolean logic, reverted back to ctrlOrSuper call 2025-08-22 09:09:06 -07:00
Alex 91f973afdb Merge branch 'fix-copy-url' into fix-copy-url-minimal
Remove boolean logic as it is not needed, revert back to using ctrlOrSuper call in linkAtPos
2025-08-22 09:09:06 -07:00
Alex Straight 14f5a879a9 fix: make regular URLs work with either ctrl or super modifiers 2025-08-22 09:09:06 -07:00
Alex eaa81be051 Merge branch 'main' into fix-copy-url 2025-08-22 09:09:06 -07:00
Alex 83b573aed7 remove commented out block 2025-08-22 09:09:06 -07:00
Alex c78fb0f895 Removed boolean logic, reverted back to ctrlOrSuper call 2025-08-22 09:09:06 -07:00
Alex 5441578f08 Merge branch 'main' into fix-copy-url 2025-08-22 09:09:06 -07:00
Alex c142473405 Merge branch 'main' into fix-copy-url
Merging main into fix-copy-url
2025-08-22 09:09:06 -07:00
Alex Straight fc1307e939 fix: make regular URLs work with either ctrl or super modifiers 2025-08-22 09:09:06 -07:00
Alex Straight 5836dc4ce6 fix: copy_url_to_clipboard copies full OSC8 URL instead of single character
OSC8 links were only detected when exact platform-specific modifiers were held (Cmd on macOS, Ctrl on Linux), but copy_url_to_clipboard should work with either. Additionally, OSC8 links were using selectionString() which gets visible text instead of the actual URI. Now we use osc8URI() for OSC8 links and fall back to selectionString() for regex-detected links.

Fixes #7491
2025-08-22 09:09:06 -07:00
Alex Straight 93c2400bf4 fix: copy_url_to_clipboard copies full OSC8 URL instead of single character
OSC8 links were only detected when exact platform-specific modifiers were held (Cmd on macOS, Ctrl on Linux), but copy_url_to_clipboard should work with either. Additionally, OSC8 links were using selectionString() which gets visible text instead of the actual URI. Now we use osc8URI() for OSC8 links and fall back to selectionString() for regex-detected links.

Fixes #7491
2025-08-22 09:09:05 -07:00
Moeeze Hassan f4009721a1 macOS: order out alert sheets to avoid Stage Manager focus loss
Signed-off-by: Moeeze Hassan <fammas.maz@gmail.com>
2025-08-22 09:05:20 -07:00
Alan Moyano a479c9b2af
i18n: add missing es_AR translations (#8347)
Part of #8344
2025-08-22 15:59:04 +02:00
Aindriú Mac Giolla Eoin 35102ddb5a Updating Irish translation for Ghostty 1.2 2025-08-22 14:53:56 +01:00
Jacob Sandlund 0444c614da update for new grapheme_break 2025-08-21 22:29:34 -04:00
Jacob Sandlund 90832d89b3 Merge remote-tracking branch 'upstream/main' into jacob/uucode 2025-08-21 21:13:40 -04:00
Mitchell Hashimoto 298f11166d
macos: move activation to after new window/tab is created (#8338)
This is a follow-up to #8064, moving the activation into the async block
such that it happens after the window is created. As discussed in #8064,
this is necessary to bring only the newly created window to the front,
rather than both the previous main window and the new window.

Also made the same change for the new tab action, which also needs to
activate in case it was triggered from the dock menu or a global
keybind.

Finally, I removed the activations within AppDelegate that are redundant
now that TerminalController itself takes care of activating.
2025-08-21 15:38:40 -07:00
Daniel Wennberg 7d60c7c75b macos: move activation to after new window/tab is created 2025-08-21 15:16:20 -07:00
Mitchell Hashimoto 056ccc9818
macOS: update sparkle (#8337)
There aren't any noteworthy changes here we're just using a very old
version. Additionally, our CI was using... different versions!
2025-08-21 14:56:50 -07:00
Mitchell Hashimoto 3ef6de4ffa
macos: in new_window action, activate App (#8064)
> [!NOTE]  
> The change might have been intentional, and so I lack context. I
mention two ways to fix below, this PR implements the first possible
fix.

This change makes sure that the new window is focused and visible.

When commit 33d128bcff removed the
TerminalManager class and moved its functionality into
TerminalController, it accidentally removed app activation for windows
triggered by global keybinds.

How the bug works:

1. Menu actions (like File → New Window) call AppDelegate.newWindow()
which: 2. Calls TerminalController.newWindow() 3. AND explicitly calls
NSApp.activate(ignoringOtherApps: true) in the AppDelegate
4. Global keybind actions trigger ghosttyNewWindow() notification
handler which:
      5. Only calls TerminalController.newWindow()
      6. Does NOT call NSApp.activate(ignoringOtherApps: true)
7. While TerminalController.newWindow() does call
NSApp.activate(ignoringOtherApps: true) internally, this call happens
before the async dispatch that shows the window, so the activation
occurs but the window isn't focused when it's actually shown.
8. In the old TerminalManager.newWindow(), the activation happened
immediately before the async dispatch, ensuring proper timing for window
focus.

To see the bug in action:
- run recent Ghostty `main`
- set up a global keybind for `new_window`
- focus some other window
- trigger keybind
- notice that Ghostty doesn't come to the foreground, but when manually
switching to Ghostty you will see that the new window _was_ created

The fix would be to either move the NSApp.activate() call back into
TerminalController.newWindow(), as it was for TerminalManager, or add
the activation call to the notification handlers in AppDelegate.
2025-08-21 14:09:44 -07:00
Mitchell Hashimoto 1ce56a12fa
update sparkle
There aren't any noteworthy changes here we're just using a very old
version. Additionally, our CI was using... different versions!
2025-08-21 14:08:32 -07:00
Aljoscha Krettek f736ee8865 macos: in new_window action, activate App
This change makes sure that the new window is focused and visible.

When commit 33d128bcff removed the
TerminalManager class and moved its functionality into
TerminalController, it accidentally removed app activation for windows
triggered by global keybinds.

How the bug works:

   1. Menu actions (like File → New Window) call AppDelegate.newWindow()
      which:
      2. Calls TerminalController.newWindow()
      3. AND explicitly calls NSApp.activate(ignoringOtherApps: true) in
         the AppDelegate
   4. Global keybind actions trigger ghosttyNewWindow() notification
      handler which:
      5. Only calls TerminalController.newWindow()
      6. Does NOT call NSApp.activate(ignoringOtherApps: true)
   7. While TerminalController.newWindow() does call
      NSApp.activate(ignoringOtherApps: true) internally, this call
      happens before the async dispatch that shows the window, so the
      activation occurs but the window isn't focused when it's actually
      shown.
   8. In the old TerminalManager.newWindow(), the activation happened
      immediately before the async dispatch, ensuring proper timing for
      window focus.

The fix would be to either move the NSApp.activate() call back into
TerminalController.newWindow(), as it was for TerminalManager, or add
the activation call to the notification handlers in AppDelegate.
2025-08-21 14:03:00 -07:00
Mitchell Hashimoto 40105e1c7e
cli: add filtering hotkey to list_themes (#8082)
## Summary

Implements the theme filtering hotkey as requested in #7930. 

## Implementation

- Adds 'f' hotkey to cycle through filtering options: all, dark, and
light.
- Integrates with existing search functionality.
- Preserves CLI `--color` flag behavior for initial state.
- Updates help menu with the new hotkey. 

**NOTE**: I noticed another PR
[#8079](https://github.com/ghostty-org/ghostty/pull/8079) opened. I
started this implementation independently prior and don't want to step
on any toes. Happy to collaborate or defer to maintainers.
2025-08-21 14:01:50 -07:00
Mitchell Hashimoto c110c0f76d
gtk-ng: add a helper to reduce boilerplate in GTK IPC (#8306) 2025-08-21 13:34:53 -07:00
Mitchell Hashimoto c675896595
ci: add 30 minute timeout to valgrind (#8333)
It usually takes less than a few minutes right now. Something is wrong
if it takes more than that.
2025-08-21 11:46:07 -07:00
Mitchell Hashimoto 53c2f915d8
gtk-ng: allow XKB remaps for non-writing-system keys (#8330)
Compromise solution to #7356

XKB is naughty. It's really really naughty. I don't understand why we
didn't just kill XKB with hammers during the Wayland migration and
change it for something much better. I don't understand why we're
content with what amounts to an OS-level software key remapper that
completely jumbles information about original physical key codes in
order to fake keyboard layouts, and not just let users who really want
to remap keys use some sort of evdev or udev-based mapper program.

In a sane system like macOS, the "c" key is always the "c" key, but it's
understood to produce the Unicode character "ц" when using a Russian
layout. XKB defies sanity, and just pretends that your "c" key is
actually a "ц" key instead, and so when you ask for the keybind "Ctrl+C"
it just shrugs in apathy (#7309). And so, we took matters into our own
hands and interpreted hardware keycodes ourselves.

But then, a *lot* of people have the ingrained muscle memory of swapping
Escape with Caps Lock so that it is easier to hit. We respect that. In a
sane system, they would use a remapper that actually makes the system
think you've hit the Escape key when in reality you've hit the Caps Lock
key, so in all intents and purposes to the OS and any app developer,
these two just have their wires swapped. But not on Linux. Somehow this
and the aforementioned case should be treated by the same key transform
algorithm, which is completely diabolical.

As a result, we have to settle for a compromise that truly satisfies
neither party — by allowing XKB remaps for keys that don't really change
depending on the layout.

The Linux input stack besets all hopes and aspirations.
2025-08-21 11:45:48 -07:00
Mitchell Hashimoto 795c745491
ci: add 30 minute timeout to valgrind
It usually takes less than a few minutes right now. Something is wrong
if it takes more than that.
2025-08-21 11:44:58 -07:00
Leah Amelia Chen 534aa508d6
gtk-ng: allow XKB remaps for non-writing-system keys
Compromise solution to #7356

XKB is naughty. It's really really naughty. I don't understand why we
didn't just kill XKB with hammers during the Wayland migration and change
it for something much better. I don't understand why we're content with
what amounts to an OS-level software key remapper that completely jumbles
information about original physical key codes in order to fake keyboard
layouts, and not just let users who really want to remap keys use some
sort of evdev or udev-based mapper program.

In a sane system like macOS, the "c" key is always the "c" key, but it's
understood to produce the Unicode character "ц" when using a Russian
layout. XKB defies sanity, and just pretends that your "c" key is
actually a "ц" key instead, and so when you ask for the keybind "Ctrl+C"
it just shrugs in apathy (#7309). And so, we took matters into our own
hands and interpreted hardware keycodes ourselves.

But then, a *lot* of people have the ingrained muscle memory of swapping
Escape with Caps Lock so that it is easier to hit. We respect that.
In a sane system, they would use a remapper that actually makes the
system think you've hit the Escape key when in reality you've hit the
Caps Lock key, so in all intents and purposes to the OS and any app
developer, these two just have their wires swapped. But not on Linux.
Somehow this and the aforementioned case should be treated by the same
key transform algorithm, which is completely diabolical.

As a result, we have to settle for a compromise that truly satisfies
neither party — by allowing XKB remaps for keys that don't really change
depending on the layout.

The Linux input stack besets all hopes and aspirations.
2025-08-22 02:02:11 +08:00
Mitchell Hashimoto d725f2346f
macOS: Add macos-dock-drop-folder-behavior (new tab or window) configuration option (#8114)
This PR adds a new configuration option
`macos-dock-drop-folder-behavior` that controls whether folders dropped
onto the Ghostty dock icon open in a new tab (default) or a new window.

## Changes

### Configuration Option Added
- **Option name**: `macos-dock-drop-folder-behavior`
- **Valid values**: 
  - `tab` (default) - Opens folders in a new tab in the main window
  - `window` - Opens folders in a new window
- **Platform**: macOS only

### Files Modified

1. **`src/config/Config.zig`**
- Added `MacOSDockDropFolderBehavior` enum with `tab` and `window`
values
   - Added configuration field with default value of `.tab`
   - Added documentation explaining the option

2. **`macos/Sources/Ghostty/Package.swift`**
   - Added `MacOSDockDropFolderBehavior` enum to match the Zig enum

3. **`macos/Sources/Ghostty/Ghostty.Config.swift`**
- Added `macosDockDropFolderBehavior` computed property to access the
configuration value from Swift

4. **`macos/Sources/App/macOS/AppDelegate.swift`**
- Modified `application(_:openFile:)` method to check the configuration
- When a folder is dropped on the dock icon, it now respects the user's
preference

## Usage

Add to your Ghostty configuration file:
```
macos-dock-drop-folder-behavior = window
```

## Motivation

This feature is useful for users (like me!) who prefer window-based
workflows over tab-based workflows when opening folders via drag and
drop on macOS.
2025-08-21 10:55:04 -07:00
Jeffrey C. Ollie dcc5aded6e
gtk-ng: more complete GTK startup/shutdown in test (#8324) 2025-08-21 12:52:10 -05:00
Mitchell Hashimoto e01ff4093a
macos: have macos-dock-drop-behavior apply to all drops 2025-08-21 10:45:17 -07:00
David Keegan f9ad061ea8 Add macos-dock-drop-folder-behavior configuration option
This adds a new configuration option that controls whether folders
dropped onto the Ghostty dock icon open in a new tab (default) or
a new window.

The option accepts two values:
- tab: Opens folders in a new tab in the main window (default)
- window: Opens folders in a new window

This is useful for users who prefer window-based workflows over
tab-based workflows when opening folders via drag and drop.
2025-08-21 10:30:26 -07:00
Mitchell Hashimoto d20376c1ff
macOS Custom Icon + Persistence (#8230)
This PR aims to improve custom icons on macOS in the following ways. (I
based this PR on the discussion #3631)

### Currently
- Current Icon customizations are not persistent *(when closing the
application the icon in dock reverts back to official icon)*
- There is no officially supported way to change icon to be something
completely custom.

### After this PR
- Current icon customizations are persistent (closing the application no
longer reverts back to official icon)
- Ghostty config `macos-icon` has a new option `custom` which by default
looks for icon `~/.config/ghostty/Ghostty.icns`. It has an accompanying
new configuration `macos-custom-icon` which allows for a different path
to be specified, it does support more than just `.icns` as well.

Both changes are based on the thread with @sfsam in
https://github.com/ghostty-org/ghostty/discussions/3631#discussioncomment-12180647

Feedback is always welcome, if I have not done something up to par
please let me know and I will do my best to correct it.

NOTE: I did notice some newlines with indents which seems to be against
convention in those files so I removed the whitespace if this is not
preferred I can revert.

---

P.S. Thanks for all the work you put into making an awesome terminal!
2025-08-21 10:13:38 -07:00
ClearAspect f7994e6412 fix: correct the cursor Y position value exposed to shader uniforms
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
2025-08-21 10:08:49 -07:00
Mitchell Hashimoto f178f4419e
macos: fix iOS builds 2025-08-21 10:03:25 -07:00
Nicholas Mata f1c68f698b Correct Swift formatting inconsistencies 2025-08-21 10:00:15 -07:00
Nicholas Mata 5948bd3f02 Add support for 'custom' on 'macos_icon' to support a completely custom app icon 2025-08-21 10:00:15 -07:00
Nicholas Mata 29419e7aac Make macos icon persistent even when app is closed 2025-08-21 10:00:15 -07:00
Mitchell Hashimoto 66e5081721
ci: add timeout to snap and windows jobs (#8329)
There have been times these runaway taking forever for unknown reasons.
2025-08-21 09:29:44 -07:00
Mitchell Hashimoto e92fe9d9f8
ci: add timeout to snap and windows jobs
There have been times these runaway taking forever for unknown reasons.
2025-08-21 09:22:14 -07:00
Mitchell Hashimoto e3e69269e5
Switch macOS builds to Tahoe (Beta 7 currently) (#8328)
This switches our macOS builds to build on Tahoe, rather than on
Sequoia.

The primary motivation is to get builds out using a new Xcode version
(our builds at the time of writing this are _still produced_ with beta
1! ONE!). Every subsequent beta has had bugs that have prevented us from
upgrading, amusingly enough. But the later betas _also_ have a bunch of
fixes I want to get in. I hope this one works...

The reason we have to use Tahoe instead of Sequoia is because on
Sequoia, builds in CI _crash xcodebuild_. This is definitely an Apple
bug but I can't reproduce it locally to create a bug report, so I'm not
sure what to do.
2025-08-21 09:19:53 -07:00
Mitchell Hashimoto 82f7cd2133
ci: switch release builds to tahoe builders 2025-08-21 09:05:34 -07:00
Mitchell Hashimoto 7bb493e6ac
ci: switch to Tahoe for builds 2025-08-21 07:36:59 -07:00
Mitchell Hashimoto 073a8b01d2
terminal: explicitly initialize undefined fields at runtime (#8323)
This works around the Zig issue as noted in the comment.

No new Valgrind issues found from this.
2025-08-21 07:34:21 -07:00
Jeffrey C. Ollie 36f7e018ae
gtk-ng: more complete GTK startup/shutdown 2025-08-21 09:29:22 -05:00
Mitchell Hashimoto 531924e7e7
terminal: explicitly initialize undefined fields at runtime
This works around the Zig issue as noted in the comment.

No new Valgrind issues found from this.
2025-08-21 07:27:43 -07:00
Mitchell Hashimoto 2ffc61d21e
gtk-ng: properly skip Zig test (#8322) 2025-08-21 07:25:30 -07:00
Jeffrey C. Ollie 2d0f930e6a
gtk-ng: properly skip Zig test 2025-08-21 09:14:06 -05:00
Mitchell Hashimoto 7a42c82d18
temp: try downloading metal explicitly 2025-08-21 07:06:40 -07:00
Mitchell Hashimoto d66747407d
ci: move to bleedging edge sequoia builds
This will bring in Xcode 26 Beta 4 which I believe fixes all the known
issue we were dealing with keeping us on beta 1.
2025-08-21 07:06:40 -07:00
Mitchell Hashimoto 0e81f8d4e2
flatpak: manually install Zig 0.14.1 (#8311)
The SDK published on Flathub updated to Zig 0.15.1 which broke the
Flathub build in CI. So let's install it ourselves so that we can
control the version.
2025-08-21 07:04:50 -07:00
Mitchell Hashimoto 4cc33b546c
Full unit test suite passing Valgrind (#8319)
This contains the various changes necessary to get the full unit test
suite passing Valgrind, and configures CI to run this.

I disabled relatively few (less than 10) tests under Valgrind because
they're way too slow: all `verifyIntegrity` tests, because those run
anyways in debug and check their own memory health, a font test that
fills out font map, and the sprite render test. Everything else runs
as-is.

I found a number of issues, most were in the tests themselves. A couple
in actual code. A funny one was some undefined memory on tabstop resize
if you exceed the default number of tabstops. I don't know any real
world program that ever even did that (memory issue aside), and that
whole file hasn't been touched since 2022, so that was funny.

No memory leaks in actual code, but a number of leaks in tests. All
resolved.

I think we're still missing some reports because of the Zig bug:
https://github.com/ziglang/zig/issues/19148 so I'm gong to audit our
codebase after this and look for cases of that.
2025-08-21 07:04:13 -07:00
Mitchell Hashimoto 793e817d74
ci: run all valgrind tests 2025-08-21 06:58:08 -07:00
Mitchell Hashimoto 96a0b9021c
font: disable sprite test in valgrind 2025-08-21 06:57:25 -07:00
Mitchell Hashimoto fe5eafac0a
font: fix fontconfig leaks in unit tests 2025-08-21 06:53:59 -07:00
Jeffrey C. Ollie 6427a21679
flatpack: add back to list of required CI jobs 2025-08-21 00:42:18 -05:00
Qwerasd d2ac29c919
font/CoreText: fix positioning for padded scaled glyphs (#8310)
When constraints increased or decreased the size significantly, the
fractional position was getting messed up by the scale. This change
separates that out so that it applies correctly.

I noticed this when messing around with constraints, adding this
constraint to every glyph and then running with `font-family=Arial` and
`adjust-cell-width = -35%` (if you want to reproduce this)
```zig
constraint = .{
    .size_horizontal = .stretch,
    .align_horizontal = .center,
    .pad_left = 0.1,
    .pad_right = 0.1,
};
```
The padding was disproportionately affecting thin glyphs that were
stretched a lot. The problem was that the padding was being multiplied
by the scale.

This also made it so the top or right of said thin glyphs often got
clipped off by the edge of the canvas.

Anyway I fixed it.

|Before|After|
|-|-|
|<img width="1824" height="1480" alt="image"
src="https://github.com/user-attachments/assets/32779f9d-a048-4a8c-b5ea-0e8a851d5119"
/>|<img width="1824" height="1480" alt="image"
src="https://github.com/user-attachments/assets/5bf449e5-699e-4bdc-ac96-2b776f9fb7fa"
/>|
2025-08-20 21:55:51 -06:00
Mitchell Hashimoto a57afd41ac
terminal: fix undefined memory access in unit test 2025-08-20 20:54:29 -07:00
Mitchell Hashimoto 566062c0a5
terminal: fix undefined memory in Tabstops code 2025-08-20 20:44:35 -07:00
Mitchell Hashimoto be51f3e729
terminal: fix uninitialized memory in Cell init 2025-08-20 20:21:26 -07:00
Mitchell Hashimoto 3ce043123b
terminal: fix undefined memory access in PageList eraseRows 2025-08-20 19:53:33 -07:00
Mitchell Hashimoto 2cebc225c0
ci: failing pagelist tests
on purpose, so we can verify CI fails
2025-08-20 19:46:37 -07:00
Jeffrey C. Ollie 1f7f678745
flatpak: manually install Zig 0.14.1
The SDK published on Flathub updated to Zig 0.15.1 which broke the
Flathub build in CI. So let's install it ourselves so that we can
control the version.
2025-08-20 19:10:25 -05:00
Qwerasd 610ce94f2d font/CoreText: fix positioning for padded scaled glyphs
When constraints increased or decreased the size significantly, the
fractional position was getting messed up by the scale. This change
separates that out so that it applies correctly.
2025-08-20 15:26:16 -06:00
Mitchell Hashimoto 4fa7b412d4
terminal: disable integrity checks under Valgrind 2025-08-20 14:05:31 -07:00
Mitchell Hashimoto fec0defd04
ci: run valgrind in CI (#8309)
This runs Valgrind on our unit test suite in CI. Since we're not
currently passing Valgrind, this will be incrementally updated with the
filters for our passing tests. Ultimately, we'll remove the filters and
run the full suite.

Valgrind is slow and hungry so this is our first and only job currently
on a large instance.
2025-08-20 13:30:09 -07:00
Mitchell Hashimoto 5287b963c9
ci: run valgrind in CI
This runs Valgrind on our unit test suite in CI. Since we're not
currently passing Valgrind, this will be incrementally updated with the
filters for our passing tests. Ultimately, we'll remove the filters and
run the full suite.

Valgrind is slow and hungry so this is our first and only job currently
on a large instance.
2025-08-20 13:25:30 -07:00
Mitchell Hashimoto f1300ec44f
terminal: fix undefined memory access in OSC parser (#8307)
Fixes #8007

Verified with `test-valgrind -Dtest-filter="OSC"` which had cond access
errors before, and none after this. Basically a copy of #8008.
2025-08-20 13:15:40 -07:00
Mitchell Hashimoto 42f0c05d7e
terminal: fix undefined memory access in OSC parser
Fixes #8007

Verified with `test-valgrind -Dtest-filter="OSC"` which had cond access
errors before, and none after this. Basically a copy of #8008.
2025-08-20 13:05:57 -07:00
Jeffrey C. Ollie 108260100c
gtk-ng: add a helper to reduce boilerplate in GTK IPC 2025-08-20 14:53:17 -05:00
Mitchell Hashimoto 6aac8bfc24
terminal: change OSC parser to explicit init to set undefined (#8304)
This works around: https://github.com/ziglang/zig/issues/19148 This lets
our `test-valgrind` command catch some issues. We'll have to follow this
pattern in more places but I want to do it incrementally so things keep
passing.

I **do not** want to blindly follow this pattern everywhere. I want to
start by focusing in only on the structs that set `undefined` as default
fields that we're also about to test in isolation with Valgrind. It's
just too much noise otherwise and not a general style I'm sure of; it's
worth it for Valgrind though.

I'm making this PR separate from any fixes because the diff is so noisy
I don't want to lose the fixes in the noise. **This PR is therefore
functionally a no-op.**
2025-08-20 12:42:46 -07:00
Mitchell Hashimoto 131f170f89
terminal: change OSC parser to explicit init to set undefined
This works around: https://github.com/ziglang/zig/issues/19148
This lets our `test-valgrind` command catch some issues. We'll have to
follow this pattern in more places but I want to do it incrementally so
things keep passing.

I **do not** want to blindly follow this pattern everywhere. I want to
start by focusing in only on the structs that set `undefined` as default
fields that we're also about to test in isolation with Valgrind. Its
just too much noise otherwise and not a general style I'm sure of; it's
worth it for Valgrind though.
2025-08-20 12:38:29 -07:00
Mitchell Hashimoto b3a80f2e47
build: add run-valgrind and test-valgrind steps (#8302)
This adds two explicit `zig build` steps: `run-valgrind` and
`test-valgrind` to run the Ghostty exe or tests under Valgrind,
respectively.

This simplifies the manual Valgrind calls in a few ways:

1. It automatically sets the CPU to baseline, which is a frequent and
requirement for Valgrind on newer CPUs, and generally safe.

2. It sets up the rather complicated set of flags to call Valgrind with,
importantly setting up our suppressions.

3. It enables pairing it with the typical and comfortable workflow of
specifying extra args (with `--`) or flags like `-Dtest-filter` for
tests.
2025-08-20 12:27:35 -07:00
Mitchell Hashimoto f87213c2f6
build: add run-valgrind and test-valgrind steps
This adds two explicit `zig build` steps: `run-valgrind` and
`test-valgrind` to run the Ghostty exe or tests under Valgrind,
respectively.

This simplifies the manual Valgrind calls in a few ways:

1. It automatically sets the CPU to baseline, which is a frequent and
   requirement for Valgrind on newer CPUs, and generally safe.

2. It sets up the rather complicated set of flags to call Valgrind with,
   importantly setting up our suppressions.

3. It enables pairing it with the typical and comfortable workflow of
   specifying extra args (with `--`) or flags like `-Dtest-filter` for
   tests.
2025-08-20 11:43:48 -07:00
Jeffrey C. Ollie a909aac252
contributing: add some notes about running valgrind (#8298) 2025-08-20 11:41:55 -05:00
Jeffrey C. Ollie 4171cd64e0
wuffs: simplify the build (#8299) 2025-08-20 11:37:51 -05:00
Jeffrey C. Ollie 3cce5d26d7
wuffs: simplify the build 2025-08-20 10:08:24 -05:00
Jeffrey C. Ollie 6032732001
contributing: add some notes about running valgrind 2025-08-20 09:03:48 -05:00
Mitchell Hashimoto b52879b467
snap: remove workaround for build failures (#8292) 2025-08-19 20:35:35 -07:00
Jeffrey C. Ollie aa26f8fd34
snap: remove workaround for build failures 2025-08-19 21:49:05 -05:00
Mitchell Hashimoto e71c23802f
AI tooling must be disclosed for contributions (#8289)
I think, at this stage of AI, it is a common courtesy to disclose this. 

In a perfect world, AI assistance would produce equal or higher quality
work than any human. That isn't the world we live in today, and in many
cases it's generating slop. I say this despite being a fan of and using
them successfully myself (with heavy supervision)! I think the major
issue is **inexperienced human drivers of AI** that aren't able to
**adequately review their generated code.** As a result, they're pull
requesting code that I'm sure they would be ashamed of if they knew how
bad it was.

The disclosure is to help maintainers assess how much attention to give
a PR. While we aren't obligated to in any way, I try to assist
inexperienced contributors and coach them to the finish line, because
getting a PR accepted is an achievement to be proud of. But if it's just
an AI on the other side, I don't need to put in this effort, and it's
rude to trick me into doing so.

**I'm a fan of AI assistance and use AI tooling myself.** But, we need
to be responsible about what we're using it for and respectful to the
humans on the other side that may have to review or maintain this code.

(In the spirit of this PR... none of this PR was AI generated. lol.)
2025-08-19 15:52:24 -07:00
Mitchell Hashimoto 7022c79521
ci: workaround snap builder issues (#8290)
Workaround produced by Namespace support. Thanks!
2025-08-19 15:52:15 -07:00
Mitchell Hashimoto b4833c83cc
ci: workaround snap builder issues
Workaround produced by Namespace support. Thanks!
2025-08-19 15:29:06 -07:00
Mitchell Hashimoto babe923c8c
AI tooling must be disclosed for contributions 2025-08-19 15:02:31 -07:00
Mitchell Hashimoto f0acd02558
macos: show copy menu item if selection start is outside viewport (#8288)
Fixes #8187

This properly handles the scenario with our `read_text` C API when the
selection start is outside the viewport. Previously we'd report null (no
text) which would cascade into things like the right click menu not
showing a copy option.
2025-08-19 14:30:06 -07:00
Mitchell Hashimoto 63ca777e0f
macos: show the copy menu item if we have any text selected 2025-08-19 14:23:50 -07:00
Mitchell Hashimoto 1c96870c17
macos: show copy menu item if selection start is outside viewport
Fixes #8187

This properly handles the scenario with our `read_text` C API when the
selection start is outside the viewport. Previously we'd report null (no
text) which would cascade into things like the right click menu not
showing a copy option.
2025-08-19 14:10:51 -07:00
Mitchell Hashimoto 5745f5048c
Configurable right click behavior (#8254)
This MR addresses #4404 following the approach suggested
[here](https://github.com/ghostty-org/ghostty/issues/4404#issuecomment-2708410143).
Implementing the behavior known e.g. from Putty or Windows Terminal.

The following configuration values for `right-click-action` are
provided:
* `context-menu` - Show the context menu.
* `paste` - Paste the contents of the clipboard.
* `copy` - Copy the selected text to the clipboard.
* `copy-and-paste` - Copy the selected text to the clipboard, paste if
nothing is selected.
*  `ignore` - Do nothing, ignore the right-click.

I followed #5935 for getting an idea on where to start. I hope this to
be a temporary solution until "bindable mouse bindings" are introduced.

This is my first time writing Zig code, so I am happy to incorporate any
feedback.

Thank you all very much for your work!
2025-08-19 13:21:12 -07:00
Mitchell Hashimoto f2de485cae
gtk-ng: attach surface size callbacks AFTER realize (#8287)
The `gdk.Surface` is only ever available *after* the window had been
first presented and mapped. Trying to get the surface during `init` like
what we had previously done will **always** return null.
2025-08-19 12:36:23 -07:00
Mitchell Hashimoto 33b1c969d7
Fix PageList Reflow OOM Conditions (#8277)
Previously, when encountering an OOM when copying graphemes, hyperlinks,
or styles to a new page during reflow, the attempted resolution was to
copy the current row in to a new page and continue on- which works in
99% of cases, but isn't sound, since it's possible for a single row to
exceed the capacity on any of these.

This led to rare but real crashes like #8009.

I've added tests that produce all of the failure conditions, and
resolved them by changing the strategy from making a new page to
increasing the capacity of the current one.

There should probably be some level of abstraction added around this,
since multiple places in the code now do this sort of thing- attempt to
add some managed memory to a page, adjusting their capacity upwards as
necessary. But for now, I kept it all inline here.
2025-08-19 12:30:53 -07:00
Luzian Bieri 54b7e1838c feat: add right-click action configuration 2025-08-19 21:29:52 +02:00
Leah Amelia Chen 7977b3695a
gtk-ng: attach surface size callbacks AFTER realize
The `gdk.Surface` is only ever available *after* the window had been
first presented and mapped. Trying to get the surface during `init`
like what we had previously done will **always** return null.
2025-08-20 03:29:15 +08:00
Mitchell Hashimoto b3f68f6653
gtk-ng: fix toggle_window_decoration (#8286)
When window-decoration=none, setting the window decoration to null would
just mean it would default to none again, creating a cycle of torment
none can break out of... that sounds a bit too dramatic doesn't it

Fixes #8274
2025-08-19 12:27:38 -07:00
Mitchell Hashimoto b65b42a5fa
zsh: minor shell integration improvements (#8281)
- test `setupZsh`
- clean up `_ghostty_file` in the early exit path
- improve some `.zshenv` comments
2025-08-19 12:07:24 -07:00
Mitchell Hashimoto 27c2babae1
config: fix accidental codeblock indents (#8284)
In our webgen we treat 4 consecutive spaces as a code block, which is
often triggered by mistake when a paragraph is encased within a list.

We should probably fix this more thoroughly at some point since I don't
think actual Markdown parsers have the same behavior, but for now we
just fall back to using 3-space indents.

As an example of this occurring on the tip website:
<img width="1177" height="1012" alt="paragraphs being erroneously turned
into code blocks"
src="https://github.com/user-attachments/assets/878a8c83-3e37-41b7-90d9-fbd5b692bf16"
/>
2025-08-19 12:06:44 -07:00
Leah Amelia Chen f3d8aac1e9
gtk-ng: fix toggle_window_decoration
When window-decoration=none, setting the window decoration to null would
just mean it would default to none again, creating a cycle of torment
none can break out of... that sounds a bit too dramatic doesn't it

Fixes #8274
2025-08-20 03:06:12 +08:00
Leah Amelia Chen 2421132d80
config: fix accidental codeblock indents
In our webgen we treat 4 consecutive spaces as a code block, which is
often triggered by mistake when a paragraph is encased within a list.

We should probably fix this more thoroughly at some point since I don't
think actual Markdown parsers have the same behavior, but for now we
just fall back to using 3-space indents.
2025-08-20 02:37:38 +08:00
Jon Parise 8300512a91 zsh: clarify that an unset ZDOTDIR defaults to HOME
This fixes the incorrect comment and uses $HOME (rather than ~) to be a
little bit more explicit.

Also, our script is named ghostty-integration, not ghostty.zsh, so
update that part of the comment, too.
2025-08-19 10:41:47 -04:00
Jon Parise e8a60a375c zsh: unset _ghostty_file in the early exit path
If we're running a too-old version of zsh, we exit early. This skipped
the _ghostty_file cleanup path below.
2025-08-19 10:36:26 -04:00
Jon Parise f430c03ff3 zsh: add tests for setupZsh 2025-08-19 10:35:05 -04:00
Qwerasd a53ec1e567 PageList: increase capacity for style OOM during reflow 2025-08-18 19:18:20 -06:00
Qwerasd ac308b0418 test(PageList): add failing test for reflow style OOM 2025-08-18 19:18:20 -06:00
Qwerasd 15aa9df051 PageList: increase capacity for grapheme OOM during reflow 2025-08-18 18:49:33 -06:00
Qwerasd 3fcfc34ef7 test(PageList): add failing test for reflow grapheme OOM 2025-08-18 18:39:10 -06:00
Qwerasd c105d70c73 PageList: increase capacity for hyperlink OOM during reflow
It's possible for the hyperlink or string capacity to be exceeded in a
single row, in which case it doesn't matter if we move the row to a new
page, it will still be a problem. This was causing actual crashes under
some circumstances.
2025-08-18 18:30:50 -06:00
Qwerasd 61fc290ad1 test(PageList): add failing test for reflow hyperlink OOM 2025-08-18 18:27:28 -06:00
Mitchell Hashimoto 6fdaf21b82
BitmapAllocator Fixes/Improvements (#8276)
Improves the bitmap allocator's handling of allocations that are 64
chunks or more.

Previously, an allocation of exactly 64 chunks could not be freed, it
slipped through a crack in the logic and caused `free` to do nothing.

Also, >64 chunk allocations no longer always start at bitmap starts,
they can now start partway through a bitmap. If this had been fixed
before, it would have exposed a memory corruption issue in `free`, since
freeing such an allocation with the old logic would have fully cleared
its starting bitmap regardless of the starting point.

Adds a bunch of tests to exercise edge cases for free.

I didn't benchmark these changes, but I have a feeling that if there's a
performance difference it will be an improvement, since `free` now marks
more efficiently I believe (it was doing one bit at a time before), and
`findFreeChunks` now uses `clz` and `ctz` (on inverted versions of the
bitmaps).

Also, looking more closely as I type this, the old logic in
`findFreeChunks` may have had a potential corruption issue as well,
which could have allowed >64 chunk allocations to overlap the starts of
following allocations. I guess we didn't see it in the wild because our
chunk sizes are chosen in a way which would generally avoid >64 chunk
allocations in the VAST majority of cases.
2025-08-18 17:17:56 -07:00
Qwerasd 6d7982c8ca bitmap_allocator: improve/fix `free`
This previously had logic in it that was very wrong and could lead to
memory corruption or a failure to properly mark data as freed.

Also introduces a bunch of tests for various edge case behavior.
2025-08-18 17:52:10 -06:00
Qwerasd 058a91d217 bitmap_allocator: improve findFreeChunks for spans >64
This allows them to be packed more efficiently, rather than always
starting at a bitmap start.
2025-08-18 17:39:46 -06:00
Mitchell Hashimoto d8842b933b
gtk-ng: use virtual methods to draw the inspector (#8237)
Insead of signals between the ImGui widget and the Inspector widget,
make the Inspector widget a subclass of the ImGui widget and use virtual
methods to handle setup and rendering of the Inspector.
2025-08-18 10:00:44 -07:00
Mitchell Hashimoto 675ba0e9b8
apprt/gtk-ng: defineVirtualMethod helper 2025-08-18 09:58:51 -07:00
Jeffrey C. Ollie 1693c9a2ac gtk-ng: add some better comments on why getClass works 2025-08-18 09:20:40 -07:00
Jeffrey C. Ollie 34d10db7ea gtk-ng: remove some woefully naive musings on GObject memory layout 2025-08-18 09:20:40 -07:00
Jeffrey C. Ollie 23b3adedc3 gtk-ng: remove signals from imgui_widget 2025-08-18 09:20:40 -07:00
Jeffrey C. Ollie dd072d2e01 gtk-ng: add some initial notes on memory layout of GObjects 2025-08-18 09:20:40 -07:00
Jeffrey C. Ollie f147a89b68 gtk-ng: use gitlab permalinks 2025-08-18 09:20:40 -07:00
Jeffrey C. Ollie 38e69b2e96 gtk-ng: use virtual methods to draw the inspector
Insead of signals between the ImGui widget and the Inspector widget,
make the Inspector widget a subclass of the ImGui widget and use virtual
methods to handle setup and rendering of the Inspector.
2025-08-18 09:20:40 -07:00
Mitchell Hashimoto 936577c581
Update iTerm2 colorschemes (#8259)
Upstream revision:
8b639f0c26
2025-08-18 09:15:47 -07:00
Leah Amelia Chen 0f7b559f0f
gtk-ng: fix race condition when checking border bell feature (#8267) 2025-08-18 10:56:06 +08:00
Jeffrey C. Ollie 7f8d215955
gtk-ng: fix race condition when checking border bell feature
Fixes #8266

When a surface is first created, there's a race condition between when
the config is set on the surface and when the code to check if a border
should be drawn around the surface is run. Fix that by exiting early if
the bell isn't ringing, before we check to see if there's a config set
on the surface and issuing the warning message.
2025-08-17 21:32:39 -05:00
Jacob Sandlund 8f0785e90a is_emoji_presentation 2025-08-17 21:33:37 -04:00
Jacob Sandlund 0b7ab006e9 nix and flatpak updates 2025-08-17 21:27:59 -04:00
Jacob Sandlund e84d8535f5 removing all ziglyph imports (aside from unicode/grapheme.zig) 2025-08-17 21:24:27 -04:00
Jacob Sandlund 1abc9b5e41 `array` 2025-08-17 19:05:40 -04:00
Jacob Sandlund 0979ea3371 Merge remote-tracking branch 'upstream/main' into jacob/uucode 2025-08-17 18:41:21 -04:00
Mitchell Hashimoto 02a942cf72
deps: update z2d to 0.7.1 tagged release (#8265)
This release contains performance and memory use improvements.

Some of the sprite font test renders had to be updated due to very minor
differences in the anti-aliasing, since the default anti-aliasing method
in z2d has been changed to MSAA rather than SSAA.
2025-08-17 15:38:32 -07:00
Qwerasd 2a9ba56cdc deps: update z2d to 0.7.1 tagged release
This release contains performance and memory use improvements.

Some of the sprite font test renders had to be updated due to very minor
differences in the anti-aliasing, since the default anti-aliasing method
in z2d has been changed to MSAA rather than SSAA.
2025-08-17 14:00:20 -06:00
mitchellh 324d92ea31 deps: Update iTerm2 color schemes 2025-08-17 00:15:25 +00:00
Luzian Bieri 933543a0d2 refactor: extract clipboard setting logic into `copySelectionToClipboards` function 2025-08-15 23:20:43 +02:00
Qwerasd 11d56235f9
Fix use-after-free in `font.Atlas.grow` (#8249)
Grow needs to allocate and might fail midway. It tries to handle this
using "undo" pattern, and restoring old state on error. But this is
exactly what steps into UAF, as, on error, both errdefer and defer are
run, and the old data is freed.

Instead, use a more robust "reservation" pattern, where we first
fallibly resrve all the resources we need, without applying any changes,
and than do the actual change once we are sure that cannot fail.
2025-08-15 13:15:23 -06:00
Qwerasd 0d4e673366 font/Atlas: add test for OOM behavior of `grow`
Similar tests should be added throughout the codebase for any function
that's supposed to gracefully handle OOM conditions. This one was added
because grow previously had a use-after-free bug under OOM, which this
would have caught.
2025-08-15 12:49:09 -06:00
Qwerasd 37ebf212d5 font/Atlas: cleanup `grow`
Reordered to form a more logical sequence of steps, cleaned up and
clarified comments, fixed invalid `appendAssumeCapacity` call which
erroneously passed `alloc`, so this compiles again.
2025-08-15 12:26:01 -06:00
Leah Amelia Chen 4f3553af5b
gtk-ng: set IM context's input-purpose as terminal (#8251) 2025-08-16 01:58:04 +08:00
Alex Kladov 4c4d3cfc3f fix UAF in grow
Grow needs to allocate and might fail midway. It tries to handle this
using "undo" pattern, and restoring old state on error. But this is
exactly what steps into UAF, as, on error, both errdefer and defer are
run, and the old data is freed.

Instead, use a more robust "reservation" pattern, where we first
fallibly resrve all the resources we need, without applying any changes,
and than do the actual change once we are sure that cannot fail.
2025-08-15 18:45:01 +01:00
Leah Amelia Chen 5d19b24776
gtk-ng: refactor CSD/SSD style class settings (#8250) 2025-08-16 01:39:24 +08:00
Leah Amelia Chen ed603b07a5
gtk-ng: set IM context's input-purpose as terminal
See https://github.com/ghostty-org/ghostty/issues/7987#issuecomment-3187597026
2025-08-16 01:35:45 +08:00
Leah Amelia Chen 11ecb516d4
gtk-ng: refactor CSD/SSD style class settings
Fixes #8127
2025-08-16 01:19:18 +08:00
Mitchell Hashimoto 0930b2daff
apprt/gtk-ng: actually handle color scheme events (#8248)
Fixes #8245

Verified behavior before and after, also tested under Valgrind (was
curious because of the config change).
2025-08-15 09:42:17 -07:00
Mitchell Hashimoto 4bcaac50f2
apprt/gtk-ng: actually handle color scheme events
Fixes #8245
2025-08-15 09:38:03 -07:00
Mitchell Hashimoto ed9415c659
apprt/gtk-ng: respect window-inherit-working-directory=false (#8247)
Fixes #8244
2025-08-15 09:27:15 -07:00
Mitchell Hashimoto 997e013d7e
apprt/gtk-ng: respect window-inherit-working-directory=false
Fixes #8244
2025-08-15 09:18:28 -07:00
Mitchell Hashimoto 5b4baee9fa
renderer: don't assume non-zero sized grid (#8246)
Fixes #8243

This adds a check for a zero-sized grid in cursor-related functions.

As an alternate approach, I did look into simply skipping a bunch of
work on zero-sized grids, but that looked like a scarier change to make
now. That may be the better long-term solution but this was an easily
unit testable, focused fix on the crash to start.
2025-08-15 09:07:22 -07:00
Mitchell Hashimoto 30c95f3bbb
ci: switch to debian 13 (#8238) 2025-08-15 09:01:44 -07:00
Mitchell Hashimoto 9ccc02b131
renderer: don't assume non-zero sized grid
Fixes #8243

This adds a check for a zero-sized grid in cursor-related functions.

As an alternate approach, I did look into simply skipping a bunch of
work on zero-sized grids, but that looked like a scarier change to make
now. That may be the better long-term solution but this was an easily
unit testable, focused fix on the crash to start.
2025-08-15 08:59:24 -07:00
Jeffrey C. Ollie 63869d8e37
ci: switch to debian 13 2025-08-14 22:42:26 -05:00
Mitchell Hashimoto 4e26bb65ae
apprt/gtk-ng: implement `maximize` and `fullscreen` (#8236)
These fell through the cracks.
2025-08-14 15:06:50 -07:00
Mitchell Hashimoto 6b1dd3e441
apprt/gtk-ng: implement `maximize` and `fullscreen`
These fell through the cracks.
2025-08-14 15:01:03 -07:00
Mitchell Hashimoto 264dbf9e46
apprt: make gtk-ng the default apprt on Linux (#8235)
The journey to rewrite our legacy GTK backend to a full GObject-based
backend is complete! The full background and motivation can be found in
the original PR: #7961. ~75 PRs later, we've reached **full parity**
with the legacy GTK backend.

Throughout the process, we've tested every feature under Valgrind, and
this build is fully clean of memory leaks and undefined access. Its
impossible to test the existing GTK backend because its full of false
positives, but based on my experience working on `-ng`, I think its
impossible we got it right. This isn't a dig at any of our GTK subsystem
maintainers; I've simply found its very complicated to get all the
memory management behaviors right with GTK. There are subtle, easy to
miss, weakly documented things, such as [clearing weak refs on
dispose](7548dcfe63).[^1]
The point is, **gtk-ng is much higher quality than legacy.**

There is only regression we know of (#8208). I'm willing to swap the
default despite this because the improvements not just in memory safety
but also behavior: splits now support spatial navigation, better
equalization behavior, etc.

At this point, I think we should swap the default to see if we missed
anything else.

[^1]: This isn't a dig at Gnome developers either. Documenting these
details is hard, too.
2025-08-14 14:05:16 -07:00
Mitchell Hashimoto a148adc5e4
apprt: make gtk-ng the default apprt on Linux 2025-08-14 12:43:15 -07:00
Mitchell Hashimoto b7913f09ad
gtk-ng: add a helper for creating GTK actions (#8228)
- Reduces boilerplate.
- Adds type safety.
- Adds comptime checks for action and group names which
  otherwise could cause panics at runtime.
2025-08-14 12:26:39 -07:00
Mitchell Hashimoto 4740242bb9
fix(renderer/generic): deinit render targets with framestate (#8234)
This was a memory leak under Metal, leaked 1 swapchain worth of targets
every time a surface was closed.

Under OpenGL I think it was all cleaned up when the GL context was
destroyed.
2025-08-14 11:52:48 -07:00
Qwerasd add7f762a6 fix(renderer/generic): deinit render targets with framestate
This was a memory leak under Metal, leaked 1 swapchain worth of targets
every time a surface was closed.

Under OpenGL I think it was all cleaned up when the GL context was
destroyed.
2025-08-14 11:47:05 -06:00
Jeffrey C. Ollie d251695fa2
gtk-ng: move actions helper to namespace 2025-08-14 12:23:14 -05:00
Jeffrey C. Ollie 0e3ec24d2c
gtk-ng: use action helper in surface 2025-08-14 12:22:42 -05:00
Jeffrey C. Ollie 6b690e6b4e
gtk-ng: use action helper in split-tree 2025-08-14 12:22:42 -05:00
Jeffrey C. Ollie 31c71c6c5a
gtk-ng: use action helper in tab 2025-08-14 12:22:39 -05:00
Jeffrey C. Ollie d66212dcce
gtk-ng: use action helper in window 2025-08-14 12:21:52 -05:00
Jeffrey C. Ollie a10b95f052
gtk-ng: use action helper in application 2025-08-14 12:21:51 -05:00
Jeffrey C. Ollie 96e252872f
gtk-ng: add a helper for creating GTK actions
- Reduces boilerplate.
- Adds type safety.
- Adds comptime checks for action and group names which
  otherwise could cause panics at runtime.
2025-08-14 12:21:51 -05:00
Mitchell Hashimoto 000efba31c
apprt/gtk-ng: clean up close handling of all types (#8233)
This cleans up our close handling of all types (surfaces, tabs,
windows). Surfaces no longer emit their scope; their scope is always
just the surface itself. For tab and window scope we use widget actions.

This makes `close_tab` work properly (previously broken).
2025-08-14 10:20:55 -07:00
Mitchell Hashimoto 83d1bdcfcb
apprt/gtk-ng: clean up close handling of all types
This cleans up our close handling of all types (surfaces, tabs, windows).
Surfaces no longer emit their scope; their scope is always just the
surface itself. For tab and window scope we use widget actions.

This makes `close_tab` work properly (previously broken).
2025-08-14 10:07:28 -07:00
Mitchell Hashimoto 3eda14e2d6
gtk-ng: port the terminal inspector (#8212)
This is a (relatively) straightforward port of the terminal inspector
from the old GTK application runtime. It's split into three widgets. At
the lowest level is a widget designed for showing a generic Dear ImGui
application. Above that is a widget that embeds the ImGui widget and
plumbs it into the core Inspector. At the top is a custom Window widget
that embeds the Inspector widget.

And then there's all the plumbing necessary to hook everything into the
rest of Ghostty.

In theory this design _should_ allow showing the Inspector in a split or
a tab in the future, not just in a separate window. It should also make
it easier to display _other_ Dear ImGui applications if they are ever
needed.
2025-08-14 09:47:09 -07:00
Mitchell Hashimoto 68f337e398
apprt/gtk-ng: close inspector window when widget loses surface 2025-08-14 09:42:26 -07:00
Mitchell Hashimoto 7548dcfe63
apprt/gtk-ng: clear weakrefs on dispose 2025-08-14 09:31:14 -07:00
Mitchell Hashimoto 76d84ff35c
valgrind supps 2025-08-14 09:27:14 -07:00
Mitchell Hashimoto 6280bd7a42
apprt/gtk-ng: far less control inspector complexity 2025-08-14 08:57:11 -07:00
Mitchell Hashimoto 3fc33089f3
apprt/gtk-ng: clean up a bunch of unused window stuff 2025-08-14 08:37:58 -07:00
Mitchell Hashimoto 48a65b05d0
apprt/gtk-ng: use a weak_ref on surface for inspector 2025-08-14 08:21:19 -07:00
Mitchell Hashimoto 43550c18c0
apprt/gtk-ng: imguiwidget uses signals instead of callbacks 2025-08-14 08:21:19 -07:00
Jeffrey C. Ollie bd7177a924 gtk-ng: port the terminal inspector
This is a (relatively) straightforward port of the terminal inspector
from the old GTK application runtime. It's split into three widgets. At
the lowest level is a widget designed for showing a generic Dear ImGui
application. Above that is a widget that embeds the ImGui widget and
plumbs it into the core Inspector. At the top is a custom Window widget
that embeds the Inspector widget.

And then there's all the plumbing necessary to hook everything into the
rest of Ghostty.

In theory this design _should_ allow showing the Inspector in a split
or a tab in the future, not just in a separate window. It should also
make it easier to display _other_ Dear ImGui applications if they are
ever needed.
2025-08-14 08:21:19 -07:00
Mitchell Hashimoto 57f1033198
gtk-ng: parametrize the new-split action (#8225)
why four when one do trick
2025-08-14 08:19:18 -07:00
Leah Amelia Chen 0979e6d2e9 gtk-ng: parametrize the new-split action
why four when one do trick
2025-08-14 08:17:01 -07:00
Mitchell Hashimoto b57f1815a4
apprt/gtk-ng: set cursor on Surface widget, not GL area (#8227)
This fixes `mouse-hide-while-typing`. Don't know why this worked before
(I tested it yesterday!) but stopped working today. But this now works,
and conceptually makes some sense.
2025-08-13 15:44:31 -07:00
Mitchell Hashimoto 997d38c362
apprt/gtk-ng: set cursor on Surface widget, not GL area
This fixes `mouse-hide-while-typing`. Don't know why this worked before
(I tested it yesterday!) but stopped working today. But this now works,
and conceptually makes some sense.
2025-08-13 15:21:08 -07:00
Leah Amelia Chen 92d6395a8d
gtk-ng: show on-screen keyboard on LMB release (#8224) 2025-08-14 05:00:17 +08:00
Leah Amelia Chen 1b1264e592
gtk-ng: only show OSD when mouse event isn't consumed 2025-08-14 04:06:02 +08:00
Leah Amelia Chen 23048dbd33
gtk-ng: add show_on_screen_keyboard binding 2025-08-14 04:06:02 +08:00
Leah Amelia Chen 0d0d3118f4
gtk-ng: show on-screen keyboard on LMB release
This aligns with VTE behavior when the on-screen keyboard is enabled in
GNOME's accessibility settings.

Closes #7987
2025-08-14 03:08:34 +08:00
Mitchell Hashimoto 5e3bd92c57
apprt/gtk-ng: prompt surface title (#8223)
Straightforward port. A hell of a lot cleaner with `-ng`.
2025-08-13 10:53:12 -07:00
Mitchell Hashimoto ad781ee9cd
gtk-ng add border to bell features (#8222) 2025-08-13 10:52:56 -07:00
Mitchell Hashimoto 8edc041eaf
apprt/gtk-ng: prompt surface title 2025-08-13 10:49:16 -07:00
Jeffrey C. Ollie 22fc90fd55
gtk-ng add border to bell features 2025-08-13 12:18:07 -05:00
Mitchell Hashimoto a843929d5a
apprt/gtk-ng: bell (#8221)
Supersedes #8129

This is a rewrite but I did take pieces of #8129. I dropped the new
feature that was mixed into the PR because I'm trying not to introduce
new features in `-ng` right now. Feel free to PR that separately
@jcollie. I also dropped some of the action group validation stuff which
admittedly would be nice, so also happy to add that.

A big change I made here is we don't need to expose `bell-features` from
surface, because we can use the relevant config that we have access to.
I passed the config as a closure parameter so it recomputes when config
changes, too.

I also fixed a bug I found where we'd lose computed titles on
non-focused tabs because `active-surface` would start returning null
(since none are focused there). We now fallback to the active surface
being the _last focused_ surface if no focused surface exists, which
matches the behavior we also have on macOS.
2025-08-13 09:29:21 -07:00
Mitchell Hashimoto 6de98eda04
apprt/gtk-ng: audio bell
Co-authored-by: Jeffrey C. Ollie <jcollie@dmacc.edu>
2025-08-13 09:22:51 -07:00
Mitchell Hashimoto d8a309c734
apprt/gtk-ng: split tree active focus should be last focused fallback
Co-authored-by: Jeffrey C. Ollie <jcollie@dmacc.edu>
2025-08-13 09:22:49 -07:00
Mitchell Hashimoto 3680c8637e
apprt/gtk-ng: tab attention for bell
Co-authored-by: Jeffrey C. Ollie <jcollie@dmacc.edu>
2025-08-13 09:22:45 -07:00
Mitchell Hashimoto d37e3828a2
apprt/gtk-ng: win.ring-bell
Co-authored-by: Jeffrey C. Ollie <jcollie@dmacc.edu>
2025-08-13 09:22:39 -07:00
Mitchell Hashimoto 408ec24165
apprt/gtk-ng: hook up bell into title
Co-authored-by: Jeffrey C. Ollie <jcollie@dmacc.edu>
2025-08-13 09:22:35 -07:00
Mitchell Hashimoto 40427b06c7
apprt/gtk-ng: surface bell-ringing property
Co-authored-by: Jeffrey C. Ollie <jcollie@dmacc.edu>
2025-08-13 09:22:16 -07:00
Jacob Sandlund 341137ce2e case folding 2025-08-13 09:56:05 -04:00
Mitchell Hashimoto f1d55468dd
apprt/gtk-ng: tab tooltips, window-subtitle, split zoom title prefix (#8218)
This brings together all our title-related functionality (so far).

To make this all work, I heavily use (abuse?) blueprint bindings with
closures. Blueprint sets up property subscription for all closure
parameters and all properties in a chain (`a.b.c`). This makes for a
really long, deeply nested property access but it saves us literally
hundreds (at least 100) lines of `notify` signal subscription
boilerplate.

This also lets some of these properties be truly dynamic and avoid
simply copying around intermediate values up the widget tree.

Unfortunately Blueprint's auto-formatter won't let us split property
access or function parameters onto separate lines so we're going to have
some very, very long lines.
2025-08-13 06:18:52 -07:00
Mitchell Hashimoto 798e872f48
apprt/gtk-ng: split zoom title 2025-08-12 15:45:59 -07:00
Mitchell Hashimoto 12bc0d7b10
apprt/gtk-ng: window-subtitle 2025-08-12 15:23:47 -07:00
Mitchell Hashimoto 502040c86a
apprt/gtk-ng: tab tooltips match our pwd 2025-08-12 15:02:23 -07:00
Mitchell Hashimoto aa4cbf444b
apprt/gtk-ng: forgot to register a prop 2025-08-12 13:45:33 -07:00
Mitchell Hashimoto bede3d8011
apprt/gtk-ng: split zoom (#8217)
This makes `toggle_split_zoom` work via a new widget action
`split-tree.zoom`. The zoom state is tracked on the core `SplitTree`
data structure. Zoom state is propagated via a `is-zoomed` property on
the split tree in GTK.

I deferred the title changes since I can do that all at once with
subtitle and other things.
2025-08-12 13:43:44 -07:00
Mitchell Hashimoto f130a724e5
apprt/gtk-ng: track is-zoomed property on surface tree 2025-08-12 13:39:38 -07:00
Mitchell Hashimoto fb846b669c
split_tree: convert Handle to enum 2025-08-12 13:34:35 -07:00
Mitchell Hashimoto 145d1c1739
split_tree: track zoomed state 2025-08-12 13:08:04 -07:00
Mitchell Hashimoto dfabb8aa4f
build(deps): bump actions/checkout from 4.2.2 to 5.0.0 (#8213)
Bumps [actions/checkout](https://github.com/actions/checkout) from 4.2.2
to 5.0.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/checkout/releases">actions/checkout's
releases</a>.</em></p>
<blockquote>
<h2>v5.0.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Update actions checkout to use node 24 by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2226">actions/checkout#2226</a></li>
<li>Prepare v5.0.0 release by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2238">actions/checkout#2238</a></li>
</ul>
<h2>⚠️ Minimum Compatible Runner Version</h2>
<p><strong>v2.327.1</strong><br />
<a
href="https://github.com/actions/runner/releases/tag/v2.327.1">Release
Notes</a></p>
<p>Make sure your runner is updated to this version or newer to use this
release.</p>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/checkout/compare/v4...v5.0.0">https://github.com/actions/checkout/compare/v4...v5.0.0</a></p>
<h2>v4.3.0</h2>
<h2>What's Changed</h2>
<ul>
<li>docs: update README.md by <a
href="https://github.com/motss"><code>@​motss</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1971">actions/checkout#1971</a></li>
<li>Add internal repos for checking out multiple repositories by <a
href="https://github.com/mouismail"><code>@​mouismail</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1977">actions/checkout#1977</a></li>
<li>Documentation update - add recommended permissions to Readme by <a
href="https://github.com/benwells"><code>@​benwells</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2043">actions/checkout#2043</a></li>
<li>Adjust positioning of user email note and permissions heading by <a
href="https://github.com/joshmgross"><code>@​joshmgross</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2044">actions/checkout#2044</a></li>
<li>Update README.md by <a
href="https://github.com/nebuk89"><code>@​nebuk89</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2194">actions/checkout#2194</a></li>
<li>Update CODEOWNERS for actions by <a
href="https://github.com/TingluoHuang"><code>@​TingluoHuang</code></a>
in <a
href="https://redirect.github.com/actions/checkout/pull/2224">actions/checkout#2224</a></li>
<li>Update package dependencies by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2236">actions/checkout#2236</a></li>
<li>Prepare release v4.3.0 by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2237">actions/checkout#2237</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/motss"><code>@​motss</code></a> made
their first contribution in <a
href="https://redirect.github.com/actions/checkout/pull/1971">actions/checkout#1971</a></li>
<li><a href="https://github.com/mouismail"><code>@​mouismail</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/checkout/pull/1977">actions/checkout#1977</a></li>
<li><a href="https://github.com/benwells"><code>@​benwells</code></a>
made their first contribution in <a
href="https://redirect.github.com/actions/checkout/pull/2043">actions/checkout#2043</a></li>
<li><a href="https://github.com/nebuk89"><code>@​nebuk89</code></a> made
their first contribution in <a
href="https://redirect.github.com/actions/checkout/pull/2194">actions/checkout#2194</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/checkout/pull/2236">actions/checkout#2236</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/checkout/compare/v4...v4.3.0">https://github.com/actions/checkout/compare/v4...v4.3.0</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/actions/checkout/blob/main/CHANGELOG.md">actions/checkout's
changelog</a>.</em></p>
<blockquote>
<h1>Changelog</h1>
<h2>V5.0.0</h2>
<ul>
<li>Update actions checkout to use node 24 by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2226">actions/checkout#2226</a></li>
</ul>
<h2>V4.3.0</h2>
<ul>
<li>docs: update README.md by <a
href="https://github.com/motss"><code>@​motss</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1971">actions/checkout#1971</a></li>
<li>Add internal repos for checking out multiple repositories by <a
href="https://github.com/mouismail"><code>@​mouismail</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1977">actions/checkout#1977</a></li>
<li>Documentation update - add recommended permissions to Readme by <a
href="https://github.com/benwells"><code>@​benwells</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2043">actions/checkout#2043</a></li>
<li>Adjust positioning of user email note and permissions heading by <a
href="https://github.com/joshmgross"><code>@​joshmgross</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2044">actions/checkout#2044</a></li>
<li>Update README.md by <a
href="https://github.com/nebuk89"><code>@​nebuk89</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2194">actions/checkout#2194</a></li>
<li>Update CODEOWNERS for actions by <a
href="https://github.com/TingluoHuang"><code>@​TingluoHuang</code></a>
in <a
href="https://redirect.github.com/actions/checkout/pull/2224">actions/checkout#2224</a></li>
<li>Update package dependencies by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/2236">actions/checkout#2236</a></li>
</ul>
<h2>v4.2.2</h2>
<ul>
<li><code>url-helper.ts</code> now leverages well-known environment
variables by <a href="https://github.com/jww3"><code>@​jww3</code></a>
in <a
href="https://redirect.github.com/actions/checkout/pull/1941">actions/checkout#1941</a></li>
<li>Expand unit test coverage for <code>isGhes</code> by <a
href="https://github.com/jww3"><code>@​jww3</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1946">actions/checkout#1946</a></li>
</ul>
<h2>v4.2.1</h2>
<ul>
<li>Check out other refs/* by commit if provided, fall back to ref by <a
href="https://github.com/orhantoy"><code>@​orhantoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1924">actions/checkout#1924</a></li>
</ul>
<h2>v4.2.0</h2>
<ul>
<li>Add Ref and Commit outputs by <a
href="https://github.com/lucacome"><code>@​lucacome</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1180">actions/checkout#1180</a></li>
<li>Dependency updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>- <a
href="https://redirect.github.com/actions/checkout/pull/1777">actions/checkout#1777</a>,
<a
href="https://redirect.github.com/actions/checkout/pull/1872">actions/checkout#1872</a></li>
</ul>
<h2>v4.1.7</h2>
<ul>
<li>Bump the minor-npm-dependencies group across 1 directory with 4
updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1739">actions/checkout#1739</a></li>
<li>Bump actions/checkout from 3 to 4 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1697">actions/checkout#1697</a></li>
<li>Check out other refs/* by commit by <a
href="https://github.com/orhantoy"><code>@​orhantoy</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1774">actions/checkout#1774</a></li>
<li>Pin actions/checkout's own workflows to a known, good, stable
version. by <a href="https://github.com/jww3"><code>@​jww3</code></a> in
<a
href="https://redirect.github.com/actions/checkout/pull/1776">actions/checkout#1776</a></li>
</ul>
<h2>v4.1.6</h2>
<ul>
<li>Check platform to set archive extension appropriately by <a
href="https://github.com/cory-miller"><code>@​cory-miller</code></a> in
<a
href="https://redirect.github.com/actions/checkout/pull/1732">actions/checkout#1732</a></li>
</ul>
<h2>v4.1.5</h2>
<ul>
<li>Update NPM dependencies by <a
href="https://github.com/cory-miller"><code>@​cory-miller</code></a> in
<a
href="https://redirect.github.com/actions/checkout/pull/1703">actions/checkout#1703</a></li>
<li>Bump github/codeql-action from 2 to 3 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1694">actions/checkout#1694</a></li>
<li>Bump actions/setup-node from 1 to 4 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1696">actions/checkout#1696</a></li>
<li>Bump actions/upload-artifact from 2 to 4 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1695">actions/checkout#1695</a></li>
<li>README: Suggest <code>user.email</code> to be
<code>41898282+github-actions[bot]@users.noreply.github.com</code> by <a
href="https://github.com/cory-miller"><code>@​cory-miller</code></a> in
<a
href="https://redirect.github.com/actions/checkout/pull/1707">actions/checkout#1707</a></li>
</ul>
<h2>v4.1.4</h2>
<ul>
<li>Disable <code>extensions.worktreeConfig</code> when disabling
<code>sparse-checkout</code> by <a
href="https://github.com/jww3"><code>@​jww3</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1692">actions/checkout#1692</a></li>
<li>Add dependabot config by <a
href="https://github.com/cory-miller"><code>@​cory-miller</code></a> in
<a
href="https://redirect.github.com/actions/checkout/pull/1688">actions/checkout#1688</a></li>
<li>Bump the minor-actions-dependencies group with 2 updates by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1693">actions/checkout#1693</a></li>
<li>Bump word-wrap from 1.2.3 to 1.2.5 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/actions/checkout/pull/1643">actions/checkout#1643</a></li>
</ul>
<h2>v4.1.3</h2>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="08c6903cd8"><code>08c6903</code></a>
Prepare v5.0.0 release (<a
href="https://redirect.github.com/actions/checkout/issues/2238">#2238</a>)</li>
<li><a
href="9f265659d3"><code>9f26565</code></a>
Update actions checkout to use node 24 (<a
href="https://redirect.github.com/actions/checkout/issues/2226">#2226</a>)</li>
<li><a
href="08eba0b27e"><code>08eba0b</code></a>
Prepare release v4.3.0 (<a
href="https://redirect.github.com/actions/checkout/issues/2237">#2237</a>)</li>
<li><a
href="631c7dc4f8"><code>631c7dc</code></a>
Update package dependencies (<a
href="https://redirect.github.com/actions/checkout/issues/2236">#2236</a>)</li>
<li><a
href="8edcb1bdb4"><code>8edcb1b</code></a>
Update CODEOWNERS for actions (<a
href="https://redirect.github.com/actions/checkout/issues/2224">#2224</a>)</li>
<li><a
href="09d2acae67"><code>09d2aca</code></a>
Update README.md (<a
href="https://redirect.github.com/actions/checkout/issues/2194">#2194</a>)</li>
<li><a
href="85e6279cec"><code>85e6279</code></a>
Adjust positioning of user email note and permissions heading (<a
href="https://redirect.github.com/actions/checkout/issues/2044">#2044</a>)</li>
<li><a
href="009b9ae9e4"><code>009b9ae</code></a>
Documentation update - add recommended permissions to Readme (<a
href="https://redirect.github.com/actions/checkout/issues/2043">#2043</a>)</li>
<li><a
href="cbb722410c"><code>cbb7224</code></a>
Update README.md (<a
href="https://redirect.github.com/actions/checkout/issues/1977">#1977</a>)</li>
<li><a
href="3b9b8c884f"><code>3b9b8c8</code></a>
docs: update README.md (<a
href="https://redirect.github.com/actions/checkout/issues/1971">#1971</a>)</li>
<li>See full diff in <a
href="11bd71901b...08c6903cd8">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4.2.2&new-version=5.0.0)](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-08-12 12:30:50 -07:00
Mitchell Hashimoto 7bcb190aa8
apprt/gtk-ng: `resize_split` action (#8215)
Ports the resize split action (tied to the `resize_split` binding
action).

This also includes fixes for splits that are exactly `0` or `1` ratio
width (full width either direction). This would previously cause
crashes.
2025-08-12 12:27:26 -07:00
Mitchell Hashimoto 93da59682f
apprt/gtk-ng: resizeSplit action 2025-08-12 11:04:34 -07:00
Mitchell Hashimoto 4afd3445c4
split_tree: fix bugs for 0/1 sized ratios 2025-08-12 10:46:43 -07:00
Jacob Sandlund f5a036a6a0 update after refactor (string field config, etc) 2025-08-12 09:43:12 -04:00
Jacob Sandlund 563cfb94ba Merge remote-tracking branch 'upstream/main' into jacob/uucode 2025-08-12 09:38:19 -04:00
dependabot[bot] 8d8812cb6a
build(deps): bump actions/checkout from 4.2.2 to 5.0.0
Bumps [actions/checkout](https://github.com/actions/checkout) from 4.2.2 to 5.0.0.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](11bd71901b...08c6903cd8)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 5.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-12 08:52:43 +00:00
Mitchell Hashimoto 2bcc2fa4bd
split_tree: resize function 2025-08-11 12:52:16 -07:00
Qwerasd 5bf632e9cc
Fix up font raster position + other small fixes (#8206)
I've cleaned up the code we use for scaling and positioning glyphs for
raster, under both CoreText and FreeType. Before we had some
imprecision, and under CoreText we were sometimes stretching glyphs in
unseemly ways. These changes make it so that our constraints can
position and size glyphs *exactly* and we don't have any chopped-off
row/column issues for CoreText. With this, PowerLine Extra symbols now
always align *perfectly* with the cell height:
||Before|After|
|-:|-|-|
|**CoreText**|<img width="105" height="245" alt="image"
src="https://github.com/user-attachments/assets/d3c1b1cb-a798-4e18-a0e0-59551893369c"
/>|<img width="106" height="246" alt="image"
src="https://github.com/user-attachments/assets/dac10c49-9ec1-4f4f-8825-a5e8c2fd3402"
/>|
|**FreeType**|<img width="105" height="245" alt="image"
src="https://github.com/user-attachments/assets/160e1e35-4a3c-42d0-9042-215301e636a1"
/>|<img width="106" height="245" alt="image"
src="https://github.com/user-attachments/assets/89bf1538-7271-4baf-88c0-51ebc4d360df"
/>|

The other changes are mainly just cleanup stuff, though one of the
changes makes it so that we do once again properly apply constraints to
symbols from the dingbats block (it was a regression, noted in #7955,
that we stopped doing that).

### Future work
This has been a problem since we introduced the custom constraints, but
I noticed it while preparing the before/after images: the left-edge PLE
symbols (meant to connect to a full block on the right) expand out to
the *right*, so if they're followed immediately by another character
than they actually get squished and don't match the right-edge symbols:

<img width="75" height="114" alt="image"
src="https://github.com/user-attachments/assets/1420b9a5-9950-4210-9934-8ef7cd7a1e19"
/>

I have a WIP change to move constraint logic to the shapers, and at that
point we can maybe do something to allow the constraint to grow in to
whitespace on the left side instead of on the right side.
2025-08-11 13:44:50 -06:00
Mitchell Hashimoto a94bd8f5c4
gtk-ng: don't use signals to toggle command palette (#8182) 2025-08-11 12:02:48 -07:00
Jeffrey C. Ollie 5bb88d259c gtk-ng: use WeakRef helper for type safety 2025-08-11 11:56:08 -07:00
Jeffrey C. Ollie 2de0c108ba gtk-ng: better handling of weak references
The upstream GIR for g_weak_ref_get is incorrect - it does not allow the
returned value to be NULL. This PR pulls in a new version of our GObject
bindings with that patched and improves the safety of dealing with the
command palette weak reference held by the window.

See ianprime0509/zig-gobject#117
2025-08-11 11:56:08 -07:00
Jeffrey C. Ollie 5c088d10a4 gtk-ng: fix memory leaks in command palette 2025-08-11 11:56:08 -07:00
Jeffrey C. Ollie 3221421a74 gtk-ng: add TODOs about passing surface that toggled command palette 2025-08-11 11:56:08 -07:00
Jeffrey C. Ollie 8af1230228 gtk-ng: don't add extra refs when activating a command in the palette 2025-08-11 11:56:08 -07:00
Jeffrey C. Ollie 2a5b7aab86 gtk-ng: don't use signals to toggle command palette 2025-08-11 11:56:08 -07:00
Mitchell Hashimoto 21a9760ff5
apprt/gtk-ng: equalize splits (#8211)
Fixes known issues from #8202. Also brings in the better equalization
logic on macOS from #7710.
2025-08-11 11:39:19 -07:00
Mitchell Hashimoto 9f037a7c23
apprt/gtk-ng: equalize splits 2025-08-11 11:35:13 -07:00
Mitchell Hashimoto a21b447c75
apprt/gtk-ng: `goto_split` (including spatial navigation for the first time for our GTK backend) (#8210)
This continues #8202 by fixing two of the known issues: `goto_split` key
binds work and closing a split moves focus to the proper place.

A big improvement in this PR is that for the first time ever in our GTK
backend, the up/down/left/right `goto_split` bindings **use spatial
navigation.** "Spatial navigation" means that the direction to move
focus is done based on the nearest split _visually_ from the current
split, rather than via a tree traversal. We did this on macOS a couple
months ago, with a lot more details there: #7523

Similar to macOS, the spatial navigation is currently based on top-left
corner. Now that our split tree is implemented in Zig though it should
be a lot easier for us to work in the current cursor position as the
reference point.

~~🚧 TODO: Going to add some unit tests for the spatial navigation before
merge.~~
2025-08-11 11:04:06 -07:00
Mitchell Hashimoto 43c3150e81
split_tree: unit tests for spatial nav, fix a bug 2025-08-11 10:59:37 -07:00
Mitchell Hashimoto 5a01877c77
apprt/gtk-ng: spatial navigation 2025-08-11 10:17:13 -07:00
Mitchell Hashimoto 70d48d03a5
apprt/gtk-ng: go to right focus when split closes 2025-08-11 09:51:58 -07:00
Mitchell Hashimoto 5903d7d10f
apprt/gtk-ng: hook up goto_split 2025-08-11 09:44:13 -07:00
Mitchell Hashimoto 984435d7ea
split_tree: deepest, previous, next traversals 2025-08-11 09:30:59 -07:00
Mitchell Hashimoto 9f959ea876
gtk-ng: fix split-divider-color config (#8209) 2025-08-11 08:38:28 -07:00
Jeffrey C. Ollie b726183981
gtk-ng: fix split-divider-color config 2025-08-11 10:28:54 -05:00
Mitchell Hashimoto a9a41aec83
apprt/gtk-ng: create/close split functionality (#8202)
This adds on to our existing foundations from #8165 and adds the ability
to create and close splits. We're still missing split navigation,
resizing via keybindings, etc. And there are a number of known issues
(listed below). But this is a strict improvement from where we're at and
includes a number of important bug fixes to our split tree.

The only nasty thing in this PR is that I learned that GTK _did not
like_ rebuilding our split widget tree on every data model change. I
don't know enough about how all the re-parenting plus size allocation
interactions work together. As a compromise, this PR adds a listener,
waits for our surface tree to "settle" by having all surfaces have no
parents, then schedules a single rebuild after that. This works well,
but results in some noticeable flashing for a frame or so. I think we
can improve this later, it works completely well enough.

Importantly, all of this is Valgrind clean. I long suspected our splits
on legacy are NOT free of leaks, but never proved it, so this makes me
happy.

## Demo



https://github.com/user-attachments/assets/e231d89f-581e-486b-ade0-1d7e6795262e



## Known Issues

I may fix this in this PR, I may follow up.

- [ ] Focus doesn't go to the right place after closing a split
- [x] Divider with a transparent background is transparent
- [x] Close split doesn't show any close confirmation dialog
- Missing features:
  * [ ] Equalize splits
  * [ ] Resize splits keybind (manual mouse action works fine)
  * [ ] Go to split keybind
2025-08-11 08:25:38 -07:00
Mitchell Hashimoto edd73fa0e4
font/freetype: convert encoding of font names (#8204)
Freetype encodes some font names internally in formats other than UTF-8.
This only affects debug logs but it was annoying me so I fixed it. There
may be other encodings that might need to be dealt with but I took care
of the one that I ran across.
2025-08-10 19:55:35 -07:00
Mitchell Hashimoto dd983d112d
gtk-ng: sync action accelerators for split-tree (#8207) 2025-08-10 19:55:22 -07:00
Jeffrey C. Ollie aba5a34335
gtk-ng: sync action accelerators for split-tree 2025-08-10 21:31:50 -05:00
Qwerasd 8c7538e996 font/freetype: port improved raster logic from CoreText
We now also have absolute perfect control over the raster position under
FreeType as well. This means that, for example, powerline extended chars
are appropriately clamped to the cell edges at all sizes.

This should be purely an improvement over what we had before, and now it
also matches what we do for CoreText.
2025-08-10 19:59:52 -06:00
Jeffrey C. Ollie e9e32d71e4
font/freetype: add a test for face name decoding using embedded fonts 2025-08-10 20:10:24 -05:00
Jeffrey C. Ollie 897d70982e
font/freetype: convert encoding of font names
Freetype encodes some font names internally in formats other than UTF-8.
This only affects debug logs but it was annoying me so I fixed it. There
may be other encodings that might need to be dealt with but I took care
of the one that I ran across.
2025-08-10 17:29:31 -05:00
Qwerasd 5383cd9c9c font/freetype: pass monochrome load flag when needed
The monochrome hinter is very aggressive but makes text actually look
tolerable when rendered in monochrome. If for some god forsaken reason
we get complaints about this, that someone wanted improperly hinted mono
glyphs, we can introduce additonal configuration; but for now, this is
just a straight improvement.
2025-08-10 16:04:54 -06:00
Qwerasd 20a9a3a8c2 font: use adjusted cell width for recentering again
The old method was nice, but had an issue that's intractible without
significant reworking in how we do shaping: combining glyphs need to
position relative to the glyph they're combining with, but if we re-
center that glyph, it will be off by some amount.
2025-08-10 15:49:54 -06:00
Qwerasd 195cbb6a1c Revert "font/Metrics: remove original_cell_width, no longer needed"
This reverts commit 23cc50b12c.
2025-08-10 15:33:47 -06:00
Qwerasd f56219be95 font/coretext: fix glyph position/scale code
Apologies to Apple, the previous comments in this section of the code
were not correct-- `shouldSubpixelQuantizeFonts` does pretty much what
the minimal documentation for it says it does, it simply quantizes the
position of the glyph and nothing more. Various bugs when testing while
writing the old code that led me to include those comments made me not
realize that the positioning is actually a lot simpler than it seems.

With this version of the positioning there are never any cut-off rows or
columns of pixels on the edges of anything and everything scales as it
should... I hope. I checked pretty thoroughly this time and I'm like 99%
sure this is correct in all cases.
2025-08-10 15:11:20 -06:00
Qwerasd ee445d2915 font: compare font Index packed structs directly
Packed structs can be compared directly now, no need to convert them to
an int anymore.
2025-08-10 15:11:20 -06:00
Qwerasd a8b9dd8dfc renderer: clean up, improve constraintWidth function 2025-08-10 14:54:51 -06:00
Mitchell Hashimoto ca4e38ff03
apprt/gtk-ng: split close confirmation 2025-08-10 13:35:30 -07:00
Mitchell Hashimoto 441af8389b
apprt/gtk-ng: split separator styling 2025-08-10 13:09:06 -07:00
Mitchell Hashimoto 0aaf80402b
Update iTerm2 colorschemes (#8195)
Upstream revision:
3cbeca99ef
2025-08-10 12:52:48 -07:00
Mitchell Hashimoto 46560d0018
apprt/gtk-ng: wait for unparent to rebuild split tree 2025-08-10 12:36:28 -07:00
mitchellh c64701e744 deps: Update iTerm2 color schemes 2025-08-10 00:15:37 +00:00
Mitchell Hashimoto b1da644b62
apprt/gtk-ng: unnecessary grab focus 2025-08-09 14:48:42 -07:00
Mitchell Hashimoto e682e99bf5
apprt/gtk-ng: hook up win split actions 2025-08-09 14:36:50 -07:00
Mitchell Hashimoto aed6a3a343
apprt/gtk-ng: clean up some changed handlers 2025-08-09 14:24:25 -07:00
Mitchell Hashimoto ec293c1fd0
apprt/gtk-ng: active surface hookups 2025-08-09 13:49:36 -07:00
Mitchell Hashimoto 8232cf33b4
apprt/gtk-ng: surface close in split tree 2025-08-09 12:36:27 -07:00
Mitchell Hashimoto a28d673467
update supps 2025-08-09 12:24:40 -07:00
Mitchell Hashimoto 9ad92d2c3d
apprt/gtk-ng: proper split operations 2025-08-09 12:21:28 -07:00
Mitchell Hashimoto 34be4de018
apprt/gtk-ng: write back split ratio to tree 2025-08-09 12:19:10 -07:00
Mitchell Hashimoto e396d9d78d
apprt/gtk-ng: setup gtk paned listeners to set position 2025-08-09 07:27:11 -07:00
Mitchell Hashimoto a3c041bcb4
apprt/gtk-ng: keep track of last focused surface 2025-08-08 15:14:41 -07:00
Mitchell Hashimoto 517f17995c
apprt/gtk-ng: rebuild the widget tree on an idle callback 2025-08-08 14:38:02 -07:00
Mitchell Hashimoto fbe28477ff
datastruct: fix split tree ascii diagram 2025-08-08 14:22:38 -07:00
Mitchell Hashimoto 75dd8e46b5
datastruct: fix split tree debug log rounding 2025-08-08 14:22:38 -07:00
Mitchell Hashimoto ae5dc3a4fb
apprt/gtk-ng: split tree new split actions 2025-08-08 14:22:38 -07:00
Mitchell Hashimoto 4742177daa
apprt/gtk-ng: template callbacks can't return bool, must be c_int (#8186)
This fixes the tab bar showing the window controls sometimes.
2025-08-08 13:39:46 -07:00
Mitchell Hashimoto 5bf8f12cf0
apprt/gtk-ng: template callbacks can't return bool, must be c_int
This fixes the tab bar showing the window controls sometimes.
2025-08-08 13:36:08 -07:00
Mitchell Hashimoto 8ae72d5f7f
apprt/gtk-ng: set resize overlay label in the idle callback (#8185)
This avoids jitter when resizing splits. I didn't see any jitter before
splits but conceptually its possible. The issue is that since we're
updating the overlay DURING A RESIZE, changing the dimensions of any
part of the widget tree causes GTK warnings and a bunch of laggy
updates.

Instead, we copy the label text to a property and update it on the idle
callback along with everything else. This also provides a natural
debounce to the label.
2025-08-08 13:14:13 -07:00
Mitchell Hashimoto 8e073505f7
apprt/gtk-ng: set resize overlay label in the idle callback
This avoids jitter when resizing splits. I didn't see any jitter before
splits but conceptually its possible. The issue is that since we're
updating the overlay DURING A RESIZE, changing the dimensions of any
part of the widget tree causes GTK warnings and a bunch of laggy
updates.

Instead, we copy the label text to a property and update it on the idle
callback along with everything else. This also provides a natural
debounce to the label.
2025-08-08 12:59:54 -07:00
Mitchell Hashimoto 729b8f9c2d
apprt/gtk-ng: add proper setters for surface properties (#8184)
This also fixes a bug where we were setting custom cursors on the wrong
gtk widget, this showed up most terribly with `mouse-hide-while-typing`
where the mouse would never reappear.
2025-08-08 12:36:42 -07:00
Mitchell Hashimoto 17101294aa
gtk-ng: add "title bar styles" (#8166)
This PR adds a "tabs" title bar style similar to the macOS title bar
style. When `gtk-titlebar-style=tabs` the title bar and the tab bar will
be merged together.

The config entry for controlling this is kept separate from macOS as
macOS has more styles defined that don't map to a GTK title bar style
and it's likely that users that use both macOS and GTK would want
different settings for each platform.

<img width="922" height="722" alt="Screenshot From 2025-08-06 16-38-28"
src="https://github.com/user-attachments/assets/3c2db235-695a-457e-9c96-5039120263fc"
/>
2025-08-08 12:34:21 -07:00
Mitchell Hashimoto 16e15554da
apprt/gtk-ng: add proper setters for surface properties
This also fixes a bug where we were setting custom cursors on the wrong
gtk widget, this showed up most terribly with `mouse-hide-while-typing`
where the mouse would never reappear.
2025-08-08 12:30:22 -07:00
Jeffrey C. Ollie cae60f7c29
gtk-ng: use single if expression instead of block 2025-08-08 13:36:45 -05:00
Jeffrey C. Ollie 0f67282dfa
gtk-ng: add "title bar styles"
This PR adds a "tabs" title bar style similar to the macOS title bar
style. When `gtk-titlebar-style=tabs` the title bar and the tab bar
will be merged together.

The config entry for controlling this is kept separate from macOS as
macOS has more styles defined that don't map to a GTK title bar style
and it's likely that users that use both macOS and GTK would want
different settings for each platform.
2025-08-08 13:32:23 -05:00
Mitchell Hashimoto 2c0bb894b8
valgrind: GtkPopover suppressions (#8183)
We get a ton of leaks from GTK.PopOver when we run the steps given in
the suppression file. I don't see how this could be us since we don't
create or do anything with the popover manually; its simply defined in
the Blueprint file.

The leaks specifically only happen when a Popover shows a sub-menu.
Without that, everything is completely clean. So I actually suspect
there's some leaks in GTK related to this behavior (not sure if they're
on purpose not, a brief look at the code doesn't look like they're
reused).

I tried alternate approaches where we create the Popover AND/OR the
MenuModel in code without the Blueprint file and we get the same leaks.

I'm kind of suspicious about this one but don't see how we can do
anything about it, so I'm going to suppress for now. The suppression
file has detailed repro steps that people can use to hopefully test this
later.
2025-08-08 11:27:47 -07:00
Mitchell Hashimoto 17b4481767
fix: capture screenshot for app intents views as NSImage (#8180)
SwiftUI's ImageRenderer must not be called outside the main thread.

The `@MainActor` annotation is only relevant for our own code, not
for calls from frameworks. The machinations around Shortcuts end up
calling the displayRepresentation method outside the main thread.

By capturing the screenshot as NSImage, all data is retained and can
be processed outside the main thread.

Thread in Discord:
https://discord.com/channels/1005603569187160125/1403384231694172372
2025-08-08 10:25:56 -07:00
Mitchell Hashimoto ef817cd267
valgrind: GtkPopover suppressions
We get a ton of leaks from GTK.PopOver when we run the steps given in
the suppression file. I don't see how this could be us since we don't
create or do anything with the popover manually; its simply defined in
the Blueprint file.
2025-08-08 10:16:02 -07:00
Alexander Lais 1f378e6775
fix: capture screenshot for app intents views as NSImage
SwiftUI's ImageRenderer must not be called outside the main thread.

The `@MainActor` annotation is only relevant for our own code, not
for calls from frameworks. The machinations around Shortcuts end up
calling the displayRepresentation method outside the main thread.

By capturing the screenshot as NSImage, all data is retained and can
be processed outside the main thread.
2025-08-08 16:53:26 +02:00
Mitchell Hashimoto a0eb4285b2
build(deps): bump namespacelabs/nscloud-cache-action from 1.2.15 to 1.2.16 (#8175)
Bumps
[namespacelabs/nscloud-cache-action](https://github.com/namespacelabs/nscloud-cache-action)
from 1.2.15 to 1.2.16.
<details>
<summary>Commits</summary>
<ul>
<li><a
href="305bfa7ea9"><code>305bfa7</code></a>
Merge pull request <a
href="https://redirect.github.com/namespacelabs/nscloud-cache-action/issues/31">#31</a>
from namespacelabs/niklas-new-pnpm</li>
<li><a
href="ca35d05e60"><code>ca35d05</code></a>
Do not touch node_modules in PNPM mode.</li>
<li>See full diff in <a
href="f2d0a9e9ed...305bfa7ea9">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.15&new-version=1.2.16)](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-08-08 07:03:15 -07:00
Leah Amelia Chen 4d9d133ebc
inspector: fix display for fractional pixel sizes (#8179) 2025-08-08 17:12:43 +08:00
Leah Amelia Chen 7663f7d922
inspector: fix display for fractional pixel sizes
#4371 2: Electric Boogaloo

Regression caused by #7953
2025-08-08 14:39:26 +08:00
dependabot[bot] 23a6d4f276
build(deps): bump namespacelabs/nscloud-cache-action
Bumps [namespacelabs/nscloud-cache-action](https://github.com/namespacelabs/nscloud-cache-action) from 1.2.15 to 1.2.16.
- [Release notes](https://github.com/namespacelabs/nscloud-cache-action/releases)
- [Commits](f2d0a9e9ed...305bfa7ea9)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-08 00:17:36 +00:00
Mitchell Hashimoto c659f9c5d2
gtk-ng: nuke .nick and .blurb from property definitions (#8173) 2025-08-07 13:43:58 -07:00
Jeffrey C. Ollie b5073b34ee
gtk-ng: nuke .nick and .blurb from property definitions 2025-08-07 13:12:56 -05:00
Mitchell Hashimoto 4aa12b76e7
apprt/gtk-ng: split tree foundations (#8165)
This begins to bring back splits to `gtk-ng`. As of this PR, **splits
still don't work**, but the architectural underpinnings for them are all
present. Namely, our tab view now embeds a `GhosttySplitTree` widget
which has a full split tree present, and all the signals and active
surface properties and so on are hooked up to the tree.

In theory, once we hook up split creation, close, etc. everything should
_just work_.

But, this PR is already very large and I don't want to make it even
larger, so I'm opening this PR to add the foundations for this while
keeping `gtk-ng` in the state it more or less is on main right now.

The meat of this is in a pure Zig data structure `SplitTree` added to
`src/datastruct`. This is a Ziggified port of our macOS implementation
(but, much better if I do say so myself). Being in pure Zig lets us
write unit tests easily, control allocations tightly, get our safety
checks, etc. There is coverage in this PR.

## Other Bugs Fixed

- Boxed accessors use the proper `g_boxed_copy/free` functions. Didn't
really cause any issues because this is the first PR where we actually
use custom implementations for that.

- `Surface` properly emits a notify event for focus change
2025-08-07 08:41:18 -07:00
Mitchell Hashimoto 326e55c8f8
apprt/gtk-ng: PR feedback 2025-08-07 08:37:22 -07:00
Mitchell Hashimoto 4a4577cf8a
apprt/gtk-ng: address some TODOs 2025-08-07 08:14:02 -07:00
Mitchell Hashimoto bc731c0ff6
apprt/gtk-ng: hook up Tab signals to surface 2025-08-07 08:14:02 -07:00
Mitchell Hashimoto 3b4c33afe0
apprt/gtk-ng: connect surface signals 2025-08-07 08:14:02 -07:00
Mitchell Hashimoto a7865d79ea
apprt/gtk-ng: render a single artificial split 2025-08-07 08:14:02 -07:00
Mitchell Hashimoto 70b050ebb4
apprt/gtk-ng: setup split tree property 2025-08-07 08:14:02 -07:00
Mitchell Hashimoto fa08434b28
apprt/gtk-ng: initial GhosttySplitTree widget 2025-08-07 08:14:02 -07:00
Mitchell Hashimoto ad1cfe8347
remove outdated comment 2025-08-07 08:14:02 -07:00
Mitchell Hashimoto 3e767c166c
datastruct: split tree node removal 2025-08-07 08:14:02 -07:00
Mitchell Hashimoto 52e264948d
apprt/gtk-ng: ASCII output for SplitTree 2025-08-07 08:14:02 -07:00
Mitchell Hashimoto 5c30ac0e8e
apprt/gtk-ng: spatial tree 2025-08-07 08:14:02 -07:00
Mitchell Hashimoto 7811c04f9d
apprt/gtk-ng: SplitTree data structure 2025-08-07 08:14:02 -07:00
Mitchell Hashimoto 6238103f21
font: disable discretionary ligatures by default (#8164)
Closes #5372

Discretionary ligatures (denoted by the OpenType feature tag `dlig`) are
sometimes used by programming fonts (e.g. Iosevka) to provide more
"complex" and uncommon ligatures that may be useful in a programming
context. Unfortunately, this has some nasty side effects with certain
Japanese fallback fonts (#5372) due to perhaps a misaligned
understanding of the OpenType spec[^spec].

The spec details that `dlig` ligatures should only be used to contract
sequences of glyphs together into one glyph, and that it should be used
only for "special effect", **at the user's preference** (emphasis mine).
Indeed, it also suggests that:

> UI suggestion: This feature should be off by default.

All of this, combined with the fact that historical, nowadays unused and
even unintelligible Kanji ligatures are explicitly included as examples
of discretionary ligatures, shows that in the Japanese context at least
that the "level of discretion" is significantly higher than what is
found in programming fonts, where it is more understood to be
"opinionated and uncommon", rather than "obsolete and unreadable".

Furthermore, it appears that a lot of common programming fonts don't
even make use of the `dlig` feature — JetBrains Mono, FiraCode and
MonoLisa lack a `dlig` feature altogether, while Inconsolata seems to
only use it for ligatures that are more commonly found in `liga` or
`calt`, such as the `->` ligature. To a lot of people, then, this change
would literally alter nothing.

Therefore, it's my opinion that we should disable `dlig` by default.
It's arguably not being used correctly in the programming font space (or
at least not in a way that's coherent with other fonts), and it only
provides a marginal benefit while potentially rendering entire sentences
in Japanese (and possibly other languages) unreadable out of the box.

If someone upgrades to tip or 1.2 and then asks "why aren't the
ligatures working anymore", then at least they can always just turn on
`dlig` by themselves.

[^spec]:
https://learn.microsoft.com/en-us/typography/opentype/spec/features_ae#tag-dlig
2025-08-07 07:14:39 -07:00
Mitchell Hashimoto 1158419b7f
build(deps): bump namespacelabs/nscloud-cache-action from 1.2.14 to 1.2.15 (#8167)
Bumps
[namespacelabs/nscloud-cache-action](https://github.com/namespacelabs/nscloud-cache-action)
from 1.2.14 to 1.2.15.
<details>
<summary>Commits</summary>
<ul>
<li><a
href="f2d0a9e9ed"><code>f2d0a9e</code></a>
Merge pull request <a
href="https://redirect.github.com/namespacelabs/nscloud-cache-action/issues/30">#30</a>
from namespacelabs/niklas-wipe-debug</li>
<li><a
href="c532e9b02c"><code>c532e9b</code></a>
Fix cache content test, and add debug outputs.</li>
<li>See full diff in <a
href="a2c6b4830e...f2d0a9e9ed">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.14&new-version=1.2.15)](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-08-07 07:12:27 -07:00
Mitchell Hashimoto f0b1b0236c
gtk/gtk-ng: update zig-gobject to pick up fix for ianprime0509/zig-gobject#115 (#8169) 2025-08-07 07:12:04 -07:00
Leah Amelia Chen f107b2f910
font/{harfbuzz,coretext}: enable dlig for test shaper
Some of the tests rely on dlig and I'm far too lazy to rewrite those
tests now
2025-08-07 11:54:31 +08:00
Jeffrey C. Ollie 3b898a9800
gtk/gtk-ng: update zig-gobject to pick up fix for ianprime0509/zig-gobject#115 2025-08-06 21:19:18 -05:00
dependabot[bot] 8774e88d4e
build(deps): bump namespacelabs/nscloud-cache-action
Bumps [namespacelabs/nscloud-cache-action](https://github.com/namespacelabs/nscloud-cache-action) from 1.2.14 to 1.2.15.
- [Release notes](https://github.com/namespacelabs/nscloud-cache-action/releases)
- [Commits](a2c6b4830e...f2d0a9e9ed)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-07 00:55:06 +00:00
Leah Amelia Chen eb96ff0757
font: disable discretionary ligatures by default
Closes #5372

Discretionary ligatures (denoted by the OpenType feature tag `dlig`) are
sometimes used by programming fonts (e.g. Iosevka) to provide more
"complex" and uncommon ligatures that may be useful in a programming
context. Unfortunately, this has some nasty side effects with certain
Japanese fallback fonts (#5372) due to perhaps a misaligned understanding
of the OpenType spec[^spec].

The spec details that `dlig` ligatures should only be used to contract
sequences of glyphs together into one glyph, and that it should be used
only for "special effect", **at the user's preference** (emphasis mine).
Indeed, it also suggests that:

> UI suggestion: This feature should be off by default.

All of this, combined with the fact that historical, nowadays unused and
even unintelligible Kanji ligatures are explicitly included as examples
of discretionary ligatures, shows that in the Japanese context at least
that the "level of discretion" is significantly higher than what is found
in programming fonts, where it is more understood to be "opinionated and
uncommon", rather than "obsolete and unreadable".

Furthermore, it appears that a lot of common programming fonts don't even
make use of the `dlig` feature —  JetBrains Mono, FiraCode and MonoLisa
lack a `dlig` feature altogether, while Inconsolata seems to only use it
for ligatures that are more commonly found in `liga` or `calt`, such as
the `->` ligature. To a lot of people, then, this change would literally
alter nothing.

Therefore, it's my opinion that we should disable `dlig` by default.
It's arguably not being used correctly in the programming font space
(or at least not in a way that's coherent with other fonts), and it only
provides a marginal benefit while potentially rendering entire sentences
in Japanese (and possibly other languages) unreadable out of the box.

If someone upgrades to tip or 1.2 and then asks "why aren't the ligatures
working anymore", then at least they can always just turn on `dlig` by
themselves.

[^spec]: https://learn.microsoft.com/en-us/typography/opentype/spec/features_ae#tag-dlig
2025-08-07 03:33:24 +08:00
Leah Amelia Chen 1d042f1e71
build: allow disabling i18n (#8158) 2025-08-06 21:09:03 +08:00
Leah Amelia Chen 5fbdb8c459
build: allow disabling i18n
GNU gettext simply is a PITA on certain platforms (i.e. Windows, musl
Linux, etc.) and currently it's not possible to cleanly remove i18n
from the build process, making building Ghostty on the aforementioned
platforms difficult. By providing users with a way to opt-out of the
i18n mechanisms (or opt-in, on platforms where i18n is disabled by
default) we can make sure that people at least have *some* way of
building Ghostty before i18n mechanisms can be integrated neatly.
2025-08-06 14:54:02 +08:00
Jacob Sandlund 7e429d73d6 block 2025-08-06 00:06:27 -04:00
Jacob Sandlund 0c393299b0 using just `get` 2025-08-05 23:59:30 -04:00
Mitchell Hashimoto 1ec8188b5c
build(deps): bump actions/download-artifact from 4.3.0 to 5.0.0 (#8156)
Bumps
[actions/download-artifact](https://github.com/actions/download-artifact)
from 4.3.0 to 5.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>v5.0.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Update README.md by <a
href="https://github.com/nebuk89"><code>@​nebuk89</code></a> in <a
href="https://redirect.github.com/actions/download-artifact/pull/407">actions/download-artifact#407</a></li>
<li>BREAKING fix: inconsistent path behavior for single artifact
downloads by ID by <a
href="https://github.com/GrantBirki"><code>@​GrantBirki</code></a> in <a
href="https://redirect.github.com/actions/download-artifact/pull/416">actions/download-artifact#416</a></li>
</ul>
<h2>v5.0.0</h2>
<h3>🚨 Breaking Change</h3>
<p>This release fixes an inconsistency in path behavior for single
artifact downloads by ID. <strong>If you're downloading single artifacts
by ID, the output path may change.</strong></p>
<h4>What Changed</h4>
<p>Previously, <strong>single artifact downloads</strong> behaved
differently depending on how you specified the artifact:</p>
<ul>
<li><strong>By name</strong>: <code>name: my-artifact</code> → extracted
to <code>path/</code> (direct)</li>
<li><strong>By ID</strong>: <code>artifact-ids: 12345</code> → extracted
to <code>path/my-artifact/</code> (nested)</li>
</ul>
<p>Now both methods are consistent:</p>
<ul>
<li><strong>By name</strong>: <code>name: my-artifact</code> → extracted
to <code>path/</code> (unchanged)</li>
<li><strong>By ID</strong>: <code>artifact-ids: 12345</code> → extracted
to <code>path/</code> (fixed - now direct)</li>
</ul>
<h4>Migration Guide</h4>
<h5> No Action Needed If:</h5>
<ul>
<li>You download artifacts by <strong>name</strong></li>
<li>You download <strong>multiple</strong> artifacts by ID</li>
<li>You already use <code>merge-multiple: true</code> as a
workaround</li>
</ul>
<h5>⚠️ Action Required If:</h5>
<p>You download <strong>single artifacts by ID</strong> and your
workflows expect the nested directory structure.</p>
<p><strong>Before v5 (nested structure):</strong></p>
<pre lang="yaml"><code>- uses: actions/download-artifact@v4
  with:
    artifact-ids: 12345
    path: dist
# Files were in: dist/my-artifact/
</code></pre>
<blockquote>
<p>Where <code>my-artifact</code> is the name of the artifact you
previously uploaded</p>
</blockquote>
<p><strong>To maintain old behavior (if needed):</strong></p>
<pre lang="yaml"><code>&lt;/tr&gt;&lt;/table&gt; 
</code></pre>
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="634f93cb29"><code>634f93c</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/download-artifact/issues/416">#416</a>
from actions/single-artifact-id-download-path</li>
<li><a
href="b19ff43027"><code>b19ff43</code></a>
refactor: resolve download path correctly in artifact download tests
(mainly ...</li>
<li><a
href="e262cbee4a"><code>e262cbe</code></a>
bundle dist</li>
<li><a
href="bff23f9308"><code>bff23f9</code></a>
update docs</li>
<li><a
href="fff8c148a8"><code>fff8c14</code></a>
fix download path logic when downloading a single artifact by id</li>
<li><a
href="448e3f862a"><code>448e3f8</code></a>
Merge pull request <a
href="https://redirect.github.com/actions/download-artifact/issues/407">#407</a>
from actions/nebuk89-patch-1</li>
<li><a
href="47225c44b3"><code>47225c4</code></a>
Update README.md</li>
<li>See full diff in <a
href="d3f86a106a...634f93cb29">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/download-artifact&package-manager=github_actions&previous-version=4.3.0&new-version=5.0.0)](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-08-05 20:14:13 -07:00
Mitchell Hashimoto 1a74ce1b10
gtk-ng: a couple of minor fixes (#8157)
A couple of minor fixes that I found while exploring tonight:

- OSC 22 wasn't working on gtk-ng. Fixed by setting the cursor shape
directly on the surface.
- Removed use of deprecated property on GLArea
2025-08-05 20:13:56 -07:00
Jeffrey C. Ollie 35e3ac8b4c
gtk-ng: remove use of deprecated use-es GLArea property 2025-08-05 19:56:00 -05:00
Jeffrey C. Ollie 288601e386
gtk-ng: fix OSC 22 not changing mouse shape on -ng 2025-08-05 19:56:00 -05:00
dependabot[bot] 7db2ab9863
build(deps): bump actions/download-artifact from 4.3.0 to 5.0.0
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 4.3.0 to 5.0.0.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](d3f86a106a...634f93cb29)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: 5.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-06 00:29:00 +00:00
Kat 2b670a8e13
update Polish translations (#8151) 2025-08-05 23:49:29 +00:00
Mitchell Hashimoto 70ec59d566
macOS: properly handle buffer allocation in ZH locale canonicalization (#8137)
Fix a bug introduced by #6885 

`fixZhLocale` returns locale string literal without copying it into the
buffer, causing the `LANGUAGE` environment variable to be set
incorrectly.
```log
$ LANG="" zig build run
...
debug(os_locale): setting LANGUAGE from preferred languages value=�����.UTF-8:�����.UTF-8:en_US.UTF-8:ja_CN.UTF-8
...
```
2025-08-05 09:41:15 -07:00
Mitchell Hashimoto 5c0e15f50f
gtk-ng: port the command palette (#8083) 2025-08-05 09:40:37 -07:00
Mitchell Hashimoto 19fde96d30
funny typos 2025-08-05 09:38:08 -07:00
Mitchell Hashimoto 8022539f82
gitignore: ignore core dumps created by valgrind (#8152) 2025-08-05 09:22:32 -07:00
Mitchell Hashimoto 10a7e39456
zig: switch all uses of callconv(.C) to callconv(.c) (#8153) 2025-08-05 09:14:52 -07:00
Jeffrey C. Ollie cf77897388
gtk-ng: port the command palette 2025-08-05 10:33:08 -05:00
Jeffrey C. Ollie 6ae333869e
zig: switch all uses of callconv(.C) to callconv(.c) 2025-08-05 10:32:03 -05:00
Jeffrey C. Ollie a50605c5df
gitignore: ignore core dumps created by valgrind 2025-08-05 10:24:58 -05:00
Aaron Ruan c1060d56b3
macOS: properly handle buffer in zh locale canonicalization 2025-08-05 22:56:28 +08:00
trag1c 5cf5f71c72
update Polish translations 2025-08-05 16:29:08 +02:00
Mitchell Hashimoto 18c2ff561f
build(deps): bump namespacelabs/nscloud-cache-action from 1.2.13 to 1.2.14 (#8148)
Bumps
[namespacelabs/nscloud-cache-action](https://github.com/namespacelabs/nscloud-cache-action)
from 1.2.13 to 1.2.14.
<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.14</h2>
<ul>
<li><a
href="93ab075400">Fix
post path cache summary and wipe non-cacheable contents in post
step.</a></li>
<li>[PNPM] <a
href="48cddb643a">Set
copy mode and avoid spurious warnings.</a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="a2c6b4830e"><code>a2c6b48</code></a>
Merge pull request <a
href="https://redirect.github.com/namespacelabs/nscloud-cache-action/issues/29">#29</a>
from namespacelabs/niklas-wipe</li>
<li><a
href="93ab075400"><code>93ab075</code></a>
Fix post path cache summary and wipe non-cacheable contents in post
step.</li>
<li><a
href="fa4ddeb1d7"><code>fa4ddeb</code></a>
Merge pull request <a
href="https://redirect.github.com/namespacelabs/nscloud-cache-action/issues/28">#28</a>
from namespacelabs/niklas-pnpm-copy</li>
<li><a
href="48cddb643a"><code>48cddb6</code></a>
Set copy mode and avoid spurious warnings.</li>
<li>See full diff in <a
href="9ff6d4004d...a2c6b4830e">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.13&new-version=1.2.14)](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-08-05 07:09:01 -07:00
dependabot[bot] ce68a864f0
build(deps): bump namespacelabs/nscloud-cache-action
Bumps [namespacelabs/nscloud-cache-action](https://github.com/namespacelabs/nscloud-cache-action) from 1.2.13 to 1.2.14.
- [Release notes](https://github.com/namespacelabs/nscloud-cache-action/releases)
- [Commits](9ff6d4004d...a2c6b4830e)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-05 07:24:31 +00:00
Mitchell Hashimoto 37bac094c7
apprt/gtk-ng: action accelerators, clean up explicit error sets (#8146)
Not a lot here, ported the action accelerators which was small.

Besides that, cleaned up a bunch of explicit error sets which allowed us
to remove some forwarded errors because they're so unlikely, and could
unify others.
2025-08-04 12:45:06 -07:00
Mitchell Hashimoto 8c85bae931
apprt/gtk-ng: background-opacity doesn't need to be a window property
We only need properties for things that are bound via the blueprint
files. Otherwise, its kind of just a pain. This fixes a bug where it
wasn't being properly set initially anyways because we didn't trigger
syncAppearance.
2025-08-04 12:41:44 -07:00
Mitchell Hashimoto 55c68d809d
apprt/gtk-ng: action accelerators, clean up explicit error sets 2025-08-04 12:35:37 -07:00
Mitchell Hashimoto 84cb4ce31a
apprt/gtk-ng: surface context menu (#8144)
Port with changes:

* Utilizes the Surface blueprint for defining the `PopoverMenu`
* We can't attach it directly to the Overlay using blueprints because an
overlay can only have a single child property and you can't see other
children via Blueprint. To overcome this, use a `Box`
* Utilizing a `menu` signal the window can listen to to refresh its
action map instead of digging into ancestor hierarchy.
2025-08-04 11:43:17 -07:00
Mitchell Hashimoto ee6d9b3116
apprt/gtk-ng: surface context menu 2025-08-04 11:28:48 -07:00
Mitchell Hashimoto 1d62f37cbb
apprt/gtk-ng: global shortcuts (#8142)
Ports global shortcuts. 

This is mostly a direct logic copy. The primary difference is I
converted `GlobalShortcuts` to a `GObject` which has a config and dbus
property and emits a trigger signal. Importantly, it's no longer tied or
dependent on the `gio.Application` in any way. The config and dbus
connection are updated as normal properties.

Verified with Valgrind we're clean. Found one memory leak I ported back
to legacy.
2025-08-04 10:37:57 -07:00
Mitchell Hashimoto c8fce8850b
apprt/gtk-ng: global shortcuts 2025-08-04 10:25:24 -07:00
Mitchell Hashimoto 41e8f1374b
gtk-ng: prevent split button from becoming focused (#8136)
Without this, if you create a new tab by clicking on the split button it
will be the focus for any new input. So for example if you create a new
tab and then immediately press the space bar a bunch of new tabs will be
created. Other keypresses will just "disappear". Only by clicking in the
new tab to focus it will keyboard input go to "the right place".
2025-08-04 08:07:52 -07:00
Jacob Sandlund 8dec520b41 testing uucode.x 2025-08-04 10:02:41 -04:00
Jacob Sandlund e5bbc9e83d Merge remote-tracking branch 'upstream/main' into jacob/uucode 2025-08-04 10:00:33 -04:00
Jon Parise eccff1ea95
fix fish shell syntax for ssh-env shell integration (#8138)
As discussed here
https://github.com/ghostty-org/ghostty/discussions/8021

This fixes invalid fish shell syntax.

As an example, run ghostty like so: `XDG_CONFIG_HOME=/tmp ghostty
--shell-integration-features=ssh-env --command="/usr/bin/env fish"`.
Setting `XDG_CONFIG_HOME` to `/tmp` is just to start from the default
configs for ghostty and fish.

Before:

```
Welcome to fish, the friendly interactive shell
Type help for instructions on how to use fish
robbiev@neo ~/s/ghostty (fish-shell-ssh)> ssh git@github.com
env: ‘command’: No such file or directory
robbiev@neo ~/s/ghostty (fish-shell-ssh) [127]>
```

After:

```
Welcome to fish, the friendly interactive shell
Type help for instructions on how to use fish
robbiev@neo ~/s/ghostty (fish-shell-ssh)> ssh git@github.com
PTY allocation request failed on channel 0
Hi robbiev! You've successfully authenticated, but GitHub does not provide shell access.
Connection to github.com closed.
robbiev@neo ~/s/ghostty (fish-shell-ssh) [1]>
```

(This fails correctly)

I've also tried with a correctly accessible ssh server but of course you
can't repro that easily if you don't have some place to ssh to.

```
Welcome to fish, the friendly interactive shell
Type help for instructions on how to use fish
robbiev@neo ~/s/ghostty (fish-shell-ssh)> ssh trinity

[robbiev@trinity:~]$ echo $TERM
xterm-ghostty
```

My understanding of the fix follows.

The script is using `command` to make sure it calls the actual ssh
binary and not some intermediate shell function with the same name (`man
command` explains).

`env` can be useful for fish compat < 3.1, where [the KEY=value syntax
was
introduced](https://fishshell.com/docs/current/faq.html#how-do-i-set-or-clear-an-environment-variable).
However because `command` is a builtin it doesn't work in this case.

So a simple solution is this, requiring fish >= 3.1

```
TERM="$ssh_term" command ssh $ssh_opts $argv
```

An
[alternative](https://serverfault.com/questions/164305/how-can-i-set-environment-variable-for-just-one-command-in-fish-shell)
for maximum fish compat could be the following:

```
begin
  set -lx TERM "$ssh_term"
  command ssh $ssh_opts $argv
end
```

According to `man set`, `-l` means local to the block and `-x` means
export.

I'm in favour of keeping `command` as it makes the integration more
predicable.

The reason I went with the current fix:
- It's easier to understand without knowing fish shell.
- [kat found that fish 3.1 should be widely
available](https://github.com/ghostty-org/ghostty/discussions/8021#discussioncomment-13877129).
2025-08-04 07:27:14 -04:00
Robbie Vanbrabant 42e4a95b64 fix fish shell syntax for ssh-env shell integration
As discussed here https://github.com/ghostty-org/ghostty/discussions/8021

This fixes invalid fish shell syntax.

As an example, run ghostty like so: `XDG_CONFIG_HOME=/tmp ghostty --shell-integration-features=ssh-env --command="/usr/bin/env fish"`. Setting XDG_CONFIG_HOME to /tmp is just to start from the default config.

Before:

```
Welcome to fish, the friendly interactive shell
Type help for instructions on how to use fish
robbiev@neo ~/s/ghostty (fish-shell-ssh)> ssh git@github.com
env: ‘command’: No such file or directory
robbiev@neo ~/s/ghostty (fish-shell-ssh) [127]>
```

After:

```
Welcome to fish, the friendly interactive shell
Type help for instructions on how to use fish
robbiev@neo ~/s/ghostty (fish-shell-ssh)> ssh git@github.com
PTY allocation request failed on channel 0
Hi robbiev! You've successfully authenticated, but GitHub does not provide shell access.
Connection to github.com closed.
robbiev@neo ~/s/ghostty (fish-shell-ssh) [1]>
```

My understanding of the fix follows.

The script is using `command` to make sure it calls the actual ssh binary and not some intermediate shell function with the same name (`man command` explains).

`env` can be useful for fish compat < 3.1, where [the KEY=value syntax was introduced](https://fishshell.com/docs/current/faq.html#how-do-i-set-or-clear-an-environment-variable). However because `command` is a builtin it doesn't work in this case.

So a simple solution is this, requiring fish >= 3.1

```
TERM="$ssh_term" command ssh $ssh_opts $argv
```

An [alternative](https://serverfault.com/questions/164305/how-can-i-set-environment-variable-for-just-one-command-in-fish-shell) for maximum fish compat could be the following:

```
begin
  set -lx TERM "$ssh_term"
  command ssh $ssh_opts $argv
end
```

According to `man set`, `-l` means local to the block and `-x` means export.

I'm in favour of keeping `command` as it makes the integration more predicable.

The reason I went with the current fix:
- It's easier to understand without knowing fish shell.
- [kat found that fish 3.1 should be widely available](https://github.com/ghostty-org/ghostty/discussions/8021#discussioncomment-13877129).
2025-08-04 11:28:39 +01:00
Jeffrey C. Ollie 83063e5527
gtk-ng: prevent split button from becoming focused 2025-08-03 13:38:49 -05:00
trag1c f0272e5fec
Added and updated translations for id_ID (#8126) 2025-08-03 17:36:43 +02:00
Mitchell Hashimoto 4efef78216
bash: upgrade to bash-preexec 0.6.0 (#8135)
https://github.com/rcaloras/bash-preexec/releases/tag/0.6.0

This is a small update for us because we've been using a patched version
of this script in Ghostty for some time, and the 0.6.0 release includes
most of the local changes we made as part of maintaining and improving
our bash shell integration.

- https://github.com/rcaloras/bash-preexec/pull/167
- https://github.com/rcaloras/bash-preexec/pull/170

We continue to maintain one local HISTCONTROL-related modification
(#2478). There are a few upstream conversations related to HISTCONTROL
that might eliminate the need for this local patch, so we may revisit
that in the future.
2025-08-03 06:44:19 -07:00
Jon Parise f4e434fffd bash: upgrade to bash-preexec 0.6.0
https://github.com/rcaloras/bash-preexec/releases/tag/0.6.0

This is a small update for us because we've been using a patched version
of this script in Ghostty for some time, and the 0.6.0 release includes
most of the local changes we made as part of maintaining and improving
our bash shell integration.

- https://github.com/rcaloras/bash-preexec/pull/167
- https://github.com/rcaloras/bash-preexec/pull/170

We continue to maintain one local HISTCONTROL-related modification
(#2478). There are a few upstream conversations related to HISTCONTROL
that might eliminate the need for this local patch, so we may revisit
that in the future.
2025-08-03 09:15:35 -04:00
trag1c 6b57a23273
i18n: Updated translation for ko_KR (#8058) 2025-08-03 14:04:44 +02:00
Jinhyeok Lee dbb1096c24
i18n: Update Korean translation metadata 2025-08-03 20:46:28 +09:00
mikailmm b0ba0a1c8c
fixed revision date
Co-authored-by: Kat <65649991+00-kat@users.noreply.github.com>
2025-08-03 12:21:37 +07:00
Mitchell Hashimoto afdaab9cc6
apprt/gtk-ng: runtime CSS and custom CSS (#8133)
A simple port, nothing creative here.

Found one definite leak in GTK, added a suppression. No leaks in Ghostty
code.
2025-08-02 20:32:59 -07:00
Mitchell Hashimoto 8e8dc76362
Update iTerm2 colorschemes (#8132)
Upstream revision:
b2742b8baf
2025-08-02 20:30:22 -07:00
Mitchell Hashimoto 053e3d307b
apprt/gtk-ng: runtime CSS and custom CSS 2025-08-02 20:28:22 -07:00
mitchellh 7a7790a212 deps: Update iTerm2 color schemes 2025-08-03 00:15:54 +00:00
Mitchell Hashimoto 78f474b143
apprt/gtk-ng: toggle_window_decorations (#8128) 2025-08-02 13:38:01 -07:00
Mitchell Hashimoto 5078fc5243
apprt/gtk-ng: toggle_window_decorations 2025-08-02 13:34:14 -07:00
Mitchell Hashimoto 7836cc8f31
apprt/gtk-ng: winproto behaviors (quick terminal, csd/ssd, blur, etc.) (#8123)
This ports over the winproto behaviors to gtk-ng. The core winproto
logic is unchanged except for trivial typing changes. The interaction
with winproto is a bit different in ng due to the class separation of
logic between surfaces and windows, but functionally the same.

Ran against Valgrind and all looks good.
2025-08-02 12:57:01 -07:00
Mitchell Hashimoto 91254bb6cc
apprt/gtk-ng: address feedback 2025-08-02 12:53:27 -07:00
mikailmm bebbeed81d
added name and email in contribution list 2025-08-03 00:31:13 +07:00
mikailmm a41cb2c827
Added last-translator name and email 2025-08-03 00:29:45 +07:00
Mitchell Hashimoto e1e525ba3d
apprt/gtk-ng: winproto callbacks for subprocess env 2025-08-01 21:16:08 -07:00
Mitchell Hashimoto 523799a45f
apprt/gtk-ng: winproto resizeEvent 2025-08-01 21:05:42 -07:00
Mitchell Hashimoto 7aa84cd372
apprt/gtk-ng: quick terminal 2025-08-01 20:51:43 -07:00
Mitchell Hashimoto 084a20c865
apprt/gtk-ng: hook up all the syncAppearance calls for winproto 2025-08-01 14:58:25 -07:00
Mitchell Hashimoto c7eee9ee7a
apprt/gtk-ng: initialize window protocol 2025-08-01 14:40:19 -07:00
Mitchell Hashimoto 469001b7f6
apprt/gtk-ng: size_limit apprt action (#8116)
This ports the same behavior from GTK, mostly. This also fixes a bug
where the limits would be enforced on reload. Instead, we should only
enforce them on the first surface ever.
2025-08-01 08:06:40 -07:00
Mitchell Hashimoto 780d4af8bc
apprt/gtk-ng: size_limit apprt action
This ports the same behavior from GTK, mostly. This also fixes a bug
where the limits would be enforced on reload. Instead, we should only
enforce them on the first surface ever.
2025-08-01 07:59:19 -07:00
mikailmm b99831ce36
Update id_ID.UTF-8.po
added and changed the translation following the terminology used by Gnome (and Apple) from help.gnome.org and support.apple.com
2025-08-01 10:25:25 +07:00
Mitchell Hashimoto 1901cbf334
apprt/gtk-ng: initial size apprt action (window-width/height) (#8115)
Simple port. I might add size limits if I get to it, but finished this
and it works so opened it up.
2025-07-31 13:58:34 -07:00
Mitchell Hashimoto 0b9130aba9
apprt/gtk-ng: initial size apprt action (window-width/height) 2025-07-31 13:28:30 -07:00
Leah Amelia Chen cf9943a3dd
gtk(wayland): bind globals correctly (#8110) 2025-07-31 18:28:05 +02:00
Leah Amelia Chen c2165fc097
gtk(wayland): bind globals correctly
Fixes #7988
2025-07-31 15:51:49 +08:00
Mitchell Hashimoto d4c825186e
apprt/gtk-ng: desktop notifications, open config, open url, present terminal (#8105)
Implements a number of minor apprt actions. More or less directly
ported. Some notes added for future improvements given the new
architecture.
2025-07-30 09:38:48 -07:00
Mitchell Hashimoto 6c952d4168
apprt/gtk-ng: desktop notification 2025-07-30 09:31:54 -07:00
Mitchell Hashimoto e7ea084cc3
apprt/gtk-ng: present surface 2025-07-30 09:20:15 -07:00
Mitchell Hashimoto 60b859dbf2
apprt/gtk-ng: open config, open url 2025-07-30 09:04:01 -07:00
Mitchell Hashimoto e7befe2ed1
apprt/gtk-ng: surface has correct initial size (#8104)
Ensure the surface has a correct initial size when created. This avoids
a rapid resize event and also the pty reports the correct size for
startup scripts.

This is a departure from macOS and legacy GTK. This has been an issue in
Ghostty for awhile so this is the proper path forward.

This works by deferring Surface initialization until the first resize
event. This MIGHT result in a frame or two not rendering but I haven't
noticed anything visually and having the correct size is far more
important.
2025-07-30 08:54:51 -07:00
Mitchell Hashimoto 7b1092f991
apprt/gtk-ng: surface has correct initial size
Ensure the surface has a correct initial size when created. This avoids
a rapid resize event and also the pty reports the correct size for
startup scripts.

This is a departure from macOS and legacy GTK. This has been an issue in
Ghostty for awhile so this is the proper path forward.

This works by deferring Surface initialization until the first resize
event. This MIGHT result in a frame or two not rendering but I haven't
noticed anything visually and having the correct size is far more
important.
2025-07-30 08:48:27 -07:00
Jacob Sandlund 807d128e20 Use `table_0_fields` build option 2025-07-30 11:22:35 -04:00
Mitchell Hashimoto 1e721ae567
apprt/gtk-ng: tabs are back! (#8098)
This brings back all tabbing behaviors.

I ran through create/close tabs and windows with Valgrind and everything
ran clean.

TODO:

- [x] goto tab keybinding
- [x] move tab
- [x] toggle tab overview (binding only, UI works!)
- [x] create window action to pull tab out into a window
2025-07-30 07:13:38 -07:00
Anthony db2984de6e cli: update var name 2025-07-30 14:29:38 +10:00
Mitchell Hashimoto fde50e0f1c
apprt/gtk-ng: create-window action 2025-07-29 15:07:04 -07:00
Mitchell Hashimoto 0cc8b6d10f
apprt/gtk-ng: remove all shortcuts on tab view 2025-07-29 14:57:50 -07:00
Mitchell Hashimoto 2847aeb181
apprt/gtk-ng: toggle tab overview 2025-07-29 14:56:16 -07:00
Mitchell Hashimoto a5188142ba
apprt/gtk-ng: move tab 2025-07-29 14:52:33 -07:00
Mitchell Hashimoto 2d1232878d
apprt/gtk-ng: goto_tab 2025-07-29 14:40:45 -07:00
Mitchell Hashimoto c78d32074e
Add Gnome Nightly Icon Set (#8100)
This adds a nightly-variant for the icons. These aren't hooked up to our
build system yet.

<img width="1024" height="1024" alt="Ghostty-Gnome-Nightly-512"
src="https://github.com/user-attachments/assets/66da56a4-110a-4e60-8d6e-93e16bb27b51"
/>
2025-07-29 12:15:54 -07:00
Mitchell Hashimoto a705b42899
Add Gnome Nightly Icon Set
This adds a nightly-variant for the icons. These aren't hooked up to our
build system yet.
2025-07-29 12:10:42 -07:00
Mitchell Hashimoto 4fb790ca4c
apprt/gtk-ng: helper for getAncestor 2025-07-29 10:58:31 -07:00
Mitchell Hashimoto 179fa8e5aa
remove bad file 2025-07-29 10:43:20 -07:00
Mitchell Hashimoto 8b14ab1221
apprt/gtk-ng: workaround for tab overview selection 2025-07-29 10:39:45 -07:00
Mitchell Hashimoto 16bb579bab
update supps 2025-07-29 10:32:03 -07:00
Mitchell Hashimoto 0da6b2049d
apprt/gtk-ng: tab overview new tab 2025-07-29 10:29:28 -07:00
Mitchell Hashimoto ccc8dac0a5
apprt/gtk-ng: new tab button 2025-07-29 10:24:25 -07:00
Mitchell Hashimoto b475cd28d5
apprt/gtk-ng: new tab, slightly broken 2025-07-29 10:17:26 -07:00
Mitchell Hashimoto 0682811107
apprt/gtk-ng: window close confirmation 2025-07-29 09:48:17 -07:00
Mitchell Hashimoto 70010ec50a
typos 2025-07-29 09:38:31 -07:00
Mitchell Hashimoto e4fb46f230
apprt/gtk-ng: close window if no tabs left 2025-07-29 09:38:09 -07:00
Mitchell Hashimoto 3bb6cdff4e
apprt/gtk-ng: window getActiveSurface 2025-07-29 09:33:38 -07:00
Mitchell Hashimoto 3f440821d9
fix up suppressions 2025-07-29 09:29:50 -07:00
Mitchell Hashimoto c0e7b92e91
apprt/gtk-ng: close tab confirmation 2025-07-29 09:27:13 -07:00
Mitchell Hashimoto 431a6328dc
apprt/gtk-ng: handle surface close request 2025-07-28 21:38:00 -07:00
Mitchell Hashimoto ed25a57d08
apprt/gtk-ng: hook up all existing surface signals 2025-07-28 21:22:23 -07:00
Mitchell Hashimoto 5279badd5b
apprt/gtk-ng: bind a bunch on page-attach/detach 2025-07-28 21:08:47 -07:00
Mitchell Hashimoto fa45f971f4
apprt/gtk-ng: title bindings 2025-07-28 12:38:40 -07:00
Mitchell Hashimoto 775f3dfca3
apprt/gtk-ng: basic tab creation 2025-07-28 10:52:33 -07:00
Mitchell Hashimoto e768b54d89
apprt/gtk-ng: new tab button in header 2025-07-28 10:21:47 -07:00
Mitchell Hashimoto bc6cbdc41a
apprt/gtk-ng: toolbar style config 2025-07-28 10:21:47 -07:00
Mitchell Hashimoto d7e42e6614
apprt/gtk-ng: tab bar top/bottom 2025-07-28 10:21:47 -07:00
Mitchell Hashimoto e7cab27c38
apprt/gtk-ng: tab bar properties 2025-07-28 10:21:47 -07:00
Mitchell Hashimoto 288461fbee
apprt/gtk-ng: setup tab views in blueprint 2025-07-28 10:21:47 -07:00
Mitchell Hashimoto 92c1f4b0b9
macOS: update Float on Top menu icon to `square.filled.on.square` (#8087)
Address a minor UI confusion introduced by #7594.

Ghostty's "Float on Top" action icon uses
`square.3.layers.3d.top.filled`, which is the same as macOS's "Bring All
to Front" action. This may cause confusion.

Before:
<img width="333" height="156" alt="image"
src="https://github.com/user-attachments/assets/5148909c-f090-4b2f-8206-c45cb30cf30e"
/>

After:
<img width="336" height="148" alt="image"
src="https://github.com/user-attachments/assets/3c3a820f-ece3-4778-af47-767758c23266"
/>
2025-07-28 10:01:14 -07:00
Mitchell Hashimoto 3278507ae8
Fix typo in VM Acceptance Criteria (#8092)
This PR fixes a small typo in the "VM Acceptance Criteria" section —
replaces "The" with "They".
2025-07-28 10:01:03 -07:00
Ahmed Harabi 87bb949a93 Fix typo in VM Acceptance Criteria ('The' → 'They') 2025-07-28 15:57:48 +00:00
Mitchell Hashimoto a5a09f5ba4
apprt/gtk-ng: port SIGUSR2 to reload config (#8091)
Nothing controversial here.
2025-07-28 08:33:22 -07:00
Mitchell Hashimoto c149ba1907
apprt/gtk-ng: port SIGUSR2 to reload config 2025-07-28 08:21:28 -07:00
Jacob Sandlund 1c445fae9b Merge remote-tracking branch 'upstream/main' into jacob/uucode 2025-07-28 08:18:57 -04:00
Mitchell Hashimoto d474c81b90
gtk-ng: fix up background of resize and url overlays (#8089)
PR #8088 had the unexpected side-effect of making the resize and url
overlays transparent as well. This PR fixes that.
2025-07-27 21:33:59 -07:00
Jeffrey C. Ollie 96573917a0
gtk-ng: fix up background of resize and url overlays
PR #8088 had the unexpected side-effect of making the resize and url
overlays transparent as well. This PR fixes that.
2025-07-27 23:28:28 -05:00
Mitchell Hashimoto 4c01d776c5
valgrind: make some GSK renderer supressions less strict 2025-07-27 21:08:15 -07:00
Mitchell Hashimoto 466aab543f
gtk-ng: add/remove 'background' css class from window depending on opacity (#8088) 2025-07-27 21:04:11 -07:00
Jeffrey C. Ollie 92c004cb25
gtk-ng: add/remove 'background' css class from window depending on opacity 2025-07-27 22:05:16 -05:00
Mitchell Hashimoto 520ba27bb7
build(deps): bump cachix/install-nix-action from 31.5.1 to 31.5.2 (#8086)
Bumps
[cachix/install-nix-action](https://github.com/cachix/install-nix-action)
from 31.5.1 to 31.5.2.
<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.5.2</h2>
<h2>What's Changed</h2>
<ul>
<li>nix: 2.30.1 -&gt; 2.30.2 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/246">cachix/install-nix-action#246</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/cachix/install-nix-action/compare/v31...v31.5.2">https://github.com/cachix/install-nix-action/compare/v31...v31.5.2</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="fc6e360bed"><code>fc6e360</code></a>
Merge pull request <a
href="https://redirect.github.com/cachix/install-nix-action/issues/246">#246</a>
from cachix/create-pull-request/patch</li>
<li><a
href="9d5112343e"><code>9d51123</code></a>
nix: 2.30.1 -&gt; 2.30.2</li>
<li>See full diff in <a
href="c134e4c9e3...fc6e360bed">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.5.1&new-version=31.5.2)](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-07-27 19:58:31 -07:00
Aaron Ruan 1f710768e9
Update Float on Top menu icon to square.filled.on.square 2025-07-28 09:26:54 +08:00
dependabot[bot] b5a34f5f3c
build(deps): bump cachix/install-nix-action from 31.5.1 to 31.5.2
Bumps [cachix/install-nix-action](https://github.com/cachix/install-nix-action) from 31.5.1 to 31.5.2.
- [Release notes](https://github.com/cachix/install-nix-action/releases)
- [Changelog](https://github.com/cachix/install-nix-action/blob/master/RELEASE.md)
- [Commits](c134e4c9e3...fc6e360bed)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-28 01:05:10 +00:00
Jacob Sandlund 16c7ebad1d Add TODO about configuration 2025-07-27 18:48:39 -04:00
Jacob Sandlund fb2cab5aee Using uucode in a few places where it's easy. 2025-07-27 18:27:46 -04:00
Mitchell Hashimoto 75d5a519c8
apprt/gtk-ng: configuration reloading, toasts (#8084)
This brings in configuration reloading and toasts to gtk-ng. 

Config reloading is fairly different in ng than legacy because we rely
on our GObject `Config` class and ref counting more heavily. We rely on
various property bindings and notify signals to propagate configuration
changes out to all subscribers. Previously we manually had to chain this
together.

Toasts are straightforward, with the main difference being that the
window owns its own toasts (surfaces can't trigger them) and triggers
them via signal emission.
2025-07-27 15:20:10 -07:00
Mitchell Hashimoto bf61f29f57
apprt/gtk-ng: create the privateObjFieldAccessor helper to unref 2025-07-27 15:11:07 -07:00
Mitchell Hashimoto c4de001023
apprt/gtk-ng: avoid reading corrupt memory in event loop 2025-07-27 14:28:21 -07:00
Mitchell Hashimoto b011706aad
suppressions 2025-07-27 14:12:26 -07:00
Mitchell Hashimoto 53c7b8922f
apprt/gtk-ng: reload config 2025-07-27 13:57:28 -07:00
Jacob Sandlund 70bc29f815 Initial testing including uucode 2025-07-27 16:30:55 -04:00
Mitchell Hashimoto ccde429bde
apprt/gtk-ng: toasts 2025-07-27 13:27:03 -07:00
Anthony 487b1d72ab cli: add filtering hotkey to list_themes 2025-07-27 17:45:12 +10:00
Mitchell Hashimoto 18831374ca
apprt/gtk-ng: fix scrolling on surface (#8080)
We forgot to specify the scroll controller's `flags` property.
2025-07-26 12:17:09 -07:00
Mitchell Hashimoto b5c1f52ddb
apprt/gtk-ng: fix scrolling on surface
We forgot to specify the scroll controller's `flags` property.
2025-07-26 12:13:51 -07:00
Mitchell Hashimoto fd1db0c8e6
apprt/gtk-ng: new window menu action
Not sure why I skipped this one, its super easy.
2025-07-26 07:29:15 -07:00
Mitchell Hashimoto c24aa0e9be
update valgrind suppressions for a Linux wayland machine 2025-07-26 07:23:34 -07:00
Mitchell Hashimoto b389171476
Add per-font size adjustment, don't adjust nf symbol font or emoji font; use non-Mono symbols nerd font (#7953)
This adds functionality for choosing different normalization metrics for
each fallback font. It's not exposed as a config option, but could be in
the future, which would probably go a long way towards addressing
concerns like #7929.

The currently available reference metrics are, in priority order:
`ic_width, ex_height, cap_height, line_height, em_size`. The default
value is `ic_width`.

By priority order, I mean that if the chosen metric is not defined in
the fallback font, we move to the next metric in the list---we don't
normalize by an estimated metric from the fallback font (however, we're
happy to use an estimated metric from the primary font, that's how
`ic_width` normalization between CJK and Latin fonts work). This extends
the pattern that was used between `ic_width` and `ex_height` in the
existing hardcoded rule. `line_height` is always defined, so the buck
stops there.

What motivated me to implement this was the fact that, with the existing
hardcoded rule, the embedded symbols-only Nerd Font was always scaled up
by a factor of 1.2, which turned out to be an important reason why it's
been difficult to make icon scaling work to everyone's satisfaction.
Accordingly, the symbols-only font is the first to take advantage of the
new functionality. If this PR is merged, #7917 is no longer needed. (To
limit the scope of this PR, it only includes the minimal changes to let
icon scaling take advantage of this functionality. I may submit a
follow-up PR with some further icon scaling improvement enabled by
this.)
2025-07-26 07:08:44 -07:00
Mitchell Hashimoto fcbc58401f
Upgrade hustcer/milestone-action to v2.9 (#8074)
Upgrade
[hustcer/milestone-action](https://github.com/hustcer/milestone-action)
to v2.9, [Release
Detail](https://github.com/hustcer/milestone-action/releases/tag/v2.9)

Fix the deprecated warning here:
https://github.com/ghostty-org/ghostty/actions/runs/16531137360/job/46756561930#step:3:37
2025-07-26 07:01:12 -07:00
Mitchell Hashimoto bdf14cf29d
gtk-ng: add ipc infrastructure and connect +new-window ipcs (#8069) 2025-07-26 07:00:59 -07:00
hustcer 259266223c Upgrade hustcer/milestone-action to v2.9 2025-07-26 11:57:13 +08:00
Jeffrey C. Ollie ed584e769f
gtk-ng: add ipc infrastructure and connect +new-window ipcs 2025-07-25 22:48:39 -05:00
Mitchell Hashimoto 858e705973
apprt/gtk-ng: window headerbar, maximize, fullscreen (#8071)
This ports over a basic headerbar, maximize, and fullscreen. The
headerbar only has the main menu button for now since we have no tabbing
or splits. The main menu has the full main menu that mainline GTK has
but most of it is disabled since we don't implement the actions yet.

I didn't use anything from your branch @tristan957 so I didn't add
coauthor but I want to note that @tristan957 worked on this as well and
I suspect there's overlap.
2025-07-25 20:45:41 -07:00
Mitchell Hashimoto a8d0a84530
apprt/gtk-ng: hook up window close confirmation 2025-07-25 15:12:55 -07:00
Mitchell Hashimoto a25a0011ea
apprt/gtk-ng: more actions 2025-07-25 14:53:18 -07:00
Mitchell Hashimoto 7d33d39a45
blp formatting 2025-07-25 13:56:41 -07:00
Mitchell Hashimoto 7f2f603fbd
apprt/gtk-ng: handle headerbar visibility by config 2025-07-25 13:52:12 -07:00
Mitchell Hashimoto 20b6d8ad79
gtk-ng: tell systemd when Ghostty is ready (#8070) 2025-07-25 13:36:45 -07:00
Mitchell Hashimoto 5fd7e0814d
typos 2025-07-25 13:36:05 -07:00
Mitchell Hashimoto 7f3dda7ea4
apprt/gtk-ng: setup headervar-visible binding 2025-07-25 13:35:43 -07:00
Mitchell Hashimoto 6cf8007cf7
apprt/gtk-ng: toggle fullscreen and maximize 2025-07-25 13:17:13 -07:00
Jeffrey C. Ollie 95df073455
gtk-ng: tell systemd when Ghostty is ready 2025-07-25 15:16:50 -05:00
Mitchell Hashimoto 5b37e86391
apprt/gtk-ng: close surface, close window 2025-07-25 12:59:47 -07:00
Mitchell Hashimoto f27fd0f550
apprt/gtk-ng: main menu button shouldn't focus 2025-07-25 12:47:26 -07:00
Mitchell Hashimoto 297e9cb8ab
new suppressions to deal solely with showing the about window 2025-07-25 12:19:34 -07:00
Mitchell Hashimoto 02e6ef7e9b
apprt/gtk-ng: setup action maps in app and window 2025-07-25 12:10:30 -07:00
Mitchell Hashimoto e865535f6e
apprt/gtk-ng: simple headerbar 2025-07-25 12:10:11 -07:00
Mitchell Hashimoto b8dd767fe4
apprt/gtk: fix double-free if quit action is used (#8068)
This fixes a double-free that Valgrind found when the quit action was
used (the keybinding to quit or the menu item). This fixes it in both
the gtk and gtk-ng apprts.

The issue stems from the fact that our quit action worked by traversing
the toplevels and destroying all windows. When all windows are
destroyed, GTK exits the main loop.

When fcitx is used as the input method editor (IME), it appears to hold
its own `gtk.Window` widget as a property (probably for the IME popup).
Unfortunately this does not react well to being destroyed externally and
triggers a double-free when the IME widget also tries to dispose itself.

I think this is probably a bug somewhere in the GTK IME widget because
it should be resilient to this kind of destruction. But, we can't
tolerate a double free in the mean time.

We can still quit by destroying only OUR windows (which cascades to
destroy everything else).
2025-07-25 12:01:54 -07:00
Mitchell Hashimoto a477921b80
apprt/gtk: fix double-free if quit action is used
This fixes a double-free that Valgrind found when the quit action was
used (the keybinding to quit or the menu item). 

The issue stems from the fact that our quit action worked by traversing the 
toplevels and destroying all windows. When all windows are destroyed,
GTK exits the main loop.

When fcitx is used as the input method editor (IME), it appears to hold
its own `gtk.Window` widget as a property (probably for the IME popup).
Unfortunately this does not react well to being destroyed externally and
triggers a double-free when the IME widget also tries to dispose itself.

I think this is probably a bug somewhere in the GTK IME widget because
it should be resilient to this kind of destruction. But, we can't
tolerate a double free in the mean time.

We can still quit by destroying only OUR windows (which cascades to
destroy everything else).
2025-07-25 11:53:22 -07:00
Qwerasd 92fa2228e9 font: use non-mono symbols nerd font for embedded symbols
I changed my mind, this is a pretty small change and relevant to the
intent of the PR. This brings the appearance of the embedded symbols
much closer to patched fonts.

With this, the sizes of most symbols are nearly identical to a patched
font, the only big difference is positioning (and TBH I think we do a
better job positioning than the patcher does, since we have knowledge
about the cell size).
2025-07-25 12:41:00 -06:00
Jeffrey C. Ollie abfab82ef7
gtk-ng: add debug warning banner (#8057) 2025-07-25 13:18:58 -05:00
Qwerasd 6af6357949 font: clean up Collection api somewhat
Move size adjustment logic out of `Entry`, I understand the impulse to
put it there but it results in passing a lot of stuff around which isn't
great.

Rework `add(...)` in to `add(...)` and `addDeferred(...)`, faces are
passed directly now instead of passing an entry, and an options struct
is used instead of positional arguments for things like style, fallback,
and size adjustment.

Change size adjustment test back to a half pixel tolerance instead of 5%
because the previous commit (allowing fractional pixel sizes) fixed the
root cause of large differences.
2025-07-25 11:50:59 -06:00
Jeffrey C. Ollie f390941fd6
gtk-ng: move debug property to window 2025-07-25 12:46:56 -05:00
Jeffrey C. Ollie 33135f19dc
gtk-ng: add debug warning banner 2025-07-25 12:46:55 -05:00
Qwerasd 9405522dd5 font: allow fractional pixel sizes 2025-07-25 11:36:03 -06:00
Mitchell Hashimoto 3cdd6f4f5e
apprt/gtk-ng: surface inheritance, new window (#8067)
This makes the `new_window` action properly inherit properties from the
parent surface that initiated the action. Today, that is only the pwd
and font size.
2025-07-25 10:29:45 -07:00
Mitchell Hashimoto 830d49c185
apprt/gtk-ng: surface inheritance, new window
This makes the `new_window` action properly inherit properties from the
parent surface that initiated the action. Today, that is only the pwd
and font size.
2025-07-25 10:17:08 -07:00
Mitchell Hashimoto 787960e56d
apprt/gtk-ng: hook up bell ringing (#8065)
For now, this just emits a signal that an embedding widget will react to
to do something like flashing the window.

I think we should implement the audio bell in the actual surface view
but I don't currently have audio drivers hooked up in my Linux VM and
I'm away from my desktop PC. :)

cc @jcollie if you're interested, pretty tightly scoped.
2025-07-25 09:29:16 -07:00
Mitchell Hashimoto b36b7031a1
apprt/gtk-ng: hook up bell ringing
For now, this just emits a signal that an embedding widget will react to
to do something like flashing the window. 

I think we should implement the audio bell in the actual surface view
but I don't currently have audio drivers hooked up in my Linux VM and
I'm away from my desktop PC. :)
2025-07-25 09:01:45 -07:00
Mitchell Hashimoto 6d6b911fad
macos: add more Tahoe menu item icons from SF Symbols (#8050)
This is a follow up to https://github.com/ghostty-org/ghostty/pull/7594
<img width="487" height="318" alt="Screenshot 2025-07-24 at 23 10 20"
src="https://github.com/user-attachments/assets/83491b18-ef64-4a8f-b63d-a0001352cc31"
/>
<img width="544" height="295" alt="Screenshot 2025-07-24 at 23 11 01"
src="https://github.com/user-attachments/assets/10922879-ac1b-409d-8a3b-c298a1411813"
/>
2025-07-25 07:24:11 -07:00
Weizhao Ouyang b7f6da7857 macos: add more Tahoe menu item icons from SF Symbols
Signed-off-by: Weizhao Ouyang <o451686892@gmail.com>
2025-07-25 22:14:13 +08:00
Jinhyeok Lee 0a8e71f862
i18n: Updated translation for ko_KR 2025-07-25 12:56:50 +09:00
Qwerasd c0ee4a252a font: revert switch to non-mono symbols nerd font
This change might be good, but it is incomplete and not relevant to the
PR that it's a part of. I'll explore making this change separately after
this, since it might be a good idea.

(It's incomplete since the attribute data was not re-generated based on
the non-mono file.)
2025-07-24 17:52:41 -06:00
Qwerasd 2054a06533 cleanup
A variety of naming, commenting, and formatting improvements + a few
explicit error sets. This commit has no functional changes, though it
does remove a couple functions that didn't really need to exist.
2025-07-24 17:48:57 -06:00
trag1c 03ea024bc1
i18n: Updated translation for nl_NL (#8040) 2025-07-24 21:29:40 +02:00
Mitchell Hashimoto 8016e0be6d
Fix tab titles not being preserved with window-save-state (#8037)
Fixes #7938



https://github.com/user-attachments/assets/766a5d7a-f660-428f-b82b-3eafea83eff3
2025-07-23 16:48:35 -07:00
Mitchell Hashimoto 70f6e8b03f
apprt/gtk-ng: surface progress bar (#8045)
Straightforward port of existing functionality. No memory leaks
detected.
2025-07-23 16:39:19 -07:00
Mitchell Hashimoto 00cce91dc4
apprt/gtk-ng: surface progress bar 2025-07-23 16:29:56 -07:00
Mitchell Hashimoto eb3f3fff83
apprt/gtk-ng: keep child_exited property up to date 2025-07-23 16:03:27 -07:00
Mitchell Hashimoto 9a3239ba9f
apprt/gtk-ng: child exited overlay (#8044)
This ports the child exited overlay.

We're able to use Zig comptime and Blueprint templates to use the same
Surface blueprint for this even if libadwaita is too old to support
banners (< 1.3) by inheriting from `gtk.Widget` instead and not
instantiating the blueprint. Its a bit noisy to maintain the `noop`
version but we should be able to test that compilation in CI (we do via
Debian 12).
2025-07-23 16:01:35 -07:00
Mitchell Hashimoto cd664078ad
apprt/gtk-ng: child exited overlay 2025-07-23 15:47:44 -07:00
Jeffrey C. Ollie 8571bd67f9
devshell: add deps that allow GTK to load SVG resources (#8041)
GTK dynamically loads librsvg when it needs to convert a SVG-only icon
(or any other SVG-only resource) for display. This PR adds the libraries
that GTK needs so that running programs from within the developer shell
can display those SVG resources.
2025-07-23 16:09:20 -05:00
Jeffrey C. Ollie 3dc45fcd55
devshell: add deps that allow GTK to load SVG resources
GTK dynamically loads librsvg when it needs to convert a SVG-only icon
(or any other SVG-only resource) for display. This PR adds the libraries
that GTK needs so that running programs from within the developer shell
can display those SVG resources.
2025-07-23 15:48:00 -05:00
Merijntje Tak e8ab00aa4b
Added translation for nl_NL 2025-07-23 22:37:03 +02:00
Mitchell Hashimoto f7424c8a76
apprt/gtk-ng: surface drag and drop (#8039) 2025-07-23 12:48:43 -07:00
Mitchell Hashimoto 550d29d930
apprt/gtk-ng: surface drag and drop 2025-07-23 12:35:31 -07:00
Mitchell Hashimoto 9ea87ec096
New icon for Linux GTK app that aligns with the Gnome HIG (#8038)
This adds a new icon for the GTK-based application that adheres (mostly)
to the Gnome Human Interface Guidelines (HIG). The icon is designed to
fit in better with other Gnome applications.

While there isn't a single standard "native" style amongst Linux
applications, I believe this better fits the general Linux desktop
ecosystem over our macOS icon.

The icon itself is undeniably Ghostty. The core design language is the
same and I don't think ayone will mistake it for anything else. I wanted
to keep the brand the same, but making it fit in better aligns with
Ghostty's goal of being "platform native".

As of this PR, you can't use the macOS icon on Linux without modifying
the source. We may provide a compile-time option to swap icons in the
future (unfortunately Linux desktop applications require hardcoding an
icon path in the desktop files, so making it runtime selectable is...
messy!)

<img width="2048" height="2048" alt="2048"
src="https://github.com/user-attachments/assets/0b15e6db-bb6d-424c-8a83-ca809759b0c4"
/>
2025-07-23 10:06:19 -07:00
Mitchell Hashimoto b50c1c4fa0
New icon for Linux GTK app that aligns with the Gnome HIG
This adds a new icon for the GTK-based application that adheres (mostly)
to the Gnome Human Interface Guidelines (HIG). The icon is designed to
fit in better with other Gnome applications. 

While there isn't a single standard "native" style amongst Linux
applications, I believe this better fits the general Linux desktop
ecosystem over our macOS icon.

The icon itself is undeniably Ghostty. The core design language is the
same and I don't think ayone will mistake it for anything else. I wanted
to keep the brand the same, but making it fit in better aligns with
Ghostty's goal of being "platform native".
2025-07-23 10:00:55 -07:00
Bryan Lee 852eb2e0d5
Fix tab titles not being preserved with window-save-state
Add serialization for tab titles in SurfaceView to persist user-set titles across app restarts. Bump TerminalRestorableState version to 4 to handle the new format.
2025-07-23 23:21:44 +08:00
Mitchell Hashimoto df57f17be8
apprt/gtk-ng: bind template callbacks so we can connect signals in blp (#8035)
This creates a helper so that we can call
[`gtk_widget_class_bind_template_callback_full`](https://docs.gtk.org/gtk4/class_method.Widget.bind_template_callback_full.html)
and register signal handlers directly in our Blueprint file. This gets
rid of a LOT of boilerplate!

A draft, since there are TODOs:

- [x] Add comptime verification of the `func` param
- [x] Convert more blueprint files
2025-07-23 07:30:25 -07:00
Mitchell Hashimoto 010e9199ca
apprt/gtk-ng: bind template callbacks so we can connect signals in blp 2025-07-23 07:24:00 -07:00
Mitchell Hashimoto 2e68f0a4d4
update zig-gobject pick up fix for ianprime0509/zig-gobject#111 (#8036) 2025-07-23 07:01:48 -07:00
Jeffrey C. Ollie 80b72dd6cb
update zig-gobject pick up fix for ianprime0509/zig-gobject#111 2025-07-22 23:45:19 -05:00
Mitchell Hashimoto eae4124ed8
build(deps): bump namespacelabs/nscloud-cache-action from 1.2.12 to 1.2.13 (#8034)
Bumps
[namespacelabs/nscloud-cache-action](https://github.com/namespacelabs/nscloud-cache-action)
from 1.2.12 to 1.2.13.
<details>
<summary>Commits</summary>
<ul>
<li><a
href="9ff6d4004d"><code>9ff6d40</code></a>
Merge pull request <a
href="https://redirect.github.com/namespacelabs/nscloud-cache-action/issues/27">#27</a>
from namespacelabs/niklas-go-single-command</li>
<li><a
href="11812fa33c"><code>11812fa</code></a>
Use a single <code>go env</code> invocation in <code>go</code> cache
mode.</li>
<li><a
href="5dd70d607c"><code>5dd70d6</code></a>
Merge pull request <a
href="https://redirect.github.com/namespacelabs/nscloud-cache-action/issues/26">#26</a>
from namespacelabs/niklas-doc</li>
<li><a
href="834227b234"><code>834227b</code></a>
document brew mode</li>
<li>See full diff in <a
href="c343d6c4c2...9ff6d4004d">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.12&new-version=1.2.13)](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-07-22 19:28:30 -07:00
dependabot[bot] 72220bb69f
build(deps): bump namespacelabs/nscloud-cache-action
Bumps [namespacelabs/nscloud-cache-action](https://github.com/namespacelabs/nscloud-cache-action) from 1.2.12 to 1.2.13.
- [Release notes](https://github.com/namespacelabs/nscloud-cache-action/releases)
- [Commits](c343d6c4c2...9ff6d4004d)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-23 01:02:04 +00:00
Mitchell Hashimoto c979ece916
build-system: Replace deprecated usages of root_source_file on addTests (#8031)
Yet another low-hanging fruit
2025-07-22 15:28:11 -07:00
Mitchell Hashimoto 95ccf3abb2
apprt/gtk-ng: move overlays and event controllers into Blueprint (#8032)
I became far less stupid and figured out how to figure this out by
reading the source code and since then I've been enlightened and can
clean up our Blueprints quite a bit. Yay!

I learned that you can add overlays to a `gtk.Overlay` with the
`[overlay]` child type. And if you embed event controllers directly,
`gtk.Widget` adds them
(https://gitlab.gnome.org/GNOME/gtk/-/blob/main/gtk/gtkwidget.c#L8805-8808).

cc @tristan957 yay!
2025-07-22 15:27:29 -07:00
Mitchell Hashimoto 2544c1fb22
apprt/gtk-ng: move overlays and event controllers into Blueprint
I became far less stupid and figured out how to figure this out by
reading the source code and since then I've been enlightened and can
clean up our Blueprints quite a bit. Yay!
2025-07-22 15:19:50 -07:00
Jayson Reis d5995ac45c
build-system: Replace deprecated usages of root_source_file on addTests 2025-07-23 00:03:44 +02:00
Jayson Reis acc2ea724f
build-system: Replace deprecated usages of addStaticLibrary with addLibrary (#8029)
Hi there, this is just a low-hanging fruit and it also prepares the way
for the future 0.15, which removes addStaticLibrary.
Please, let me know what to do on the `// TODO` comments.
2025-07-22 14:47:18 -07:00
Mitchell Hashimoto c903754b70
apprt/gtk-ng: clipboard support (#8030)
This ports over read/write clipboard to gtk-ng.

This was a surprisingly massive amount of work! The clipboard
confirmation dialog is non-trivial: it supports multiple read/write
types, blurring, remember choice, and spans multiple Adw versions. I was
able to port all of the functionality into a single
`CloseConfirmationDialog` class and make use of a good amount of
Blueprint binds to simplify some stuff.
2025-07-22 14:45:26 -07:00
Mitchell Hashimoto 04143645f2
apprt/gtk-ng: fixed missing icon for hide button 2025-07-22 14:38:36 -07:00
Mitchell Hashimoto 2855c44118
typos 2025-07-22 14:36:21 -07:00
Mitchell Hashimoto 5c21d9a123
prettier 2025-07-22 14:36:21 -07:00
Mitchell Hashimoto 7e329d3e4c
apprt/gtk-ng: paste can't remember 2025-07-22 14:36:21 -07:00
Mitchell Hashimoto 4d39f2728a
apprt/gtk-ng: implement remember 2025-07-22 14:36:21 -07:00
Mitchell Hashimoto 58a5f3f1f8
apprt/gtk-ng: emit signal when clipboard read/write 2025-07-22 14:36:21 -07:00
Mitchell Hashimoto a6e0878b11
apprt/gtk-ng: hook up all the dialogs 2025-07-22 14:36:21 -07:00
Mitchell Hashimoto b11dadafb1
apprt/gtk-ng: clipboard confirm 2025-07-22 14:36:21 -07:00
Mitchell Hashimoto 46e395055d
apprt/gtk-ng: implement blur 2025-07-22 14:36:21 -07:00
Mitchell Hashimoto 222c3c888d
apprt/gtk-ng: clipboard confirmation dialog 2025-07-22 14:36:21 -07:00
Mitchell Hashimoto a91ed99054
apprt/gtk-ng: fix focus deadlock 2025-07-22 14:36:21 -07:00
Mitchell Hashimoto a4f494e2ae
apprt/gtk-ng: wip set clipboard 2025-07-22 14:36:21 -07:00
Mitchell Hashimoto c3acbf1a49
apprt/gtk-ng: clipboard read 2025-07-22 14:36:21 -07:00
Mitchell Hashimoto 49cf8d80a6
core: use std.testing.expectEqualStrings where appropriate (#8025) 2025-07-22 13:40:25 -07:00
Jeffrey C. Ollie cc0a688b5d
core: use std.testing.expectEqualStrings where appropriate 2025-07-22 13:08:24 -05:00
Leah Amelia Chen 7eab97653d
terminal/osc: allow empty payloads (#8023) 2025-07-23 02:57:04 +09:00
Leah Amelia Chen c194f7a0cd
i18n(zh_CN): update strings 2025-07-22 17:38:49 +00:00
Leah Amelia Chen a01a40394a
i18n: update translations 2025-07-22 17:25:57 +00:00
Leah Amelia Chen a7b7c10474
gtk: only show clipboard toast when content isn't empty 2025-07-22 17:25:57 +00:00
Leah Amelia Chen d3f40d70e2
terminal/osc: allow empty payloads
xterm docs explicitly say that empty payloads should be permitted and
are used to clear the selected clipboards, so we need to implement that
correctly. The GTK apprt still shows a "Copied to Clipboard" toast though
and we might want to change that too
2025-07-22 16:50:29 +00:00
Daniel Wennberg 54b56af570 Rewrite comment for clarity 2025-07-22 09:30:43 -07:00
Daniel Wennberg 53b029284d Fix off-by-one error & adjust overline pos in cell height mod 2025-07-22 09:17:07 -07:00
Mitchell Hashimoto 820879d2ef
apprt/gtk-ng: port surface cgroup logic (#8013)
Absolutely nothing interesting here, just porting our cgroup logic.
2025-07-21 21:24:41 -07:00
Mitchell Hashimoto 8f8f2ebd2d
apprt/gtk-ng: surfaces start in cgroup if enabled 2025-07-21 21:21:09 -07:00
Mitchell Hashimoto 578fd7f7f8
apprt/gtk-ng: resize overlay (#8012)
This implements the resize overlay. This is implemented using a new
mostly generic `ResizeOverlay` class that can probably be renamed one
day to something like `TemporaryOverlay` since it is generic to show a
label with a duration.

The only user-facing change here is `after-first` behavior has been
changed in the config to actually mean "after a delay." The
`after-first` behavior has been problematic since we introduced it on
both macOS and Linux because a lot of windowing systems may perform
multiple resizes very quickly at startup (especially tiling ones) so its
less about being "first" and more about semantically only showing the
overlay for user-driven resizes. We should rename this, eventually.

The valgrind suppression file change is mostly to handle an alternate
machine, but its all the same stuff (GTK renderers, GPU drivers, etc.),
nothing new in our app code.
2025-07-21 21:05:14 -07:00
Mitchell Hashimoto 4aaacc04a5
fix logger name 2025-07-21 20:54:16 -07:00
Mitchell Hashimoto 6abb9ec427
ignore valgrind supp file for typos 2025-07-21 20:51:58 -07:00
Mitchell Hashimoto 66ce764d67
valgring supps for VMware VGA 2025-07-21 20:49:08 -07:00
Mitchell Hashimoto 9caf5f5a86
apprt/gtk-ng: ResizeOverlay class 2025-07-21 20:48:59 -07:00
Mitchell Hashimoto c6abf65dd1
apprt/gtk-ng: resize overlay 2025-07-21 14:02:16 -07:00
Mitchell Hashimoto e34248a2ad
apprt/gtk-ng: hovered url overlay (#8010)
I was going to do more overlays but this introduced enough new
complexity that I want to PR this on its own.

Valgrind clean!
2025-07-21 14:02:10 -07:00
Mitchell Hashimoto 58ccfb558a
apprt/gtk-ng: mouse over link to show tooltip 2025-07-21 12:56:03 -07:00
Mitchell Hashimoto 7711f6b5b6
apprt/gtk-ng: setup basic css resources 2025-07-21 09:58:46 -07:00
Mitchell Hashimoto 55a384e165
apprt/gtk-ng: implement quit timer, close app confirmation (#8006)
This PR tidies up our quit logic to match the GTK implementation,
respecting quit delays and also showing a confirmation dialog if
required. There shouldn't be anything surprising here, its mostly a
copy/paste of the old logic with very small tweaks to fit the new style.
2025-07-21 09:32:21 -07:00
Mitchell Hashimoto 2333815b6c
apprt/gtk-ng: implement app close confirmation dialog 2025-07-21 09:06:10 -07:00
Mitchell Hashimoto ab8717e320
apprt/gtk-ng: hook up basic quit functionality (no confirm) 2025-07-21 08:36:08 -07:00
Mitchell Hashimoto 3e83364937
apprt/gtk-ng: hook up quit timer 2025-07-21 08:36:08 -07:00
Mitchell Hashimoto 805c8601a9
apprt/gtk-ng: hook up title, pwd surface properties (#8005)
Continuing to plumb along the APIs necessary basic surface functionality
before moving onto windowing functionality. This adds title/pwd as
properties to Surface, adds abstractions necessary to manage that memory
correctly, and also adds a tiny change to renderers to make everything
slightly more usable under Valgrind.
2025-07-21 08:35:55 -07:00
Mitchell Hashimoto 7e834a1c32
apprt/gtk-ng: some actions 2025-07-21 08:15:42 -07:00
Mitchell Hashimoto edb5f7c69d
slow down our cursor timer under valgrind 2025-07-21 07:28:23 -07:00
Mitchell Hashimoto e911d53a2e
apprt/gtk-ng: get-title 2025-07-21 07:16:19 -07:00
Mitchell Hashimoto ef686d62aa
apprt/gtk-ng: clear memory properly 2025-07-21 07:08:46 -07:00
Mitchell Hashimoto cd82a610c3
apprt/gtk-ng: abstract helper for private string fields 2025-07-21 06:55:28 -07:00
Mitchell Hashimoto 9440c775c7
apprt/gtk-ng: set title 2025-07-20 15:23:43 -07:00
Mitchell Hashimoto 793e271989
apprt/gtk-ng: set pwd 2025-07-20 15:17:03 -07:00
Mitchell Hashimoto a88689ca75
apprt/gtk-ng: mouse shape,visibility (#7999)
Relatively simple port. A few cool things:

1. We use properties on `GhosttySurface` to set this now and standard
property listeners
2. We make `terminal.MouseShape` a GObject enum if we have gobject
available.
3. The property based approach means we don't have to manage
`*gdk.Cursor` memory anywhere anymore.

And, we're still Valgrind clean.
2025-07-20 14:53:24 -07:00
Mitchell Hashimoto fb2021bc9f
apprt/gtk-ng: correct default mouse shapes 2025-07-20 14:39:02 -07:00
Mitchell Hashimoto 4ffbd93ab5
apprt/gtk-ng: surface mouse visibility 2025-07-20 14:35:16 -07:00
Mitchell Hashimoto ecd14a8739
apprt/gtk-ng: surface mouse shape 2025-07-20 14:35:16 -07:00
Mitchell Hashimoto 2c6d978ed5
pkg/oniguruma: fix memory leak for failed regex searches (#7998)
Found by Valgrind:

```
==265734== 320 bytes in 8 blocks are definitely lost in loss record 13,786 of 15,141
==265734==    at 0x5A65810: malloc (in /nix/store/l431jn8ahj09g5c1arrl7q6wcxngg21q-valgrind-3.24.0/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==265734==    by 0x3D799EB: onig_region_resize (.cache/zig/p/N-V-__8AAHjwMQDBXnLq3Q2QhaivE0kE2aD138vtX2Bq1g7c/src/regexec.c:923)
==265734==    by 0x3D81BCA: onig_region_resize_clear (.cache/zig/p/N-V-__8AAHjwMQDBXnLq3Q2QhaivE0kE2aD138vtX2Bq1g7c/src/regexec.c:949)
==265734==    by 0x3DA814F: search_in_range (.cache/zig/p/N-V-__8AAHjwMQDBXnLq3Q2QhaivE0kE2aD138vtX2Bq1g7c/src/regexec.c:5454)
==265734==    by 0x3DA7F25: onig_search (.cache/zig/p/N-V-__8AAHjwMQDBXnLq3Q2QhaivE0kE2aD138vtX2Bq1g7c/src/regexec.c:5414)
==265734==    by 0x382E7E8: regex.Regex.searchAdvanced (regex.zig:61)
==265734==    by 0x382E974: regex.Regex.search (regex.zig:48)
==265734==    by 0x382EC08: terminal.StringMap.SearchIterator.next (StringMap.zig:40)
==265734==    by 0x39ADDCD: renderer.link.Set.matchSetFromLinks (link.zig:320)
==265734==    by 0x39AE5C7: renderer.link.Set.matchSet (link.zig:95)
==265734==    by 0x39BCCE1: renderer.generic.Renderer(renderer.OpenGL).rebuildCells (generic.zig:2307)
==265734==    by 0x39C3BDB: renderer.generic.Renderer(renderer.OpenGL).updateFrame (generic.zig:1228)
==265734==    by 0x3993E88: renderer.Thread.renderCallback (Thread.zig:607)
==265734==    by 0x3993CFF: renderer.Thread.wakeupCallback (Thread.zig:524)
==265734==    by 0x39C522E: callback (async.zig:679)
==265734==    by 0x39C522E: watcher.async.AsyncEventFd(api.Xev(.io_uring,backend.io_uring)).waitPoll__anon_592685__struct_596870.callback (async.zig:181)
==265734==    by 0x3970EAE: backend.io_uring.Completion.invoke (io_uring.zig:804)
==265734==    by 0x3973AD8: backend.io_uring.Loop.tick___anon_586861 (io_uring.zig:193)
==265734==    by 0x3973BCD: backend.io_uring.Loop.run (io_uring.zig:84)
==265734==    by 0x3978673: dynamic.Xev(&.{ .io_uring, .epoll }[0..2]).Loop.run (dynamic.zig:172)
==265734==    by 0x3978972: renderer.Thread.threadMain_ (Thread.zig:263)
==265734==    by 0x3954580: renderer.Thread.threadMain (Thread.zig:202)
==265734==    by 0x39279CA: Thread.callFn__anon_573552 (Thread.zig:488)
==265734==    by 0x38F4594: Thread.PosixThreadImpl.spawn__anon_570448.Instance.entryFn (Thread.zig:757)
==265734==    by 0x6E567EA: start_thread (pthread_create.c:448)
==265734==    by 0x6ED9FB3: clone (clone.S:100)
==265734==
```
2025-07-20 14:29:40 -07:00
Mitchell Hashimoto 9bdc29e00f
pkg/oniguruma: fix memory leak for failed regex searches
Found by Valgrind:

```
==265734== 320 bytes in 8 blocks are definitely lost in loss record 13,786 of 15,141
==265734==    at 0x5A65810: malloc (in /nix/store/l431jn8ahj09g5c1arrl7q6wcxngg21q-valgrind-3.24.0/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==265734==    by 0x3D799EB: onig_region_resize (.cache/zig/p/N-V-__8AAHjwMQDBXnLq3Q2QhaivE0kE2aD138vtX2Bq1g7c/src/regexec.c:923)
==265734==    by 0x3D81BCA: onig_region_resize_clear (.cache/zig/p/N-V-__8AAHjwMQDBXnLq3Q2QhaivE0kE2aD138vtX2Bq1g7c/src/regexec.c:949)
==265734==    by 0x3DA814F: search_in_range (.cache/zig/p/N-V-__8AAHjwMQDBXnLq3Q2QhaivE0kE2aD138vtX2Bq1g7c/src/regexec.c:5454)
==265734==    by 0x3DA7F25: onig_search (.cache/zig/p/N-V-__8AAHjwMQDBXnLq3Q2QhaivE0kE2aD138vtX2Bq1g7c/src/regexec.c:5414)
==265734==    by 0x382E7E8: regex.Regex.searchAdvanced (regex.zig:61)
==265734==    by 0x382E974: regex.Regex.search (regex.zig:48)
==265734==    by 0x382EC08: terminal.StringMap.SearchIterator.next (StringMap.zig:40)
==265734==    by 0x39ADDCD: renderer.link.Set.matchSetFromLinks (link.zig:320)
==265734==    by 0x39AE5C7: renderer.link.Set.matchSet (link.zig:95)
==265734==    by 0x39BCCE1: renderer.generic.Renderer(renderer.OpenGL).rebuildCells (generic.zig:2307)
==265734==    by 0x39C3BDB: renderer.generic.Renderer(renderer.OpenGL).updateFrame (generic.zig:1228)
==265734==    by 0x3993E88: renderer.Thread.renderCallback (Thread.zig:607)
==265734==    by 0x3993CFF: renderer.Thread.wakeupCallback (Thread.zig:524)
==265734==    by 0x39C522E: callback (async.zig:679)
==265734==    by 0x39C522E: watcher.async.AsyncEventFd(api.Xev(.io_uring,backend.io_uring)).waitPoll__anon_592685__struct_596870.callback (async.zig:181)
==265734==    by 0x3970EAE: backend.io_uring.Completion.invoke (io_uring.zig:804)
==265734==    by 0x3973AD8: backend.io_uring.Loop.tick___anon_586861 (io_uring.zig:193)
==265734==    by 0x3973BCD: backend.io_uring.Loop.run (io_uring.zig:84)
==265734==    by 0x3978673: dynamic.Xev(&.{ .io_uring, .epoll }[0..2]).Loop.run (dynamic.zig:172)
==265734==    by 0x3978972: renderer.Thread.threadMain_ (Thread.zig:263)
==265734==    by 0x3954580: renderer.Thread.threadMain (Thread.zig:202)
==265734==    by 0x39279CA: Thread.callFn__anon_573552 (Thread.zig:488)
==265734==    by 0x38F4594: Thread.PosixThreadImpl.spawn__anon_570448.Instance.entryFn (Thread.zig:757)
==265734==    by 0x6E567EA: start_thread (pthread_create.c:448)
==265734==    by 0x6ED9FB3: clone (clone.S:100)
==265734==
```
2025-07-20 14:17:03 -07:00
Mitchell Hashimoto 98f71d3e7a
apprt/gtk-ng: abstract our alert vs msg dialog into a superclass (#7995)
This introduces a new `GhosttyDialog` class that either inherits from
`adw.MessageDialog` or `adw.AlertDialog`, depending on the version of
libadwaita we compile against. This is the same logic we used
previously.

This lets us have a single libadw 1.2 blueprint file for all dialogs and
we just do the right thing at compile time!
2025-07-20 13:21:22 -07:00
Mitchell Hashimoto 001dfcf3d6
apprt/gtk-ng: abstract our alert vs msg dialog into a superclass
This introduces a new `GhosttyDialog` class that either inherits from 
`adw.MessageDialog` or `adw.AlertDialog`, depending on the version of
libadwaita we compile against. This is the same logic we used
previously.

This lets us have a single libadw 1.2 blueprint file for all dialogs and 
we just do the right thing at compile time!
2025-07-20 13:18:56 -07:00
Mitchell Hashimoto 357dd26cf9
apprt/gtk-ng: implement `Surface.close` (#7994)
A small, simple change. This implements the `Surface.close` apprt
required function. After this PR, a process exiting within the terminal
will close the window properly (unless `wait-after-command` is set of
course!).

This doesn't yet show close confirmation. I'm working on some dialog
refactors on the side to see if we can simplify our Adw 1.2 vs. 1.5
dialogs and didn't want to include it here.

Close now works by the `GhosttySurface` class emitting the
`close-request` signal (similar to a `gtk.Window`) and the parent
container is responsible for closing it. This will let us reuse the
surface within different contexts: tabs, splits, etc.

This also remove the unused `shouldClose`, `setShouldClose` apprt APIs
which are a holdover from the glfw days!
2025-07-20 07:05:12 -07:00
Mitchell Hashimoto aadb2c05e5
apprt/gtk-ng: hook up Surface.close 2025-07-19 14:19:32 -07:00
Mitchell Hashimoto 2e9ee16455
core: remove Surface.shouldClose
This was a noop in all of our apprts and I think is a holdover from the
glfw days.
2025-07-19 14:03:48 -07:00
Mitchell Hashimoto aa7cceebe9
gtk: update zig-gobject to get improved gobject accessors (#7992) 2025-07-19 13:20:54 -07:00
Mitchell Hashimoto 8220db8ce1
apprt/gtk-ng: update to the new typedaccessor API 2025-07-19 13:17:17 -07:00
Jeffrey C. Ollie 22b2344f50 gtk: update zig-gobject to get improved gobject accessors 2025-07-19 13:01:33 -07:00
Mitchell Hashimoto 1ec4383931
Fully remove the redrawSurface API (#7991)
This is a tiny addon from the recent gtk-ng work. We've moved redraw
requests into the apprt action system (the `render` action). I waited
until I had my macOS machine to verify that this fix could work. We can
now remove this completely.

We can probably remove the redraw inspector API too at some point but
I'm not there yet with the GTK backend so I'll just wait on it.
2025-07-19 12:59:36 -07:00
Mitchell Hashimoto 7f0c247767
Fully remove the redrawSurface API
This is a tiny addon from the recent gtk-ng work. We've moved redraw
requests into the apprt action system (the `render` action). I waited
until I had my macOS machine to verify that this fix could work. We can
now remove this completely.

We can probably remove the redraw inspector API too at some point but
I'm not there yet with the GTK backend so I'll just wait on it.
2025-07-19 07:30:20 -07:00
Mitchell Hashimoto 88b317dba3
apprt/gtk-ng: surface input (mouse, keyboard, focus, etc.) (#7986)
This ports back all our event controllers back to the `GhosttySurface`. 

With this PR, the terminal is now usable again at a very very simple
level!

This also brings back `winproto` but its still filled with
incompatibilities. I just need to bring that back so modifiers worked
properly. We'll fix that up in a future PR.

This also fixes one undefined memory access in debug modes found by
Valgrind.
2025-07-19 06:42:31 -07:00
Jon Parise a2b473b77f
fish: fix ssh-term infocmp shell expansion (#7960) 2025-07-19 08:00:40 -04:00
HuaDeity d8c64c0511
Remove unnecessary stderr redirection in fish integration 2025-07-19 16:52:55 +08:00
HuaDeity 6769f3c307
Fix shell variable expansion in fish SSH setup 2025-07-19 16:52:03 +08:00
Mitchell Hashimoto 238015c171
termio: simplify logging to remove undefined access 2025-07-18 15:17:41 -07:00
Mitchell Hashimoto 5ef36b39c4
apprt/gtk-ng: port keyEvent 2025-07-18 15:09:15 -07:00
Mitchell Hashimoto c2ddb6eca6
apprt/gtk-ng: scroll 2025-07-18 15:02:06 -07:00
Mitchell Hashimoto 9659b484b5
apprt/gtk-ng: cursor position 2025-07-18 15:02:05 -07:00
Mitchell Hashimoto 6f01897907
apprt/gtk-ng: mouse click 2025-07-18 15:02:05 -07:00
Mitchell Hashimoto c23adeef38
apprt/gtk-ng: surface input 2025-07-18 15:02:05 -07:00
Mitchell Hashimoto 1037428813
apprt/gtk-ng: bring over just enough winproto to compile 2025-07-18 15:01:58 -07:00
Mitchell Hashimoto 39f4cf3d19
apprt/gtk-ng: very basic no-input surface (#7985)
This ports over the `new_window` functionality and shows a single
no-input, no-tab, no-split surface. The surface renders (e.g. the cursor
blinks) and it is a full Ghostty surface underneath so the shell prompt
shows up and everything. However, the surface doesn't respond to input.

I'm going to put this PR up in this state so that it isn't too much all
at once.

This work also required some core libghostty improvements that just
didn't fit the model being built here. They're extremely minimal,
however (basically going from struct fields to struct decls so we can do
some logic).

A couple new Valgrind suppressions had to be added to deal with GLAreas.
These suppressions were necessary before we ever hooked up our renderers
so they're caused by GTK itself. Only two, though! Other than that,
Ghostty runs **Valgrind clean**.

<img width="1726" height="714" alt="2025-07-18-131732_hyprshot"
src="https://github.com/user-attachments/assets/9c8bfe86-705c-4173-916b-df2b9b54dbfd"
/>
2025-07-18 14:55:35 -07:00
Mitchell Hashimoto 432fec7065
comments 2025-07-18 13:12:09 -07:00
Mitchell Hashimoto 7c77133a83
apprt/gtk-ng: implement size callbacks for surface 2025-07-18 13:07:31 -07:00
Mitchell Hashimoto f0a0333bc0
apprt/gtk-ng: hook up surface render 2025-07-18 12:43:24 -07:00
Mitchell Hashimoto 2ab5d3cd81
apprt/gtk-ng: implement the quit_timer action to just quit 2025-07-18 11:42:44 -07:00
Mitchell Hashimoto 7c9e913ca9
apprt/gtk-ng: hook up surface initialization 2025-07-18 11:42:44 -07:00
Mitchell Hashimoto 9f2ff0cb9c
apprt/gtk-ng: introduce a basic surface 2025-07-18 11:42:44 -07:00
Mitchell Hashimoto 40818d4f7c
terminal: viewport_pin must be initialized (#7982)
Even though the viewport pin isn't used unless the `viewport` is `pin`,
it's still possible to access undefined data through `clone`. Valgrind
found this:

```
==107091== Conditional jump or move depends on uninitialised value(s)
==107091==    at 0x392B96A: terminal.PageList.clone (PageList.zig:540)
==107091==    by 0x392C9A0: terminal.Screen.clonePool (Screen.zig:348)
==107091==    by 0x392DF7A: terminal.Screen.clone (Screen.zig:330)
==107091==    by 0x394E6D4: renderer.generic.Renderer(renderer.OpenGL).updateFrame (generic.zig:1129)
==107091==    by 0x3919BF8: renderer.Thread.renderCallback (Thread.zig:607)
==107091==    by 0x3919A6F: renderer.Thread.wakeupCallback (Thread.zig:524)
==107091==    by 0x394FA6E: callback (async.zig:679)
==107091==    by 0x394FA6E: watcher.async.AsyncEventFd(api.Xev(.io_uring,backend.io_uring)).waitPoll__anon_436371__struct_440666.callback (async.zig:181)
==107091==    by 0x38F781E: backend.io_uring.Completion.invoke (io_uring.zig:804)
==107091==    by 0x38FA448: backend.io_uring.Loop.tick___anon_431479 (io_uring.zig:193)
==107091==    by 0x38FA53D: backend.io_uring.Loop.run (io_uring.zig:84)
==107091==    by 0x38FEFE3: dynamic.Xev(&.{ .io_uring, .epoll }[0..2]).Loop.run (dynamic.zig:172)
==107091==    by 0x38FF2E2: renderer.Thread.threadMain_ (Thread.zig:263)
==107091==    by 0x38DDF80: renderer.Thread.threadMain (Thread.zig:202)
==107091==    by 0x38B5C0A: Thread.callFn__anon_421402 (Thread.zig:488)
==107091==    by 0x3888604: Thread.PosixThreadImpl.spawn__anon_418943.Instance.entryFn (Thread.zig:757)
==107091==    by 0x6C6E7EA: start_thread (pthread_create.c:448)
==107091==    by 0x6CF1FB3: clone (clone.S:100)
==107091==
```
2025-07-18 11:42:26 -07:00
Mitchell Hashimoto d2ec05a102
terminal: viewport_pin must be initialized
Even though the viewport pin isn't used unless the `viewport` is `pin`,
it's still possible to access undefined data through `clone`. Valgrind
found this:

```
==107091== Conditional jump or move depends on uninitialised value(s)
==107091==    at 0x392B96A: terminal.PageList.clone (PageList.zig:540)
==107091==    by 0x392C9A0: terminal.Screen.clonePool (Screen.zig:348)
==107091==    by 0x392DF7A: terminal.Screen.clone (Screen.zig:330)
==107091==    by 0x394E6D4: renderer.generic.Renderer(renderer.OpenGL).updateFrame (generic.zig:1129)
==107091==    by 0x3919BF8: renderer.Thread.renderCallback (Thread.zig:607)
==107091==    by 0x3919A6F: renderer.Thread.wakeupCallback (Thread.zig:524)
==107091==    by 0x394FA6E: callback (async.zig:679)
==107091==    by 0x394FA6E: watcher.async.AsyncEventFd(api.Xev(.io_uring,backend.io_uring)).waitPoll__anon_436371__struct_440666.callback (async.zig:181)
==107091==    by 0x38F781E: backend.io_uring.Completion.invoke (io_uring.zig:804)
==107091==    by 0x38FA448: backend.io_uring.Loop.tick___anon_431479 (io_uring.zig:193)
==107091==    by 0x38FA53D: backend.io_uring.Loop.run (io_uring.zig:84)
==107091==    by 0x38FEFE3: dynamic.Xev(&.{ .io_uring, .epoll }[0..2]).Loop.run (dynamic.zig:172)
==107091==    by 0x38FF2E2: renderer.Thread.threadMain_ (Thread.zig:263)
==107091==    by 0x38DDF80: renderer.Thread.threadMain (Thread.zig:202)
==107091==    by 0x38B5C0A: Thread.callFn__anon_421402 (Thread.zig:488)
==107091==    by 0x3888604: Thread.PosixThreadImpl.spawn__anon_418943.Instance.entryFn (Thread.zig:757)
==107091==    by 0x6C6E7EA: start_thread (pthread_create.c:448)
==107091==    by 0x6CF1FB3: clone (clone.S:100)
==107091==
```
2025-07-18 11:39:18 -07:00
Mitchell Hashimoto d924593993
apprt/gtk-ng: extract common methods into a mixin (#7981)
Every GObject class we're ever going to make has the same handful of
methods. This adds *just enough* noise to be annoying. This commit
extracts the common ones so far into a central mixin. Since Zig is
removing `usingnamespace` and has no other mixin mechanism, we must
forward the decls, but this is still cleaner imo than what we did
before.

I suspect longer term we can probably abstract more of the `zig-gobject`
boilerplate into a higher level abstraction but I'm not confident doing
that yet across the 4 classes we have so far.

Credit to @pluiedev for pointing this out.
2025-07-18 07:34:47 -07:00
Mitchell Hashimoto 833f7f1142
apprt/gtk-ng: extract common methods into a mixin
Every GObject class we're ever going to make has the same handful of
methods. This adds *just enough* noise to be annoying. This commit
extracts the common ones so far into a central mixin. Since Zig is
removing `usingnamespace` and has no other mixin mechanism, we must
forward the decls, but this is still cleaner imo than what we did
before.

I suspect longer term we can probably abstract more of the `zig-gobject`
boilerplate into a higher level abstraction but I'm not confident doing
that yet across the 4 classes we have so far.
2025-07-18 07:31:29 -07:00
Jeffrey C. Ollie 49ed5bc870
core/gtk: add support for displaying a progress bar with OSC 9;4 (#7975)
Ghostty has had support for a while (since PR #3124) for parsing
progress reports but never did anything with them. This PR adds the core
infrastructure and an implementation for GTK.

On GTK, the progress bar will show up as a thin bar along the top of the
terminal. Under normal circumstances it will use whatever you have set
as your accent color. If the progam sending the progress report
indicates an error, it will change to a reddish color.
2025-07-18 09:15:36 -05:00
Daniel Wennberg 652bae7379 Update a straggling name and signature 2025-07-18 00:58:08 -07:00
Daniel Wennberg a7c560c159 Calculate scaled size directly, eliminate redundant resizes 2025-07-18 00:58:08 -07:00
Jeffrey C. Ollie 38f044cd87
gtk-ng: fix missing progress_report action 2025-07-17 22:39:02 -05:00
Jeffrey C. Ollie 2d76c105bf
gtk: remove notes about accessibility 2025-07-17 22:36:27 -05:00
Jeffrey C. Ollie c015a6248d
gtk: add comments about C API types to sync 2025-07-17 22:36:27 -05:00
Jeffrey C. Ollie 7a60fb2d08
core/gtk: add support for displaying a progress bar with OSC 9;4
Ghostty has had support for a while (since PR #3124) for parsing progress
reports but never did anything with them. This PR adds the core
infrastructure and an implementation for GTK.

On GTK, the progress bar will show up as a thin bar along the top of
the terminal. Under normal circumstances it will use whatever you have
set as your accent color. If the progam sending the progress report
indicates an error, it will change to a reddish color.
2025-07-17 22:36:27 -05:00
Mitchell Hashimoto 7d99042070
gtk-ng: port ConfigErrorsDialog (#7968)
This ports the config errors dialog from `apprt/gtk` to `gtk-ng`. 

The major change here is that we now use proper template bindings for
the content. To do this, a `ghostty.Config` is now wrapped in a GObject
`GhosttyConfig` to make it safe to pass around (ref count) and to
provide helpful properties like the diagnostics buffer we bind to.

As a minor change, I stripped the `Ghostty` prefix from our GObject
classes in Zig code. For templates its all still there as is the norm.

This retains the exact same version requirements and layout as the
existing one.
2025-07-17 20:26:43 -07:00
Daniel Wennberg 054b7325dc Add unwrapConst, avoid constCast 2025-07-17 17:27:45 -07:00
Daniel Wennberg ce507f35df Use em size as nerd font reference metric 2025-07-17 17:04:47 -07:00
Daniel Wennberg e7d28a85c8 Make size normalization reference customizable per face 2025-07-17 17:04:47 -07:00
Daniel Wennberg 6491ea41fb Move face metric fallback estimates to the FaceMetric struct 2025-07-17 15:45:47 -07:00
Mitchell Hashimoto 9b99e41cb2
apprt/gtk-ng: fix config textbuffer memory leak 2025-07-17 13:29:42 -07:00
Mitchell Hashimoto 8556877883
Add valgrind suppression file 2025-07-17 12:52:20 -07:00
Mitchell Hashimoto 155ddc3f8f
Surface: use rect selection state when setting selection on release (#7972)
Looks like 52354b8 missed noting the outgoing screen selection state's
rectangle flag when setting the selection on mouse release, this was
causing the selection that was actually set to be
standard/wrap-selected. This corrects that by just shipping said flag
when calling `setSelection`.
2025-07-17 12:46:13 -07:00
Chris Marchesi 3febc7c5ee
Surface: use rect selection state when setting selection on release
Looks like 52354b8 missed noting the outgoing screen selection state's
rectangle flag when setting the selection on mouse release, this was
causing the selection that was actually set to be
standard/wrap-selected. This corrects that by just shipping said flag
when calling setSelection.
2025-07-17 12:37:20 -07:00
Mitchell Hashimoto b2fe9fd7db
apprt/gtk-ng: fix merge conflict 2025-07-17 10:00:05 -07:00
Mitchell Hashimoto 562bd7e458
comments 2025-07-17 09:55:59 -07:00
Mitchell Hashimoto cac32fc60d
apprt/gtk-ng: hook up adw < 1.5 support 2025-07-17 09:55:59 -07:00
Mitchell Hashimoto 039e248ec9
typos 2025-07-17 09:55:59 -07:00
Mitchell Hashimoto 31c5af74c5
apprt/gtk-ng: handle config reloading 2025-07-17 09:55:58 -07:00
Mitchell Hashimoto 0da47903f4
apprt/gtk-ng: hook up all the refs to show the dialog 2025-07-17 09:55:58 -07:00
Mitchell Hashimoto b253e2efe2
apprt/gtk-ng: proper memory management for config errors dialog 2025-07-17 09:55:58 -07:00
Mitchell Hashimoto b1aab1e7bf
apprt/gtk-ng: remove Ghostty-prefix from Zig-side classes 2025-07-17 09:55:58 -07:00
Mitchell Hashimoto 531d4a480e
apprt/gtk-ng: hook up all the bindings for the config errors dialog 2025-07-17 09:55:30 -07:00
Mitchell Hashimoto c3ba6e252e
apprt/gtk-ng: use the GhosttyConfig class to wrap our config 2025-07-17 09:55:30 -07:00
Mitchell Hashimoto 897649a3af
apprt/gtk-ng: GhosttyConfigErrors 2025-07-17 09:55:29 -07:00
Mitchell Hashimoto e76a151b42
apprt/gtk-ng: GhosttyConfig 2025-07-17 09:55:29 -07:00
Leah Amelia Chen 0d61b94c10
apprt/gtk-ng: assert that GTK is uninitialized in setGtkEnv (#7965) 2025-07-17 18:15:07 +08:00
Tristan Partin 2695361274 apprt/gtk-ng: assert that GTK is uninitialized in setGtkEnv
Signed-off-by: Tristan Partin <tristan@partin.io>
2025-07-16 22:38:37 -06:00
Mitchell Hashimoto 015efcf9e5
Introducing `gtk-ng`, the next evolution of our GTK apprt (#7961)
Surprise, @ghostty-org/gtk! Hopefully a happy one.

This PR introduces the boilerplate for a new apprt I'm calling `gtk-ng`.
The `gtk-ng` apprt is still GTK, but built up from first principles
using the GObject type system, Blueprint files, etc. This will
ultimately replace and become `gtk` (the `-ng` suffix will be stripped
once we fully replace our existing GTK apprt).

In this PR, the `gtk-ng` apprt does nothing more but show a "Hello,
Ghostty" GTK window. It doesn't run a terminal, yet. 😄 I want to
use this PR to introduce the boilerplate and share my motivations.

Since `gtk-ng` and `gtk` are separate apprts, I can PR small,
reviewable, and risky changes into `gtk-ng` rather than opening some
mega-PR that replaces everything all at once. Simultaneously, we can
continue to iterate on and maintain our shipping `gtk` apprt without
dealing with conflicts.

> [!IMPORTANT]
>
> To reiterate, this PR doesn't change anything about our `gtk` apprt.
Builds by default will still use the `gtk` apprt and we can continue to
build both `gtk` and `gtk-ng` side by side (actually, a very important
property until we can be confident we've reached parity).

## A Refactor, Not a Rewrite

The primary goal of this apprt is to _primarily_ be a **refactor, not a
rewrite.**

As much as possible, I'm going to be bringing over a lot of the same
logic from `gtk` as long as it fits and makes sense, but applying it to
our new structure and lifecycle. For example in this PR you can see how
we handle style manager, cgroups, etc. and how that fits within the new
`GhosttyApplication` class.

Our GTK apprt from a business logic standpoint is _pretty damn good_ and
_pretty damn stable_. There's no need to rock that boat and try to
rewrite core logic such as input handling, X11/Wayland stuff, etc. It
just has to be massaged into the new structure.

## Why? 

**Object-oriented, reference-counted systems are good for UI,
actually.** Experience iterating on the non-trivial macOS application
has really reaffirmed that OOP and memory managed systems are really,
really nice for GUI. I'm not a huge OOP fan in general, but it fits GUI
patterns extremely well. And memory management of any form (GC, Ref
Counts, etc.) is important in GUIs where "objects" are handed off to
various owners at different times, the most concrete example being:
splits moving across windows or into an undo management system.

**Blueprint and UI definitions have been a success.** These were
introduced in an incremental way into the `apprt/gtk` (thanks ❤️ )
and have been great. But our existing non-GObject system makes it hard
to go _all in_ on them, e.g. bindings. Moving to a full GObject-based
system will let us fully adopt this.

**`zig-gobject` is good and stable.** This didn't really exist when we
started the GTK apprt (see the long history below). Since adopting it,
its proven to be an excellent, stable dependency. I'm ready to go all-in
on it.

**Memory management has been a challenge.** Our mix of GObject and
non-GObject lifetimes within the GTK apprt has consistently been a
source of memory leaks at best and crashes at worst. For example,
`Window`, `Surface`, `Tab`, etc. have weird lifetimes that we try to
pair alongside their GTK counterparts and its nasty and I don't think
anyone who maintains this will disagree. By representing all of these
concepts as GObject or Widget subclasses, we'll align all their
lifetimes as expected.

**Personally, I've grown a lot, particularly from working on the macOS
side.** I think all of us as programmers can agree that _programming in
multiple languages makes us better programmers_. Similarly, building the
macOS app has shown me patterns and techniques that would make our
GTK-based application better. I'd like to bring those to the GTK side.
(Likewise, I've improved the macOS side from periods of time working on
the GTK side and I suspect that might happen again!)

### Longer Background

It's easy to rewrite. And I think our maintainers know that I'm not a
fan of rewrites. I think its the wrong decision most of the time. It is
easy to look at "legacy" code (especially code you didn't write
yourself), be disgusted, and think you can rewrite it all better. But no
engineer sets out to create technical debt, and I think its worth
respecting how and why some code came to be before embarking on
something new. This section does that.

#### The Beginning

Ghostty started as a pure Zig-based GLFW app, with no concept of
"apprt". It was Linux-only, and X11-only. At some point, I refactored
out the "apprt" system in order to introduce GTK4 (GTK4 came before any
macOS work). For the initial GTK4 work, I decided to just call into the
libgtk C APIs directly. There were various contributing factors for this
decision:

1. Zig was _rapidly_ changing, and we were on nightly Zig. This was
around the Zig 0.11, 0.12 times. Taking on new Zig dependencies was
really dangerous because Zig nightly could break all of us at any
moment.

2. [`zig-gobject`](https://github.com/ianprime0509/zig-gobject) was
brand new and unstable. Given point 1, I discarded it and did straight C
APIs.

3. Ghostty itself was very simple. We didn't support tabs, we didn't
support splits. We were still primarily concerned with making the
terminal stable. We weren't on the "native UI" part of our roadmap quite
yet. This was our initial foray in that direction.

4. On a personal level, I hadn't done real native GUI programming in a
_long_ time (on any platform). Recall the macOS apprt didn't exist yet,
either. Jumping into "plain old Zig" with "plain old C APIs" was a
practical, no-nonsense way for me to get going.

Given all this, I still believe I (it was only me then) made the right
decision for the time.

#### Zig, GTK apprt Stabilization

Eventually, the factors listed above changed: (1) Zig stabilized more
and Ghostty moved to stable Zig for various reasons. (2) `zig-gobject`
became a mature, stable library. (3) Ghostty the application has become
increasingly complex (in a good way, we support a ton of awesome
"platform UI" features).

Socially, the @ghostty-org/gtk subsystem team was created and is filled
with people who are experienced with GTK and Linux in general. This team
introduced more idiomatic GTK concepts into the project such as
blueprint files, a `zig-gobject` migration, and more.

The @ghostty-org/gtk subsystem maintainers have done an awesome job
iterating on this change within the existing `apprt/gtk`. This has been
often frustrating, but it was a pragmatic approach to move us towards
the future and let us ship new features into GTK4 to pursue our platform
UI goals.

#### GUI Maturity

We're now at the point where the core Ghostty terminal (the core,
terminal emulation) is incredibly stable. We don't have exact numbers
but we can confidently assume its used by thousands of people everyday
for real, professional work.

As such, most of the changes within the 1.1 and 1.2 cycle have been at
the apprt/GUI layer, introducing significantly more complexity:
localization, more X11/Wayland integrations, more text to native
elements like the process exit overlay, etc.

I recently rewrote the entire terminal, tab, and split data model in the
macOS app to give us a better foundation for future functionality, and
to improve our memory management story (surface leaks were a common
problem before, and they haven't happened since since the lifetime of a
surface is so much more obvious). This also let me iterate more quickly
on more features such as undo/redo, but will also more easily enable
things like split titles, merging splits into tabs/windows, etc. (not
done yet).

I think its time for this type of change within the GTK apprt as well.
We have the collective real world experience and we've put in the work
in iteration to understand what needs to be done.
2025-07-16 12:28:57 -07:00
Mitchell Hashimoto 426fa8d8f9
apprt/gtk-ng: move our app initialization all into the App class 2025-07-16 12:20:13 -07:00
Jeffrey C. Ollie 50a88dcfe7
linux/systemd: add an app- prefix to the systemd unit (#7959)
The XDG Freedesktop Portal has a _major_ undocumented requirement for
programs that are launched/controlled by `systemd` to interact with the
Portal. The unit _must_ be named `app-<appid>.service`. The Portal uses
the systemd unit name figure out what the program's application ID is
and it will only look at unit names that begin with `app-`. I can find
no place that this is documented other than by inspecting the code or
the
issue and PR that introduced this feature. See the following code:


7d4d48cf07/src/xdp-utils.c (L152-L220)

This may fix many people's issues with getting global shortcuts
to work.

Note that this is a breaking change if you have been using Ghostty
compiled from source since
https://github.com/ghostty-org/ghostty/pull/7433 was merged. You will
need to ensure
that any Ghosty systemd unit files _not_ prefixed with `app-` are
deleted.

Original discussion/PR in the XDG Desktop Portal repository:

https://github.com/flatpak/xdg-desktop-portal/issues/579
https://github.com/flatpak/xdg-desktop-portal/pull/719

Originally discussed on Discord:

https://discord.com/channels/1005603569187160125/1394845362186879026

Co-authored-by: ambareeshbalaji@gmail.com
2025-07-16 11:48:34 -05:00
Mitchell Hashimoto faa0c36def
CODEOWNERS add gtk to gtk-ng 2025-07-16 09:47:52 -07:00
Mitchell Hashimoto bb0ea99d91
ci: test gtk-ng 2025-07-16 09:46:17 -07:00
Mitchell Hashimoto 3257203b6c
apprt/gtk-ng: start basic window 2025-07-16 09:40:34 -07:00
Mitchell Hashimoto bb96388902
apprt/gtk-ng: cgroup base setup 2025-07-16 09:40:34 -07:00
Mitchell Hashimoto ce06eb5f64
apprt/gtk-ng: application startup to initialize styles 2025-07-16 09:40:34 -07:00
Mitchell Hashimoto ecb77fb8bc
apprt/gtk-ng: gresource creation, resource registration in Application 2025-07-16 09:40:34 -07:00
Mitchell Hashimoto 9c6cf61cd4
apprt/gtk-ng: GhosttyApplication and boilerplate to run 2025-07-16 09:40:34 -07:00
Mitchell Hashimoto 2f9660c02c
apprt/gtk-ng: boilerplate 2025-07-16 09:40:34 -07:00
Jeffrey C. Ollie 959b2c8d7f
linux/systemd: add comments explaining need for app- prefix 2025-07-16 10:53:19 -05:00
HuaDeity 2f2f1df637
shell-integration.fish: don't use $ssh_terminfo 2025-07-16 23:34:36 +08:00
Jeffrey C. Ollie 2435cee11b
linux/systemd: add an app- prefix to the systemd unit
The XDG Freedesktop Portal has a _major_ undocumented requirement for
programs that are launched/controlled by `systemd` to interact with the
Portal. The unit _must_ be named `app-<appid>.service`. The Portal uses
the systemd unit name figure out what the program's application ID is
and it will only look at unit names that begin with `app-`. I can find
no place that this is documented other than by inspecting the code or the
issue and PR that introduced this feature. See the following code:

7d4d48cf07/src/xdp-utils.c (L152-L220)

This may fix many people's issues with getting global shortcuts
to work.

Note that this is a breaking change if you have been using Ghostty
compiled from source since #7433 was merged. You will need to ensure
that any Ghosty systemd unit files _not_ prefixed with `app-` are
deleted.

Original discussion/PR in the XDG Desktop Portal repository:

https://github.com/flatpak/xdg-desktop-portal/issues/579
https://github.com/flatpak/xdg-desktop-portal/pull/719

Originally discussed on Discord:

https://discord.com/channels/1005603569187160125/1394845362186879026

Co-authored-by: ambareeshbalaji@gmail.com
2025-07-16 10:26:30 -05:00
trag1c f44c24ef88
Add missing Dutch translations, fix grammar, improve flow (#7889) 2025-07-15 17:30:56 +02:00
Mitchell Hashimoto 55a2e73b00
build(deps): bump namespacelabs/nscloud-cache-action from 1.2.9 to 1.2.12 (#7948)
[![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.9&new-version=1.2.12)](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-07-15 06:08:26 -07:00
dependabot[bot] 1c4aea1515
build(deps): bump namespacelabs/nscloud-cache-action
---
updated-dependencies:
- dependency-name: namespacelabs/nscloud-cache-action
  dependency-version: 1.2.12
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-15 06:19:39 +00:00
Mitchell Hashimoto 0c01c4c4ec
fix: rename tab title popup focus (#7944)
This fixes issue #7940 

<img width="394" height="354" alt="Screenshot 2025-07-14 at 17 20 03"
src="https://github.com/user-attachments/assets/453c49ed-2b91-4520-a8fe-031159454453"
/>
2025-07-14 20:26:07 -07:00
Mitchell Hashimoto 34af1feed3
windows: get +ssh-cache building on Windows (#7947)
There are still problems linking due to `gettext`. No idea if this
actually _works_ on Windows. File locking had to be disabled on Windows
because of a bug in the Zig std library. Adding all of the explicit
error sets happened due to disabling file locking. Fixing permissions
had to be disabled on Windows as the Windows file system does not
support permissions in the way that POSIX systems like macOS and Linux
do.
2025-07-14 19:55:56 -07:00
Mitchell Hashimoto 869db0357a
apprt: clean up stray struct (#7946) 2025-07-14 19:55:33 -07:00
Jeffrey C. Ollie 15567bfc24
windows: get +ssh-cache building on Windows
There are still problems linking due to `gettext`. No idea if this
actually _works_ on Windows. File locking had to be disabled on Windows
because of a bug in the Zig std library. Adding all of the explicit
error sets happened due to disabling file locking. Fixing permissions
had to be disabled on Windows as the Windows file system does not
support permissions in the way that POSIX systems like macOS and Linux
do.
2025-07-14 18:14:09 -05:00
William Walker 7962651dd8
fix: rename tab title popup focus 2025-07-14 17:23:59 -04:00
Jeffrey C. Ollie 38a81a7aed
apprt: clean up stray struct 2025-07-14 15:58:32 -05:00
Mitchell Hashimoto c75c4a9685
cli/gtk: add +new-window action (#7896)
This will (on GTK) use a D-Bus method call to tell a running Ghostty
instance to open a new window. If D-Bus activation is configured
properly, Ghostty does not need to be running first.

This could be extended to other platforms, e.g. AppleScript on macOS.

When Ghostty develops a native API, that could be used instead to create
a new window.
2025-07-14 13:29:18 -07:00
Jeffrey C. Ollie dd3853abeb
cli/gtk: move IPC/sendIPC to App/performIpc 2025-07-14 14:48:12 -05:00
Jeffrey C. Ollie f5eb413c31
cli/gtk: clean ups and better error handling in GTK new-window IPC 2025-07-14 14:48:12 -05:00
Jeffrey C. Ollie 7d05f4c0c5
cli/gtk: don't set GHOSTTY_CLASS 2025-07-14 14:48:12 -05:00
Jeffrey C. Ollie 361d03b578
cli/gtk: remove --release and --debug flags, use optional for arguments 2025-07-14 14:48:12 -05:00
Jeffrey C. Ollie 58867b0717
cli/gtk: add some more C bits 2025-07-14 14:48:12 -05:00
Jeffrey C. Ollie 81358c8dca
cli/gtk: replace @hasDecl for performAction-style API
Instead of using @hasDecl, use a performAction-stype API. The C
interface for interfacing with macOS (or any other apprt where Ghostty
is embedded) is unfinished.
2025-07-14 14:48:11 -05:00
Jeffrey C. Ollie 72e47cf8bc
cli/gtk: move actual IPC code tp apprt 2025-07-14 14:48:11 -05:00
Jeffrey C. Ollie 824185f23e
cli/gtk: add -e to +new-window
This adds the `-e` flag to the `+new-window` CLI action. This allows a
command to be passed from the CLI to the running instance of Ghostty.
Nothing is done with that command besides logging its presence.
2025-07-14 14:48:11 -05:00
Jeffrey C. Ollie 721702fce4
cli/gtk: move GTK-specific code to a new file in a subdirectory 2025-07-14 14:48:11 -05:00
Jeffrey C. Ollie 340d190bf0
cli/gtk: clarify +new-window documentation and improve instance discovery
- Add a `GHOSTTY_CLASS` environment variables to any command executed by
  Ghostty to make discovering the correct application ID easier.

- Add a flag to force the relelase application ID.

- Ensure that CLI flags to `+new-window` are mutually exclusive.

- Fix documentation about D-Bus activation requirements.
2025-07-14 14:48:11 -05:00
Jeffrey C. Ollie 7845399c00
cli/gtk: add +new-window action
This will (on GTK) use a D-Bus method call to tell a running
Ghostty instance to open a new window. If D-Bus activation is
configured properly, Ghostty does not need to be running first.

This could be extended to other platforms, e.g. AppleScript on macOS
eventually.

When Ghostty develops a native API, that could be used instead to create
a new window.
2025-07-14 14:48:10 -05:00
Mitchell Hashimoto ca5e361977
macos: restore tabs correctly into a single window (#7942)
Fixes #7941

I don't fully understand the fix here. Its code we've had for awhile it
was just in the wrong place after I refactored our window management.
The comment clearly states why its there but I don't know why it is
required.
2025-07-14 11:31:52 -07:00
Mitchell Hashimoto 02b08e0ec9
macos: restore tabs correctly into a single window
Fixes #7941

I don't fully understand the fix here. Its code we've had for awhile it
was just in the wrong place after I refactored our window management.
The comment clearly states why its there but I don't know why it is
required.
2025-07-14 11:22:38 -07:00
Mitchell Hashimoto 37c2c3a4ba
build: update libxev to remove usingnamespace usage (#7935)
This drops our `usingnamespace` usage to one more library (zigimg via
libvaxis) which should get fixed soon. With that, we have zero
usingnamespace and we should be able to test incremental compilation
with Zig (no binary mode, so Sema only) amongst other future features.
2025-07-13 21:50:32 -07:00
Mitchell Hashimoto 355c8a4d16
build: update libxev to remove usingnamespace usage
This drops our `usingnamespace` usage to one more library (zigimg via
libvaxis) which should get fixed soon. With that, we have zero
usingnamespace and we should be able to test incremental compilation
with Zig (no binary mode, so Sema only) amongst other future features.
2025-07-13 21:36:37 -07:00
Mitchell Hashimoto a40c2c3c16
build(deps): bump cachix/install-nix-action from 31.5.0 to 31.5.1 (#7933)
Bumps
[cachix/install-nix-action](https://github.com/cachix/install-nix-action)
from 31.5.0 to 31.5.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.5.1</h2>
<h2>What's Changed</h2>
<ul>
<li>nix: 2.30.0 -&gt; 2.30.1 by <a
href="https://github.com/xokdvium"><code>@​xokdvium</code></a> in <a
href="https://redirect.github.com/cachix/install-nix-action/pull/245">cachix/install-nix-action#245</a>
<strong>[SECURITY]</strong> Builds with Nix 2.30.0 on macOS were
executed with elevated privileges (root), instead of the build users. <a
href="https://github.com/NixOS/nix/security/advisories/GHSA-qc7j-jgf3-qmhg">https://github.com/NixOS/nix/security/advisories/GHSA-qc7j-jgf3-qmhg</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/xokdvium"><code>@​xokdvium</code></a>
made their first contribution in <a
href="https://redirect.github.com/cachix/install-nix-action/pull/245">cachix/install-nix-action#245</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/cachix/install-nix-action/compare/v31.5.0...v31.5.1">https://github.com/cachix/install-nix-action/compare/v31.5.0...v31.5.1</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="c134e4c9e3"><code>c134e4c</code></a>
Merge pull request <a
href="https://redirect.github.com/cachix/install-nix-action/issues/245">#245</a>
from xokdvium/2.30.1</li>
<li><a
href="a55d6df62f"><code>a55d6df</code></a>
nix: 2.30.0 -&gt; 2.30.1</li>
<li>See full diff in <a
href="cebd211ec2...c134e4c9e3">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.5.0&new-version=31.5.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-07-13 21:22:33 -07:00
dependabot[bot] 1a826a1e51
build(deps): bump cachix/install-nix-action from 31.5.0 to 31.5.1
Bumps [cachix/install-nix-action](https://github.com/cachix/install-nix-action) from 31.5.0 to 31.5.1.
- [Release notes](https://github.com/cachix/install-nix-action/releases)
- [Changelog](https://github.com/cachix/install-nix-action/blob/master/RELEASE.md)
- [Commits](cebd211ec2...c134e4c9e3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-14 00:55:26 +00:00
Mitchell Hashimoto 1c0677faab
nix: fix flake input (#7924)
Setting `zig/flake-compat` to follow `""` (the current flake, ghostty)
is incorrect and introduces an unnecessary dependency cycle. This causes
problems in my NixOS configuration, because I collect flake inputs
recursively and add them to my system closure to work around
https://github.com/NixOS/nix/issues/3995#issuecomment-1537108310.

The other change to `flake.lock` was done automatically by my version of
Nix (Lix 2.91.3).
2025-07-13 14:09:40 -07:00
Mitchell Hashimoto cdfec43b66
Update iTerm2 colorschemes (#7926)
Upstream revision:
92f2065077
2025-07-13 14:09:30 -07:00
mitchellh b43fa129d6 deps: Update iTerm2 color schemes 2025-07-13 00:15:37 +00:00
Naïm Camille Favier c61e36b035
nix: use rev instead of ref for flake inputs
Works around https://git.lix.systems/lix-project/lix/issues/520
2025-07-13 00:40:19 +02:00
Naïm Camille Favier ad3f837b36
nix: fix flake input
Setting `zig/flake-compat` to follow `""` (the current flake, ghostty)
is incorrect and introduces an unnecessary dependency cycle.
2025-07-13 00:32:15 +02:00
Mitchell Hashimoto b5000dcd94
fix webdata build, run it in CI (#7921)
This fixes our build for `-Demit-webdata`. Turns out we weren't running
this in CI so this adds that there.
2025-07-12 07:03:08 -07:00
Mitchell Hashimoto 658567bbbd
fix webdata build, run it in CI
This fixes our build for `-Demit-webdata`. Turns out we weren't 
running this in CI so this adds that there.
2025-07-12 06:46:00 -07:00
Merijntje Tak eb9e6614e5
Add new translations for Dutch 2025-07-12 08:54:25 +02:00
Merijntje Tak cbdaceb1cb
Merge remote-tracking branch 'upstream/main' 2025-07-12 08:52:42 +02:00
Merijntje Tak beaf665ea9
Update to imperative 2025-07-12 06:54:50 +02:00
Jeffrey C. Ollie e67a62453d
core/gtk: add apprt action to show native GUI warning when child exits (#7836)
Addresses #7649 for the core and GTK. macOS support will need to be
added later.

This adds an apprt action to show a native GUI warning of some kind when
the child process of a terminal exits.

Also adds a basic GTK implementation of this. In GTK it overlays an
Adwaita banner at the bottom of the window (similar to the banner that
shows up in at the top of windows in debug builds).
![Screenshot From 2025-07-08
14-49-59](https://github.com/user-attachments/assets/5de4c065-6b35-4ef5-ba26-171c40c0c5ee)
![Screenshot From 2025-07-08
14-50-14](https://github.com/user-attachments/assets/d6259aa1-6eb2-4c7f-9a9b-13dbad706a3e)
2025-07-11 23:14:18 -05:00
Jeffrey C. Ollie 5a5e0df574
i18n: update translations 2025-07-11 22:57:17 -05:00
Jeffrey C. Ollie 1abc3ba1da
gtk: change child exited verbiage to be clearer and code cleanup 2025-07-11 22:56:22 -05:00
Jeffrey C. Ollie 9ee25e8a69
gtk: use close button in show_child_exited banner 2025-07-11 22:56:22 -05:00
Jeffrey C. Ollie 8cea111329
gtk: add some comments for show_child_exited 2025-07-11 22:56:21 -05:00
Jeffrey C. Ollie 49243db4b3
gtk: GtkBox not needed for show_child_exited 2025-07-11 22:56:21 -05:00
Jeffrey C. Ollie 7fd900647e
show_child_exited: remove emojis 2025-07-11 22:56:21 -05:00
Jeffrey C. Ollie f24ec13963
remove unused css class from gtk child exited widget 2025-07-11 22:56:21 -05:00
Jeffrey C. Ollie bf0659f07b
use checkmark for icon if child exits normally 2025-07-11 22:56:21 -05:00
Jeffrey C. Ollie 3d89a68fff
fix error set for function return signature 2025-07-11 22:56:21 -05:00
Jeffrey C. Ollie 28c7083876
gtk show_child_edit: use different text for normal/abnormal exit
Without this, the only indication would be the difference between a red
or a green background which would be problematic for users with limited
vision or color blindness.
2025-07-11 22:56:21 -05:00
Jeffrey C. Ollie 5219bc51e5
show child exited: return a boolean if native GUI is shown
If a native GUI is shown by the runtime when a child exits, use the
returned boolean to determine if text should be show in the terminal to
avoid duplicating information.
2025-07-11 22:56:21 -05:00
Jeffrey C. Ollie 103772ee8f
show child exited: make GTK banner transparent 2025-07-11 22:56:21 -05:00
Jeffrey C. Ollie cd9174e7e8
show child exited: fix macos build 2025-07-11 22:56:20 -05:00
Jeffrey C. Ollie 033d8c3099
core/gtk: add apprt action to show native GUI warning when child exits
Addresses #7649 for the core and GTK. macOS support will need to be
added later.

This adds an apprt action to show a native GUI warning of some kind when
the child process of a terminal exits.

Also adds a basic GTK implementation of this. In GTK it overlays an
Adwaita banner at the bottom of the window (similar to the banner that
shows up in at the top of windows in debug builds).
2025-07-11 22:56:20 -05:00
trag1c 391290aa4a
i18n: Update Korean Translations (#7885) 2025-07-11 21:29:52 +02:00
Merijntje Tak 1ed28d62e6
Update last revision date 2025-07-11 20:24:41 +02:00
Merijntje Tak f91fb5645b
Updated translation of "Command Palette", see discussion in PR. 2025-07-11 19:40:04 +02:00
Hojin You c4e10a1ac1
Update po/ko_KR.UTF-8.po
remove extra space

Co-authored-by: trag1c <dev@jakubr.me>
2025-07-11 10:06:34 -04:00
Mitchell Hashimoto 6c0adaed0f
renderer: Allow the renderer to draw transparent cells (#7913)
Fixes #5917

Allows the terminal to draw transparent cells even if they don't have
the same background color, on user demand, with the
`background-opacity-cells` feature

<img width="2560" height="1440" alt="transparent"
src="https://github.com/user-attachments/assets/8c076671-3603-41a1-957d-46ddaeffa1ff"
/>
2025-07-11 07:01:54 -07:00
nferhat 991426e84e renderer: Allow the renderer to draw transparent cells
Co-authored-by: Kat <65649991+00-kat@users.noreply.github.com>
2025-07-11 06:59:01 -07:00
Mitchell Hashimoto 4aa28988a6
build: `zig build test` runs Xcode tests on macOS (#7909)
Related to #7879

This commit updates `zig build test` to run Xcode tests, too. These run
in parallel to the Zig tests, so they don't add any time to the test.

The Xcode tests will _not_ run when: (1) the target is not macOS, or (2)
the `-Dtest-filter` option is non-empty. This makes it so that this
change doesn't affect non-macOS and doesn't affect the general dev cycle
because you usually will run `-Dtest-filter` when developing a core
feature.

I didn't add a step to only run Xcode tests because I find that when I'm
working in Xcode I'm probably going to run the tests from there anyways.
The integration with `zig build test` is just a convenience, especially
around CI.

Speaking of CI, this change also makes it so this will run in CI.
2025-07-10 21:21:46 -07:00
Mitchell Hashimoto 2dce107738
ci: downgrade back to Xcode 26 beta 1, the icon is broken in beta 3 (#7911) 2025-07-10 21:15:37 -07:00
Mitchell Hashimoto cb3f67e810
build(deps): bump namespacelabs/nscloud-cache-action from 1.2.8 to 1.2.9 (#7910)
Bumps
[namespacelabs/nscloud-cache-action](https://github.com/namespacelabs/nscloud-cache-action)
from 1.2.8 to 1.2.9.
<details>
<summary>Commits</summary>
<ul>
<li><a
href="0ac1550c04"><code>0ac1550</code></a>
Merge pull request <a
href="https://redirect.github.com/namespacelabs/nscloud-cache-action/issues/21">#21</a>
from namespacelabs/niklas-not-silent</li>
<li><a
href="02b3441b28"><code>02b3441</code></a>
Make tool executions not silent</li>
<li>See full diff in <a
href="449c929cd5...0ac1550c04">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.8&new-version=1.2.9)](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-07-10 21:12:38 -07:00
Mitchell Hashimoto cfad2e817b
ci: downgrade back to Xcode 26 beta 1, the icon is broken in beta 3 2025-07-10 21:11:57 -07:00
Mitchell Hashimoto 9fa26387ef
build: `zig build test` runs Xcode tests on macOS
Related to #7879

This commit updates `zig build test` to run Xcode tests, too. These run
in parallel to the Zig tests, so they don't add any time to the test.

The Xcode tests will _not_ run when: (1) the target is not macOS, or (2)
the `-Dtest-filter` option is non-empty. This makes it so that this
change doesn't affect non-macOS and doesn't affect the general dev cycle
because you usually will run `-Dtest-filter` when developing a core
feature.

I didn't add a step to only run Xcode tests because I find that when I'm
working in Xcode I'm probably going to run the tests from there anyways.
The integration with `zig build test` is just a convenience, especially
around CI.

Speaking of CI, this change also makes it so this will run in CI.
2025-07-10 21:08:51 -07:00
dependabot[bot] 099a2d7f03
build(deps): bump namespacelabs/nscloud-cache-action from 1.2.8 to 1.2.9
Bumps [namespacelabs/nscloud-cache-action](https://github.com/namespacelabs/nscloud-cache-action) from 1.2.8 to 1.2.9.
- [Release notes](https://github.com/namespacelabs/nscloud-cache-action/releases)
- [Commits](449c929cd5...0ac1550c04)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-11 00:13:59 +00:00
Jon Parise c03942d3c1
bash: preserve an existing ENV value (#7908) 2025-07-10 19:06:31 -04:00
Mitchell Hashimoto 9a3a6a8352
ci: add shellcheck linting for shell scripts (#7904)
Resolves #7882
2025-07-10 14:42:13 -07:00
Jon Parise 01233a48d1 bash: preserve an existing ENV value
Our bash shell integration code uses ENV (in POSIX mode) to bootstrap
our shell integration script. This had the side effect of overwriting an
existing ENV value.

This change preserves ENV by storing it temporarily in GHOSTTY_BASH_ENV.

Note that this doesn't enable --posix mode support for automatic shell
integration. (--posix does work; we just skip shell integration when
that flag is specified.) We can reconsider implementing full --posix
support separately.
2025-07-10 15:47:55 -04:00
Bryan Lee cbb3f6f64f
ci: add shellcheck linting for shell scripts
Add shellcheck to CI pipeline to ensure shell scripts follow best practices
and catch common errors. Fix existing shellcheck warnings in test scripts
to pass the new linting requirements.
2025-07-11 02:54:05 +08:00
Hojin You 4dc4911ece
Update po/ko_KR.UTF-8.po 2025-07-10 14:46:46 -04:00
Merijntje Tak 3d0e29f3ff
Reverted change, updated ellipsis for unicode char 2025-07-10 19:53:57 +02:00
Qwerasd cc646ecf46
Fix custom shader cursor uniforms not set for non-block cursors (#7897)
Fixes #7893

Previously, custom shader cursor uniforms were only updated when the
cursor glyph was in the front (block) cursor list. This caused non-block
cursors (such as bar, underline, hollow block, and lock) to be missing
from custom shader effects.

This commit adds a helper to the cell contents struct to retrieve the
current cursor glyph from either the front or back cursor lists, and
updates the renderer to use this helper when setting custom shader
uniforms. As a result, custom shaders now receive correct cursor
information for all supported cursor styles.
2025-07-10 09:26:46 -06:00
Mitchell Hashimoto 1172332621
ci: update sequoia builders to xcode 26 beta 3, output version in CI (#7901)
The `-edge` variant of these builders will always use the latest macOS
images that may not be stable. We'll remove this once Xcode 26 is
released.
2025-07-10 07:27:17 -07:00
Mitchell Hashimoto c23e3f8586
ci: update sequoia builders to xcode 26 beta 3, output version in CI
The `-edge` variant of these builders will always use the latest macOS
images that may not be stable. We'll remove this once Xcode 26 is
released.
2025-07-10 07:08:24 -07:00
Jon Parise 530785926e
elvish: revise the ssh integration (#7894)
The previous implementation wasn't quite working. This revision reworks
it in a few ways:

- Fix various syntax issues
- Redirect the `ssh` command to our 'ssh-integration' function
- Locate the `ghostty` binary using $GHOSTTY_BIN_DIR
- Use os:temp-dir to create our temporary directory

Also, consistently use 2-space indents, which is the Elvish standard.
2025-07-10 07:58:37 -04:00
ClearAspect 36a3a3ffa4
Add tests for getCursorGlyph() helper function 2025-07-10 01:48:44 -04:00
Qwerasd 1de35bbcb9
Fix viewport going out of bounds when zooming out (#7899)
The viewport pin was allowed to go below the active pin during resize,
which caused a use of null when trying to get the bottom right of the
viewport since going down by the active row count from the viewport pin
ends up below the bottom of the active area.

Ran in to this while doing font work because I was scrolled up slightly
and increasing and decreasing to see stuff at different sizes.
2025-07-09 23:15:26 -06:00
Qwerasd ea4a056d34 test(terminal/PageList): resize keeps viewport <= active
This tests for the bug fixed in the last commit.
2025-07-09 22:47:01 -06:00
Mitchell Hashimoto 68418ecd53
Modernize our benchmarks (#7891)
This PR modernizes our benchmarks. This PR focuses on the benchmark
_framework_ and not the benchmarks themselves. That will come in later
PRs.

We now produce two binaries with `-Demit-bench`: `ghostty-bench` and
`ghostty-gen`. The former is our benchmark tool. The latter is our
synthetic data generation tool. The benchmarking CLI usually takes in
data from the synthetic generator but we want to do that offline because
synthetic data generation can be slow and CPU intensive and mess up our
benchmarks.

Our previous benchmark-specific binaries (like
`ghostty-bench-codepoint-width`) are all gone. This is all executed as
subcommands in the format similar to Ghostty users: `ghostty-bench
+codepoint-width --other --args`.

Previously, synthetic data generation was a mess and all unified with
`ghostty-bench-stream` which is just nasty. A dedicated CLI now gets us
args like `ghostty-gen +osc --p-valid=0.5`. Neat!

## Signposts and Xcode/Instruments on macOS

The benchmark framework now automatically emits
[signposts](https://developer.apple.com/documentation/os/recording-performance-data)
around the code that is under test. This is surfaced in Instruments as a
region that you can visualize and zoom in on so you can omit any of the
other overhead.

Additionally, I've integrated benchmarks with libghostty and our Xcode
project so you can just right click a benchmark to open it in
Instruments.

These are macOS-specific niceties but the core benchmarking tool is
platform-agnostic.

## Generalized CLI Actions

The `src/cli/action.zig` file was generalized so that it can be shared
amongst our three action-ized binaries. The Ghostty-specific actions are
now in `src/cli/ghostty.zig`. As an added bonus, our action parsing is
now fully unit tested.

I don't like mixing refactors in with other tasks in PRs but in this
case this one was done to enable not one but two other consumers in the
same PR, so I think it fits.

## TODO

Some things I want to do before merge.

- [ ] Add flags to `ghostty-bench` to configure once mode vs duration
mode
2025-07-09 21:42:53 -07:00
Mitchell Hashimoto 1317a55a9d
build: make the xcframework step dsym aware, even though we don't use it (#7898)
This was in pursuit of trying to get line numbers in `zig build run` on
macOS to work, but I wasn't able to figure that out and this wasn't the
right path because static libs can't have dsyms. But, it may still be
useful to make the xcframework step dsym aware for future use so I'm
PRing this.

This also updates our libghostty build steps to use the new
`root_module` form which is recommend for Zig 0.14 and we forgot to
update long ago.
2025-07-09 21:41:10 -07:00
Mitchell Hashimoto cc0d7acaef
build: make the xcframework step dsym aware, even though we don't use it
This was in pursuit of trying to get line numbers in `zig build run` on
macOS to work, but I wasn't able to figure that out and this wasn't the
right path because static libs can't have dsyms. But, it may still be
useful to make the xcframework step dsym aware for future use so I'm
PRing this.
2025-07-09 21:35:02 -07:00
Qwerasd 6744e57c68 fix(terminal/PageList): update viewport in row count resize
Before, if the row count increase past the active area then we added new
rows to make sure that we had enough for the active area, but we didn't
make sure that the viewport pin wasn't below the active area pin, which
meant that later on if someone tried to get the bottom right pin for the
viewport it would overshoot and we'd use null. This resulted in either a
memory corruption bug in ReleaseFast if you scaled down the font while
scrolled up slightly, or in Debug mode it was just a crash.
2025-07-09 22:28:08 -06:00
ClearAspect 88736a2ddb
Fix custom shader cursor uniforms not set for non-block cursors (#7893)
Fixes #7893

Previously, custom shader cursor uniforms were only updated when the
cursor glyph was in the front (block) cursor list. This caused non-block
cursors (such as bar, underline, hollow block, and lock) to be missing
from custom shader effects.

This commit adds a helper to the cell contents struct to retrieve the
current cursor glyph from either the front or back cursor lists, and
updates the renderer to use this helper when setting custom shader
uniforms. As a result, custom shaders now receive correct cursor
information for all supported cursor styles.
2025-07-10 00:21:21 -04:00
Jon Parise 5cdfe3d70e elvish: revise the ssh integration
The previous implementation wasn't quite working. This revision reworks
it in a few ways:

- Fix various syntax issues
- Redirect the `ssh` command to our 'ssh-integration' function
- Locate the `ghostty` binary using $GHOSTTY_BIN_DIR
- Use os:temp-dir to create our temporary directory

Also, consistently use 2-space indents, which is the Elvish standard.
2025-07-09 22:19:13 -04:00
Mitchell Hashimoto d0c5191aef
build(deps): bump cachix/install-nix-action from 31.4.1 to 31.5.0 (#7892)
Bumps
[cachix/install-nix-action](https://github.com/cachix/install-nix-action)
from 31.4.1 to 31.5.0.
<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.5.0</h2>
<h2>What's Changed</h2>
<ul>
<li>nix: 2.29.1 -&gt; 2.30.0 by <a
href="https://github.com/github-actions"><code>@​github-actions</code></a>
in <a
href="https://redirect.github.com/cachix/install-nix-action/pull/244">cachix/install-nix-action#244</a>
Release notes: <a
href="https://nix.dev/manual/nix/2.30/release-notes/rl-2.30.html">https://nix.dev/manual/nix/2.30/release-notes/rl-2.30.html</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/cachix/install-nix-action/compare/v31.4.1...v31.5.0">https://github.com/cachix/install-nix-action/compare/v31.4.1...v31.5.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="cebd211ec2"><code>cebd211</code></a>
Merge pull request <a
href="https://redirect.github.com/cachix/install-nix-action/issues/244">#244</a>
from cachix/create-pull-request/patch</li>
<li><a
href="358e2ef1b2"><code>358e2ef</code></a>
nix: 2.29.1 -&gt; 2.30.0</li>
<li>See full diff in <a
href="f0fe604f8a...cebd211ec2">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.4.1&new-version=31.5.0)](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-07-09 18:23:05 -07:00
dependabot[bot] e962e9b517
build(deps): bump cachix/install-nix-action from 31.4.1 to 31.5.0
Bumps [cachix/install-nix-action](https://github.com/cachix/install-nix-action) from 31.4.1 to 31.5.0.
- [Release notes](https://github.com/cachix/install-nix-action/releases)
- [Changelog](https://github.com/cachix/install-nix-action/blob/master/RELEASE.md)
- [Commits](f0fe604f8a...cebd211ec2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-10 00:22:27 +00:00
Mitchell Hashimoto 74b94ef30a
remove src/bench 2025-07-09 15:06:24 -07:00
Mitchell Hashimoto a09452bf1b
synthetic: add osc/utf8 generators 2025-07-09 15:06:24 -07:00
Mitchell Hashimoto a28b7e9205
synthetic cli (ghostty-gen) 2025-07-09 15:06:24 -07:00
Mitchell Hashimoto b5ff0442d4
bench: remove old benchmarks we converted 2025-07-09 15:06:24 -07:00
Mitchell Hashimoto 99ed984af2
benchmark: add GraphemeBreak and TerminalParser benchmarks 2025-07-09 15:06:24 -07:00
Mitchell Hashimoto 5890826356
benchmark: add codepoint width benchmark 2025-07-09 15:06:24 -07:00
Mitchell Hashimoto c990d35d6d
macos: add benchmark tests to our Xcode project 2025-07-09 15:06:24 -07:00
Mitchell Hashimoto 20bb71c627
libghostty: export benchmark CLI API 2025-07-09 15:06:24 -07:00
Mitchell Hashimoto 01b2545d1d
macos: fix signpost API to use proper mach header base addr 2025-07-09 15:06:24 -07:00
Mitchell Hashimoto d30771ecff
pkg/macos: use new @ptrcast for os.log 2025-07-09 15:06:24 -07:00
Mitchell Hashimoto b8f5cf9d52
initial `ghostty-bench` program 2025-07-09 15:06:24 -07:00
Mitchell Hashimoto 1739418f6f
cli: make the action parser (+foo) generic and reusable 2025-07-09 15:06:24 -07:00
Mitchell Hashimoto 0e8ccc7352
benchmark: a new package and framework for benchmarking 2025-07-09 15:06:23 -07:00
Mitchell Hashimoto 8506637ae6
macos: add signpost API 2025-07-09 15:06:23 -07:00
Jon Parise 464dc78172
shell-integration: use $GHOSTTY_BIN_DIR/ghostty (#7887) 2025-07-09 17:46:22 -04:00
Merijntje Tak 88d1cdc067
Add missing Dutch translations, fix grammar, improve flow
- Add missing translations for Dutch
- Fix minor grammar mistakes
- Update entries to flow more naturally and in line with other Dutch
apps
2025-07-09 23:37:50 +02:00
Jon Parise f5f2a4dd20 shell-integration: use $GHOSTTY_BIN_DIR/ghostty
Locate our ghostty binary using $GHOSTTY_BIN_DIR rather than searching
the PATH.
2025-07-09 17:25:34 -04:00
Jon Parise 87579b8594
shell-integration: simplify "ssh target" checks (#7884) 2025-07-09 16:32:11 -04:00
Hojin You 9818543ebe Update Korean Translations 2025-07-09 16:27:22 -04:00
Jon Parise e522d54d7b shell-integration: simplify "ssh target" checks
This value is always set to a non-empty string, and we only need this
value after we've determined that 'ssh_hostname' is non-empty.

In bash and zsh, we also don't need to check for the 'ghostty' command
before we attempt to add the target to the cache. That command will
safely fail silently if it's not available.
2025-07-09 15:59:59 -04:00
Mitchell Hashimoto 9ba9e29843
fish: prefer 'command -q' to check for commands (#7880)
This is a fish built-in 'command' option that's the more idiomatic way
to check for the availability of a command.

https://fishshell.com/docs/current/cmds/command.html
2025-07-09 11:59:39 -07:00
Jon Parise a1cb52dcd3 fish: prefer 'command -q' to check for commands
This is a fish built-in 'command' option that's the more idiomatic way
to check for the availability of a command.

https://fishshell.com/docs/current/cmds/command.html
2025-07-09 14:34:00 -04:00
Jeffrey C. Ollie 5dbef8b47a
linux: switch systemd user service to type notify-reload (#7791)
This enables `systemd` to send SIGUSR2 to Ghostty to signal it to reload
the configuration. This is much easier and reliable than using a script
to search process listings for Ghostty's main PID to send the signal to.
The command to do so is:

`systemctl reload --user com.mitchellh.ghostty.service`
2025-07-09 13:30:26 -05:00
Jeffrey C. Ollie 248acbea5b
gtk: remove NOTIFY_SOCKET from the inherited environment variables 2025-07-09 13:11:02 -05:00
Jeffrey C. Ollie c9d0bbefc2
linux: switch systemd user service to type=notify-reload
This allows `systemctl` to send SIGUSR2 to Ghostty to trigger a reload,
which is more convenient than scripting `ps` and `kill` to find the
Ghostty main PID.
2025-07-09 13:11:01 -05:00
Jeffrey C. Ollie e18f16d94d
linux: add functions for notifying systemd about process state
Functions for notifying systemd that we are ready or have started
reloading the configuration.
2025-07-09 13:11:01 -05:00
Mitchell Hashimoto 5ef51b8213
Run GTK unit tests in CI, fix broken tests (#7878) 2025-07-09 11:03:40 -07:00
Mitchell Hashimoto 86dbfb98d7
Run GTK unit tests in CI, fix broken tests
We only ran `apprt=none` tests in CI, which misses a huge surface area
of unit tests. Thankfully only a couple were broken. This fixes that.
2025-07-09 10:56:30 -07:00
Mitchell Hashimoto d8e7a6634e
build: temporarily disable stderr capture on distcheck 2025-07-09 10:22:50 -07:00
Qwerasd ffc6fe8686
Improve CoreText "Quantization" (#7876)
The old math didn't allow fractional pixels on the left and bottom, and
stretched glyphs vertically since the height was always rounded up. At
very small font sizes this looked good, but at medium and even large
sizes this just made things inconsistent and janky.

These new calculations are practically pixel-identical to whatever
CoreText is doing in 99% of cases, and the remaining cases seem to be
some sort of auto-hinting since it's internal features of the glyph
getting repositioned.

Over all, I still prefer this to CoreText's quantize option, but if this
causes further issues we should probably just revert the whole thing and
go ahead and add an extra pixel of padding to the bottom and left...
2025-07-09 10:52:57 -06:00
Qwerasd 579b15bef7 font/coretext: rework glyph quantization math
The old math didn't allow fractional pixels on the left and bottom, and
stretched glyphs vertically since the height was always rounded up. At
very small font sizes this looked good, but at medium and even large
sizes this just made things inconsistent and janky.

These new calculations are practically pixel-identical to whatever
CoreText is doing in 99% of cases, and the remaining cases seem to be
some sort of auto-hinting since it's internal features of the glyph
getting repositioned.

Over all, I still prefer this to CoreText's quantize option, but if this
causes further issues we should probably just revert the whole thing and
go ahead and add an extra pixel of padding to the bottom and left...
2025-07-09 10:33:28 -06:00
Mitchell Hashimoto e68c1d2cad
config: add available since for SSH shell integration 2025-07-09 09:30:22 -07:00
Mitchell Hashimoto 5a5c9e4387
Add SSH Integration Configuration Option (#7608)
Addresses #4156 and #5892, specifically by implementing @mitchellh's
[request](https://github.com/ghostty-org/ghostty/discussions/5892#discussioncomment-12283628)
for "opt-in shell integration".

## Problem

Ghostty's custom `xterm-ghostty` TERM value breaks terminal
functionality when SSHing to remote systems that lack the corresponding
terminfo entry. This affects enterprise environments, legacy servers,
and ephemeral instances.

## Solution

Adds two independent SSH integration flags within the existing
`shell-integration-features` configuration:

```
shell-integration-features = ssh-env,ssh-terminfo
```

- **`ssh-env`**: TERM compatibility fix (xterm-ghostty → xterm-256color)
+ environment variable propagation (COLORTERM, TERM_PROGRAM,
TERM_PROGRAM_VERSION)
- **`ssh-terminfo`**: Automatic terminfo installation on remote hosts
with caching and utility commands

Flags work independently and harmoniously when combined, allowing users
granular control over SSH integration behavior.

## Implementation

Adds SSH wrapper functions across bash, zsh, fish, and elvish that
handle TERM compatibility, environment propagation, and terminfo
installation. Follows the same pattern as existing shell integration
features - client-side only with graceful fallback behavior.

The flag-based approach allows users to choose exactly the features they
need:
- Environment compatibility only: `ssh-env`
- Terminfo installation only: `ssh-terminfo` 
- Optimal experience: `ssh-env,ssh-terminfo`
- No SSH integration: omit both flags

## Evolution Note

Based on maintainer feedback, this evolved from a progressive
enhancement approach (`ssh-integration = basic | full`) to independent
flags within `shell-integration-features`. See discussion below for the
complete architectural evolution and rationale.
2025-07-09 09:28:40 -07:00
Qwerasd b915084c38 font/coretext: don't use vertical overlap constraints 2025-07-09 10:28:35 -06:00
Mitchell Hashimoto 8ab3010bb8
cli: rewrite ssh-cache diskcache and test IO 2025-07-09 09:20:14 -07:00
Mitchell Hashimoto 7cfb026e84
cli: ssh-cache stylistic changes 2025-07-09 06:47:17 -07:00
Mitchell Hashimoto bcb4e624a4
cli: fix macOS builds 2025-07-09 06:45:29 -07:00
Mitchell Hashimoto 2f4af5eb87
Changed behaviour of bold-color (#7871)
Continuation of discussion in
https://github.com/ghostty-org/ghostty/discussions/3134

This changes the behaviour of the new bold-color option to only affect
the default foreground text when set to a static colour. By using a
static colour, the remaining colours are rendered as bright.
2025-07-09 06:37:21 -07:00
Mitchell Hashimoto 7af3f28e5e
core: document which release added config entries (#7859)
For each config entry, add a comment specifying in which release it was
first added. In some cases I note when certain aspects of each config
entry were modified.
2025-07-09 06:34:37 -07:00
Robert Ian Hawdon 94cca0cc17 Updated comment 2025-07-09 11:35:44 +01:00
Robert Ian Hawdon 57fdfe76bb Changed behaviour of bold-color 2025-07-09 11:33:12 +01:00
Leah Amelia Chen b90deebfb2
build: disable fuzzy matching for msgmerge (#7866) 2025-07-09 15:15:21 +08:00
Jeffrey C. Ollie 13805f7cc5
build: disable fuzzy matching for msgmerge
CI is currently configured to fail if there are any fuzzy matches in
translation files. This change prevents `msgmerge` from creating any
fuzzy matches when translations are updated.
2025-07-08 22:17:20 -05:00
Jeffrey C. Ollie 527dcea266
core: avalability of config entry since 1.0.0 can be assumed 2025-07-08 22:06:27 -05:00
Jeffrey C. Ollie 1a3a03577b
core: document which release added config entries
For each config entry, add a comment specifying in which release it was
first added. In some cases I note when certain aspects of each config
entry were modified.
2025-07-08 22:06:27 -05:00
Mitchell Hashimoto f0549e182e
build: update zig build update-translations (#7862)
- The order of the arguments to xgettext influences the output. Since
  directorty walking does not guarantee that files will be listed in
  a deterministic order (especially when run on different systems) the
  translation files would see a lot of churn depending on who updated
  them last.

  In this update the files are sorted so that the arguments to xgettext
  are always in the same order. This should reduce churn in the future.

- Mark all of the files as inputs so that the Zig build system caching
  will work properly.
2025-07-08 16:33:45 -07:00
Jeffrey C. Ollie 68c9ab63b5
i18n: update translations 2025-07-08 15:21:34 -05:00
Jeffrey C. Ollie b8d5c1cf42
build: update `zig build update-translations`
- The order of the arguments to xgettext influences the output. Since
  directorty walking does not guarantee that files will be listed in
  a deterministic order (especially when run on different systems) the
  translation files would see a lot of churn depending on who updated
  them last.

  In this update the files are sorted so that the arguments to xgettext
  are always in the same order. This should reduce churn in the future.

- Mark all of the files as inputs so that the Zig build system caching
  will work properly.
2025-07-08 15:21:19 -05:00
Qwerasd 638a31cc8c
Hopefully Last Nerd Fonts Tweak (#7861)
With these two changes (see commits for details) our scaling should be
identical to the nerd font patcher in all the ways that matter and even
slightly better in some others.

I'm really hoping this is the last change I have to make to the nerd
font scaling...
2025-07-08 13:28:06 -06:00
Qwerasd 8b8e0bedad font: add scale groups to nerd font constraints
We do this by characterizing the shared bounding boxes in a static copy
of the symbols only nerd font when we're doing the codegen. This allows
us to get results of our scaling that are just as good as in a patched
font, since related glyphs can now be sized and positioned relative to
each other.
2025-07-08 12:00:22 -06:00
Qwerasd 1430660933 font: constrain width of two-cell icon-height icons
This stops things like folder icons from becoming over-wide. The patcher
typically makes these glyphs always 1 cell wide, but since we know how
it will be displayed we have the benefit of being able to make it more
than 1 cell when there's room. This makes our dynamic scaling *better*
than a static patched font :D
2025-07-08 11:56:49 -06:00
Jason Rayne f6319efaa1
Merge branch 'main' into ssh-integration 2025-07-08 10:46:29 -07:00
Jason Rayne f95476b181
refactor: apply maintainer feedback to SSH integration scripts across all shells
- Update Bash script (baseline): Simplify cache checking logic, clarify
"xterm-ghostty terminfo" message, remove unnecessary ssh_opts from
terminfo installation, remove extra success message
- Align ZSH/Fish/Elvish with updated Bash: Remove extra success
messages, adopt simplified cache checking, standardize setup messages
- Apply Elvish improvements: Remove unnecessary try/catch blocks, use
idiomatic error handling patterns
- Apply Fish improvements: Replace string pattern matching with
efficient `contains` checks on split features list
2025-07-08 10:45:42 -07:00
Qwerasd 731da5aea5
font/coretext: disable Apple's quantization, do it ourselves (#7854)
Using the "subpixel quantization" option for rendering our glyph was
creating bad edge cases where we'd lose the bottom or left row / column
of pixels in a glyph sometimes. I investigated the exact effect of this
option and it seems like beyond quantizing the position and scale it's
also doing some rudimentary auto-hinting. That said, the auto-hinting
doesn't do that much for us, and the fact that it horizontally snaps
coordinates to thirds of a pixel instead of whole pixels makes things
worse in terms of legibility at small pixel sizes, so ultimately it's
better with our own handling anyway.

I extensively compared the result of Apple's option with our own manual
quantization here and I'm pretty sure this will always match the
apparent whole pixel sizes, and where it differs (other than things like
crossbars) it seems to make glyphs generally more legible not less.

### Comparisons at several pixel sizes
Images have been scaled 8x so you can see the pixels
|Before (main)|After (this PR)|
|-|-|
|![image](https://github.com/user-attachments/assets/405d1fd3-a18c-43d9-bd0a-be4966bc04bd)|![image](https://github.com/user-attachments/assets/becc1459-baa4-4c9f-b68d-0b3fdb3a51ab)|
|![image](https://github.com/user-attachments/assets/00f33fac-bdef-4579-9344-8bd1aee9e0e9)|![image](https://github.com/user-attachments/assets/b88f9cd1-6c0c-4253-a25d-c14143d90089)|
|![image](https://github.com/user-attachments/assets/78ad227c-9b11-4ae1-a9f6-f682eaa0f16d)|![image](https://github.com/user-attachments/assets/50b619df-bef7-4b8b-b041-cc4ca21e850c)|
2025-07-08 10:29:13 -06:00
Qwerasd a67b8b35f6 font/coretext: disable Apple's quantization, do it ourselves
Using the "subpixel quantization" option for rendering our glyph was
creating bad edge cases where we'd lose the bottom or left row / column
of pixels in a glyph sometimes. I investigated the exact effect of this
option and it seems like beyond quantizing the position and scale it's
also doing some rudimentary auto-hinting. That said, the auto-hinting
doesn't do that much for us, and the fact that it horizontally snaps
coordinates to thirds of a pixel instead of whole pixels makes things
worse in terms of legibility at small pixel sizes, so ultimately it's
better with our own handling anyway.

I extensively compared the result of Apple's option with our own manual
quantization here and I'm pretty sure this will always match the whole
pixel sizes, and where it differs (other than things like crossbars) it
seems to make glyphs generally more legible not less.
2025-07-07 21:26:23 -06:00
Jason Rayne 740c9c6644
Merge branch 'main' into ssh-integration 2025-07-07 11:33:44 -07:00
Jason Rayne f279937377
refactor: simplify terminfo handling and remove base64 dependency
- Default ssh_term to xterm-256color to eliminate fallback assignments
- Remove base64 and replace infocmp -Q2 with standard -0 -x options for
compatibility
- Use process substitution instead of intermediate ssh_config variable
- Always set TERM explicitly since ssh_term is always defined
2025-07-07 11:33:26 -07:00
Mitchell Hashimoto 26522ab8c2
ci: switch Apple notarization to an new account (#7852)
The Ghostty Apple ID has been frozen. I'm working on figuring out how to
get it back. In the meantime, this switches the notarization to my
personal Apple ID.

I originally created the dedicated Apple ID to limit access since we
were using app passwords. But I've since discovered that we can create
API tokens that have limited access, so I don't think this is a problem
anymore.
2025-07-07 11:21:40 -07:00
Mitchell Hashimoto 9d81a5f5ec
ci: switch Apple notarization to an new account
The Ghostty Apple ID has been frozen. I'm working on figuring out how to
get it back. In the meantime, this switches the notarization to my
personal Apple ID.

I originally created the dedicated Apple ID to limit access since we
were using app passwords. But I've since discovered that we can create
API tokens that have limited access, so I don't think this is a problem
anymore.
2025-07-07 11:08:44 -07:00
Jason Rayne 22edfd2c5d
Merge branch 'main' into ssh-integration 2025-07-07 10:01:22 -07:00
Jason Rayne c3b14dff71
refactor: simplify SSH terminfo and environment handling
- Simplify feature detection to use single wildcard check
- Replace ssh_env array with simple ssh_term string variable
- Use TERM environment prefix instead of save/restore pattern
- Remove unnecessary backgrounded subshell for cache operations
2025-07-07 10:00:56 -07:00
Qwerasd 5bc41dc694
Nerd Font Icon Height Constraint (#7850)
Nerd font icons were ***WAY*** too big depending on your font setup,
this is because we were always using the full cell height when the nerd
font patcher instead uses an "icon height" for most things. The patcher
calculates the icon height as two thirds of the font's cap height and
one third of the line height, but I've chosen to instead use 1.2 times
the cap height for more consistent results across fonts-- if the user
wants their icons bigger, they can use the `adjust-icon-height` metric
modifier (and they can also use it to make them smaller if they want
that for some reason).

I also adjusted the attributes to user horizontal cover + vertical fit
for `^` stretch modes (proportional scaling but scale up), which makes
it so that it never exceeds the cell size, since first it covers
horizontally and then scales down to fit vertically if necessary;
previously, if there were a particularly wide glyph that was scaled with
cover/cover it would exceed the available width and overflow in to
neighboring cells which wasn't good.
2025-07-07 10:25:53 -06:00
Jason Rayne e0035e153d
Merge branch 'main' into ssh-integration 2025-07-07 09:07:14 -07:00
Jason Rayne 08db61e27e
refactor: simplify SSH environment variable handling
- Remove complex ssh_exported_vars tracking and local environment
modification in favor of trusting Ghostty's local environment
- Replace regex patterns with glob-based feature detection for better
performance
- Fix local variable declaration consistency throughout
- Streamline logic while maintaining all functionality
2025-07-07 09:06:15 -07:00
Qwerasd bcb6ee6db6 config: add adjust-icon-height option
Metric modifier for the `icon_height` metric.
2025-07-07 10:04:11 -06:00
Qwerasd c47459b4a2 font: add icon height to nerd font constraints
Icons were often WAY too big before because they were filling the whole
cell in height, which isn't great lol. This commit adds an `icon_height`
metric which is used to constrain glyphs that shouldn't be the size of
the entire cell.
2025-07-07 10:04:11 -06:00
Mitchell Hashimoto fb271a67ec
font/coretext: fix horizontal bearing calculation (#7848)
This was subtly wrong in a way that was most obvious when text switched
from regular to bold, where it would seem to wiggle since the bearings
of each letter would shift by a pixel in either direction. This affected
applications like fzf which uses bold to dynamically highlight the line
you have selected.
2025-07-07 08:59:31 -07:00
Mitchell Hashimoto 4aff16c148
gtk: rebuild gresources.c/h if CSS or icons change (#7849) 2025-07-07 08:59:07 -07:00
Jeffrey C. Ollie 5b1d390379
gtk: rebuild gresources.c/h if CSS or icons change 2025-07-07 10:38:08 -05:00
Qwerasd 23cc50b12c font/Metrics: remove original_cell_width, no longer needed 2025-07-07 09:09:37 -06:00
Qwerasd e1e2f823ba font/coretext: fix horizontal bearing calculation
This was subtly wrong in a way that was most obvious when text switched
from regular to bold, where it would seem to wiggle since the bearings
of each letter would shift by a pixel in either direction. This affected
applications like fzf which uses bold to dynamically highlight the line
you have selected.
2025-07-07 08:57:20 -06:00
Kat 292d89dbe2
Add Hebrew Translations (#6758)
Pull request to add Hebrew translations, as discussed in the Discord.
2025-07-07 06:28:09 +00:00
Qwerasd 00d1e34957
Fallback Font Size Adjustment (#7840)
This PR changes `font.Collection` to automagically adjust the sizes of
added fonts so that their metrics (specifically their ex height, or
their ideograph character width if they have one) match the primary
font. This is like
[`font-size-adjust`](https://developer.mozilla.org/en-US/docs/Web/CSS/font-size-adjust)
from CSS.

This is a big win for users who use mixed writing systems and rely
heavily on fallback fonts. For example, in #7774 it's pointed out that
CJK characters are not very well harmonized with existing Latin glyphs,
well:
|Before (`main`)|After (this PR)|
|-|-|
|<img width="326" alt="image"
src="https://github.com/user-attachments/assets/c11d372d-ec69-426d-b008-1f56a7430f23"
/>|<img width="326" alt="image"
src="https://github.com/user-attachments/assets/efcb56ea-0572-481a-b632-a0b5cd170fa9"
/>|

This also improves our handling of the horizontal alignment of fallback
glyphs. It's not an ideal solution; it only works for glyphs narrower
than the cell width because it messes with ligatures if we include
glyphs wider than the cell width; and most things would look better if
the center were proportionally remapped based on the ratio from the
glyph advance to the cell width, but that messes with glyphs designed to
align vertically so it can't be done, instead the original advance width
is centered in the cell width.
2025-07-06 23:01:55 -06:00
Qwerasd 08fd1688ff font: add test for size adjustment, fix small bug in resize
Previously produced very wrong values when calling Collection.setSize,
since it was assuming that the provided face had the same point size as
the primary face, which isn't true during resize-- so instead we just
have faces keep track of their set size, this is generally useful.
2025-07-06 22:45:13 -06:00
Qwerasd d33161ad66 fix(font): include line gap in `lineHeight` helper 2025-07-06 22:40:43 -06:00
Mitchell Hashimoto de814d32ef
macos: open URLs with NSWorkspace APIs instead of `open` (#7843)
Fixes #5256

This updates the macOS apprt to implement the `OPEN_URL` apprt action to
use the NSWorkspace APIs instead of the `open` command line utility.

As part of this, we removed the `ghostty_config_open` libghostty API and
instead introduced a new `ghostty_config_open_path` API that returns the
path to open, and then we use the `NSWorkspace` APIs to open it (same
function as the `OPEN_URL` action).
2025-07-06 21:11:45 -07:00
Mitchell Hashimoto b7ffbf933f
macos: open URLs with NSWorkspace APIs instead of `open`
Fixes #5256

This updates the macOS apprt to implement the `OPEN_URL` apprt action to
use the NSWorkspace APIs instead of the `open` command line utility.

As part of this, we removed the `ghostty_config_open` libghostty API and
instead introduced a new `ghostty_config_open_path` API that returns the
path to open, and then we use the `NSWorkspace` APIs to open it (same
function as the `OPEN_URL` action).
2025-07-06 21:01:01 -07:00
Mitchell Hashimoto db45fab85e
bash: conditionally add cursor shape sequences (#7839)
In #7808, we stopped using PS0 to reset the cursor shape because
restoring PS0 in __ghostty_preexec was causing issues (#7802).

The alternate approach of printing the cursor reset escape sequence
directly from __ghostty_preexec caused a new issue: the input cursor
would persist longer than intended, such as when a suspended vim process
was restored to the foreground.

This change takes a different approach. We now conditionally add the
cursor shape escape sequences to PS0 (and PS1, for consistency) when
they don't already appear. The fixes the cursor shape reset problem.

The main downside to this approach is that PS0 will continue to contain
this escape sequence; it won't be cleared/reset in __ghostty_preexec for
the reasons described in #7808. This feels like an acceptable outcome
because there's no harm in the modified PS0 existing for the life of the
bash session (rather than it being modified and then restored for each
command cycle), and it's consistent with how some other terminals' bash
integration works (e.g. kitty).
2025-07-06 19:46:10 -07:00
Mitchell Hashimoto fbb1994934
font: fix nerd font patcher ypadding twice what it should be (#7841)
The nerd font patcher uses `ypadding` as a single subtraction from the
cell height, which means that half of it should go to the top padding
and the other half to the bottom, but we were setting it for both the
top and bottom! This was making the heavy brackets way too small lol
(0.4 of the cell height instead of 0.7)

#7834 introduced the *opposite* problem to what it fixed haha. This
fixes it for real!
2025-07-06 19:43:15 -07:00
Qwerasd 327caf903c font: fix nerd font patcher ypadding twice what it should be
The nerd font patcher uses `ypadding` as a single subtraction from the
cell height, which means that half of it should go to the top padding
and the other half to the bottom, this was making the heavy brackets way
too small lol (0.4 of the cell height instead of 0.7)
2025-07-06 17:20:39 -06:00
Qwerasd db08bf1655 font: adjust fallback font sizes to match primary metrics
This better harmonizes fallback fonts with the primary font by matching
the heights of lowercase letters. This should be a big improvement for
users who use mixed scripts and so rely heavily on fallback fonts.
2025-07-06 16:55:50 -06:00
Jon Parise 65a7c81c94 bash: conditionally add cursor shape sequences
In #7808, we stopped using PS0 to reset the cursor shape because
restoring PS0 in __ghostty_preexec was causing issues (#7802).

The alternate approach of printing the cursor reset escape sequence
directly from __ghostty_preexec caused a new issue: the input cursor
would persist longer than intended, such as when a suspended vim process
was restored to the foreground.

This change takes a different approach. We now conditionally add the
cursor shape escape sequences to PS0 (and PS1, for consistency) when
they don't already appear. The fixes the cursor shape reset problem.

The main downside to this approach is that PS0 will continue to contain
this escape sequence; it won't be cleared/reset in __ghostty_preexec for
the reasons described in #7808. This feels like an acceptable outcome
because there's no harm in the modified PS0 existing for the life of the
bash session (rather than it being modified and then restored for each
command cycle), and it's consistent with how some other terminals' bash
integration works (e.g. kitty).
2025-07-06 18:39:32 -04:00
Qwerasd d3aece21d8 font: more generic bearing adjustments
This generally adjusts the bearings of any glyph whose original advance
was narrower than the cell, which helps a lot with proportional fallback
glyphs so they aren't just left-aligned. This only applies to situations
where the glyph was originally narrower than the cell, so that we don't
mess up ligatures, and this centers the old advance width in the new one
rather than adjusting proportionally, because otherwise we can mess up
glyphs that are meant to align with others when placed vertically.
2025-07-06 16:34:31 -06:00
Mitchell Hashimoto 78e861b50e
core/gtk: open urls using an apprt action instead of doing it directly (#5988)
Partial implementation of #5256

This implements the core changes necessary to open urls using an apprt
action rather than doing it directly from the core.

Implements the open_url action in the GTK apprt.

Note that this should not be merged until a macOS-savvy developer can
add an implementation of the open_url action for the macOS apprt.
2025-07-06 15:19:55 -07:00
Mitchell Hashimoto cbcb0b795c
Fallback to cross-platform minimal open when apprt is not available 2025-07-06 15:15:48 -07:00
Jeffrey C. Ollie 70a2a0afd5 better ABI check for apprt.Action.CValue 2025-07-06 15:02:48 -07:00
Jeffrey C. Ollie 9583ea1b7a core/gtk: open urls using an apprt action instead of doing it directly
Partial implementation of #5256

This implements the core changes necessary to open urls using an apprt
action rather than doing it directly from the core.

Implements the open_url action in the GTK and GLFW apprts.

Note that this should not be merged until a macOS-savvy developer can add
an implementation of the open_url action for the macOS apprt.
2025-07-06 15:02:48 -07:00
Qwerasd b10b0f06c3 font: remove unused fields from Glyph
We can reintroduce `advance` if we ever want to do proportional string
drawing, but we don't use it anywhere right now. And we also don't need
`sprite` anymore since that was just there to disable constraints for
sprites back when we did them on the GPU.
2025-07-06 15:53:59 -06:00
Sl (Shahaf Levi) 3ff11cdd86 Add Hebrew Translations 2025-07-06 23:38:22 +03:00
Mitchell Hashimoto 185a4ea10b
Added bold-color option (#7168)
As discussed in https://github.com/ghostty-org/ghostty/discussions/3134

To allow for the option to render bold text in a different colour for
better visibility as an extension of `bold-is-bright`.

This is a feature that is available in other terminals.
2025-07-06 12:59:04 -07:00
Robert Ian Hawdon 52790fb92c Added bold-color option 2025-07-06 12:56:43 -07:00
Jeffrey C. Ollie f40c9a4d38
keybind: add copy_title_to_clipboard action (#7833)
Fixes #7829

This will copy the terminal title to the clipboard. If the terminal
title is not set or the title is empty the action has no effect.
2025-07-06 14:34:20 -05:00
Jeffrey C. Ollie 7884872d4e
keybind: don't clobber the clipboard if the title is empty 2025-07-06 14:15:11 -05:00
Mitchell Hashimoto 04c5bb2984
Add link-previews option (#7831)
Implement the `link-previews` option from
https://github.com/ghostty-org/ghostty/discussions/7727.

The feature request isn't accepted yet, but I had a bit of free time to
write this up and it was pretty quick, so I figure there's no harm in
proposing an implementation.

Demo of `link-previews = osc8`:



https://github.com/user-attachments/assets/17a72ab2-c727-4a85-9edd-9b6e7da05d98
2025-07-06 12:09:39 -07:00
Mitchell Hashimoto c4e2a70010
Nerd Font Constraint Fixes (#7834)
Fixes #7820, and while fixing that I noticed that we need to respect the
cell width constraints since certain glyphs should not expand to 2
cells; before fixing that the heavy bracket would align differently
depending on if it had whitespace after it, which was obviously wrong
and looked terrible.
2025-07-06 12:06:13 -07:00
Jeffrey C. Ollie a0595e07b2
linux/kde: add KDE shortcut to desktop file (#7835)
Fixes #7673

This adds `Ctrl+Alt+T` as a KDE shortcut to the desktop file. If Konsole
is installed (or any other prorgam that has the same shortcut) the user
will need to go into the KDE system settings and manually reassign the
`Ctrl+Alt+T` shortcut to Ghostty.

If Ghostty is the only terminal installed that claims that shortcut KDE
_should_ automatically enable the shortcut (but YMMV).

Non-KDE systems will ignore this setting and if the user desires a
global shortcut to open a Ghostty window it will need to be accomplished
in other ways.
2025-07-06 13:23:21 -05:00
Jeffrey C. Ollie a23b5328a5
keybind: rename copy_title to copy_title_to_clipboard
Co-authored-by: Jon Parise <jon@indelible.org>
2025-07-06 13:12:00 -05:00
Jeffrey C. Ollie 871f90e448
linux/kde: add KDE shortcut to desktop file
Fixes #7673

This adds `Ctrl+Alt+T` as a KDE shortcut to the desktop file. If Konsole
is installed (or any other prorgam that has the same shortcut) the user
will need to go into the KDE system settings and manually reassign the
`Ctrl+Alt+T` shortcut to Ghostty.

If Ghostty is the only terminal installed that claims that shortcut KDE
_should_ automatically enable the shortcut (but YMMV).

Non-KDE systems will ignore this setting and if the user desires a
global shortcut to open a Ghostty window it will need to be accomplished
in other ways.
2025-07-06 13:05:00 -05:00
Qwerasd c7e65b0c1c font: respect cell width attributes in nerd font constraints
This mostly applies to powerline glyphs, but is also relevant for heavy
bracket characters, which need to always be 1 wide otherwise they look
silly because they misalign depending on if there's a space after them
or not.
2025-07-06 11:23:49 -06:00
Jeffrey C. Ollie 3cf56b8af3
keybind: add copy_title action
Fixes #7829

This will copy the terminal title to the clipboard. If the terminal
title is not set it has no effect.
2025-07-06 12:12:27 -05:00
Qwerasd 8f989f6bfd font: fix nerd font codegen to handle ypadding properly
Previously `ypadding` was effectively ignored, since it's mutually
exclusive with `overlap`. This had a noticeable effect on the heavy
bracket characters U+276C...U+2771, which were much taller than they
should have been.

I also fixed the vertical overlap limit, since negative `overlap` values
are used in the nerd font attributes to create padding on all sides of
the cell, so we don't want to limit the magnitude of the overlap for
vertical padding, we only want to limit it if the value is positive.

That change fixed the vertical padding for a handful of ranges, which
should give more consistent results.
2025-07-06 11:02:00 -06:00
Qwerasd 7de4d569b0 Revert "rely on stdin/stdout instead of hardcoded paths"
This reverts commit 2fca0477bc.

The idea of using stdin and stdout was the integrate it in to the build
script, but since we don't want to do that because it contains an eval,
it just makes it more annoying to use.
2025-07-06 10:49:49 -06:00
Mitchell Hashimoto d790b0f60e
chore(ci): pin GitHub Actions to specific SHAs (#7816)
Follow-up on #7076

SHAs were generated using
[pinact](https://github.com/suzuki-shunsuke/pinact).

By the way, all repository workflows don’t declare permissions, so they
use the defaults, which are usually [too
permissive](https://docs.zizmor.sh/audits/#excessive-permissions), I’d
suggest using per-workflow/job permissions instead, since most (if not
all) jobs don’t need full access. If that’s added, it should go in a
separate issue/PR so we can review the minimum needed per job.

Refs:

https://docs.github.com/en/actions/how-tos/security-for-github-actions/security-guides/automatic-token-authentication#permissions-for-the-github_token

You can check everything with this SARIF file:


[ghostty-sarif.json](https://github.com/user-attachments/files/21081630/ghostty-sarif.json)
read it at https://microsoft.github.io/sarif-web-component/
2025-07-06 07:06:38 -07:00
Mitchell Hashimoto 43083f3af5
Add linux kernel information to +version (#7790)
Adds basic kernel information to `ghostty +version`. 
`ghostty +version` on my machine now prints:
```
Ghostty 1.1.4-kernel-version-info+cdbc78bce

Version
  - version: 1.1.4-kernel-version-info+cdbc78bce
  - channel: tip
Build Config
  - Zig version   : 0.14.1
  - build mode    : builtin.OptimizeMode.Debug
  - app runtime   : apprt.Runtime.gtk
  - font engine   : font.main.Backend.fontconfig_freetype
  - renderer      : renderer.generic.Renderer(renderer.OpenGL)
  - libxev        : io_uring
  - kernel version: 6.15.4-200.fc42.x86_64
  - desktop env   : other
  - GTK version   :
    build         : 4.18.5
    runtime       : 4.18.5
  - libadwaita    : enabled
    build         : 1.7.4
    runtime       : 1.7.4
  - libX11        : enabled
  - libwayland    : enabled

```


PS This is my first time writing prod code in Zig, so any suggestions
and guidelines are welcome
2025-07-06 07:01:26 -07:00
Mitchell Hashimoto b9ef1c9a0d
Add action to set font size (#7818)
Fixes #7795 

Adds the `set_font_size` keybind action.
2025-07-06 07:00:35 -07:00
Breno A. 0a1ade0158 pin GitHub Actions to specific SHAs 2025-07-06 06:59:50 -07:00
Jeffrey C. Ollie eb5694794c keybind: add set_font_size
Fixes #7795

This allows the font size to be set to an absolute value.
2025-07-06 06:42:14 -07:00
Mitchell Hashimoto 48394d0328
gtk: don't allow focusing on tab overview or menu buttons (#7826)
This prevents GTK from focusing on those buttons, which would prevent
focus from returning to the terminal after those buttons had been used.
2025-07-06 06:39:56 -07:00
Mitchell Hashimoto d347b0929a
Add termio to terminal CODEOWNERS group (#7828)
The termio directory contains the implementation of many terminal
features that those in the terminal reviewer group may want to be
notified about.

---

An example of a terminal related PR that only changed files in the
`termio` directory (and thus didn't assign @ghostty-org/terminal):
https://github.com/ghostty-org/ghostty/pull/7725

I included the entire `termio` directory. If others in the
@ghostty-org/terminal group think this is too broad we can narrow it
down.
2025-07-06 06:38:07 -07:00
Gregory Anders 9f3f9205d8 Add link-previews option 2025-07-06 08:33:11 -05:00
Gregory Anders 64dd10b98f Add termio to terminal CODEOWNERS group
The termio directory contains the implementation of many terminal
features that those in the terminal reviewer group may want to be
notified about.
2025-07-06 08:28:24 -05:00
Jeffrey C. Ollie b752ade112
gtk: don't allow focusing on tab overview or menu buttons
This prevents GTK from focusing on those buttons, which would prevent
focus from returning to the terminal after those buttons had been used.
2025-07-06 01:05:17 -05:00
Qwerasd dc18f1a2b9
"Better Glyph Constraint Logic" follow-up (#7822)
Follow-up to #7809, a handful of small fixes/improvements, explained
individually in each commit message.

> [!NOTE]
> Similar to the inverted "monochrome" ft flag fix from #7809, it was
pointed out that "force-autohint" was also inverted, so I did invert
that too, this has the same result of no impact on users who haven't
explicitly set it, but a breaking behavior change for users who have set
it. *These changes definitely need to be pointed out in the 1.2 release
notes!*
2025-07-05 23:04:09 -06:00
Mitchell Hashimoto 104a46cfa4
macos: support configuration via CLI arguments (#7823)
This makes it so `zig build run` can take arguments such as
`--config-default-files=false` or any other configuration. Previously,
it only accepted commands such as `+version`.

Incidentally, this also makes it so that the app in general can now take
configuration arguments via the CLI if it is launched as a new instance
via `open`. For example:

    open -n Ghostty.app --args --config-default-files=false

This previously didn't work. This is kind of cool.

To make this work, the libghostty C API was modified so that
initialization requires the CLI args, and there is a new C API to try to
execute an action if it was set.
2025-07-05 21:44:12 -07:00
Mitchell Hashimoto 753f3ea72b
refactor nerd font codegen script (#7819)
Mainly added type annotations, cleaned up weird AI slop and used more
idiomatic stuff.
This requires Python 3.12 to run (I can downgrade it if need be).
2025-07-05 21:36:04 -07:00
Mitchell Hashimoto 984d123fe4
macos: support configuration via CLI arguments
This makes it so `zig build run` can take arguments such as
`--config-default-files=false` or any other configuration. Previously,
it only accepted commands such as `+version`.

Incidentally, this also makes it so that the app in general can now take
configuration arguments via the CLI if it is launched as a new instance
via `open`. For example:

    open -n Ghostty.app --args --config-default-files=false

This previously didn't work. This is kind of cool.

To make this work, the libghostty C API was modified so that
initialization requires the CLI args, and there is a new C API to try to
execute an action if it was set.
2025-07-05 21:31:23 -07:00
Qwerasd 8f50c7f269 font/sprite: no more margin in atlas region
We no longer need a margin in the atlas because we always sample with
nearest neighbor and our glyphs are always pixel perfect, no worry about
interpolation between adjacent glyphs anymore!
2025-07-05 22:13:26 -06:00
Qwerasd 87f35bd1c1 renderer/opengl: explicit texture options
This sets up for a couple improvments (see TODO comments) and also sets
the glyph atlas textures to nearest neighbor sampling since we can do
that now that we never scale glyphs.
2025-07-05 22:10:39 -06:00
Mitchell Hashimoto 82cad3cf33
macOS: zig build run disables window saved state (#7821) 2025-07-05 21:00:33 -07:00
Mitchell Hashimoto 8c3caee15c
macOS: zig build run disables window saved state 2025-07-05 19:58:17 -07:00
Qwerasd 02d82720d2 font/freetype: fix negated force-autohint flag
The behavior of this flag was the opposite of its description in the
docs- luckily, at the same time, the default (true) was the opposite
from what the default actually is in freetype, so users who haven't
explicitly set this flag won't see a behavior difference from this.
2025-07-05 20:40:12 -06:00
Qwerasd fff16bff69 font/coretext: fix bitmap size calculation, prevent clipping
Previously, many glyphs were having their top and right row/column of
pixels clipped off due to not accounting for the slight bearing in the
width and height calculation here.
2025-07-05 20:36:35 -06:00
trag1c 2fca0477bc
rely on stdin/stdout instead of hardcoded paths 2025-07-06 02:28:28 +02:00
trag1c 4b6c461d6f
refactor nerd font codegen script 2025-07-06 02:08:46 +02:00
Jason Rayne f242c6b5c4
Merge branch 'main' into ssh-integration 2025-07-05 14:54:31 -07:00
Mitchell Hashimoto b799462745
Better Glyph Constraint Logic (#7809)
This is a big'un.

- **Glyph constraint logic is now done fully on the CPU** at the
rasterization stage, so it only needs to be done once per glyph instead
of every frame. This also lets us eliminate padding between glyphs on
the atlas because we're doing nearest-neighbor sampling instead of
interpolating-- which ever so slightly increases our packing efficiency.
- **Special constraints for nerd font glyphs** are applied based roughly
on the constraints they use in their patcher. It's a simplification of
what they do, the largest difference being that they scale groups of
glyphs based on a shared bounding box so that they maintain relative
size to one another, but that would require loading all glyphs on the
group and I'd want to do that on font load TBH and at that point I'd
basically be re-implementing the nerd fonts patcher in Zig to patch
fonts at load time which is way beyond the scope I want to have. (Fixes
#7069)
- These constraints allow for **perfectly sized and centered emojis**,
this is very nice.
- **Changed the default embedded fonts** from 4 copies (regular, italic,
bold, bold italic) of a patched (and outdated) JetBrains Mono to a
single JetBrains Mono variable font and a single Nerd Fonts Symbols Only
font. This cuts the weight of those down from 9MB to 3MB!
- **FreeType's `renderGlyph` is significantly reworked**, and the new
code is, IMO, much cleaner- although there are probably some edge case
behavior differences I've introduced.

> [!NOTE]
> One breaking change I definitely introduced is changing the
`monochrome` freetype load flag config from its previous completely
backwards meaning to instead the correct one (I also changed the
default, so this won't affect any user who hasn't touched it, but users
who set the `monochrome` flag will find their fonts quite crispy after
this change because they will have no anti-aliasing anymore)

### Future work

Following this change I want to get to work on automatic font size
matching (a la CSS
[`font-size-adjust`](https://developer.mozilla.org/en-US/docs/Web/CSS/font-size-adjust)).
I set the stage for that quite some time ago so it shouldn't be too much
work and it will be a big benefit for users who regularly use multiple
writing systems and so have multiple fonts for them that aren't
necessarily size-compatible.
2025-07-05 14:37:46 -07:00
Mitchell Hashimoto 9ff77a5622
build: switch symbols over 2025-07-05 14:23:10 -07:00
Mitchell Hashimoto 43404bf4dc
build: try again, also do symbol packages 2025-07-05 14:21:27 -07:00
Mitchell Hashimoto d772b2ce39
ci: fix release workflows to not build macos app 2025-07-05 14:14:09 -07:00
Mitchell Hashimoto 28b54fe22b
build: fix JBM zip to tar.gz 2025-07-05 14:10:28 -07:00
Mitchell Hashimoto 390812828a
Nuke GLFW, make `zig build run` on macOS build the Xcode project (#7815)
This PR does two things.

1. Build system improvements to make developing on macOS more enjoyable 
2. Delete the GLFW apprt

## Build System Improvements (macOS)

On macOS, there are a few major improvements:

* `zig build` now produces a full macOS app bundle and copies it into
`zig-out`
* `zig build run` now builds the macOS app and runs it, streaming logs
directly into the terminal
* `-Demit-macos-app` can control whether app bundle is created
* `-Dxcframework-target` can be set to one of `native` or `universal` to
control whether the xcframework uses only your target machines arch or
creates a universal one with macOS and iOS. This defaults to `native`
for the `run` command and `universal` for all others.
* The general flow of the `build.zig` file was improved to be more
declarative

## Nuke GLFW

> This deletes the GLFW apprt from the Ghostty codebase.
> 
> The GLFW apprt was the original apprt used by Ghostty (well, before
> Ghostty even had the concept of an "apprt" -- it was all just a single
> application then). It let me iterate on the core terminal features,
> rendering, etc. without bothering about the UI. It was a good way to
get
> started. But it has long since outlived its usefulness.
> 
> We've had a stable GTK apprt for Linux (and Windows via WSL) and a
> native macOS app via libghostty for awhile now. The GLFW apprt only
> remained within the tree for a few reasons:
> 
>   1. Primarily, it provided a faster feedback loop on macOS because
>      building the macOS app historically required us to hop out of the
>      zig build system and into Xcode, which is slow and cumbersome.
> 
>   2. It was a convenient way to narrow whether a bug was in the
> core Ghostty codebase or in the apprt itself. If a bug was in both
>      the glfw and macOS app then it was likely in the core.
> 
>   3. It provided us a way on macOS to test OpenGL.
> 
> All of these reasons are no longer valid. Respectively:
> 
> 1. Our Zig build scripts now execute the `xcodebuild` CLI directly and
>      can open the resulting app, stream logs, etc. This is the same
> experience we have on Linux. (Xcode has always been a dependency of
>      building on macOS in general, so this is not cumbersome.)
> 
>   2. We have a healthy group of maintainers, many of which have access
>      to both macOS and Linux, so we can quickly narrow down bugs
>      regardless of the apprt.
> 
> 3. Our OpenGL renderer hasn't been compatible with macOS for some time
>      now, so this is no longer a useful feature.
> 
> At this point, the GLFW apprt is just a burden. It adds complexity
> across the board, and some people try to run Ghostty with it in the
real
> world and get confused when it doesn't work (it's always been lacking
in
> features and buggy compared to the other apprts).
> 
> So, it's time to say goodbye. Its bittersweet because it is a big part
> of Ghostty's history, but we've grown up now and it's time to move on.
> Thank you, goodbye.
> 
> (NOTE: If you are a user of the GLFW apprt, then please fork the
project
> prior to this commit or start a new project based on it. We've warned
> against using it for a very, very long time now.)
2025-07-05 13:49:24 -07:00
Mitchell Hashimoto 0929f39e89
build: xcodebuild properly sets up resources 2025-07-05 13:36:31 -07:00
Jason Rayne 2d2df4b99f
Merge branch 'main' into ssh-integration 2025-07-05 13:34:47 -07:00
Jason Rayne a727b59b2b
fix: replace custom const with std lib, remove dead-weight test
- Replaced custom const `SECONDS_PER_DAY` with `std.time.s_per_day`
- Removed concurrent access test - would need real file ops to be
meaningful
2025-07-05 13:24:59 -07:00
Jason Rayne a22074a85c
fix: optimize SSH integration and improve error handling
- Replace dual-loop SSH config parsing with efficient single-pass case
statement
- Remove overly cautious timeout logic from cache checks for simplicity
- Add base64 availability check with xterm-256color fallback when
missing
- Include hostname in terminfo setup messages for better UX
- Maintain SendEnv/SetEnv dual approach for maximum OpenSSH
compatibility (relying on SetEnv alone seems to drop some vars during my
tests, despite them being explicitly included in AcceptEnv on the remote
host)
2025-07-05 13:24:59 -07:00
Mitchell Hashimoto 8653229607
ci: don't use the new macOS app emit yet 2025-07-05 07:26:02 -07:00
Mitchell Hashimoto 8b44d0b3bb
build: make `zig build run` on macOS work with an empty zig-out 2025-07-05 07:22:42 -07:00
Mitchell Hashimoto 5fc0bbc58f
build: add -Demit-macos-app 2025-07-05 07:05:36 -07:00
Mitchell Hashimoto f04a388f00
bash: stop using PS0 for the 'cursor' feature (#7808)
Our use of PS0 (which bash runs before command execution) was causing
raw command sequences to be printed between multiple commands in a
sequence.

    $ alias garbage='echo start
    > echo end'

    $ garbage
    start
    �\���dend

I wasn't able to definitely track down all of the reasons for why this
only happens in the command sequence case, but I suspect it's related to
the way that __ghostty_preexec runs from within the bash DEBUG trap (by
way of bash-preexec).

This problem occurs when PS0 is set to _any_ string (even "") inside of
__ghostty_preexec, which also rules out most/any Ghostty-specific code.
PS1 and PS2 appear to be safe to (re)set in this context.

Fortunately, we can avoid using PS0 entirely by instead printing the
cursor reset escape sequence directly from __ghostty_precmd because it
also runs just before command execution.

Fixes #7802
2025-07-04 21:05:41 -07:00
Mitchell Hashimoto d223cfce1d
fix: draw cursor on top of text for most cursor styles (#7810)
This addresses #7739.

## Changes
* Added second cursor list to the renderer as suggested
* Modified `Contents.setCursor` to accept a cursor style argument in
order to conditionally render the cursor
* Not sure if this the optimal workaround so suggestions would be
appreciated

## Screenshots
Block:
![Screenshot 2025-07-04 at 7 10
19 PM](https://github.com/user-attachments/assets/39caf936-863b-42f3-9ca9-a32a2da237b8)

Hollow block:
![Screenshot 2025-07-04 at 7 10
06 PM](https://github.com/user-attachments/assets/5063e1a0-06c7-46d1-9118-5855bff7cc5c)
2025-07-04 21:05:04 -07:00
Daniel 1a4b128af3 replace nested if for readability 2025-07-04 21:36:17 -04:00
Jon Parise b8931dd1db bash: stop using PS0 for the 'cursor' feature
Our use of PS0 (which bash runs before command execution) was causing
raw command sequences to be printed between multiple commands in a
sequence.

    $ alias garbage='echo start
    > echo end'

    $ garbage
    start
    �\���dend

I wasn't able to definitely track down all of the reasons for why this
only happens in the command sequence case, but I suspect it's related to
the way that __ghostty_preexec runs from within the bash DEBUG trap (by
way of bash-preexec).

This problem occurs when PS0 is set to _any_ string (even "") inside of
__ghostty_preexec, which also rules out most/any Ghostty-specific code.
PS1 and PS2 appear to be safe to (re)set in this context.

Fortunately, we can avoid using PS0 entirely by instead printing the
cursor reset escape sequence directly from __ghostty_precmd because it
also runs just before command execution.
2025-07-04 20:06:06 -04:00
Daniel 0b4a1e2154 added test for other cursor style 2025-07-04 18:54:55 -04:00
Daniel a9fc3b6fa0 enable drawing cursor on top or bottom based on style 2025-07-04 18:50:23 -04:00
Daniel de3e77570e add second cursor list 2025-07-04 18:26:27 -04:00
Qwerasd 41ff0b440b fix tests 2025-07-04 16:10:36 -06:00
Mitchell Hashimoto 91ee75ae4d
build: add -Dxcframework-target to specify the target for builds 2025-07-04 15:01:14 -07:00
Mitchell Hashimoto 3793dac313
build: zig build run only builds xcframework for current arch 2025-07-04 14:56:25 -07:00
Qwerasd 1ab2603e0f font/freetype: remove freetype_convert.zig
This is no longer needed since we're now using the FT_Bitmap_Convert
function from FreeType to do any conversions we need instead.
2025-07-04 15:47:35 -06:00
Qwerasd ec20c455c7 renderer: remove all gpu-side glyph constraint logic
Now that it's done at the rasterization stage, we don't need to handle
it on the GPU. This also means that we can switch to nearest neighbor
interpolation in the Metal shader since we're guaranteed to be pixel
perfect. Accidentally, we were already nearest neighbor in the OpenGL
shaders because I used the Rectangle texture mode in the big renderer
rework, which doesn't support interpolation- anyway, that's no longer
problematic since we won't be scaling glyphs on the GPU anymore.
2025-07-04 15:47:35 -06:00
Qwerasd f292132762 font: add constraint width to glyph cache key 2025-07-04 15:47:28 -06:00
Qwerasd 1a8a048136 font/sfnt: simpler and more efficient FixedType conversions 2025-07-04 15:47:28 -06:00
Qwerasd 5553f7bf68 font: always maximize size of emoji and center them 2025-07-04 15:47:28 -06:00
Qwerasd 95c8747ab5 renderer: apply glyph constraints when rasterizing glyphs 2025-07-04 15:47:28 -06:00
Qwerasd 1775b75f2c font: generate glyph constraints based on nerd font patcher 2025-07-04 15:47:28 -06:00
Qwerasd e441094af0 font: add constraint logic to rasterizers
This is in preparation to move constraint off the GPU to simplify our
shaders, instead we only need to constrain once at raster time and never
again.

This also significantly reworks the freetype renderGlyph function to be
generally much cleaner and more straightforward.

This commit doesn't actually apply the constraints to anything yet, that
will be in following commits.
2025-07-04 15:47:28 -06:00
Mitchell Hashimoto fb9c52ecf4
Nuke GLFW from Orbit
This deletes the GLFW apprt from the Ghostty codebase.

The GLFW apprt was the original apprt used by Ghostty (well, before
Ghostty even had the concept of an "apprt" -- it was all just a single
application then). It let me iterate on the core terminal features,
rendering, etc. without bothering about the UI. It was a good way to get
started. But it has long since outlived its usefulness.

We've had a stable GTK apprt for Linux (and Windows via WSL) and a
native macOS app via libghostty for awhile now. The GLFW apprt only
remained within the tree for a few reasons:

  1. Primarily, it provided a faster feedback loop on macOS because
     building the macOS app historically required us to hop out of the
     zig build system and into Xcode, which is slow and cumbersome.

  2. It was a convenient way to narrow whether a bug was in the
     core Ghostty codebase or in the apprt itself. If a bug was in both
     the glfw and macOS app then it was likely in the core.

  3. It provided us a way on macOS to test OpenGL.

All of these reasons are no longer valid. Respectively:

  1. Our Zig build scripts now execute the `xcodebuild` CLI directly and
     can open the resulting app, stream logs, etc. This is the same
     experience we have on Linux. (Xcode has always been a dependency of
     building on macOS in general, so this is not cumbersome.)

  2. We have a healthy group of maintainers, many of which have access
     to both macOS and Linux, so we can quickly narrow down bugs
     regardless of the apprt.

  3. Our OpenGL renderer hasn't been compatible with macOS for some time
     now, so this is no longer a useful feature.

At this point, the GLFW apprt is just a burden. It adds complexity
across the board, and some people try to run Ghostty with it in the real
world and get confused when it doesn't work (it's always been lacking in
features and buggy compared to the other apprts).

So, it's time to say goodbye. Its bittersweet because it is a big part
of Ghostty's history, but we've grown up now and it's time to move on.
Thank you, goodbye.

(NOTE: If you are a user of the GLFW apprt, then please fork the project
prior to this commit or start a new project based on it. We've warned
against using it for a very, very long time now.)
2025-07-04 14:12:18 -07:00
Mitchell Hashimoto 7bd90e6ec4
Build system can build macOS app bundle and open it
`zig build run` on macOS now builds the app bundle via the `xcodebuild`
CLI and runs it. The experience for running the app is now very similar
to Linux or the prior GLFW build, where the app runs, blocks the zig
command, and logs to the terminal.

`xcodebuild` has its own build cache system that we can't really hook
into so it runs on every `zig build run` command, but it does cache and
I find its actually relatively fast so I think this is a good
replacement for the glfw-based system.
2025-07-04 13:32:15 -07:00
Mitchell Hashimoto 908eb6d156
On wait-after-command (or abnormal exit), only close on encoded key (#7800)
Fixes #7794

This commit also resets some terminal state to give us a better chance
of getting an encoded key, such as ensuring keyboard input is enabled
and disabling any Kitty protocols. This shouldn't ever be set but just
in case!
2025-07-04 07:47:57 -07:00
Mitchell Hashimoto d4743378cf
macOS: remove @DeferredProperty usage from TerminalEntity (#7799)
This fixes an Apple Shortcuts crash for macOS 15 and earlier.
Unfortunately it looks like we can't guard these with `@available`. I'm
going to report an Apple Feedback about this but for now this gets
shortcuts working on macOS 15 and earlier.
2025-07-04 07:42:21 -07:00
Mitchell Hashimoto eea073c97b
On wait-after-command (or abnormal exit), only close on encoded key
Fixes #7794

This commit also resets some terminal state to give us a better chance
of getting an encoded key, such as ensuring keyboard input is enabled
and disabling any Kitty protocols. This shouldn't ever be set but just
in case!
2025-07-04 07:41:01 -07:00
Mitchell Hashimoto d8838cff0b
macOS: remove @DeferredProperty usage from TerminalEntity
This fixes an Apple Shortcuts crash for macOS 15 and earlier.
Unfortunately it looks like we can't guard these with `@available`. I'm
going to report an Apple Feedback about this but for now this gets
shortcuts working on macOS 15 and earlier.
2025-07-04 07:30:26 -07:00
Leah Amelia Chen 887a77fbab
Request translators to update the CODEOWNERS file (#7798) 2025-07-04 08:38:58 +00:00
Kat 95d9b1e627
Request translators to update the CODEOWNERS file. 2025-07-04 18:08:18 +10:00
Jason Rayne 5ec18f426c
tests: use ! operator instead of == false for consistency
Co-authored-by: Kat <65649991+00-kat@users.noreply.github.com>
2025-07-03 23:17:46 -07:00
Jason Rayne 1bdcbac96c
Merge branch 'main' into ssh-integration 2025-07-03 22:41:29 -07:00
Mitchell Hashimoto 1213e919d4
Handle `exec` failures more gracefully (#7793)
Fixes #7792

Our error handling for `exec` failing within the forked process never
actually worked! It triggered all sorts of issues. We didn't catch this
before because it used to be exceptionally hard to fail an exec because
we used to wrap ALL commands in a `/bin/sh -c`.

However, we now support direction execution, most notably when you do
`ghostty -e <command>` but also via the `direct:` prefix on configured
commands.

This fixes up our exec failure handling by printing a useful error
message and avoiding any errdefers in the child which was causing the
double-close.
2025-07-03 21:39:08 -07:00
Mitchell Hashimoto e494d94fb3
Handle `exec` failures more gracefully
Fixes #7792

Our error handling for `exec` failing within the forked process never
actually worked! It triggered all sorts of issues. We didn't catch this
before because it used to be exceptionally hard to fail an exec because
we used to wrap ALL commands in a `/bin/sh -c`.

However, we now support direction execution, most notably when you do
`ghostty -e <command>` but also via the `direct:` prefix on configured
commands.

This fixes up our exec failure handling by printing a useful error
message and avoiding any errdefers in the child which was causing the
double-close.
2025-07-03 21:31:03 -07:00
Jason Rayne 75c703071a
feat(ssh): rewrite SSH cache system in native Zig
- Eliminates standalone bash dependency
- Consolidates `+list-ssh-cache` and `+clear-ssh-cache` actions into
single `+ssh-cache` action with args
- Structured cache format with timestamps and expiration support
- Memory-safe entry handling with proper file locking
- Comprehensive hostname validation (IPv4/IPv6/domains)
- Atomic updates via temp file + rename
- Updated shell integrations for improved cross-platform support and
reliability
- Cache operations are now unit-testable
2025-07-03 20:11:45 -07:00
Bartosz Sokorski c32f7adb10 Add linux kernel information to +version 2025-07-04 01:40:15 +02:00
Jason Rayne e25aa9f424
docs: update to reflect changes after porting terminfo host caching to Zig
- Minor tweak to Config.zig to show the new action.
- Rolled back README.md to remove reference to the now non-existent
'shared' subdir and bash-based cache script.
2025-07-03 16:22:57 -07:00
Qwerasd d751a93ecf font: use variable JetBrains Mono for embedded font
This cuts down our file size significantly.
2025-07-03 16:27:59 -06:00
Qwerasd c2484f48ef font: add jb mono and symbols-only nerd font as dependencies
Rather than using binaries statically in our source tree; this makes
them easier to update. This also makes it so that they are separated
from each other rather than using a patched JB mono as our fallback.
2025-07-03 15:59:04 -06:00
Mitchell Hashimoto 8e14d26275
config: for now, make goto_tab NOT performable on macOS (#7788)
Fixes #7786
Fixes regression from #7683

This is a band-aid fix. The issue is that performable keybinds don't
show up in the reverse mapping that GUI toolkits use to find their key
equivalents. The full explanation of why is already in Binding.zig.

For macOS, we have a way to validate menu items before they're triggered
so we ideally do want a way to get reverse mappings even with
performable keybinds. But I think this wants to be optional and that's
all a bigger change. For now, this is a simple fix that will work.
2025-07-03 13:51:54 -07:00
Mitchell Hashimoto e1be836283
config: for now, make goto_tab NOT performable on macOS
Fixes #7786
Fixes regression from #7683

This is a band-aid fix. The issue is that performable keybinds don't
show up in the reverse mapping that GUI toolkits use to find their key
equivalents. The full explanation of why is already in Binding.zig.

For macOS, we have a way to validate menu items before they're triggered
so we ideally do want a way to get reverse mappings even with
performable keybinds. But I think this wants to be optional and that's
all a bigger change. For now, this is a simple fix that will work.
2025-07-03 13:45:41 -07:00
Mitchell Hashimoto 3e9cfacb7d
feat: support selection foreground being cell foreground (#5219)
This resolves #2685.

## Changes

* Created `SelectionColor` tagged union that can take a `Color`,
`cell-foreground`, or `cell-background`
* Used the new union to implement the feature for Metal and OpenGL
* Removed the use of `invert_selection_fg_bg` during rendering as
suggested in the issue

## Demo

macOS:


https://github.com/user-attachments/assets/b5b2db83-bb62-4929-8e3c-870a1e1a7a5c

Ubuntu:


https://github.com/user-attachments/assets/259dd707-d9d9-4590-8f3c-a67ccdef34bc


Any feedback would be helpful, I'm sure there's a lot of room for
improvement here.
2025-07-03 09:31:27 -07:00
Mitchell Hashimoto 32764f3a1d
fix test syntax 2025-07-03 09:29:36 -07:00
Mitchell Hashimoto 465ac5b1b7
clean up some of the color usage, use exhaustive switches 2025-07-03 09:25:56 -07:00
Qwerasd ffbba3e460
renderer/opengl: fix issue with cell bg alignment on some systems (#7783)
Discussed in #7714, fix confirmed by user as working.

Okay, so, what the hell? This implies that on this user's system,
something that *should* be an integer multiple of the cell width, when
divided by the cell width, is giving some epsilon less than the proper
result. I can only guess that this is driver or hardware weirdness,
possibly the fragcoord is being converted from a low precision float in
NDC to the fragment-space coordinate so we're not actually getting an
integer multiple, and the epsilon less is actually before the division?

Regardless, switching it back to use halves for pixel coordinates fixes
this and shouldn't break the math at all, since `floor((n * k + 0.5)/k)`
should always yield `n` just like without the `+ 0.5`.
2025-07-03 10:05:52 -06:00
Mitchell Hashimoto e87e5e7361
backwards compatibility handlers for removed fields 2025-07-03 07:30:55 -07:00
Daniel 95de198761 Squash and rebase, updated refactored version with selection and cursor cell color changes 2025-07-03 07:14:37 -07:00
Daniel 9e341a3d60 Created tagged union for selection colors, enabled parsing
Implemented cell color for Metal

Removed use of selection-invert-fg-bg

Mirrored feature to OpenGL

Added tests for SelectionColor

Fixed selection on inverted cell behavior

Implemented cell colors for cursor-text

Implemented cell colors for cursor-color, removed uses of cursor-invert-fg-bg during rendering

Updated docs for dynamically colored options

Updated docstrings, cleaned up awkward formatting, and moved style computation to avoid unnecssary invocations

Bump version in docstrings
2025-07-03 07:14:37 -07:00
Mitchell Hashimoto 7bb6d3b728
Do not resolve the symbolic link for the initial working directory (#7773)
Fixes #7769
2025-07-03 07:11:01 -07:00
Basil Crow 182f8ddd1a Do not resolve the symbolic link for the initial working directory 2025-07-03 07:09:24 -07:00
Qwerasd 1270e04480 renderer/opengl: maybe fix issue with cell bg alignment
By using integers for the fragcoords I may have stepped on an edge case
which causes cell background positions to be shifted by 1 px under some
circumstances. I couldn't reproduce that issue in a VM, so I'm making
this commit for the user who was having the problem to test it.
2025-07-02 17:43:05 -06:00
Mitchell Hashimoto f1f9d5eb4b
Fix some config help that caused website errors when copied 2025-07-02 16:21:37 -07:00
Qwerasd 4d609a884e
(macOS) Memory Leak Fixes (#7770)
This PR contains fixes for 4 different memory leaks that affected
Ghostty on macOS.

1. (whenever a font is loaded) CoreText font features dict list wasn't
properly released. Fixed by releasing.
2. (whenever a font is searched for) CoreText discovery iterator
descriptors weren't properly released. Fixed by releasing.
3. (during resize) Metal texture descriptors were not properly released.
Fixed by releasing.
4. (every frame) Objective-C runtime blocks for buffer completion
handler and IOSurfaceLayer set surface were not properly deallocated due
to issues with the internal implementation in `zig-objc`. Fixed in
`zig-objc`, dependency hash updated with fix.

A handful of small apparent leaks remain but their cause is not clear
and they're all static (not increasing over time, seemingly).

### Xcode memory graph "leaks" comparison
|Before (main)|After (this PR)|
|-|-|
|<img width="445" alt="image"
src="https://github.com/user-attachments/assets/d1c89918-8ab2-4201-bf1e-9b3a519a85a8"
/>|<img width="445" alt="image"
src="https://github.com/user-attachments/assets/88c60807-756e-48d8-9918-2a52d6556035"/>|

<sup>Images taken after launching Ghostty, creating 4 tabs, and rapidly
switching between them to force render many frames.</sup>

---

Hopefully this fixes the occasional OOM issues some users have reported.
2025-07-02 17:08:34 -06:00
Qwerasd 8ed08aaecf deps: update zig-objc
This update also fixes a memory leak that was caused by blocks not being
deallocated and just collecting every single frame, slowly accumulating
memory until OOM.
2025-07-02 16:38:13 -06:00
trag1c 16513e4eb6
Adding a Bulgarian localization. (#7390) 2025-07-02 22:34:55 +02:00
trag1c 5dd1ebb583
add newline to end of file 2025-07-02 22:17:17 +02:00
Qwerasd 1f733c9e7f renderer/metal: properly release texture descriptors
Fixes memory leak. We always need to release these descriptors; the
textures themselves will retain or copy them if necessary.
2025-07-02 11:48:30 -06:00
Qwerasd a91f9ed0e2 font/coretext: fix small memory leak 2025-07-02 11:38:26 -06:00
Qwerasd 2a836b0ab7 font/coretext: fix small memory leak 2025-07-02 11:02:33 -06:00
Qwerasd 776d25b065
Even More Sprite Glyphs (#7761)
Follow-on to #7755, adds the sixteenth blocks from the Symbols for
Legacy Computing Supplement and a few circle/ellipse glyphs that connect
to existing glyphs.

In order to add the one sixteenth blocks I reworked block element
alignment to not use the `yHalfs`, `yThirds`, etc. functions, but
instead a more versatile `Fraction` type I introduced, and making these
changes slightly affected how the vertical/horizontal eighths glyphs are
sized, and the horizontal center-point alignment of the smooth mosaic
glyphs for odd cell widths (shifted by half a pixel), but I believe both
of these to be improvements.

### Circle/ellipse glyphs
```
Existing sprites:
🯠 🯡 🯢 🯣

Which connect like so:
🯢🯡🯣
🯠

New sprites:
𜸀 𜸁 𜸋 𜸌

Which connect like so:
🯡𜸀𜸀🯣 🯢 𜸋𜸌
    𜸁
    𜸁
    🯠
```
|Main (via font)|This PR (via sprites)|
|-|-|
|![image](https://github.com/user-attachments/assets/b0102f7e-1cb3-4842-a8c6-352df6d5264f)|![image](https://github.com/user-attachments/assets/9a35d444-39ff-41e1-a632-597f195090a8)|

### Diffs
|Range|||||
|-|-|-|-|-|
|U+1CE00...U+1CEFF|![sprite_face_diff-U+1CE00 U+1CEFF-9x17+1](https://github.com/user-attachments/assets/632daca9-9d1e-458b-b645-3841de9f4915)|![sprite_face_diff-U+1CE00 U+1CEFF-11x21+2](https://github.com/user-attachments/assets/47731d99-9e1a-4005-a56c-dc9af3c38160)|![sprite_face_diff-U+1CE00 U+1CEFF-12x24+3](https://github.com/user-attachments/assets/2a4fd0d7-4114-480d-91e8-f8182ef0ff2b)|![sprite_face_diff-U+1CE00 U+1CEFF-18x36+4](https://github.com/user-attachments/assets/17b886b8-ad6d-4503-85dd-10ea2f734c09)|
|U+1FB00...U+1FBFF|![sprite_face_diff-U+1FB00 U+1FBFF-9x17+1](https://github.com/user-attachments/assets/c24814ea-67ef-4030-819b-a3f3d6ddac0c)|![sprite_face_diff-U+1FB00 U+1FBFF-11x21+2](https://github.com/user-attachments/assets/354ebadf-5d9c-4681-86c8-f6c21f82932e)|![sprite_face_diff-U+1FB00 U+1FBFF-12x24+3](https://github.com/user-attachments/assets/9fbb2c21-9ccd-466c-9bde-b8ce63e5df8b)|![sprite_face_diff-U+1FB00 U+1FBFF-18x36+4](https://github.com/user-attachments/assets/f76866ab-21c4-43b8-a591-009c4399ce17)|
2025-07-01 17:42:51 -06:00
Mitchell Hashimoto d88adb131c
linux: add install target to systemd user service (#7757)
This will allow users to enable Ghostty startup on login. Users will
need to explicitly enable startup on login via this command:

```sh
systemctl enable --user com.mitchellh.ghostty.service
```
2025-07-01 16:03:58 -07:00
Mitchell Hashimoto d9d884b6e2
reload configuration on SIGUSR2 (#7759)
This is done at the apprt-level for a couple reasons.

  (1) For libghostty, we don't have a way to know what the embedding
      application is doing, so its risky to create signal handlers that
      might overwrite the application's signal handlers.

  (2) It's extremely messy to deal with signals and multi-threading.
      Apprts have framework access that handles this for us.

For GTK, we use g_unix_signal_add.

For macOS, we use `DispatchSource.makeSignalSource`. This is an awkward
API but made for this purpose.
2025-07-01 16:03:48 -07:00
Qwerasd cff6860fd9 font/sprite: update reference images 2025-07-01 17:03:10 -06:00
Qwerasd 0cd95a791f font/sprite: add sflc supplement circle/ellipse glyphs 2025-07-01 16:52:17 -06:00
Mitchell Hashimoto 2fa4fc8902
reload configuration on SIGUSR2
This is done at the apprt-level for a couple reasons.

  (1) For libghostty, we don't have a way to know what the embedding
      application is doing, so its risky to create signal handlers that
      might overwrite the application's signal handlers.

  (2) It's extremely messy to deal with signals and multi-threading.
      Apprts have framework access that handles this for us.

For GTK, we use g_unix_signal_add.

For macOS, we use `DispatchSource.makeSignalSource`. This is an awkward
API but made for this purpose.
2025-07-01 15:51:58 -07:00
Qwerasd ffe06f1ccd font/sprite: add sixteenth blocks from slfc supplement 2025-07-01 16:26:57 -06:00
Qwerasd c838d3d7d2 font/sprite: remove `yHalfs` and friends, use `Fraction`
Introduces `fill`, which fills between two `Fraction`s, use this instead
of `yHalfs` and friends wherever they're used, which also means we can
remove `rect`.

This commit does change alignment of the vertical/horizontal eighths in
certain cell sizes, but the change is for the better IMO. Also changes
the center-point alignment of smooth mosaics for odd cell widths, but
the change is no more than half a pixel at worst and is probably an
improvement ultimately.
2025-07-01 16:00:45 -06:00
Jeffrey C. Ollie 190c744a6f
linux: add install target to systemd user service
This will allow users to enable Ghostty startup on login. Users will
need to explicitly enable startup on login via this command:

```sh
systemctl enable --user com.mitchellh.ghostty.service
```
2025-07-01 16:51:23 -05:00
Qwerasd ac87154362 font/sprite: introduce `Fraction` enum for cell fractions
I've included a compatibility test here to make sure that the numbers
from this are in line with the numbers produced by xHalfs, yThirds, etc.

After this commit I'll introduce a helper function that fills based on a
span specified with this enum to replace any uses of xHalfs and friends.

Once I do that I'll remove them and the compatibility test, this should
be a much cleaner interface for this and make it easier to consistently
align block elements with each other.
2025-07-01 15:04:21 -06:00
Qwerasd 5c4a30d85f
More Sprite Glyphs (#7755)
Follow-up to #7732, but even more to come, these were just some low
hanging fruit which it would be nice to merge early.

Adds these characters from the Symbols for Legacy Computing Supplement
block:
```
𜰛 𜰜 𜰝 𜰞

𜰰𜰱𜰲𜰳
𜰴  𜰷 𜰵𜰶 𜸖𜸘
𜰸  𜰻 𜰹𜰺 𜸗𜸙
𜰼𜰽𜰾𜰿
```
How this looks in Ghostty:
|Main (via font)|This PR (via sprites)|
|-|-|
|<img width="256" alt="image"
src="https://github.com/user-attachments/assets/f6000984-7e4a-4ec0-b282-9d0905bd54ed"
/>|<img width="256" alt="image"
src="https://github.com/user-attachments/assets/0d880458-3025-4e42-b2ba-cf84f540d503"
/>|

This PR also adjusts the way block quadrants are drawn for better
alignment with other block elements, this matches how we handle sextants
already.

### Diffs
|Range|||||
|-|-|-|-|-|
|U+1CC00...U+1CCFF|![sprite_face_diff-U+1CC00
U+1CCFF-9x17+1](https://github.com/user-attachments/assets/1adfded7-bd08-414b-8965-dfc07c5c31f8)|![sprite_face_diff-U+1CC00
U+1CCFF-11x21+2](https://github.com/user-attachments/assets/836cd64e-5013-47c8-b819-ac391f630579)|![sprite_face_diff-U+1CC00
U+1CCFF-12x24+3](https://github.com/user-attachments/assets/91483e65-6fc8-401c-b5ed-e5a97d7dd5ac)|![sprite_face_diff-U+1CC00
U+1CCFF-18x36+4](https://github.com/user-attachments/assets/02d7b2fe-bbf5-4431-a3b7-d7ab3ab94714)|
|U+1CE00..U+1CEFF|![sprite_face_diff-U+1CE00
U+1CEFF-9x17+1](https://github.com/user-attachments/assets/aa690cda-a8f3-4307-9f90-bb6ad9c9e7d2)|![sprite_face_diff-U+1CE00
U+1CEFF-11x21+2](https://github.com/user-attachments/assets/e96fd3db-9ed4-40e2-9770-86b9921717b0)|![sprite_face_diff-U+1CE00
U+1CEFF-12x24+3](https://github.com/user-attachments/assets/799859eb-0ff6-4f0e-8f69-6c0c5e1e1c04)|![sprite_face_diff-U+1CE00
U+1CEFF-18x36+4](https://github.com/user-attachments/assets/5049ca8b-2502-470d-853f-f600cd9d235c)|
|U+2500...U+25FF|![sprite_face_diff-U+2500
U+25FF-9x17+1](https://github.com/user-attachments/assets/37467f96-eaaa-4951-8d56-87ad614fc44e)|![sprite_face_diff-U+2500
U+25FF-11x21+2](https://github.com/user-attachments/assets/776e25e8-b257-4ec2-9f0a-98cb3e08aaa2)|||
2025-07-01 14:04:01 -06:00
Qwerasd adace942d0 font/sprite: update reference images 2025-07-01 13:20:10 -06:00
Qwerasd b4d83e6349 font/sprite: align quadrants better with other glyphs
Use `xHalfs` and `yHalfs` so that the dimensions of each quadrant are
appropriately aligned with block elements like the one half block, which
could be 1px taller than the bottom quadrants before this change.

This is in line with what we do for sextants, the fact that on odd-sized
cells there's a 1px overlap is considered acceptable there so I assume
it's acceptable here too.
2025-07-01 13:15:54 -06:00
Qwerasd 0414e9e281 font/sprite: add (some) sflc supplement box drawing chars 2025-07-01 13:15:54 -06:00
Qwerasd dd9ca556f9 font/sprite: add sflc supplement circle pieces 2025-07-01 13:15:54 -06:00
Mitchell Hashimoto a4005946e1
Fix abnormal exit detection on macOS (#7752)
I made an oopsie with #7705 and omitted the check entirely on macOS when
the original logic only omitted the exit code check.
2025-07-01 12:15:53 -07:00
Mitchell Hashimoto fbdaea7456
Update src/Surface.zig
Co-authored-by: Gregory Anders <greg@gpanders.com>
2025-07-01 12:15:45 -07:00
Mitchell Hashimoto 114c3f5665
Fix abnormal exit detection on macOS
I made an oopsie with #7705 and omitted the check entirely on macOS when
the original logic only omitted the exit code check.
2025-07-01 12:06:50 -07:00
Qwerasd eea7088919
Sprite Face Rework (#7732)
- Large rework of how we draw sprite font glyphs, explained in the
commit message and comments.
- Adds separated block sextants from symbols for legacy computing
supplement
- Adds explicit underline cursor instead of using underline glyph for
it, resolves #7651, supersedes #7685

Currently we support these glyphs with the sprite font:
```
─━│┃┄┅┆┇┈┉┊┋┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋╌╍╎╏═║╒╓╔╕╖╗╘╙╚╛╜╝╞╟╠╡╢╣╤╥╦╧╨╩╪╫╬╭╮╯╰╱╲╳╴╵╶╷╸╹╺╻╼╽╾╿▀▁▂▃▄▅▆▇█▉▊▋▌▍▎▏▐░▒▓▔▕▖▗▘▙▚▛▜▝▞▟◢◣◤◥◸◹◺◿⠀⠁⠂⠃⠄⠅⠆⠇⠈⠉⠊⠋⠌⠍⠎⠏⠐⠑⠒⠓⠔⠕⠖⠗⠘⠙⠚⠛⠜⠝⠞⠟⠠⠡⠢⠣⠤⠥⠦⠧⠨⠩⠪⠫⠬⠭⠮⠯⠰⠱⠲⠳⠴⠵⠶⠷⠸⠹⠺⠻⠼⠽⠾⠿⡀⡁⡂⡃⡄⡅⡆⡇⡈⡉⡊⡋⡌⡍⡎⡏⡐⡑⡒⡓⡔⡕⡖⡗⡘⡙⡚⡛⡜⡝⡞⡟⡠⡡⡢⡣⡤⡥⡦⡧⡨⡩⡪⡫⡬⡭⡮⡯⡰⡱⡲⡳⡴⡵⡶⡷⡸⡹⡺⡻⡼⡽⡾⡿⢀⢁⢂⢃⢄⢅⢆⢇⢈⢉⢊⢋⢌⢍⢎⢏⢐⢑⢒⢓⢔⢕⢖⢗⢘⢙⢚⢛⢜⢝⢞⢟⢠⢡⢢⢣⢤⢥⢦⢧⢨⢩⢪⢫⢬⢭⢮⢯⢰⢱⢲⢳⢴⢵⢶⢷⢸⢹⢺⢻⢼⢽⢾⢿⣀⣁⣂⣃⣄⣅⣆⣇⣈⣉⣊⣋⣌⣍⣎⣏⣐⣑⣒⣓⣔⣕⣖⣗⣘⣙⣚⣛⣜⣝⣞⣟⣠⣡⣢⣣⣤⣥⣦⣧⣨⣩⣪⣫⣬⣭⣮⣯⣰⣱⣲⣳⣴⣵⣶⣷⣸⣹⣺⣻⣼⣽⣾⣿𜰡𜰢𜰣𜰤𜰥𜰦𜰧𜰨𜰩𜰪𜰫𜰬𜰭𜰮𜰯𜴀𜴁𜴂𜴃𜴄𜴅𜴆𜴇𜴈𜴉𜴊𜴋𜴌𜴍𜴎𜴏𜴐𜴑𜴒𜴓𜴔𜴕𜴖𜴗𜴘𜴙𜴚𜴛𜴜𜴝𜴞𜴟𜴠𜴡𜴢𜴣𜴤𜴥𜴦𜴧𜴨𜴩𜴪𜴫𜴬𜴭𜴮𜴯𜴰𜴱𜴲𜴳𜴴𜴵𜴶𜴷𜴸𜴹𜴺𜴻𜴼𜴽𜴾𜴿𜵀𜵁𜵂𜵃𜵄𜵅𜵆𜵇𜵈𜵉𜵊𜵋𜵌𜵍𜵎𜵏𜵐𜵑𜵒𜵓𜵔𜵕𜵖𜵗𜵘𜵙𜵚𜵛𜵜𜵝𜵞𜵟𜵠𜵡𜵢𜵣𜵤𜵥𜵦𜵧𜵨𜵩𜵪𜵫𜵬𜵭𜵮𜵯𜵰𜵱𜵲𜵳𜵴𜵵𜵶𜵷𜵸𜵹𜵺𜵻𜵼𜵽𜵾𜵿𜶀𜶁𜶂𜶃𜶄𜶅𜶆𜶇𜶈𜶉𜶊𜶋𜶌𜶍𜶎𜶏𜶐𜶑𜶒𜶓𜶔𜶕𜶖𜶗𜶘𜶙𜶚𜶛𜶜𜶝𜶞𜶟𜶠𜶡𜶢𜶣𜶤𜶥𜶦𜶧𜶨𜶩𜶪𜶫𜶬𜶭𜶮𜶯𜶰𜶱𜶲𜶳𜶴𜶵𜶶𜶷𜶸𜶹𜶺𜶻𜶼𜶽𜶾𜶿𜷀𜷁𜷂𜷃𜷄𜷅𜷆𜷇𜷈𜷉𜷊𜷋𜷌𜷍𜷎𜷏𜷐𜷑𜷒𜷓𜷔𜷕𜷖𜷗𜷘𜷙𜷚𜷛𜷜𜷝𜷞𜷟𜷠𜷡𜷢𜷣𜷤𜷥𜹑𜹒𜹓𜹔𜹕𜹖𜹗𜹘𜹙𜹚𜹛𜹜𜹝𜹞𜹟𜹠𜹡𜹢𜹣𜹤𜹥𜹦𜹧𜹨𜹩𜹪𜹫𜹬𜹭𜹮𜹯𜹰𜹱𜹲𜹳𜹴𜹵𜹶𜹷𜹸𜹹𜹺𜹻𜹼𜹽𜹾𜹿𜺀𜺁𜺂𜺃𜺄𜺅𜺆𜺇𜺈𜺉𜺊𜺋𜺌𜺍𜺎𜺏🬀🬁🬂🬃🬄🬅🬆🬇🬈🬉🬊🬋🬌🬍🬎🬏🬐🬑🬒🬓🬔🬕🬖🬗🬘🬙🬚🬛🬜🬝🬞🬟🬠🬡🬢🬣🬤🬥🬦🬧🬨🬩🬪🬫🬬🬭🬮🬯🬰🬱🬲🬳🬴🬵🬶🬷🬸🬹🬺🬻🬼🬽🬾🬿🭀🭁🭂🭃🭄🭅🭆🭇🭈🭉🭊🭋🭌🭍🭎🭏🭐🭑🭒🭓🭔🭕🭖🭗🭘🭙🭚🭛🭜🭝🭞🭟🭠🭡🭢🭣🭤🭥🭦🭧🭨🭩🭪🭫🭬🭭🭮🭯🭰🭱🭲🭳🭴🭵🭶🭷🭸🭹🭺🭻🭼🭽🭾🭿🮀🮁🮂🮃🮄🮅🮆🮇🮈🮉🮊🮋🮌🮍🮎🮏🮐🮑🮒🮓🮔🮕🮖🮗🮘🮙🮚🮛🮜🮝🮞🮟🮠🮡🮢🮣🮤🮥🮦🮧🮨🮩🮪🮫🮬🮭🮮🮯🮽🮾🮿🯎🯏🯐🯑🯒🯓🯔🯕🯖🯗🯘🯙🯚🯛🯜🯝🯞🯟🯠🯡🯢🯣🯤🯥🯦🯧🯨🯩🯪🯫🯬🯭🯮🯯
```
Screenshot:
<img width="1121" alt="image"
src="https://github.com/user-attachments/assets/d0979bf0-f585-415b-bbc7-b7b399adce25"
/>

I plan on doing a follow-up PR with a lot of new supported glyphs now
that it's so much easier to add them.
2025-07-01 13:05:20 -06:00
trag1c 7cb7cdf88d
i18n: add Korean translations (#6963)
This pull request adds Korean translations.

I do want to add that while I do speak Korean _I am not a native
speaker_. I've done my best to provide translations as natural as
possible, but I'd love it if a native speaker could improve it before
merging.
2025-07-01 09:57:47 +02:00
trag1c f773baa418
remove blank line in CODEOWNERS 2025-07-01 09:36:07 +02:00
Qwerasd 95fbeb5b82 style(font/sprite): annotate type for value 2025-06-30 16:44:21 -06:00
Qwerasd a00a727e77 test(font/Atlas): add test case for `setFromLarger` 2025-06-30 16:37:26 -06:00
RME 8c5122876f
Fixed po/ko_KR.UTF-8.po
Co-authored-by: Hojin You <dev.hojin@gmail.com>
2025-06-30 22:11:49 +02:00
Mitchell Hashimoto 3cf181a670
macos: don't overwrite the .fullScreen styleMask option in reapplyHiddenStyle (#7738)
Fixes #7625 (which apparently didn't catch anyone's attention, but I'd
be very surprised if no one were able to reproduce it if they tried;
also, re discord chat)
2025-06-30 11:31:04 -07:00
Daniel Wennberg 886e33d7b7 make hiddenStyleMask static 2025-06-30 11:21:55 -07:00
Daniel Wennberg b1f788a768 macos: don't overwrite the .fullScreen styleMask option in reapplyHiddenStyle 2025-06-30 10:36:48 -07:00
Qwerasd 05eeaddb04 update flatpak hash 2025-06-30 11:21:50 -06:00
Qwerasd 8b6e1fe5b1 font/sprite: update reference PNGs to match new z2d export 2025-06-30 11:16:47 -06:00
Qwerasd 61b7dffcaa deps: update z2d
We need to use this version of z2d so that we can get reproducible PNG
exports in CI for testing, since previously the PNG export was affected
by the CPU arch / features because it depended on vector width.
2025-06-30 11:16:47 -06:00
Qwerasd 2084d5f256 font/sprite+renderer: never constrain sprite glyphs
This was creating problems with the branch drawing glyphs at some sizes.

In the future the whole "foreground modes" thing needs to be reworked,
so this is just a stopgap until that gets turned in to something nicer.
2025-06-30 11:16:47 -06:00
Qwerasd e691404a57 prettier format 2025-06-30 11:16:47 -06:00
Qwerasd 4f9d7c565a font/sprite: add explicit underline cursor
Resolves #7651 - uses cursor thickness rather than underline thickness.
2025-06-30 11:16:47 -06:00
Qwerasd c96af1b3b1 font/sprite: add separated sextants from sflc supplement 2025-06-30 11:16:47 -06:00
Qwerasd 1377e6d225 font/sprite: rework sprite font drawing
This is a fairly large rework of how we handle the sprite font drawing.
Drawing routines are now context-less, provided only a canvas and some
metrics. There is now a separate file per unicode block / PUA area.
Sprites are now drawn on canvases with an extra quarter-cell of padding
on each edge, and automatically cropped when sent to the atlas, this
allows sprites to extend past cell boundaries which makes it possible to
have, for example, diagonal box drawing characters that connect across
cell diagonals instead of being pinched in.

Most of the sprites the code is just directly ported from the old code,
but I've rewritten a handful. Moving forward, I'd like to rewrite more
of these since the way they're currently written isn't ideal.

This rework, in addition to improving the packing efficiency of sprites
on the atlas, and allowing for out-of-cell drawing, will make it a lot
easier to add new sprites in the future, since all it takes now is to
add a single function and an import (if it's a new file).

I reworked the regression/change testing to be more robust as well, it
now covers all sprite glyphs (except non-codepoint ones) and does so at
4 different sizes. Addition/removal of glyphs will no longer create diff
noise in the generated diff image, since the position in the image of
each glyph is now fixed.
2025-06-30 11:16:47 -06:00
Damyan Bogoev 9ad4537d03
Update po/bg_BG.UTF-8.po
Co-authored-by: Pavel Atanasov <37866329+reo101@users.noreply.github.com>
2025-06-30 19:47:58 +03:00
Damyan Bogoev 87df0004c9
Update po/bg_BG.UTF-8.po
Co-authored-by: Pavel Atanasov <37866329+reo101@users.noreply.github.com>
2025-06-30 19:47:43 +03:00
Damyan Bogoev 4fe3a01f1b
Update po/bg_BG.UTF-8.po
Co-authored-by: Pavel Atanasov <37866329+reo101@users.noreply.github.com>
2025-06-30 19:47:38 +03:00
Damyan Bogoev 0653bcb16e
Update po/bg_BG.UTF-8.po
Co-authored-by: Pavel Atanasov <37866329+reo101@users.noreply.github.com>
2025-06-30 19:47:30 +03:00
Mitchell Hashimoto 66f73f7133
surface: add timer-based scrolling during selection (#4422)
Adds a timer to continuously scroll during selection when outside the
viewport, 15ms per line.

Currently the scrolling behavior requires you to jiggle the mouse to
continuously scroll upwards/downwards when selecting text.


### Before


https://github.com/user-attachments/assets/18e6c547-ed04-4098-88b4-35360f8c8c3c

### After


https://github.com/user-attachments/assets/46d5a6fc-b38e-46cf-b00f-52c8bc289f52
2025-06-30 09:42:45 -07:00
Mitchell Hashimoto 81cef6e63b
various cleanups around scroll timers 2025-06-30 09:40:49 -07:00
moni-dz f73c90bf5d surface: add timer-based scrolling during selection 2025-06-30 09:17:20 -07:00
moni-dz c00b8740aa termio: add selection scrolling callback 2025-06-30 09:15:53 -07:00
Mitchell Hashimoto ffcd633c01
Introduce `font-shaping-break` config option (#5374)
Adds the config option as described in #4515.

Plumbed it into the `RunIterator` and updated all the tests that rely on
that, adding additional cases to the cursor boundary tests where I found
them.

Closes #4515
2025-06-30 09:12:14 -07:00
Mitchell Hashimoto 73ff4b8f74
move runIterator options to dedicated struct 2025-06-30 09:05:09 -07:00
Daniel Patterson beb961fb80 Introduce `font-shaping-break` config option 2025-06-30 08:06:00 -07:00
Damyan Bogoev 2850c3b58a Adding Bulgarian localization. 2025-06-30 16:51:11 +03:00
RME 9aa2383e05
Merge branch 'main' into ko_kr 2025-06-30 15:05:01 +02:00
RME 6484df9134
update debug build string, line 251 2025-06-30 15:01:44 +02:00
RME e25029eff6
add ko_KR i18n to CODEOWNERS 2025-06-30 15:00:15 +02:00
Mitchell Hashimoto 2592286988
termio: indicate support for OSC 52 in primary DA report (#7725)
This is an extension agreed upon by modern terminals to indicate that
they support copying to the clipboard with XTerm's OSC 52 sequence. It
is only reported when writing to the clipboard is actually allowed.

Ref: #7590
2025-06-29 19:18:53 -07:00
Mitchell Hashimoto 747076abbf
terminal: introduce testWriteSemanticString (#7733)
This test-only function wraps testWriteString with semantic prompt
marking. This replaces the manual, row-based semantic_prompt field
manipulation we were doing in all of our prompt-related test setups.

This function's heuristics are a little complex because it wraps
testWriteString as a "black box"; we don't benefit from that function's
own line-based logic to know which rows need to be updated with the
semantic prompt flag. We need to infer them externally instead.

I considered adding an options argument to testWriteString that would
allow passing e.g. a semantic_prompt prompt. Given that it's called from
200+ places, that would involve a lot of unrelated changes, but it
remains an "option" (ha!) if there's value there for other cases.

I also have plans that move us from row-based to cell-based semantic
tracking, where the current semantic type is tracked by the cursor. In
that implementation, testWriteString can update the written cells
directly, and testWriteSemanticString just helps manage the cursor's
state. Introducing testWriteSemanticString here and now therefore helps
bridge us to that world while maintaining test consistency.
2025-06-29 19:16:53 -07:00
Mitchell Hashimoto 20c6a6fcf2
update libxev to workaround the io_uring regression in Linux 6.15.4 (#7731)
Fixes #7724

Background at the end of the commit message. The fix in libxev is
described in the PR and commit we pin to here, but basically we swap
read for poll for eventfd/timerfd. libxev commit:
75a10d0fb3

From Jens Axboe on X:

> This will fix it: https://pastebin.com/n7JSZWpW which makes me
suspicious
> that it's an S_IFREG check somewhere else, as anon inodes are now
listed as
> regular files. Has potentially pretty broad implications...

> I think I can already answer why that breaks things - io_uring checks
if
> this is a regular file, and if it is, it doesn't do short reads. Short
> reads on regular files (or a bdev) will cause application issues, as
> basically nobody expects them.

> Now we have what acts like a char dev, but where io_uring will retry
IO
> because the application asked for more data than what was delivered.
This
> will cause the weird slowdowns as data isn't delivered as soon as it's
> available.

## Backporting to 1.1.3

It's a bit risky, but we can back port the libxev update to 1.1.3 (and
release a 1.1.4) since we don't plan on a 1.2 release for a couple
months. Realistically, we've been running the latest libxev on tip
(before this commit) for awhile and there haven't been issues so I think
it's safe enough.

I think we should let this merge settle for a few days at least before
we do that back port though.
2025-06-29 19:03:58 -07:00
Kat 098038cf70
i18n: Add Irish (ga_IE) translation (#7650)
This PR introduces support for Irish (Gaeilge), the first official
language of Ireland and an EU working language.

The translation file was initialized using the standard gettext tooling:

` msginit -i po/com.mitchellh.ghostty.pot -l $LANG -o "po/$LANG.po"`

The locale code `ga_IE` follows ISO standards for Gaeilge as spoken in
Ireland.

I'm happy to volunteer as the ongoing maintainer of the Irish
translation and will keep it up to date as Ghostty evolves.

Go raibh maith agat!
2025-06-30 01:56:54 +00:00
Jon Parise a82223259a terminal: introduce testWriteSemanticString
This test-only function wraps testWriteString with semantic prompt
marking. This replaces the manual, row-based semantic_prompt field
manipulation we were doing in all of our prompt-related test setups.

This function's heuristics are a little complex because it wraps
testWriteString as a "black box"; we don't benefit from that function's
own line-based logic to know which rows need to be updated with the
semantic prompt flag. We need to infer them externally instead.

I considered adding an options argument to testWriteString that would
allow passing e.g. a semantic_prompt prompt. Given that it's called from
200+ places, that would involve a lot of unrelated changes, but it
remains an "option" (ha!) if there's value there for other cases.

I also have plans that move us from row-based to cell-based semantic
tracking, where the current semantic type is tracked by the cursor. In
that implementation, testWriteString can update the written cells
directly, and testWriteSemanticString just helps manage the cursor's
state. Introducing testWriteSemanticString here and now therefore helps
bridge us to that world while maintaining test consistency.
2025-06-29 19:51:35 -04:00
Mitchell Hashimoto d0e12cc082
update libxev to workaround the io_uring regression in Linux 6.15.4
Fixes #7724

Background at the end of the commit message. The fix in libxev is
described in the PR and commit we pin to here, but basically we swap
read for poll for eventfd/timerfd.

From Jens Axboe on X:

> This will fix it: https://pastebin.com/n7JSZWpW which makes me suspicious
> that it's an S_IFREG check somewhere else, as anon inodes are now listed as
> regular files. Has potentially pretty broad implications...

> I think I can already answer why that breaks things - io_uring checks if
> this is a regular file, and if it is, it doesn't do short reads. Short
> reads on regular files (or a bdev) will cause application issues, as
> basically nobody expects them.

> Now we have what acts like a char dev, but where io_uring will retry IO
> because the application asked for more data than what was delivered. This
> will cause the weird slowdowns as data isn't delivered as soon as it's
> available.
2025-06-29 15:11:24 -07:00
Aindriú Mac Giolla Eoin 5da461dc35 Corrected 2 strings for better readability and consistency 2025-06-29 21:20:20 +01:00
trag1c 7106a3d716
Add Argentinian Spanish translation and locale support (#7397) 2025-06-29 21:23:31 +02:00
Alan Moyano 046f21f2dc Adding email address 2025-06-29 16:02:23 -03:00
Alan Moyano ff599b5cf7 Improving Argentinian voseo 2025-06-29 16:02:23 -03:00
Alan Moyano 14ba7effcd Fixing issues and making the translation more similar to the es_BO version 2025-06-29 16:02:23 -03:00
Alan Moyano 43a3338491
Merge branch 'ghostty-org:main' into main 2025-06-29 15:59:29 -03:00
James Holderness 7f0778bcf2 termio: indicate support for OSC 52 in primary DA report
This is an extension agreed upon by modern terminals to indicate that
they support copying to the clipboard with XTerm's OSC 52 sequence. It
is only reported when writing to the clipboard is actually allowed.
2025-06-29 15:32:17 +01:00
Mitchell Hashimoto 0d55a1deef
Introduce action for copying into clipboard (#7721)
This introduces an action for copying the path of a written
screen/selection file into the clipboard.

Pasting the path into the terminal doesn't work well if you have a
program still running and opening the file outside the terminal (on
macOS in TextEdit by default) isn't always a great experience.

Allowing to copy the file path into the clipboard seems like a minor and
hopefully uncontroversial addition. 😅
2025-06-29 06:56:21 -07:00
RME ad5ab92333
Update po/ko_KR.UTF-8.po
Co-authored-by: Hojin You <dev.hojin@gmail.com>
2025-06-29 15:42:18 +02:00
Troels Thomsen ef06e3d02c Introduce action for copying into clipboard 2025-06-29 09:32:48 +02:00
Mitchell Hashimoto cc2c45ff4e
Update iTerm2 colorschemes (#7718)
Upstream revision:
6fa671fdc1
2025-06-28 19:27:54 -07:00
Mitchell Hashimoto 67fe3d418a
config: fix regression where we halted parsing on deprecated field (#7719)
Fix regression from d44a6cde2c where we
halted parsing on deprecated fields, which was not the intended
behavior.

This commit fixes that and adds a test to verify it.
2025-06-28 19:27:43 -07:00
Mitchell Hashimoto 5ab7ceb589
config: fix regression where we halted parsing on deprecated field
Fix regression from d44a6cde2c where
we halted parsing on deprecated fields, which was not the intended
behavior.

This commit fixes that and adds a test to verify it.
2025-06-28 19:24:07 -07:00
mitchellh 2f978fbdcf deps: Update iTerm2 color schemes 2025-06-29 00:15:18 +00:00
Mitchell Hashimoto 2637400904
gtk: add "remember choice" toggle for clipboard confirmation dialog (#6783)
Implements #6763 (not backporting to the 1.2 version since I'm way too
lazy)


![image](https://github.com/user-attachments/assets/9c9aca3e-8b42-4d47-8a96-841612add812)
2025-06-28 14:55:31 -07:00
Mitchell Hashimoto d44a6cde2c
config: more general purpose backwards compatibility handlers (#7717)
Fixes #7706

We previously had a very specific backwards compatibility handler for
handling renamed fields. We always knew that wouldn't scale but I wanted
to wait for a real case. Well, #7706 is a real case, so here we are.

This commit makes our backwards compatibility handler more general
purpose, and makes a special-case handler for renamed fields built on
top of this same general purpose system. The new system lets us do a lot
more with regards to backwards compatibility.

To start, this addresses #7706 by allowing us to handle a removed single
enum value of a still-existing field.

In the future, I think this may continue to get _more_ general purpose
by moving the handlers from functions to structs so we can have more
metadata like descriptions and so on that we may use to generate docs or
other help strings.
2025-06-28 14:48:02 -07:00
RME a219aae7fc
Merge branch 'main' into ko_kr 2025-06-28 23:23:11 +02:00
Mitchell Hashimoto 84432a7beb
config: more general purpose backwards compatibility handlers
Fixes #7706

We previously had a very specific backwards compatibility handler for
handling renamed fields. We always knew that wouldn't scale but I wanted
to wait for a real case. Well, #7706 is a real case, so here we are.

This commit makes our backwards compatibility handler more general
purpose, and makes a special-case handler for renamed fields built on
top of this same general purpose system. The new system lets us do a lot
more with regards to backwards compatibility.

To start, this addresses #7706 by allowing us to handle a removed single
enum value of a still-existing field.
2025-06-28 13:06:43 -07:00
Jon Parise 5e76606120
fix: enable `boo` on FreeBSD (#7716) 2025-06-28 14:55:28 -04:00
-k 4fac5f3749
fix: enable `boo` on FreeBSD 2025-06-28 13:08:56 -04:00
Leah Amelia Chen f6d1c274b9
gtk(wayland): prevent gtk4-layer-shell crash on old versions (#7712)
Supersedes #7154

In gtk4-layer-shell versions < 1.0.4, the app could crash upon opening a
quick terminal window on certain compositors that implement the
`xdg_wm_dialog_v1` protocol. The exact reason is a bit complicated, but
is nicely summarized in the upstream issue (wmww/gtk4-layer-shell#50).

The circumstances that could cause this crash to occur should gradually
diminish as distros update to newer gtk4-layer-shell versions, but this
is known to crash on Fedora 41 and Hyprland, which could be a sizable
chunk of our userbase given that this would also occur on GNOME/Mutter
and KDE/KWin. The diff should be minimal enough that this can be removed
or reverted once this band-aid fix is no longer necessary.
2025-06-28 17:09:24 +02:00
Leah Amelia Chen 0973abf9f9
translations(zh_CN): add lines from #6783 2025-06-28 17:08:29 +02:00
Leah Amelia Chen fbe94156f9
translations: update 2025-06-28 17:06:49 +02:00
Leah Amelia Chen ce015899f3
gtk: add "remember choice" toggle for clipboard confirmation dialog 2025-06-28 17:06:40 +02:00
Leah Amelia Chen 5fa737834b
gtk(wayland): prevent gtk4-layer-shell crash on old versions
Supersedes #7154

In gtk4-layer-shell versions < 1.0.4, the app could crash upon opening
a quick terminal window on certain compositors that implement the
`xdg_wm_dialog_v1` protocol. The exact reason is a bit complicated,
but is nicely summarized in the upstream issue (wmww/gtk4-layer-shell#50).

The circumstances that could cause this crash to occur should gradually
diminish as distros update to newer gtk4-layer-shell versions, but this
is known to crash on Fedora 41 and Hyprland, which could be a sizable
chunk of our userbase given that this would also occur on GNOME/Mutter
and KDE/KWin. The diff should be minimal enough that this can be removed
or reverted once this band-aid fix is no longer necessary.
2025-06-28 16:41:19 +02:00
Mitchell Hashimoto 1607f761d2
Equalize splits based on children oriented in the same direction (#7710)
This changes equalization so it only counts children oriented in the
same direction.

This makes splits a bit more aesthetic, and replicates how split
equalization works in neovim.

### This is how splits look before this change:

Notice how the left pane gets squeezed.

Before equalization
<img width="1440" alt="Screenshot 2025-06-28 at 8 47 40 AM"
src="https://github.com/user-attachments/assets/498d3026-cfde-4856-b88b-677b2e77b4a0"
/>

After equalization
<img width="1440" alt="Screenshot 2025-06-28 at 8 47 49 AM"
src="https://github.com/user-attachments/assets/2cf7bb60-62da-4d42-882c-d8324cc7bdb6"
/>



---

### And here's how the equalization works after this change:

Before equalization
<img width="1440" alt="Screenshot 2025-06-28 at 8 48 18 AM"
src="https://github.com/user-attachments/assets/39974948-573c-48e8-93a2-7504968f1418"
/>

After equalization
<img width="1440" alt="Screenshot 2025-06-28 at 8 48 24 AM"
src="https://github.com/user-attachments/assets/d97adccd-976e-45a5-b98e-6e5596cf89d3"
/>


For many splits it looks much more aesthetic:
<img width="1440" alt="Screenshot 2025-06-28 at 8 48 28 AM"
src="https://github.com/user-attachments/assets/012d84fc-400f-4864-b8d4-cf7ce53067fb"
/>
<img width="1440" alt="Screenshot 2025-06-28 at 8 48 35 AM"
src="https://github.com/user-attachments/assets/204583ad-66e6-4a1d-a3a0-d2805a8daded"
/>
2025-06-28 07:26:49 -07:00
Mitchell Hashimoto 5364c2d723
Don't pass arena allocator to internal_os.open (#7711)
This fixes #7702 by no longer passing the arena allocator to a task that
outlives its caller.

As far as I can tell, a reference to `config_path` may live on in the
`argv` field of the ChildProcess after the arena is cleared (unless
`argv` itself becomes a dangling pointer because the literal it's
referencing goes out of scope? Struggling to wrap my head around some of
the finer points of Zig array/slice/literal semantics). However, I
suppose it's safe to assume that `argv` is never referenced after
`exe.spawn()` has returned, in which case there's no issue. If this were
a problem, it would apply equally to all uses of `internal_os.open`, not
just the open config code path.
2025-06-28 06:57:50 -07:00
Mitchell Hashimoto 3dc4321689
deps: Default gtk4-layer-shell system integration to true (#6706)
Closes #6632 
When compiling the dynamic lib and linking, the rpath resolves to the
compile cache location instead of the install location for the lib. This
resulted in loading the dylib failing when the compile cache was removed
or the install location is changed.

Based on https://github.com/ziglang/zig/issues/5827 , we specify the
rpath to search relative to the executable.
Previous state:
- dynamic lib was not installed to the output directory -> now appears
in `$OUT/lib/libgtk4-layer-shell.so`
- rpath only included the compile cache location, not the install
location.
Before:
```sh
$ patchelf --print-rpath zig-out/bin/ghostty
/home/anthony/dev/ghostty-pure/.zig-cache/o/0254fb4753185c5429180337a720248d
$ ldd zig-out/bin/ghostty
        ...
        libgtk4-layer-shell.so => /home/anthony/dev/ghostty-pure/.zig-cache/o/0254fb4753185c5429180337a720248d/libgtk4-layer-shell.so (0x00007f7975468000)
        ...
$  ldd zig-out/bin/ghostty
        ...
        libgtk4-layer-shell.so => not found
        ...
```

After:

```sh
$ zig build
$ patchelf --print-rpath zig-out/bin/ghostty
/home/anthony/dev/ghostty/.zig-cache/o/f45360ddde653cb3bc70966c326dd96d:$ORIGIN/../lib/
$ ldd zig-out/bin/ghostty
        ...
        libgtk4-layer-shell.so => /home/anthony/dev/ghostty/.zig-cache/o/f45360ddde653cb3bc70966c326dd96d/libgtk4-layer-shell.so (0x00007fbf81ad8000)
        ...
 $ rm -r .zig-cache/
 $ ldd zig-out/bin/ghostty
        ...
        libgtk4-layer-shell.so => /home/anthony/dev/ghostty/zig-out/bin/../lib/libgtk4-layer-shell.so (0x00007f60dc087000)
        ...
```
2025-06-28 06:56:50 -07:00
azhn a8cad9831a Remove copying libgtk4-layer-shell.so from cache since install is fixed 2025-06-28 19:21:32 +10:00
azhn 46b86570f2 deps: Enable building gtk4-layer-shell without system integration 2025-06-28 19:02:30 +10:00
azhn 33e07c87c9 deps: Default gtk4-layer-shell system integration to true
We default system-integration to true as this is a shared library that
must be installed on a library path and it is recommended to use the
system package.

If the system does not package gtk4-layer-shell then doing `zig build
-fno-sys` will now correctly build and install the shared library under
a lib/ subdirectory of the output prefix.

The output prefix should be a default library path (`/lib`, `/usr/lib`,
or a lib64 variant) otherwise a custom library path can be configured
using ldconfig (see `man ld.so 8`)
2025-06-28 19:01:26 +10:00
Daniel Wennberg 4ae75cc868 Don't pass arena allocator to os.open 2025-06-28 00:21:38 -07:00
Islam Sharabash 22a624e560 Equalize splits based on children oriented in the same direction
This changes equalization so it only counts children oriented in the
same direction.

This makes splits a bit more aesthetic, and replicates how split
equalization works in neovim.
2025-06-28 09:01:41 +02:00
Mitchell Hashimoto 206d41844e
terminal: fix unexpected line wrapping in tests (#7709)
These tests write specific lines into a 10-column-wide test screen. The
"prompt3$ input3\n" writes exceed that column limit, and some of their
characters wrap onto the following line.

These tests' current assertions aren't sensitive to that overflow, but I
spotted the problem while doing some related work, and I thought it
worth making these corrections to avoid any future surprises.
2025-06-27 19:43:12 -07:00
Jon Parise 138f74524e terminal: fix unexpected line wrapping in tests
These tests write specific lines into a 10-column-wide test screen. The
"prompt3$ input3\n" writes exceed that column limit, and some of their
characters wrap onto the following line.

These tests' current assertions aren't sensitive to that overflow, but
I spotted the problem while doing some related work, and I thought it
worth making these corrections to avoid any future surprises.
2025-06-27 22:34:46 -04:00
Mitchell Hashimoto 98b1af8353
Move child exit handling logic to apprt thread (#7705)
Fixes #7500
Supersedes #7582

This commit moves the child exit handling logic from the IO thead to the
apprt thread. The IO thread now only sends a `child_exited` message to
the apprt thread with metadata about the exit conditions (exit code,
runtime).

From there, the apprt thread can handle the exit situation however is
necessary. This commit doesn't change the behavior but it does fix the
issue #7500. The behavior is: exit immediately, show abnormal exit
message, wait for user input, etc.

This also gets us closer to #7649.
2025-06-27 10:51:55 -07:00
Mitchell Hashimoto 591ef0f40f
Move child exit handling logic to apprt thread
Fixes #7500
Supersedes #7582

This commit moves the child exit handling logic from the IO thead to the
apprt thread. The IO thread now only sends a `child_exited` message to
the apprt thread with metadata about the exit conditions (exit code,
runtime).

From there, the apprt thread can handle the exit situation however is
necessary. This commit doesn't change the behavior but it does fix the
issue #7500. The behavior is: exit immediately, show abnormal exit
message, wait for user input, etc.

This also gets us closer to #7649.
2025-06-27 10:36:23 -07:00
Mitchell Hashimoto 2775792b20
core: only update selection clipboard on left mouse release (#7704)
Fixes #4800, supercedes #5995

This is a rewrite of #5995 (though the solution is mostly the same since
this is pretty straightforward). The main difference is the rebase on
the new mouse handling we've had since, and I also continue to update
the selection clipboard on non-left-mouse events.
2025-06-27 09:45:52 -07:00
Mitchell Hashimoto 52354b8bec
core: only update selection clipboard on left mouse release
Fixes #4800, supercedes #5995

This is a rewrite of #5995 (though the solution is mostly the same since
this is pretty straightforward). The main difference is the rebase on
the new mouse handling we've had since, and I also continue to update
the selection clipboard on non-left-mouse events.
2025-06-27 09:40:37 -07:00
Mitchell Hashimoto 4b5ccf79a5
fix compilation issue, tests should've caught this but GHA failed 2025-06-27 09:16:00 -07:00
Mitchell Hashimoto 240c9b8afc
gtk: add option to always display the tab bar (#5590)
Also fixes crashes in both vanilla GTK and Adwaita implementations of
`closeTab`, which erroneously close windows twice when there are no more
tabs left (we probably already handle it somewhere else).
2025-06-27 09:14:13 -07:00
Mitchell Hashimoto 331769bc6b
core: don't copy App and apprt.App (#5509)
Besides avoiding copying, this allows consumers to choose to allocate
these structs on the stack or to allocate on the heap. It also gives the
apprt.App a stable pointer sooner in the process.
2025-06-27 09:13:54 -07:00
Mitchell Hashimoto 83690744b2
reintroduce App.create 2025-06-27 09:12:20 -07:00
Jeffrey C. Ollie 1979fb92f4 embedded: fix core app init 2025-06-27 09:05:32 -07:00
Jeffrey C. Ollie 3c49d87751 fix order of defer 2025-06-27 09:05:32 -07:00
Jeffrey C. Ollie c6f23bbb32 core: con't copy App and apprt.App
Besides avoiding copying, this allows consumers to choose to allocate
these structs on the stack or to allocate on the heap. It also gives the
apprt.App a stable pointer sooner in the process.
2025-06-27 09:05:32 -07:00
Mitchell Hashimoto 070e017b1b
Update CODEOWNERS for localization managers (#7701) 2025-06-27 06:59:37 -07:00
Mitchell Hashimoto 937b10b422
Update CODEOWNERS for localization managers 2025-06-27 06:58:15 -07:00
Qwerasd 979d72056b
OpenGL: Fix Custom Shaders (#7697)
Ref: GitHub Discussion #7696 

See commit messages for details.
2025-06-26 17:19:19 -06:00
Qwerasd d6db3013be renderer/OpenGL: switch image texture from Rect to 2D
We were using the Rectangle target for simpler addressing, since that
allows for pixel coordinates instead of normalized coordinates, but
there are downsides to rectangle textures, including not supporting
compressed texture formats, and we do probably want to use compressed
formats in the future, so I'm making this change now.
2025-06-26 16:38:19 -06:00
Qwerasd 810ab6a844 renderer/OpenGL: revert change to compressed texture format
This was applied to the wrong thing by accident, making the custom
shader ping-pong textures compressed, which breaks custom shaders
because compressed texture formats are not color renderable.

Additionally, I've not switched the compressed format to the correct
texture options, because I tried that and it turns out that the default
compression applied by drivers can't be trusted to be good quality and
generally speaking looks terrible. In the future we can explore doing
the compression ourselves CPU-side with something like b7enc_rdo.
2025-06-26 16:34:51 -06:00
Mitchell Hashimoto 6d6dcf863a
Correct AppStream metainfo XML, broken trailing tags 2025-06-26 13:37:20 -07:00
Mitchell Hashimoto c12b280782
dbus and systemd activation - take 2 (#7679)
This replaces #7433. The improvements are:

1) Install the systemd user service in the proper directory depending on
if it's a 'user' install or a 'system' install. This is controlled
either by using the `--system` build flag (as most packages will) or by
the `-Dsystem-package` flag.

2) Add the absolute path to the `ghostty` binary in the application
file, the DBus service, and the systemd user service. This is done so
that they do not depend on `ghostty` being in the `PATH` of whatever is
launching Ghostty. That `PATH` is not necessarily the same as the `PATH`
in a user shell (especially for DBus activation and systemd user
services).

3) Adjust the DBus bus name that is expected by the system depending on
the optimization level that Ghostty is compiled with.
2025-06-26 13:31:29 -07:00
Mitchell Hashimoto d92d1cac2a
remove unused TODO.md 2025-06-26 13:16:55 -07:00
Mitchell Hashimoto 3d01bb43cc
terminal/Screen: account for rectangle selection in clone (#7692)
Fixes an issue where rectangle selections would appear visually wrong if
their start or end were out of the viewport area, because when cloning
them the restored pins were defaulting to the start and end of the row
instead of the appropriate column.

This issue is shown in discussion #7687.
2025-06-26 13:15:48 -07:00
Mitchell Hashimoto b4e81949ee
wrong service name for dbus systemd service 2025-06-26 13:12:05 -07:00
Mitchell Hashimoto 77654eb01c
use tail to clear the first line of the template 2025-06-26 13:07:41 -07:00
Mitchell Hashimoto 739b691a6d
use cmake formatting to template, avoids the custom binary 2025-06-26 10:28:46 -07:00
Jeffrey C. Ollie 73d5eb928c fix up formatting of desktop_template.zig 2025-06-26 10:28:46 -07:00
Jeffrey C. Ollie 8a95212197 fix up the name in the metainfo when templating 2025-06-26 10:28:46 -07:00
Jeffrey C. Ollie fa4f420768 replace sed with a simple Zig program for templating desktop files 2025-06-26 10:28:46 -07:00
Jeffrey C. Ollie eb5a488b57 clean up duplicated code in installation of desktop services 2025-06-26 10:28:46 -07:00
Jeffrey C. Ollie 9c95ce28ae drop system-package option 2025-06-26 10:28:46 -07:00
Jeffrey C. Ollie cf561fcc55 rename templated files with .in suffix 2025-06-26 10:28:46 -07:00
Jeffrey C. Ollie b68f9f2321 make sure that the desktop file uses the absolute path everywhere 2025-06-26 10:28:46 -07:00
Jeffrey C. Ollie ddada2fb3f flatpak: remove references to systemd unit
Replaces #7676

When building as a flatpak, don't install the systemd user services
since flatpaks can't use them. Remove references to the systemd service
from the DBus service.

Also, customize the app metadata depending on the debug mode.

Co-authored-by: Leorize <leorize+oss@disroot.org>
2025-06-26 10:28:46 -07:00
Jeffrey C. Ollie 81403f59ce dbus and systemd activation - take 2
This replaces #7433. The improvements are:

1) Install the systemd user service in the proper directory depending
on if it's a 'user' install or a 'system' install. This is controlled
either by using the `--system` build flag (as most packages will) or by
the `-Dsystem-package` flag.

2) Add the absolute path to the `ghostty` binary in the application
file, the DBus service, and the systemd user service. This is done so
that they do not depend on `ghostty` being in the `PATH` of whatever
is launching Ghostty. That `PATH` is not necessarily the same as the
`PATH` in a user shell (especially for DBus activation and systemd user
services).

3) Adjust the DBus bus name that is expected by the system depending on
the optimization level that Ghostty is compiled with.
2025-06-26 10:28:46 -07:00
Qwerasd f7ee6b3bda terminal/Screen: clean up selection remap in clone
Cleans up the logic, checks for out of bounds using rows instead of
sel.contains because that excludes cases where a rectangle selection
doesn't include the leftmost column.

Also adds test for clipping behavior of rectangular selections.
2025-06-26 11:26:03 -06:00
Qwerasd 360124ded0 terminal/Screen: account for rectangle selection in clone
Fixes an issue where rectangle selections would appear visually wrong if
their start or end were out of the viewport area, because when cloning
them the restored pins were defaulting to the start and end of the row
instead of the appropriate column.
2025-06-25 23:16:43 -06:00
Jason Rayne 076f742dd4
fix: replace non-existent GHOSTTY_VERSION with TERM_PROGRAM_VERSION in shell integration
GHOSTTY_VERSION was mistakenly referenced but is never set. Use
TERM_PROGRAM_VERSION which is actually provided by Exec.zig from
build_config.version_string.
2025-06-25 17:50:15 -07:00
Jason Rayne b5372468e4
docs: clarify infocmp/tic requirements for ssh-terminfo feature
infocmp is required locally to extract terminfo, tic is required on
remote hosts to install it
2025-06-25 17:47:26 -07:00
Jason Rayne eed2006b4d
fix: correct resources directory fallback path and eliminate code duplication in ssh_cache
- Fix fallback path from full path to "src" since full path is built
later
- Extract duplicate code from listCachedHosts and clearCache into
runCacheCommand helper
- Addresses feedback from @00-kat
2025-06-25 17:47:01 -07:00
Jason Rayne 1873add697
docs: call out bash dependency 2025-06-25 17:00:17 -07:00
Jason Rayne e5e2a56c98
fix: use imported modules consistently in action dispatch 2025-06-25 16:47:17 -07:00
Jason Rayne 59229d7681
style: revert fish_indent quote removal
forgot to disable autoformat for this buffer (again)
2025-06-25 16:36:08 -07:00
Jason Rayne 931efcd1e3
fix: restore background-image config accidentally removed during rebase 2025-06-25 16:15:41 -07:00
Jason Rayne 21d95c42c6
docs: improve clear-ssh-cache description (missed in previous commit)
Clarifies this clears hosts cached by SSH shell integration, completing
mitchellh's feedback on both action descriptions.
2025-06-25 15:58:13 -07:00
Jason Rayne 0ccb7cf353
docs: improve SSH cache CLI action descriptions
- Clarify that +list-ssh-cache shows shell integration cached hosts
- Add note about +clear-ssh-cache command and when to use it

Addresses mitchellh's feedback on action descriptions.
2025-06-25 15:46:18 -07:00
Jason Rayne f617c9b3b7
docs: update ssh-terminfo description to reference new CLI actions
Updates Config.zig documentation to reflect that SSH cache management is
now handled by proper CLI actions (+list-ssh-cache and +clear-ssh-cache)
rather than shell wrapper commands.

Fixes documentation missed in e8c8a51.
2025-06-25 15:46:18 -07:00
Jason Rayne 0565ed3954
refactor: replace ghostty wrapper with proper CLI actions for terminfo cache management
- Add +list-ssh-cache and +clear-ssh-cache CLI actions
- Remove ghostty() wrapper functions from all shell integrations
- Improve variable naming in shell scripts for readability

Addresses @00-kat's feedback about CLI discoverability and naming
consistency. The new CLI actions follow established Ghostty patterns
and are discoverable via `ghostty --help`, while maintaining clean
separation of concerns between shell logic and cache management.
2025-06-25 15:46:18 -07:00
Jason Rayne 6789b7fb6e
docs: add shared directory section to shell-integration README 2025-06-25 15:46:18 -07:00
Jason Rayne 8a2fa6485e
refactor: extract SSH cache functionality to shared script
Addresses feedback about separation of concerns in shell integration
scripts.

Extracts host caching logic to
`src/shell-integration/shared/ghostty-ssh-cache` and updates all four
shell integrations to use the shared script. The `shared/` subdirectory
preserves the existing organizational pattern where all shell-specific
code lives in subdirectories. This cleanly separates SSH transport logic
from cache management while reducing code duplication by ~25%.

All existing SSH integration behavior remains identical.
2025-06-25 15:46:18 -07:00
Jason Rayne bbb02a8392
test: update shell integration tests for SSH flags
Add ssh-env and ssh-terminfo fields to existing setupFeatures tests.
2025-06-25 15:46:18 -07:00
Jason Rayne c8d5e60390
docs: expand flag descriptions, usage overview 2025-06-25 15:46:18 -07:00
Jason Rayne 81641e56b1
ssh-integration: replace levels with flags, optimize implementation
Rewrote shell functions to support the two new flags for
shell-integration-features:
- ssh-env: TERM compatibility + best effort environment variable
propagation (anything beyond TERM will depend on what the remote host
allows)
- ssh-terminfo: automatic terminfo installation with control socket
orchestration
- Flags work independently or combined

Implementation optimizations:
- ~65% code reduction through unified execution path
- Eliminated GHOSTTY_SSH_INTEGRATION environment variable system
- Replaced complex function dispatch with direct flag detection
- Consolidated 4 cache helper functions into single _ghst_cache()
utility
- Simplified control socket management (removed multi-step
orchestration)
- Subsequent connections to cached hosts are now directly executed and
more reliable

New additions:
- If ssh-terminfo is enabled, ghostty will be wrapped to provide users
with convenient commands to invoke either of the two utility functions:
`ghostty ssh-cache-list` and `ghostty ssh-cache-clear`
2025-06-25 15:46:18 -07:00
Jason Rayne e73313ed40
change: migrate SSH integration from standalone option to shell-integration-features flags
- Add ssh_env and ssh_terminfo flags to ShellIntegrationFeatures
- Remove SSHIntegration enum and ssh-integration config option
- Update setupFeatures to handle new flags via reflection
- Remove setupSSHIntegration function and all references

Integrates SSH functionality into existing shell-integration-features
system for better consistency and user control.
2025-06-25 15:46:18 -07:00
Jason Rayne ddd3da487e
fix: update cache file location 2025-06-25 15:46:18 -07:00
Jason Rayne 30683979bc
fix: catch up to current state 2025-06-25 15:46:18 -07:00
Jason Rayne f206e76841
ssh-integration: improve host caching, new method for "full" integration
Need a sanity check on this new approach for "full" to help determine if
it's worth additional iteration/refinement.

It solves the double auth issue, successfully propagates env vars, and
avoids output noise for connections that happen after terminfo is
installed. The only issue I don't have time to fix tonight is the fact
that it drops the MOTD for cached (re)connections.
2025-06-25 15:46:18 -07:00
Jason Rayne 69f9976394
fix: manual formatting pass to ensure consistency with existing patterns 2025-06-25 15:46:18 -07:00
Jason Rayne 4cebee5c8e
fix: add client-side caching to eliminate redundant terminfo installations
- Cache known hosts with terminfo in
$GHOSTTY_RESOURCES_DIR/terminfo_hosts
- Skip installation step for cached hosts (single connection instead of
two)
- Use secure file permissions (600) and atomic writes
- Extract SSH target safely from command arguments
- Maintains full functionality while improving user experience on
repeated connections
2025-06-25 15:46:18 -07:00
Jason Rayne b6bb9abfbc
fix: address comprehensive shell integration code review issues
- Fix elvish function name mismatch and use conj for list operations
- Simplify terminfo installation command per ghostty docs (tic -x -)
- Fix conditional structure to ensure error messages always print
- Remove redundant checks and optimize array initialization
- Use consistent patterns across bash, fish, elvish, and zsh
implementations
2025-06-25 15:46:18 -07:00
Jason Rayne 995fb09813
fix: add builtin prefix for safety and consistency 2025-06-25 15:46:18 -07:00
Jason Rayne 2ddcf2fffe
fix: remove resources_dir var, add builtin prefix for consistency 2025-06-25 15:46:18 -07:00
Jason Rayne 3319b2b6ed
docs: added full stop for consistency 2025-06-25 15:46:18 -07:00
Jason Rayne fb8f6c77dd
fix: remove dangling resources_dir var 2025-06-25 15:46:18 -07:00
Jason Rayne 80475e1d17
fix: critical elvish syntax errors for environment variables 2025-06-25 15:46:18 -07:00
Jason Rayne af28763a34
fix: trailing newline in Config.zig 2025-06-25 15:46:18 -07:00
Jason Rayne 8fafd5ace1
docs: expand SSH integration configuration documentation
Add detailed explanations of shell function behavior, TERM compatibility
trade-offs, environment variable propagation, and authentication
requirements per maintainer feedback.
2025-06-25 15:46:18 -07:00
Jason Rayne 4206ab1210
fix: use idiomatic Fish shell syntax in SSH integration
- Use `set --append` for array operations
- Use `type -q` for command existence checks
2025-06-25 15:46:18 -07:00
Jason Rayne 050cb3bfec
fix: remove unnecessary jsonStringify method 2025-06-25 15:46:18 -07:00
Jason Rayne 2e9a0e92db
fix: clean up SSH environment variable propagation 2025-06-25 15:46:18 -07:00
Jason Rayne b07b3e4608
fish: revert all formatting changes
Keeps only functional additions for SSH integration wrapper,
preserving original line breaks and indentation to minimize
diff noise per maintainer feedback.
2025-06-25 15:46:18 -07:00
Jason Rayne c70643404c
bash: revert all formatting changes
Keeps only functional additions for SSH integration wrapper,
preserving original line breaks and indentation to minimize
diff noise per maintainer feedback.
2025-06-25 15:46:18 -07:00
Jason Rayne 842ced9212
bash: preserve mixed indentation in SSH integration changes
Preserves existing mixed indentation in ghostty.bash to minimize
diff noise per maintainer feedback.
2025-06-25 15:46:18 -07:00
Jason Rayne 2babdb458f
refactor: simplify ssh integration environment variable checks 2025-06-25 15:46:18 -07:00
Jason Rayne 34af3ffbaf
docs: inline ssh-integration documentation instead of referencing enum 2025-06-25 15:46:18 -07:00
Jason Rayne 8f93d8fe03
fix: use kebab-case for ssh-integration enum values 2025-06-25 15:46:18 -07:00
Jason Rayne 142e07c502
feat: add SSH integration wrapper for shell integration
- Implements opt-in SSH wrapper following sudo pattern
- Supports term_only, basic, and full integration levels
- Fixes xterm-ghostty TERM compatibility on remote systems
- Propagates shell integration environment variables
- Allows for automatic installation of terminfo if desired
- Addresses GitHub discussions #5892 and #4156
2025-06-25 15:43:32 -07:00
Mitchell Hashimoto fa47db5363
config: add `command-palette-entry` config option (#7688)
Implements #7158 for GTK
2025-06-25 16:48:10 -04:00
Mitchell Hashimoto 9eec80e038
Terminal Background Image Support (#7686)
Adds support for background images via the `background-image` config.

Resolves #3645, supersedes PRs #4226 and #5233.

See docs of added config keys for usage details.

> [!NOTE]
> Unlike what is implied by the original issue, because this is
implemented in the renderer it is inherently per-surface not per-window,
meaning a window with a split will have two copies of the background
image.

### Future work
- We should probably introduce code in the apprts that tells surfaces
their position and size relative to the window, which would allow us to
add a `background-image-area` config with options for `surface` and
`window` to control that behavior (and probably default it to `window`).
That apprt code would also allow for window-relative custom shader
locations, which is also a fairly common user request, so I think it's
worth it.
- Currently if you use a high res background image this is fairly
inefficient, since each surface independently loads a copy of the
background image. On systems with limited VRAM this could be an issue
for users who use a lot of surfaces, so it may be worth making a shared
image cache to avoid this problem.
- ~~It's probably worth using compressed texture formats for images,
I'll look in to doing that.~~ (c43702c)
2025-06-25 16:45:40 -04:00
Mitchell Hashimoto a8091fedf3
fix tests 2025-06-25 16:28:31 -04:00
Mitchell Hashimoto 6c2ea8637e
config: add more docs for `background-image` 2025-06-25 16:27:23 -04:00
Qwerasd 5cb175ff63 renderer/OpenGL: use compressed texture formats for images
BPTC is required to be available OpenGL >= 4.2 and our minimum is 4.3 so
this is safe in terms of support. I tested briefly in a VM and didn't
encounter any problems so this should just be a complete win.

(Note: texture data is already automatically compressed on Metal)
2025-06-25 16:27:23 -04:00
Qwerasd da46a47726 renderer: add support for background images
Adds support for background images via the `background-image` config.

Resolves #3645, supersedes PRs #4226 and #5233.

See docs of added config keys for usage details.
2025-06-25 16:27:23 -04:00
Qwerasd 03bdb92292 renderer: clean up `image.zig`, reduce repetitive code 2025-06-25 16:27:23 -04:00
Qwerasd ca5f301eb1 util: introduce helper for detecting file types 2025-06-25 16:27:23 -04:00
Leah Amelia Chen dbe6035da0 config: add `command-palette-entry` config option 2025-06-25 16:18:20 -04:00
Leah Amelia Chen d419e5c922 gtk(command_palette): filter out more unimplemented actions 2025-06-25 16:18:20 -04:00
Leah Amelia Chen 832f27596c gtk(command_palette): grab focus correctly 2025-06-25 16:18:20 -04:00
Mitchell Hashimoto a5f1413a1c
config: make split/tab navigation keybinds performable (#7683)
Fixes #7680
2025-06-25 16:06:15 -04:00
Leah Amelia Chen 9a5aed51a3
config: make split/tab navigation keybinds performable
Fixes #7680
2025-06-25 15:20:24 +02:00
Mitchell Hashimoto 74a03ebd6e
Revert "linux: add dbus and systemd activation services (#7433)" (#7678)
Reverts two commits:

977cd530c7
820b7e432b

These break build from source on Linux for two reasons:

1.) The systemd user service needs to be installed in the `share`
prefix, not the `lib` prefix. This lets it get picked up in `~/.local`
but is also correct for just standard FHS paths.

2.) The `ghostty` path in the systemd user service needs to be absolute.
We should interpolate in the build install prefix to form an absolute
path.
2025-06-24 22:12:02 -04:00
Mitchell Hashimoto f941a2185e
Revert "linux: add dbus and systemd activation services (#7433)"
Reverts two commits:

977cd530c7
820b7e432b

These break build from source on Linux for two reasons:

1.) The systemd user service needs to be installed in the `share`
prefix, not the `lib` prefix. This lets it get picked up in `~/.local`
but is also correct for just standard FHS paths.

2.) The `ghostty` path in the systemd user service needs to be absolute.
We should interpolate in the build install prefix to form an absolute
path.
2025-06-24 22:07:09 -04:00
Mitchell Hashimoto 00aad86625
font: faster glyph hashing (#7677)
There are two main improvements being made here. First, we move away
from using autohash and instead use a one-shot strategy similar to the
Style hashing. Since the GlyphKey includes the Metrics struct, which
contains quite a few fields, autohash was performing expensive and
unnecessary repeated updates.

The second improvement is actually just, not hashing Metrics. By
ignoring the Metrics field, we can fit the rest of the GlyphKey into a
64-bit packed struct and just return that as the hash! It ends up being
unique for each GlyphKey in renderGlyph, and is nearly a zero-cost
operation.

This ends up boosting the performance (on my machine at least), from
around 560fps to 590fps on the DOOM-fire benchmark.
2025-06-24 19:12:30 -04:00
Mitchell Hashimoto 820b7e432b
flatpak: remove references to systemd unit (#7676)
Flatpak currently does not export systemd user units. As such, remove
references to it from D-Bus services to prevent D-Bus daemon from trying
to start a non-existent service.

Additionally, make sure that the D-Bus service name is correct for debug
builds.

Follow up to #7433
2025-06-24 19:06:07 -04:00
David Rubin 93dcb1954d
faster glyph hashing
There are two main improvements being made here. First, we move away from using autohash and instead
use a one-shot strategy similar to the Style hashing. Since the GlyphKey includes the Metrics struct,
which contains quite a few fields, autohash was performing expensive and unnecessary repeated updates.

The second improvement is actually just, not hashing Metrics. By ignoring the Metrics field, we can
fit the rest of the GlyphKey into a 64-bit packed struct and just return that as the hash! It
ends up being unique for each GlyphKey in renderGlyph, and is nearly a zero-cost operation.

This ends up boosting the performance (on my machine at least), from around 560fps to 590fps on the
DOOM-fire benchmark.
2025-06-24 15:47:54 -07:00
Leorize 32e61d2a23
flatpak: remove references to systemd unit
Flatpak currently does not export systemd user units. As such, remove
references to it from D-Bus services to prevent D-Bus daemon from trying
to start a non-existent service.

Additionally, make sure that the D-Bus service name is correct for debug
builds.
2025-06-24 17:34:41 -05:00
Mitchell Hashimoto 977cd530c7
linux: add dbus and systemd activation services (#7433) 2025-06-24 18:14:24 -04:00
Mitchell Hashimoto 4c3db76733
fix: always wait on open command to avoid defunct processes (#7657)
Without waiting on the xdg-open process on linux/freebsd, we end up with
a defunct (zombie) process after each time we open a URL.

For example, after click on two URLs in a ghostty, here is the output of
`ps ux | grep xdg-open`:

```
pbui      8364  0.0  0.0      0     0 tty7     Z+   05:03   0:00 [xdg-open] <defunct>
pbui      8453  0.0  0.0      0     0 tty7     Z+   05:03   0:00 [xdg-open] <defunct>
```

Perhaps we should revisit 695bc30, which removed the wait in the first
place. On my machine running Alpine Linux 3.22, `xdg-open` does not stay
alive and finishes immediately, thus making it safe to call wait (and
not block). This is also the case on my other machine running Ubuntu
24.04: `xdg-open` launches the URL in a browser and terminates
immediately.

Either way, this process must be waited upon eventually. Otherwise, we
will accumulate a collection of defunct processes until the terminal
itself terminates.
2025-06-24 08:08:31 -04:00
Mitchell Hashimoto 5f6cdb0c4e
core, gtk: implement host resources dir for Flatpak (#6661)
Introduces host resources directory as a new concept: A directory
containing application resources that can only be accessed from the host
operating system. This is significant for sandboxed application runtimes
like Flatpak where shells spawned on the host should have access to
application resources to enable integrations.

Alongside this, apprt is now allowed to override the resources lookup
logic.
2025-06-24 07:54:37 -04:00
Peter Bui 3d89fadc85 fix: always wait on open command to avoid defunct processes
To avoid blocking on waiting for the child process, perform the wait in
a detached thread.
2025-06-24 07:50:53 -04:00
Aindriú Mac Giolla Eoin c12bccc9c5 Replaced 6 strings with táb rather than cluaisín 2025-06-24 12:45:21 +01:00
Mitchell Hashimoto 0b5092bf3a
pwd: fix hostname resolution on macos (#7029)
## Description

Yet another edge case in #2484 

When macOS's "Private WiFi address" feature is enabled it'll change the
hostname to a mac address. Mac addresses look like URIs with a hostname
and port component, e.g. `12:34:56:78:90:12` where `:12` looks like port
`12`. However, mac addresses use hex numbers and as such can also
contain letters `a` through `f`. So, a mac address like
`ab💿ef🆎cd:ef` is valid, but will not be parsed as a URI, because
`:ef` is not a valid port.

This commit attempts to fix that by checking if the hostname is a valid
mac address when `std.Uri.parse()` fails and constructing a new
`std.Uri` struct using that information.

It's not perfect, but is equally compliant with the URI spec as
`std.Uri` currently is. Meaning not at all compliant 😅

## Testing instructions

### Unit tests

> [!IMPORTANT]
> I don't know if these tests are run in CI or if they're picked up by
`zig build test`. I get an unrelated crash that mentions `minidump` and
an invalid OSC command when I try to run `zig build test` on my mac.

1. Make sure `zig test src/os/hostname.zig` is passing.

### Manual testing instructions

#### Setup - Enable the "Private WiFi address" setting

> [!IMPORTANT]
> You must be connected to WiFi to be able to test this.

1. Open your mac's "System Settings".
2. Go to Network &rarr; Wi-Fi &rarr; Details.

<img width="710" alt="image"
src="https://github.com/user-attachments/assets/fe30cfe7-8e77-4421-8b36-2f7aab0918dd"
/>

3. Set the "Private Wi-Fi address" setting to `Rotating`.

<img width="710" alt="image"
src="https://github.com/user-attachments/assets/bd695c20-106c-46bd-8862-cbdce55fed6f"
/>

> [!IMPORTANT]
> Now you wait. The private Wi-Fi address will eventually rotate to a
mac address that ends with a non-digit, e.g. `0a`, `ff`, `e2`, etc.
You'll notice this when your shell integration stops working, e.g. you
open a new tab in Ghostty and the shell is in your home directory
instead of whichever directory you had open in your previous tab.

#### Testing the changes

1. Open Ghostty.
3. `cd` to any directory that isn't the default (usually `$HOME`)
directory, e.g. `cd Documents`.
4. Open a new tab (<kbd>Cmd+T</kbd>) or split (<kbd>Cmd+D</kbd>).
5. Assuming the setup steps have been followed you should:
    * On `main`:  land in `$HOME` in the new tab or split.
* On this branch: land in the same working directory as the original tab
or split.
2025-06-24 07:40:14 -04:00
Leorize faf9d59160 core, apprt: make runtimes implement resourcesDir directly 2025-06-24 07:36:09 -04:00
Leorize 1688f2576c core, gtk: implement host resources dir for Flatpak
Introduces host resources directory as a new concept: A directory
containing application resources that can only be accessed from the host
operating system. This is significant for sandboxed application runtimes
like Flatpak where shells spawned on the host should have access to
application resources to enable integrations.

Alongside this, apprt is now allowed to override the resources lookup
logic.
2025-06-24 07:35:28 -04:00
Mitchell Hashimoto 82859bd844
cli: +edit-config command to open the config file in $EDITOR (#7668)
This adds a new CLI `ghostty +edit-config`. This will open the config
file in the user's specified `$EDITOR`. If Ghostty has never been
configured, this will also create the initial config file with some
default templated contents (the same as that which we introduced back in
Ghostty 1.0.1 or something -- not new behavior here).

This is useful on its own because it will find the correct configuration
path to open. If users are terminal users anyway (not a big stretch
since this is a terminal app), this will allow them to easily edit
config right away.

This is also forward looking: I want to replace our "Open Config" action
to open a Ghostty window executing this command so that users can edit
their config in a terminal editor. This has been heavily requested since
forever (short of a full GUI settings editor, which is not ready yet). I
don't do this in this PR but plan to in a future PR.

Even further forward looking: when we have an API, we can have
`edit-config` auto-reload the config on exit. This isn't possible today
but this is where we'd put that.
2025-06-24 07:30:50 -04:00
Mitchell Hashimoto 865ba546a9
cli: +edit-config command to open the config file in $EDITOR
This adds a new CLI `ghostty +edit-config`. This will open the config
file in the user's specified `$EDITOR`. If Ghostty has never been
configured, this will also create the initial config file with some
default templated contents (the same as that which we introduced back in
Ghostty 1.0.1 or something -- not new behavior here).

This is useful on its own because it will find the correct configuration
path to open. If users are terminal users anyway (not a big stretch
since this is a terminal app), this will allow them to easily edit
config right away.

This is also forward looking: I want to replace our "Open Config" action
to open a Ghostty window executing this command so that users can edit
their config in a terminal editor. This has been heavily requested since
forever (short of a full GUI settings editor, which is not ready yet). I
don't do this in this PR but plan to in a future PR.
2025-06-24 07:17:05 -04:00
Aindriú Mac Giolla Eoin b8bc37fb95 Changed Pailéad ordú to Pailéad ordaithe 2025-06-24 09:22:33 +01:00
Qwerasd f0db524924
Miscellaneous Renderer Cleanup (#7671)
This PR is a collection of small improvements, cleanup, and fixes to the
renderer, as a follow-up to #7620.

### Summary of changes
- The nearly identical-between-backends `cell.zig` and `image.zig` are
now both unified.
- Shader pipeline preparation is now even DRYer in preparation for
future changes that will involve adding new pipelines, where I don't
want to be slowed down by having to add them in multiple places to get
things working. There is now a single source of truth at the top of
`shaders.zig` for what core pipelines are available and how they're
configured.
- Global background color drawn in a separate step before individual
cell background colors, this is required to be able to draw kitty images
between these layers. Can't use the clear color for this because that
would require color space conversions on the CPU-side which we don't yet
have utilities for.
- Fixed a bug with the kitty image z-index logic where not having
foreground images made the background images act as foreground images.
- Moved the custom shader uniform buffer to the frame state so we don't
create a new one every frame like we were before.
- Fixed color glyphs under OpenGL being channel-swapped because the
texture format was RGBA when the data was BGRA (#7670).
2025-06-23 21:07:11 -06:00
Qwerasd 1fb5e8691a naming: ArrayListPool -> ArrayListCollection
Also remove unnecessary and confusing default value for the lists.
2025-06-23 20:47:19 -06:00
Qwerasd c465317e4e font/atlas: fix testing code that used old enum name
Forgot to change these instances when I renamed rgb(a) to bgr(a), which
was breaking test builds. Also went ahead and fixed some code that was
assuming rgba was actually rgba order and added a note to another part.
2025-06-23 18:01:34 -06:00
Qwerasd 41ae32814f renderer: fix color glyph rendering under OpenGL
Also changes color atlas to always use an sRGB internal format so that
the texture reads automatically linearize the colors.

Renames the misleading `rgba` atlas format to `bgra`, since both
FreeType and CoreText are set up to draw color glyphs in bgra.
2025-06-23 18:01:34 -06:00
Qwerasd f5439c860a renderer: extract kitty image upload in drawFrame to fn
For cleanliness -- also updated some comments while I was at it.
2025-06-23 18:01:34 -06:00
Qwerasd 706a43138e renderer: keep post uniform buffer in frame state
This avoids creating a new buffer for this every frame.
2025-06-23 18:01:34 -06:00
Qwerasd 1da40ccbac fix(renderer): kitty image z-index accounting
The previous logic would consider all images fg if the only present
placements were bg, or consider mg images fg if there were no fg.
2025-06-23 18:01:34 -06:00
Qwerasd 4c3ab14571 renderer: make shader pipeline prep code DRYer
In this format it will be a lot easier to iterate on this since adding
and removing pipelines only has to be done in a single place.

This commit also separates out the main background color from individual
cell background color drawing, because sometimes kitty images need to be
between the main background and individual cell backgrounds (kitty image
z-index seems to be entirely broken at the moment, I intend to fix it in
future commits).
2025-06-23 18:01:34 -06:00
Qwerasd df8dc33ab6 renderer: unify `image.zig`
The code in metal/image.zig and opengl/image.zig was virtually identical
save for the texture options, so I've moved that to the GraphicsAPI and
unified them in to renderer/image.zig
2025-06-23 13:12:17 -06:00
Qwerasd 7eb3e813dd datastruct: move ArrayListPool from renderer/cell.zig 2025-06-23 13:06:41 -06:00
Qwerasd 4b01cc1d88 renderer: unify `cell.zig`
The code in metal/cell.zig and opengl/cell.zig was virtually identical
aside from the types for the cell data, moved it to renderer/cell.zig
2025-06-23 12:21:30 -06:00
Mitchell Hashimoto 373fc6bcbf
docs: document uniforms available to custom shaders (#7653) 2025-06-23 04:47:28 -07:00
Aindriú Mac Giolla Eoin 72fb87b20e Updated Irish to sentence case, updated struct, added ga_IE to supported locales 2025-06-23 09:27:22 +01:00
Mitchell Hashimoto 3e79c4b7ea
macOS: Run scripts using stdin rather than executing directly (#7654)
Fixes #7647

See #7647 for context. This commit works by extending the `input` work
introduced in #7652 to libghostty so that the macOS can take advantage
of it. At that point, it's just the macOS utilizing `input` in order to
set the command and `exit` up similar to Terminal and iTerm2.

This applies both to files opened directly by Ghostty as well as the App
Intent to run a command in a new terminal.
2025-06-22 18:15:32 -07:00
Mitchell Hashimoto 471098df30
macOS: Run scripts using stdin rather than executing directly
Fixes #7647

See #7647 for context. This commit works by extending the `input` work
introduced in #7652 to libghostty so that the macOS can take advantage
of it. At that point, its just the macOS utilizing `input` in order to
set the command and `exit` up similar to Terminal and iTerm2.
2025-06-22 21:06:32 -04:00
Mitchell Hashimoto 0721955dde
`input` configuration to pass input as stdin on startup (#7652)
This adds a new configuration `input` that allows passing either raw
text or file contents as stdin when starting the terminal.

The input is sent byte-for-byte to the terminal, so control characters
such as `\n` will be interpreted by the shell and can be used to run
programs in the context of the loaded shell. After the input is sent, it
switches to `stdin` as usual.

Example: `ghostty --input="hello, world\n"` will start the your default
shell, run `echo hello, world`, and then show the prompt

The `--input` configuration can be repeated to send multiple data
concatenated directly to together. Values can be also be prefixed with
`file:` to send a file contents, e.g. `file:data.txt`. File contents are
limited to 10MB to prevent excessive memory usage and avoid malicious
use. Beyond that, users should write their own script...

This is all in pursuit of #7647, but we're not there yet.
2025-06-22 16:20:39 -07:00
Qwerasd 7ca9cd1994 docs: document uniforms available to custom shaders 2025-06-22 17:07:26 -06:00
Mitchell Hashimoto 1947afade9
`input` configuration to pass input as stdin on startup
This adds a new configuration `input` that allows passing either raw
text or file contents as stdin when starting the terminal.

The input is sent byte-for-byte to the terminal, so control characters
such as `\n` will be interpreted by the shell and can be used to run
programs in the context of the loaded shell.

Example: `ghostty --input="hello, world\n"` will start the your default
shell, run `echo hello, world`, and then show the prompt.
2025-06-22 18:18:16 -04:00
Aindriú Mac Giolla Eoin 84b1984f08 Added Irish translation 2025-06-22 19:45:02 +01:00
Qwerasd 8573d53fe6
Custom Shader Cursor Uniforms (#7648)
Supersedes #6912, implements #6901

Also included in this PR is a fix/cleanup of the custom shader uniform
handling, moved the CPU-side custom shader uniforms struct to the main
renderer struct instead of having it be per-frame, moved the layout
struct to `shadertoy.zig` since it has the `std140` layout for both
backends.

Also, I added the current/previous cursor colors to the uniforms, since
I figured they'd be useful to have and it's a trivial addition.

### Future Work
- This extension to the shadertoy uniforms needs to be documented
somewhere so it's discoverable by users.
- The flipped Y axis on Metal still needs to be fully addressed instead
of just being patched over like it is right now.
2025-06-22 12:04:12 -06:00
Qwerasd d0ff2452d5 renderer: add cursor color to custom shader uniforms 2025-06-22 11:05:16 -06:00
Qwerasd bb576d1340 renderer: add custom shader cursor uniforms
Based on / supersedes PR #6912, implements discussion #6901

Co-authored-by: Krone Corylus <ahustinkrone@gmail.com>
2025-06-22 11:05:16 -06:00
Mitchell Hashimoto f07816f188
macOS: Fix window-decoration=none regression on Tahoe (#7644)
This regression may have existed on Sequoia too, but I only saw it on
Tahoe.

The issue is that we should not be setting up titlebar accessory views
when there is no titlebar. This was triggering an AppKit assertion.

To further simplify things, I always use the basic window styling if
window decorations are off, too.
2025-06-22 08:19:47 -07:00
Mitchell Hashimoto 02e05a85fc
macOS: Fix window-decoration=none regression on Tahoe
This regression may have existed on Sequoia too, but I only saw it on
Tahoe.

The issue is that we should not be setting up titlebar accessory views
when there is no titlebar. This was triggering an AppKit assertion.

To further simplify things, I always use the basic window styling if
window decorations are off, too.
2025-06-22 07:28:30 -07:00
Mitchell Hashimoto f4a2772045
build: simulator should use iphoneos metal, its the -m flags important 2025-06-22 07:11:12 -07:00
Qwerasd c7a7474be0 renderer: move custom shader uniforms out of frame state
These should not be independent per-frame, that makes the time
calculations all sorts of jank.

Also moves the uniforms struct layout in to `shadertoy.zig` and cleans
up the handling in general somewhat.
2025-06-21 23:07:18 -06:00
Qwerasd 5bfdb1b9cf
The Big Renderer Rework (#7620)
It's here, the long-foretold and long-procrastinated renderer rework!
Hopefully this makes it easier to adapt and modify the renderer in the
future and ensures feature parity between Metal and OpenGL. Despite
having been a lot of work to write initially, with the abstraction layer
in place I feel like working on the renderer will be a much more
pleasant experience going forward.

## Key points
- CPU-side renderer logic is now mostly unified via a generic
`Renderer`.
- A graphics API abstraction layer over OpenGL and Metal has been
introduced.
- Minimum OpenGL version bumped to `4.3`, so can no longer be run on
macOS; I used the nix VM stuff for my testing during development. (Edit
by @mitchellh: Note for readers that Ghostty still works on macOS, but
the OpenGL backend doesn't, only the Metal one)
- The OpenGL backend now supports linear blending! Woohoo! The default
`alpha-blending` has been updated to `linear-corrected` since it's
essentially a strict improvement over `native`. The default on macOS is
still `native` though to match other mac apps in appearance, since macOS
users are more sensitive to text appearance.
- Custom shaders can now be hot reloaded.
- The background color is once again drawn by us, so custom shaders can
interact with it properly. In general, custom shaders should be a little
more robust.

## The abstraction layer
The general hierarchy of the abstraction layer is as such:
```
 [ GraphicsAPI ] - Responsible for configuring the runtime surface
    |     |        and providing render `Target`s that draw to it,
    |     |        as well as `Frame`s and `Pipeline`s.
    |     V
    | [ Target ] - Represents an abstract target for rendering, which
    |              could be a surface directly but is also used as an
    |              abstraction for off-screen frame buffers.
    V
 [ Frame ] - Represents the context for drawing a given frame,
    |        provides `RenderPass`es for issuing draw commands
    |        to, and reports the frame health when complete.
    V
 [ RenderPass ] - Represents a render pass in a frame, consisting of
   :              one or more `Step`s applied to the same target(s),
 [ Step ] - - - - each describing the input buffers and textures and
   :              the vertex/fragment functions and geometry to use.
   :_ _ _ _ _ _ _ _ _ _/
   v
 [ Pipeline ] - Describes a vertex and fragment function to be used
                for a `Step`; the `GraphicsAPI` is responsible for
                these and they should be constructed and cached
                ahead of time.

 [ Buffer ] - An abstraction over a GPU buffer.

 [ Texture ] - An abstraction over a GPU texture.
```
More specific documentation can be found on the relevant structures.

## Miscellany
Renderers (which effectively just means the generic renderer) are now
expected to only touch GPU resources in `init`, certain lifecycle
functions such as the `displayRealized`/`displayUnrealized` callbacks
from GTK-- and `drawFrame`; and are also expected to be thread-safe.
This allows the renderer thread to build the CPU-side buffers
(`updateFrame`) even if we can only *draw* from the app thread.

Because of this change, we can draw synchronously from the main thread
on macOS when necessary to always have a frame of the correct size
during a resize animation. This was necessary to allow the background to
be drawn by our GPU code (instead of setting a background color on the
layer) while still avoiding holes during resize.

The OpenGL backend now theoretically has access to multi-buffering, but
it's disabled (by setting the buffer count to 1) because it
synchronously waits for frames to complete anyway which means that the
extra buffers were just a waste of memory.

## Validation
To validate that there are no significant or obvious problems, I
exercised both backends with a variety of configurations, and visually
inspected the results. Everything looks to be in order.

The images are available in a gist here:
https://gist.github.com/qwerasd205/c1bd3e4c694d888e41612e53c0560179

## Memory
Here's a comparison of memory usage for ReleaseFast builds on macOS,
between `main` and this branch.
Memory figures given are values from Activity Monitor measuring windows
of the same size, with two tabs with 3 splits each.

||Before|After|
|-:|-|-|
|**Memory**|247.9 MB|224.2 MB|
|**Real Memory**|174.4 MB|172.5 MB|

Happily, the rework has slightly *reduced* the memory footprint- likely
due to removing the overhead of `CAMetalLayer`. (The footprint could be
reduced much further if we got rid of multi-buffering and satisfied
ourselves with blocking for each frame, but that's a discussion for
another day.)

If someone could do a similar comparison for Linux, that'd be much
appreciated!

## Notes / future work
- There are a couple structures that *can* be unified using the
abstraction layer, but I haven't gotten around to unifying yet.
Specifically, in `renderer/(opengl|metal)/`, there's `cell.zig` and
`image.zig`, both of which are substantially identical between the two
backends. `shaders.zig` may also be a candidate for unification, but
that might be *overly* DRY.
- ~~I did not double-check the documentation for config options, which
may mention whether certain options can be hot-reloaded; if it does then
that will need to be updated.~~ Fixed: be5908f
- The `fragCoord` for custom shaders originates at the top left for
Metal, but *bottom* left for OpenGL; fixing this will be a bit annoying,
since the screen texture is likewise vertically flipped between the two.
Some shaders rely on the fragcoord for things like falling particles, so
this does need to be fixed.
- `Target` should be improved to support multiple types of targets right
now it only represents a framebuffer or iosurface, but it should also be
able to represent a texture; right now a kind of messy tagged union is
used so that steps can accept both.
- Custom shader cursor uniforms (#6912) and terminal background images
(#4226, #5233) should be much more straightforward to implement on top
of this rework, and I plan to make follow-up PRs for them once this is
merged.
- I *do* want to do a rework of the pipelines themselves, since the way
we're rendering stuff is a bit messy currently, but this is already a
huge enough PR as it is- so for now the renderer still uses the same
rendering passes that Metal did before.
- We should probably add a system requirements section to the README
where we can note the minimum required OpenGL version of `4.3`, any even
slightly modern Linux system will support this, but it would be good to
document it somewhere user-facing anyway.

# TODO BEFORE MERGE
- [x] Have multiple people test this on both macOS and linux.
- [ ] ~~Have someone with a better dev setup on linux check for memory
leaks and other problems.~~ (Skipped, will merge and let tip users
figure this out, someone should *specifically* look for memory leaks
before the next versioned release though.)
- [x] Address any code review feedback.
2025-06-21 22:00:01 -06:00
Mitchell Hashimoto 5521af4b2b
Update iTerm2 colorschemes (#7640)
Upstream revision:
e436898274
2025-06-21 19:49:39 -07:00
mitchellh fece388f58 deps: Update iTerm2 color schemes 2025-06-22 00:15:04 +00:00
Mitchell Hashimoto 9d922e1c62
feat: add FreeBSD support (#7606)
- [x] Waiting for mitchellh/libxev#167
- [x] Translations
- [x] x11
- [x] Wayland
- [ ] CI
2025-06-21 14:16:52 -07:00
Mitchell Hashimoto 888daca891
ci: remove freebsd test for now 2025-06-21 14:12:13 -07:00
-k 097d1ad21e ci: switch to `freebsd-firecracker-action` 2025-06-21 14:11:50 -07:00
-k b32b1e7188 fix: set `resources_dir` on FreeBSD 2025-06-21 14:11:50 -07:00
-k 8b0de9be4a build: fix terminfo location on FreeBSD 2025-06-21 14:11:50 -07:00
-k 89b39775e5 build: fix `fontconfig` paths on FreeBSD 2025-06-21 14:11:50 -07:00
Mitchell Hashimoto 43a46d1741
flatpak: update hash 2025-06-21 14:11:50 -07:00
Mitchell Hashimoto c4d594980a
update nix hash 2025-06-21 14:11:50 -07:00
Mitchell Hashimoto 2314d3dbf0
ci: run freebsd tests on Namespace 2025-06-21 14:11:50 -07:00
-k d6b2d0ef2a fix: update `libxev` 2025-06-21 14:11:50 -07:00
-k a209494b43 build: comment `locale` trim 2025-06-21 14:11:50 -07:00
-k 43b8472ad2 style: fix formatting 2025-06-21 14:11:50 -07:00
-k 16348549c4 fix: enable i18n on FreeBSD 2025-06-21 14:11:50 -07:00
-k 780ee894d8 build: disable i18n on FreeBSD
for now
2025-06-21 14:11:50 -07:00
-k 3e582a6158 test: fix desktop cases 2025-06-21 14:11:50 -07:00
-k 4d7a667dd1 build(deps): bump charlesrocket/libxev to `e29fc0c`
Waiting for mitchellh/libxev#167
2025-06-21 14:11:50 -07:00
-k 451043357d ci: add freebsd job 2025-06-21 14:11:50 -07:00
-k baa41c3291 fix(config): enable cgroups for linux only 2025-06-21 14:11:50 -07:00
-k 6e190acf31 fix(config): fix `quick-terminal-autohide` comment 2025-06-21 14:11:50 -07:00
-k 8e7e9cb8ec fix: check DE env var on FreeBSD 2025-06-21 14:11:50 -07:00
-k e2937448bb fix: get GTK env var on FreeBSD 2025-06-21 14:11:50 -07:00
-k e2f86f03b8 test: fix desktop cases on BSD 2025-06-21 14:11:50 -07:00
-k c1830b563d Import `libxev` fork
Temp
2025-06-21 14:11:50 -07:00
-k e09657e263 Add FreeBSD support
Following 7aeadb06ee
2025-06-21 14:11:50 -07:00
Mitchell Hashimoto 0e75dc899c
Ghostty Icon Update for macOS Tahoe (#7638)
Fixes #7564 

This updates the Ghostty icon to be compatible with macOS Tahoe
(supports glass effects, light/dark, tinting, etc.). This icon is made
in the new Apple Icon Composer as the source format, and all other
formats are exported from it. The icon is made by [Michael
Flarup](https://flarup.co), the same designer as our original icon.

This commit also updates the icon for non-Apple platforms because the
icon is fundamentally the same and I don't see any reason to maintain
multiple icons of fundamentally the same design and style.

This commit also includes updates to the macOS app so that the About
Window and so on will use the new icon.

## Icon Styles Demo


https://github.com/user-attachments/assets/4b4ea331-9b24-4648-a3f8-8605c1282071

## Glass Demos


https://github.com/user-attachments/assets/f5d04b27-4aae-4178-bd62-ddc739ffb144


https://github.com/user-attachments/assets/11bee1ac-a3e9-4ea9-8bad-3fd1f4babc62


https://github.com/user-attachments/assets/3dae1be9-a2df-465e-a133-022ecaa462b2

## Tinted


https://github.com/user-attachments/assets/e1a9ec28-b8cb-4160-9158-8953e9fb1320
2025-06-21 12:48:52 -07:00
Mitchell Hashimoto c1c3f639c5
macos: Ghostty Icon Update for macOS Tahoe
This updates the Ghostty icon to be compatible with macOS Tahoe
(supports glass effects, light/dark, tinting, etc.). This icon is made
in the new Apple Icon Composer as the source format, and all other
formats are exported from it.

This commit also updates the icon for non-Apple platforms because the
icon is fundamentally the same and I don't see any reason to maintain
multiple icons of fundamentally the same design and style.

This commit also includes updates to the macOS app so that the About
Window and so on will use the new icon.
2025-06-21 12:34:49 -07:00
Mitchell Hashimoto 95ac157bc5
feat(translation): add missing pt_BR translation (#7632)
Add missing translation
2025-06-21 07:14:22 -07:00
Mitchell Hashimoto 6fe72db0c4
macOS: App Intents (#7634)
This PR integrates Ghostty on macOS with the [App
Intents](https://developer.apple.com/documentation/appintents) system.
The focus of this initial work was on enabling [Apple
Shortcuts](https://support.apple.com/guide/shortcuts/welcome/ios) on
macOS, but App Intents are the same underlying system that powers a
number of other Apple features such as Spotlight, Siri, Widgets, and
more. We don't do much with these latter ones yet, though.

Additionally, this PR begins to refactor and untangle some of our
libghostty API calls from macOS views. Presently, macOS views and view
controllers directly call into the libghostty API and own libghostty
data models. This tight coupling is kind of nasty because it tends to
also couple libghostty API calls to the main GUI thread when they don't
really have to be (they just have to not be concurrently accessed). This
becomes an issue because App Intents run on background threads. This PR
starts to extract out some of this business logic into standalone
classes, but we still force all execution onto the main thread during
the transition.

**Version requirement:** Most of the shortcuts will work on macOS 13,
but there are some that require macOS 14, and some functionality will
require macOS 26. We gracefully degrade in all scenarios (the
capabilities that are unavailable just don't show up on older systems).

> [!IMPORTANT]
>
> This bumps our build requirements on macOS to Xcode 26 and the macOS
26 SDK. **You can still build on macOS 15,** but you must be using the
Xcode 26 beta. This includes a README update about that.

## Why?

Apple Shortcuts is an extremely powerful scripting tool on Apple
platforms. It comes with a number of built-in capabilities such as
moving windows, taking screenshots, fetching secrets, and more. By
integrating with Apple Shortcuts, it allows Ghostty to become scriptable
to a certain extent while also being able to take advantage of this
large ecosystem.

It is a huge downside that Shortcuts is Apple-only and I still would
like to make Ghostty scriptable to some extent on Linux and other
platforms as well. This work doesn't preclude that goal, but gives us an
answer to a large subset of users (macOS users), which is great.

Beyond this, no terminals integrate with Apple Shortcuts except the
built-in Terminal. And even then, the built-in Terminal only exposes two
actions (run script and run script over SSH). I think there's a lot that
can be done by exposing more functionality and I'm excited to see what
people do with this.

Finally, I think Shortcuts is possibly a way we can do some GUI testing
on macOS. That remains to be explored but it seems promising.

## Capability

The initial set of Shortcut actions is shown in the screenshot below:

![CleanShot 2025-06-20 at 12 19
47@2x](https://github.com/user-attachments/assets/07ac3901-8871-4ee5-a7da-663e0e2a90db)

These can be combined with the built-in shortcuts to do some pretty
interesting things.

### Future

There are more capabilities I'd like to expose, but they require
changing core parts of Ghostty that I didn't want to mix into this PR.

## Security

Scripting Ghostty can be considered a security risk, since it allows
arbitrary command execution, reading terminal output, etc. Therefore,
Ghostty will ask for permission prior to allowing any Shortcut to remote
control it:

<img width="859" alt="image"
src="https://github.com/user-attachments/assets/62344248-9c2c-402d-80f6-3fe3910d23fd"
/>

This can be directly overridden using the new `macos-shortcuts`
configuration, which defaults to `ask` but can also be set to `deny` or
`allow` with self-explanatory behaviors.
2025-06-21 07:07:10 -07:00
Mitchell Hashimoto 296f340ff4
macos: the approval dialog is now forever 2025-06-21 06:53:09 -07:00
Mitchell Hashimoto 020976bf88
macos: address some feedback 2025-06-21 06:42:32 -07:00
Mitchell Hashimoto e4c13cdba8
macos: Optional/Array extensions need to build for iOS too 2025-06-21 06:39:20 -07:00
Mitchell Hashimoto b6559d0899
macos: add a macos-shortcut config 2025-06-21 06:39:20 -07:00
Mitchell Hashimoto 647f29bad1
macos: intents all ask for permission 2025-06-21 06:39:20 -07:00
Mitchell Hashimoto 027171bd5d
macos: can set env vars on new terminal 2025-06-21 06:39:20 -07:00
Mitchell Hashimoto f8bc9b547c
macos: support env vars for surface config, clean up surface config 2025-06-21 06:39:20 -07:00
Mitchell Hashimoto e6c24fbf0a
macos: remove confirmation option for close terminal 2025-06-21 06:39:20 -07:00
Mitchell Hashimoto 2c1e83ba2f
macos: intent to open quick terminal 2025-06-21 06:39:20 -07:00
Mitchell Hashimoto f096675eaf
macos: Close Terminal Intent 2025-06-21 06:39:20 -07:00
Mitchell Hashimoto 0a27aef508
README: note Xcode 26 requirement 2025-06-21 06:39:20 -07:00
Mitchell Hashimoto 2df301e2fb
macos: mouse pos and scroll intents 2025-06-21 06:39:20 -07:00
Mitchell Hashimoto bc134016f7
macos: move mousePos and mousScroll to Ghostty.Surface 2025-06-21 06:39:20 -07:00
Mitchell Hashimoto 4445a9c637
macos: add mouse button intent 2025-06-21 06:39:19 -07:00
Mitchell Hashimoto 71b6e223af
macos: input keyboard event can send modifiers and actions now 2025-06-21 06:39:19 -07:00
Mitchell Hashimoto 93619ad420
macos: Ghostty.Key 2025-06-21 06:39:19 -07:00
Mitchell Hashimoto a6074040e7
macos: input intent 2025-06-21 06:39:19 -07:00
Mitchell Hashimoto c904e86883
macos: invoke keybind intent 2025-06-21 06:39:19 -07:00
Mitchell Hashimoto 14e46d0979
macos: InvokeCommandPaletteIntent and CommandEntity 2025-06-21 06:39:19 -07:00
Mitchell Hashimoto 5259d0fa55
macos: starting to work on new libghostty data models 2025-06-21 06:39:19 -07:00
Mitchell Hashimoto bbb69c8f27
macos: NewTerminalIntent returns Terminal, can split 2025-06-21 06:39:19 -07:00
Mitchell Hashimoto 683b38f62c
macos: can specify parent terminal for new terminal intent 2025-06-21 06:39:19 -07:00
Mitchell Hashimoto b8d4463754
macos: terminal not found should be an error 2025-06-21 06:39:19 -07:00
Mitchell Hashimoto e51a93ee7c
macos: Terminal entity has screen contents deferred 2025-06-21 06:39:19 -07:00
Mitchell Hashimoto 93f0ee2089
macos: GetTerminalDetails intent 2025-06-21 06:39:18 -07:00
Mitchell Hashimoto 2aa731a64e
macos: TerminalEntity 2025-06-21 06:39:18 -07:00
Mitchell Hashimoto 7ae5018fe8
macos: new terminal intent 2025-06-21 06:39:18 -07:00
Mário Victor Ribeiro Silva b249fe0b2c fix: undo poedit formatting 2025-06-20 21:15:03 -03:00
Qwerasd ddf1a5b23d renderer: move drawFrame AutoreleasePool handling to GraphicsAPI
Introduces `drawFrameStart`/`drawFrameEnd` for this purpose.
2025-06-20 16:21:44 -06:00
Qwerasd ab926fc842 naming(GraphicsAPI): repeat -> presentLastTarget 2025-06-20 15:51:48 -06:00
Qwerasd a802108558 renderer: remove unused surface parameter from updateFrame 2025-06-20 15:49:53 -06:00
Qwerasd 8b9e6641f2 style(renderer): explicit result type
In case of future breaking changes to `options`
2025-06-20 15:48:44 -06:00
Qwerasd 3e7d64b5ce style(renderer): explicit empty error set for OpenGL init 2025-06-20 15:45:43 -06:00
Qwerasd ea7a91e2ba style(renderer): explicit error sets 2025-06-20 15:18:41 -06:00
Qwerasd 9d00018f8b renderer: minimize initial size of GPU resources
These will all be resized anyway on the first frame, so there's no point
in preallocating sizes that will be too small.
2025-06-20 15:18:41 -06:00
Qwerasd 2f10caec8f renderer: clarify why SwapChain.defunct is required 2025-06-20 15:18:41 -06:00
Qwerasd 6b7d751007 renderer: make GraphicsAPI.swap_chain_count required 2025-06-20 15:18:41 -06:00
Qwerasd dccbec2283 style(renderer): capture generic consts as decls in returned struct
Out of an abundance of caution, since there have been issues in the past
relating to consts outside of the returned struct.
2025-06-20 15:18:41 -06:00
Qwerasd b9e35c5970 renderer: uncomment resize message handling
We need this to get info about the padding, even if we do derive the
grid and screen size separately.

In the future this should possibly be changed to a message that only
sends the padding info and nothing else.
2025-06-20 15:18:41 -06:00
Qwerasd 8b23e73d20 metal: retain IOSurfaceLayer ourselves instead of relying on the view
If this was Swift code, we'd be using a strong reference, which would
retain the layer for us and release it when the object is deallocated,
but this is Zig land so we have to do that manually.

NOTE: We don't *have* to do this, but it fits much better with Zig idiom
and hopefully avoids potential future footguns. We should do this to any
autoreleased objects that we persist a reference to in a Zig struct.
2025-06-20 15:18:41 -06:00
Qwerasd e8460e80b2 docs: update info about runtime change of `custom-shader`
Also removes incorrect information about OpenGL requirement, since the
minimum required OpenGL is now unconditionally 4.3
2025-06-20 15:18:41 -06:00
Qwerasd 541bb0d4d9 fix window cross-compilation 2025-06-20 15:18:41 -06:00
Qwerasd ea1e507af7 unwrap unnecessary @"" identifiers 2025-06-20 15:18:41 -06:00
Qwerasd 6dc5ae7a00 format (remove empty lines) 2025-06-20 15:18:41 -06:00
Qwerasd ac2eef9aeb renderer: disable multi-buffering for OpenGL
Frames are sequential for OpenGL since the completion handler always
calls `glFinish`, so the extra buffers do nothing but waste memory.
2025-06-20 15:18:41 -06:00
Qwerasd 371d62a82c renderer: big rework, graphics API abstraction layers, unified logic
This commit is very large, representing about a month of work with many
interdependent changes that don't separate cleanly in to atomic commits.

The main change here is unifying the renderer logic to a single generic
renderer, implemented on top of an abstraction layer over OpenGL/Metal.

I'll write a more complete summary of the changes in the description of
the PR.
2025-06-20 15:18:41 -06:00
Qwerasd 521872442a vendor: update glad to OpenGL 4.3 2025-06-20 15:18:41 -06:00
Qwerasd 7cfc906c60 debug: properly set thread names on macOS 2025-06-20 15:18:41 -06:00
Qwerasd 77c050c156 refactor(Metal): make pipeline handling DRYer 2025-06-20 15:18:41 -06:00
Qwerasd f40cd3cae3 chore: improve Metal API definitions a bit 2025-06-20 15:18:41 -06:00
Mitchell Hashimoto f55c77bc81
build: Use correct SDK for iOS Simulator shader build (#7636)
This PR makes the build script use the correct SDK and version flag for
the iOS Simulator.

Without this PR, the terminal fails to initialize on the iOS Simulator:

```
Compiler failed to build request
metal error=Target OS is incompatible: library was not compiled for the simulator
error initializing surface err=error.MetalFailed
```


<details>
<summary>With the PR</summary>


![image](https://github.com/user-attachments/assets/13735334-1321-42d5-8f01-4d5f6a7660ba)
</details>

Fixes #7635.
2025-06-20 14:01:54 -07:00
Zhaofeng Li fda08a6999 build: Use correct SDK for iOS Simulator shader build 2025-06-20 14:02:07 -06:00
Mário Victor Ribeiro Silva b89cb59d79 translation(pt_BR): add missing translation 2025-06-20 10:23:10 -03:00
RME cb991620b9
Apply suggestions from code review
Co-authored-by: Hojin You <dev.hojin@gmail.com>
2025-06-19 13:51:34 +02:00
Mitchell Hashimoto d0e145292e
snap: vendor libgtk4-layer-shell.so (#7623)
vendor libgtk4-layer-shell.so to ensure it's available at runtime
regardless of host system.
2025-06-18 08:38:43 -07:00
Ken VanDine 7d2da23021 snap: vendor libgtk4-layer-shell.so 2025-06-18 10:06:35 -04:00
Mitchell Hashimoto 5a788bfa90
build: use `xcrun --sdk <sdk> metal` for metal paths (#7619)
This wasn't working before but it just requires a restart of the machine
for the changes to take effect. The namespace runners have this prebuilt
so this should work now.

The other workaround was flaky for unknown reasons so I'd prefer to go
back to this.
2025-06-17 16:36:43 -07:00
Mitchell Hashimoto 30a8ba1bf6
macos: disambiguate close tab vs close window for confirmation (#7618)
This fixes an issue where pressing the red close button in a window or
the "x" button on a tab couldn't differentiate and would always close
the tab or close the window (depending on tab counts).

It seems like in both cases, AppKit triggers the `windowShouldClose`
delegate method on the controller, but for the close window case it
triggers this on ALL the windows in the group, not just the one that was
clicked.

I implemented a kind of silly coordinator that debounces
`windowShouldClose` calls over 100ms and uses that to differentiate
between the two cases.
2025-06-17 16:24:46 -07:00
Mitchell Hashimoto 559fd92295
build: use `xcrun --sdk <sdk> metal` for metal paths
This wasn't working before but it just requires a restart of the machine
for the changes to take effect. The namespace runners have this prebuilt
so this should work now.

The other workaround was flaky for unknown reasons so I'd prefer to go
back to this.
2025-06-17 16:23:29 -07:00
Mitchell Hashimoto 51b9fa751a
macos: disambiguate close tab vs close window for confirmation
This fixes an issue where pressing the red close button in a window or
the "x" button on a tab couldn't differentiate and would always close
the tab or close the window (depending on tab counts).

It seems like in both cases, AppKit triggers the `windowShouldClose`
delegate method on the controller, but for the close window case it
triggers this on ALL the windows in the group, not just the one
that was clicked.

I implemented a kind of silly coordinator that debounces
`windowShouldClose` calls over 100ms and uses that to differentiate
between the two cases.
2025-06-17 16:16:14 -07:00
Mitchell Hashimoto 7d01332574
macOS tip regression: Confirm close on window close (#7617)
Fixes #7615

We were incorrectly closing the window without confirmation when there
were no tabs.

This was part of the undo/redo PR.
2025-06-17 15:20:53 -07:00
Mitchell Hashimoto e6c77789d3
macOS: Confirm close on window close
Fixes #7615

We were incorrectly closing the window without confirmation when there
were no tabs.
2025-06-17 15:03:10 -07:00
Mitchell Hashimoto 676d11fd06
ci: build macOS releases with Xcode 26 (#7616)
Resolves #7591

This moves our CI to build macOS on Sequoia (macOS 15) with Xcode 26,
including the new macOS 26 beta SDK. This includes tip releases. Stable
releases continue to use Xcode 15 and the stable SDK, in case we need to
make a release before macOS Tahoe is stable (though, if its late enough
in the cycle, we may even cut a full release with it).

Importantly, this will make our builds on macOS 26 use the new styling.

I've added a new job that ensures we can continue to build with Xcode 16
and the macOS 15 SDK, as well, although I think that might come to an
end when we switch over to an IconComposer-based icon. I'll verify then.
For now, we continue to support both.

I've also removed our `hasLiquidGlass` check, since this will now always
be true for macOS 26 builds.
2025-06-17 14:04:57 -07:00
Mitchell Hashimoto 6d283c012e
ci: build macOS releases with Xcode 26
Resolves #7591

This moves our CI to build macOS on Sequoia (macOS 15) with Xcode 26,
including the new macOS 26 beta SDK.

Importantly, this will make our builds on macOS 26 use the new styling.

I've added a new job that ensures we can continue to build with Xcode 16 and
the macOS 15 SDK, as well, although I think that might come to an end
when we switch over to an IconComposer-based icon. I'll verify then. For
now, we continue to support both.

I've also removed our `hasLiquidGlass` check, since this will now always
be true for macOS 26 builds.
2025-06-17 13:44:13 -07:00
Mitchell Hashimoto f794693bdc
bash: remove dependency on $GHOSTTY_RESOURCES_DIR (#7611)
We were depending on $GHOSTTY_RESOURCES_DIR for two reasons:

1. To locate our script-adjacent bash-preexec.sh script
2. To restrict our script's execution to environments in which
$GHOSTTY_RESOURCES_DIR is available (i.e. Ghostty-only shells)

For (1), we can instead determine our directory using $BASH_SOURCE[0].
This is slightly differently than our previous behavior, where we'd
always load bash-preexec.sh from the $GHOSTTY_RESOURCES_DIR hierarchy,
even if ghostty.bash from source from somewhere else on the file system
... but we never relied on that behavior, even in development.

For (2), there's no harm in source'ing this script outside of Ghostty,
and if that does become a concern, we can restore this condition or use
something more targeted based on those specific cases.

Historically, I believe (2) was in place to enable (1), so addressing
(1) removes the need for (2).

And lastly, none of the other shell integration scripts depend on
$GHOSTTY_RESOURCES_DIR.
2025-06-17 06:48:54 -07:00
Jon Parise b629f3337a bash: remove dependency on $GHOSTTY_RESOURCES_DIR
We were depending on $GHOSTTY_RESOURCES_DIR for two reasons:

1. To locate our script-adjacent bash-preexec.sh script
2. To restrict our script's execution to environments in which
   $GHOSTTY_RESOURCES_DIR is available (i.e. Ghostty-only shells)

For (1), we can instead determine our directory using $BASH_SOURCE[0].
This is slightly differently than our previous behavior, where we'd
always load bash-preexec.sh from the $GHOSTTY_RESOURCES_DIR hierarchy,
even if ghostty.bash from source from somewhere else on the file system
... but we never relied on that behavior, even in development.

For (2), there's no harm in source'ing this script outside of Ghostty,
and if that does become a concern, we can restore this condition or use
something more targeted based on those specific cases.

Historically, I believe (2) was in place to enable (1), so addressing
(1) removes the need for (2).

And lastly, none of the other shell integration scripts depend on
$GHOSTTY_RESOURCES_DIR.
2025-06-16 19:54:27 -04:00
Mitchell Hashimoto d0f116da35
macOS: Basic Read-Only Accessibility Integration (#7601)
This integrates with macOS accessibility APIs to expose Ghostty terminal
structure and content.

This is a very, very bare implementation and the terminal contents
currently reported are the _full screen and scrollback_ which is way too
much for realistic human accessibility use. The target use case for this
PR is to enable automated tooling (namely, AI screen readers). However,
this is all groundwork we'll need to iterate and improve the
accessibility work anyways.

To make this work, I also replatformed some of our hacky C APIs onto a
more robust `ghostty_surface_read_text` API that can now read arbitrary
ranges of the screen into C strings for consumers to use. This will be
useful in more places going forward (hint hint).

## Before

Accessibility tooling can't read anything, Ghostty has no attributes, no
contents, just shows up as a square.

![CleanShot 2025-06-15 at 14 06
55@2x](https://github.com/user-attachments/assets/55eba1b4-6fd4-4d78-9434-5d672f374c67)

## After

A lot of metadata, including the screen contents as text.

![CleanShot 2025-06-15 at 14 07
25@2x](https://github.com/user-attachments/assets/e14cb7df-e4e2-4cc4-a214-004a8459f353)

Also, split hierarchies are navigable:



https://github.com/user-attachments/assets/a7b2ffb7-dbeb-41b2-8705-9c3200812c4d
2025-06-15 15:10:27 -07:00
Mitchell Hashimoto a2b4a2c0e4
macos: complete more ax APIs for terminal accessibility 2025-06-15 14:00:39 -07:00
Mitchell Hashimoto e69c756c89
macos: auto-expire cached screen contents 2025-06-15 13:55:06 -07:00
Mitchell Hashimoto 839d89f2dc
macos: simple cache of screen contents for ax 2025-06-15 13:46:40 -07:00
Mitchell Hashimoto e1ee180172
apprt/embedded: API to read text can get top left/bottom right coords 2025-06-15 13:06:38 -07:00
Mitchell Hashimoto c5f921bb06
apprt/embedded: improve text reading APIs (selection, random points) 2025-06-15 07:59:19 -07:00
Mitchell Hashimoto b46673e631
macos: Tahoe menu item icons, missed the "Ghostty" menu entirely (#7599)
This is a follow up to #7594, I missed an entire menu.
2025-06-15 07:57:11 -07:00
Mitchell Hashimoto be437f5b64
macos: bare minimum terminal ax 2025-06-15 07:56:05 -07:00
Mitchell Hashimoto c90eb2e952
macos: AX for debug warning 2025-06-15 07:56:05 -07:00
Mitchell Hashimoto 4237dad240
macOS: simple SplitView AX
Proper labels, action to move the divider
2025-06-15 07:56:05 -07:00
Mitchell Hashimoto 57c79fa357
macos: Tahoe menu item icons, missed the "Ghostty" menu entirely
This is a follow up to #7594, I missed an entire menu.
2025-06-15 07:48:20 -07:00
Mitchell Hashimoto db28ab4340
macos 15 regression: transparent style shouldn't draw border (#7597)
This fixes a regression from our Tahoe window styling changes on
earlier, stable versions of macOS. We need to set
"titlebarAppearsTransparent" to true in order to hide the bottom border.
2025-06-15 06:57:05 -07:00
Mitchell Hashimoto 7cc7f6cb06 macos 15 regression: transparent style shouldn't draw border
This fixes a regression from our Tahoe window styling changes on
earlier, stable versions of macOS. We need to set 
"titlebarAppearsTransparent" to true in order to hide the bottom
border.
2025-06-15 06:51:11 -07:00
Mitchell Hashimoto 9e45da17d0
macos: menu item symbols for Tahoe (#7594)
This is recommended for macOS Tahoe and all standard menu items now have
associated images. This makes our app look more polished and native for
macOS Tahoe.

On earlier versions of macOS (macOS 15 and earlier), we _do not_ set the
menu item image. Cocoa has supported menu item images for a long time
but it isn't idiomatic to show them in earlier versions, so we only do
this for later macOS versions.

For icon choice, I tried to copy other native macOS apps as much as
possible, mostly from Xcode. It looks like a lot of apps aren't updated
yet. I'm absolutely open to suggestions for better icons but I think
these are a good starting point.

One menu change is I moved "reset font size" above "increase font size"
which better matches other apps (e.g. Terminal.app).


https://github.com/user-attachments/assets/50a68326-221f-454f-9a9c-078878010a63
2025-06-14 19:50:58 -07:00
Mitchell Hashimoto 202020cd7d macos: menu item symbols for Tahoe
This is recommended for macOS Tahoe and all standard menu items now have
associated images. This makes our app look more polished and native for
macOS Tahoe.

For icon choice, I tried to copy other native macOS apps as much as
possible, mostly from Xcode. It looks like a lot of apps aren't updated
yet. I'm absolutely open to suggestions for better icons but I think
these are a good starting point.

One menu change is I moved "reset font size" above "increase font size"
which better matches other apps (e.g. Terminal.app).
2025-06-14 19:44:24 -07:00
Mitchell Hashimoto bfb1daffbe
macos: set toolbar title `isBordered` to avoid glass view (#7593)
This was recommended by the WWDC25 session on AppKit updates. My hack
was not the right approach.
2025-06-14 15:04:49 -07:00
Mitchell Hashimoto c4a978b07a
macos: set toolbar title `isBordered` to avoid glass view
This was recommended by the WWDC25 session on AppKit updates. My hack
was not the right approach.
2025-06-14 13:50:02 -07:00
Kristófer R 2f33eee166
fix comptime if statement 2025-06-14 16:26:03 -04:00
Mitchell Hashimoto 22776adc28
ci: update macOS builders to Sequoia (15) and Xcode 16.4 (#7592)
We have been building on macOS 14 and Xcode 16.0 for a longggg time now.
This gets us to a version that will be running Xcode 26 eventually so we
can ultimately build for Tahoe on a stable OS.

This should change nothing in the interim.
2025-06-14 12:48:31 -07:00
Mitchell Hashimoto 5b9f4acbc8
ci: update macOS builders to Sequoia (15) and Xcode 16.4
We have been building on macOS 14 and Xcode 16.0 for a longggg time now.
This gets us to a version that will be running Xcode 26 eventually so
we can ultimately build for Tahoe on a stable OS.

This should change nothing in the interim.
2025-06-14 12:32:48 -07:00
Mitchell Hashimoto f26dec559a
macOS: Tahoe Titlebar Styling Fixes (#7588)
Fixes #7568 
Fixes #7563 

This PR incorporates all the fixes necessary to make all of our
`macos-titlebar-style` values work on macOS Tahoe.

All titlebar styles are significantly more efficient on macOS Tahoe. I
was able to refactor a lot of our complicated logic out of `update`
ticks (which are called on _every event loop tick_) to being eventful,
so the CPU required to render any titlebar style on Tahoe is
dramatically lowered. This fix _might_ be able to be back ported but I
tried my best to not modify Sequoia and earlier codebases to keep them
stable.

The major change here is `macos-titlebar-style = tabs`, which takes on a
whole new look with Tahoe. The ultimate goal of this setting is that the
_native tab bar_ goes into the titlebar, and we've respected that here.
For more background, see #7563 on why we can't easily mimic the Sequoia
style. I think longer term, for people who don't want capsule-tabs in
their titlebar, we'll need a custom tab bar.

## Future Improvements

There are obviously future improvements that can be made. I think for
example the readability in some cases of the `tabs` styling is pretty
bad. But I wonder if Apple themselves will do something about this with
the tab bar, so I'm going to hold out on caring too much.

The main goal of this PR was to make sure Ghostty was usable when
recompiled with the v26 SDKs.

## Screenshots

> [!NOTE]
>
> Ignore the weird background color glitches in the titlebar. That's a
screenshot artifact (bug probably in macOS) and not actually visible
when running.

### `macos-titlebar-style = tabs`

![CleanShot 2025-06-13 at 12 40
43@2x](https://github.com/user-attachments/assets/8728631e-fd0b-47f3-b195-099a7e0e5b72)
![CleanShot 2025-06-13 at 12 40
34@2x](https://github.com/user-attachments/assets/4c280666-4aba-4ae1-9730-cac96e2c88ed)

### `macos-titlebar-style = transparent`

![CleanShot 2025-06-13 at 12 43
53@2x](https://github.com/user-attachments/assets/1743b109-d4bf-4f37-9d73-2e0a0ba21789)
![CleanShot 2025-06-13 at 12 43
45@2x](https://github.com/user-attachments/assets/8cd884b8-5d13-458d-a204-a0ff81698be4)

### `macos-titlebar-style = native`

![CleanShot 2025-06-13 at 12 45
21@2x](https://github.com/user-attachments/assets/781300dc-2229-4d73-80d5-f75105ba0e38)
![CleanShot 2025-06-13 at 12 45
15@2x](https://github.com/user-attachments/assets/ac71b117-ef5a-46bd-8d13-a95a4cb8f5a3)

## TODO

- [x] A really weird bug where if I resize vertically to create
scrollback then create a new tab my font size is... tiny?
- [x] Verify no major regressions on Sequoia
- [x] Sequoia regression: non-native fullscreen with titlebar tabs
doesn't work
- [x] Sequoia regression: reset split zoom button doesn't restore for
tabs titlebar going to zero tabs
- [x] Sequoia regression: transparent isn't working
- [x] Check macOS 26 gates on Solarium instead of version?
- [ ] Merge all windows doesn't create titlebar tabs on Tahoe
2025-06-14 07:02:12 -07:00
Mitchell Hashimoto 928603c23e
macos: use a runtime liquid glass check for our Tahoe styling 2025-06-13 20:20:56 -07:00
Mitchell Hashimoto 1b6142b271 macos: don't restore tab bar with non-native fs 2025-06-13 15:02:06 -07:00
Mitchell Hashimoto ac4b0dcac0 macos: fix transparent tabs on sequoia 2025-06-13 14:57:54 -07:00
Mitchell Hashimoto 1388c277d5 macos: sequoia should use same tab bar identifier as TerminalWindow 2025-06-13 14:43:04 -07:00
Mitchell Hashimoto 8cfc904c0c macos: fix up some sequoia regressions 2025-06-13 14:39:12 -07:00
Mitchell Hashimoto a7df90ee55
macos: remove split zoom accessory when tabs appear 2025-06-13 13:36:42 -07:00
Mitchell Hashimoto f7f0514b9f
macos: move old toolbar into ventura file 2025-06-13 13:14:16 -07:00
Mitchell Hashimoto 59812c3b02
macos: remove TODO 2025-06-13 12:27:44 -07:00
Mitchell Hashimoto b1b74d3421
comments 2025-06-13 12:25:21 -07:00
Mitchell Hashimoto 00d41239da
macOS: prep the tab bar when system appearance changes 2025-06-13 12:22:29 -07:00
Jeffrey C. Ollie c1d04a6175
gtk: document effect of changing the class on launching Ghostty 2025-06-13 10:22:17 -05:00
Jeffrey C. Ollie e5c737a423
linux: use launched-from for new window action 2025-06-13 10:22:16 -05:00
Jeffrey C. Ollie 57392dfcb5
linux: use explicit launched-from config in service files 2025-06-13 10:22:16 -05:00
Jeffrey C. Ollie 649cca61eb
gtk: use exhaustive switch for initial-window 2025-06-13 10:22:16 -05:00
Jeffrey C. Ollie 8824d11e1c
linux: add dbus and systemd activation services 2025-06-13 10:22:12 -05:00
Mitchell Hashimoto 17ad77b5b0
macos: fix background color of terminal window to match surface 2025-06-12 21:36:00 -07:00
Mitchell Hashimoto 9d9c451b0a
macos: titlebar tabs handle hidden traffic buttons 2025-06-12 20:03:21 -07:00
Mitchell Hashimoto d84c30ce71
macos: titlebar tabs should be transparent 2025-06-12 18:10:37 -07:00
Mitchell Hashimoto 5f99670247
macos: tahoe titlebar tabs taking shape 2025-06-12 17:52:15 -07:00
Mitchell Hashimoto 6ae8bd737a
macos: hide the reset zoom titlebar accessory when tab bar is shown 2025-06-12 15:13:23 -07:00
Mitchell Hashimoto 5c8f1948ce
macos: remove the duplicated reset zoom accessory view from legacy 2025-06-12 14:42:09 -07:00
Mitchell Hashimoto de40e7ce02
macos: non-native fullscreen should restore toolbars 2025-06-12 14:36:33 -07:00
Mitchell Hashimoto 658ec2eb6f
macos: add reset zoom to all window titles 2025-06-12 14:33:53 -07:00
Mitchell Hashimoto 70029bf82a
macos: tahoe terminal tabs shows title 2025-06-12 13:39:19 -07:00
Mitchell Hashimoto 5877913ab8
macoS: Split out terminal tabs for ventura vs tahoe 2025-06-12 12:06:30 -07:00
Mitchell Hashimoto fd785f98bb
macos: titlebar tabs uses legacy window for now 2025-06-12 11:39:10 -07:00
Mitchell Hashimoto ccfd33022f
macos: only titlebar tabs uses legacy styling now 2025-06-11 15:18:02 -07:00
Mitchell Hashimoto e5cb33e911
typos 2025-06-11 15:18:02 -07:00
Mitchell Hashimoto 63e56d0402
macos: titlebar fonts work with new terminal window 2025-06-11 15:18:02 -07:00
Mitchell Hashimoto a804dab288
macos: native terminal style works with new subclasses 2025-06-11 15:18:02 -07:00
Mitchell Hashimoto dfa7a114de
macos: make transparent titlebars robust against show/hide tabs 2025-06-11 15:18:02 -07:00
Mitchell Hashimoto 3595b2a847
macos: transparent titlebar handles transparent background 2025-06-11 15:18:02 -07:00
Mitchell Hashimoto 6ce7f612a6
macos: transparent titlebar needs to be rehidden when tabs change 2025-06-11 15:18:02 -07:00
Mitchell Hashimoto 7d02977482
macos: add NSView hierarchy debugging code 2025-06-11 15:18:02 -07:00
Mitchell Hashimoto 4d33a73fc4
wip: redo terminal window styling 2025-06-11 15:18:02 -07:00
Mitchell Hashimoto c3d65d3975
build(deps): bump softprops/action-gh-release from 2.2.2 to 2.3.2 (#7569)
Bumps
[softprops/action-gh-release](https://github.com/softprops/action-gh-release)
from 2.2.2 to 2.3.2.
<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.2</h2>
<ul>
<li>fix: revert fs <code>readableWebStream</code> change</li>
</ul>
<h2>v2.3.1</h2>
<!-- raw HTML omitted -->
<h2>What's Changed</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>New Contributors</h2>
<ul>
<li><a href="https://github.com/WailGree"><code>@​WailGree</code></a>
made their first contribution in <a
href="https://redirect.github.com/softprops/action-gh-release/pull/629">softprops/action-gh-release#629</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/softprops/action-gh-release/compare/v2.3.0...v2.3.1">https://github.com/softprops/action-gh-release/compare/v2.3.0...v2.3.1</a></p>
<h2>v2.3.0</h2>
<!-- raw HTML omitted -->
<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>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/softprops/action-gh-release/compare/v2.2.2...v2.3.0">https://github.com/softprops/action-gh-release/compare/v2.2.2...v2.3.0</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.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>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="72f2c25fcb"><code>72f2c25</code></a>
release 2.3.2</li>
<li><a
href="552dc5524b"><code>552dc55</code></a>
fix: revert <code>fs:readableWebStream</code> change (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/632">#632</a>)</li>
<li><a
href="f3cad8bcbf"><code>f3cad8b</code></a>
release 2.3.1</li>
<li><a
href="07a2257003"><code>07a2257</code></a>
fix: fix file closing issue (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/629">#629</a>)</li>
<li><a
href="d5382d3e6f"><code>d5382d3</code></a>
release 2.3.0</li>
<li><a
href="a0e2122208"><code>a0e2122</code></a>
feat: migrate from jest to vitest (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/626">#626</a>)</li>
<li><a
href="8836085300"><code>8836085</code></a>
chore: replace <code>mime</code> with <code>mime-types</code> (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/624">#624</a>)</li>
<li><a
href="86463358d8"><code>8646335</code></a>
chore: bump node to 20.19.2</li>
<li><a
href="46b284799f"><code>46b2847</code></a>
chore(deps): bump the npm group across 1 directory with 5 updates (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/623">#623</a>)</li>
<li><a
href="37fd9d0351"><code>37fd9d0</code></a>
chore(deps): bump undici from 5.28.5 to 5.29.0 (<a
href="https://redirect.github.com/softprops/action-gh-release/issues/621">#621</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/softprops/action-gh-release/compare/v2.2.2...v2.3.2">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.2.2&new-version=2.3.2)](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-06-11 06:54:43 -07:00
Kristófer R 31e386afa6
use else if instead of else { if } 2025-06-10 22:03:33 -04:00
dependabot[bot] 990b6a6b08
build(deps): bump softprops/action-gh-release from 2.2.2 to 2.3.2
Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 2.2.2 to 2.3.2.
- [Release notes](https://github.com/softprops/action-gh-release/releases)
- [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md)
- [Commits](https://github.com/softprops/action-gh-release/compare/v2.2.2...v2.3.2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-11 00:31:07 +00:00
Mitchell Hashimoto 76a3612195
macos: hidden titlebar windows should cascade on new tab (#7567)
Windows with `macos-titlebar-style = hidden` create new windows when the
new tab binding is pressed. This behavior has existed for a long time.

However, these windows did not cascade, meaning they'd appear overlapped
directly on top of the previous window, which is kind of nasty.

This commit changes it so that new windows created via new tab from a
hidden titlebar window will cascade.
2025-06-10 14:38:48 -07:00
Mitchell Hashimoto 3db5b3da75
macos: hidden titlebar windows should cascade on new tab
Windows with `macos-titlebar-style = hidden` create new windows when the
new tab binding is pressed. This behavior has existed for a long time.

However, these windows did not cascade, meaning they'd appear overlapped
directly on top of the previous window, which is kind of nasty.

This commit changes it so that new windows created via new tab from a
hidden titlebar window will cascade.
2025-06-10 14:31:41 -07:00
Mitchell Hashimoto e5f5e19eef
macos: for windowShouldClose, only close the tab if we have multiple (#7566)
Fixes a regression from our undo/redo rework. We were accidentally
closing the entire window when the "X" button in the tab bar was
clicked.
2025-06-10 12:46:47 -07:00
Mitchell Hashimoto 1f340b4b2d
macos: for windowShouldClose, only close the tab if we have multiple
Fixes a regression from our undo/redo rework. We were accidentally
closing the entire window when the "X" button in the tab bar was
clicked.
2025-06-10 12:39:09 -07:00
Mitchell Hashimoto 8b5cceed3e
ci: pin gh-action-release to 2.2.2 to workaround issue
https://github.com/softprops/action-gh-release/issues/628
2025-06-10 12:30:22 -07:00
Mitchell Hashimoto 95a04eebc8
macos: unsplit window shouldn't allow split zooming (#7565)
This was always the case, and is a recent regression from the SplitTree
rework. This brings it back to the previous behavior.
2025-06-10 12:21:58 -07:00
Mitchell Hashimoto 2b9a6a4820
macos: unsplit window shouldn't allow split zooming
This was always the case, and is a recent regression from the SplitTree
rework. This brings it back to the previous behavior.
2025-06-10 12:11:18 -07:00
Mitchell Hashimoto 40340e994c
font/sprite: add corner pieces from Geometric Shapes block (#7562)
Resolves #3344

Adds ◢ ◣ ◤ ◥ ◸ ◹ ◺ ◿

(The outlined versions aren't perfect, if someone actually uses them and
is dissatisfied they can be improved in the future.)

### Before

![image](https://github.com/user-attachments/assets/72ce8f0a-6109-4c89-b4a9-090ebba401b2)
### After

![image](https://github.com/user-attachments/assets/d10f7569-e476-40e8-9e54-a8d75f2453bb)
2025-06-10 11:57:33 -07:00
Mitchell Hashimoto c9e6f8bc8d
license: update copyright notices to include contributors (#7561)
Updates all copyright notices to include "Ghostty contributors" to
reflect the fact that Mitchell is not the sole copyright owner.

Also adds "Ghostty contributors" to the author section in the manpages,
linking https://github.com/ghostty-org/ghostty/graphs/contributors for
proper credit.

This change was discussed in the Discord.
2025-06-10 11:35:54 -07:00
Qwerasd 12ad0fa4b6 font/sprite: add corner pieces from Geometric Shapes block
◢ ◣ ◤ ◥ ◸ ◹ ◺ ◿
2025-06-10 12:18:56 -06:00
Qwerasd 3d692e46f4 license: update copyright notices to include contributors
Updates all copyright notices to include "Ghostty contributors" to
reflect the fact that Mitchell is not the sole copyright owner.

Also adds "Ghostty contributors" to the author section in the manpages,
linking https://github.com/ghostty-org/ghostty/graphs/contributors for
proper credit.
2025-06-10 10:20:26 -06:00
Mitchell Hashimoto ad4facf8f1
build: Xcode 26, macOS Tahoe support (build tooling only) (#7559)
This updates our build script and CI to support Xcode 26 and macOS
Tahoe. **This doesn't update the Ghostty app to resolve any Tahoe
issues.**

For CI, we've added a new build job that runs on macOS Tahoe with Xcode
26. I've stopped short of updating our tip release job, since I think I
want to wait until I verify a bit more about Tahoe before we flip that
bit. Also, ideally, we'd run Xcode 26 on Sequoia (macOS 15) for
stability reasons and Namespace doesn't have Xcode 26 on 15 yet.

For builds, this updates our build script to find Metal binaries using
`xcodebuild -find-executable` instead of `xcrun`. The latter doesn't
work with Xcode 26, but the former does and also still works with older
Xcodes. I'm not sure if this is a bug but I did report it: FB17874042.
2025-06-10 07:22:28 -07:00
Mitchell Hashimoto b0e0aadaf3
build: Xcode 26, macOS Tahoe support (build tooling only)
This updates our build script and CI to support Xcode 26 and macOS
Tahoe. **This doesn't update the Ghostty app to resolve any Tahoe
issues.**

For CI, we've added a new build job that runs on macOS Tahoe with Xcode
26. I've stopped short of updating our tip release job, since I think I
want to wait until I verify a bit more about Tahoe before we flip that
bit. Also, ideally, we'd run Xcode 26 on Sequoia (macOS 15) for
stability reasons and Namespace doesn't have Xcode 26 on 15 yet.

For builds, this updates our build script to find Metal binaries using
`xcodebuild -find-executable` instead of `xcrun`. The latter doesn't
work with Xcode 26, but the former does and also still works with older
Xcodes. I'm not sure if this is a bug but I did report it: FB17874042.
2025-06-10 07:10:40 -07:00
Mitchell Hashimoto 57cd5ef085
feat: implement mode 1048 for saving/restoring cursor position (#7553)
Implements mode 1048 for saving/restoring cursor position.

This is the same as mode 1049 but only saves cursor position without
touching the alternate screen.

**save/restore cursor position:**
- `ESC[?1048h` - save cursor position  
- `ESC[?1048l` - restore cursor position

**Quick test:**
```bash
printf '\e[5;10H[SAVED HERE]'
printf '\e[?1048h'                # save position
printf '\e[15;1HMoved somewhere else...'
printf '\e[?1048l'                # restore 
printf ' RESTORED!'           # should appear next to [SAVED HERE]
```

Fixes #7473
2025-06-09 07:14:59 -07:00
Mitchell Hashimoto 5e77bd6e9b
termio: unconditionally show "process exited" message (#7556)
We previously only showed this message if the user had
`wait-after-command` set to true, since if its false the surface would
close anyways.

With the latest undo feature on macOS, this is no longer the case; a
exited process can be undone and reopened. I considered disallowing
undoing an exited surface, but I think there is value in being able to
go back and recapture output in scrollback if you wanted to.
2025-06-09 06:57:59 -07:00
Alex Straight 59bc980250 feat: implement mode 1048 for saving/restoring cursor position 2025-06-09 06:55:38 -07:00
Mitchell Hashimoto a87c68d49a
termio: unconditionally show "process exited" message
We previously only showed this message if the user had
`wait-after-command` set to true, since if its false the surface would
close anyways.

With the latest undo feature on macOS, this is no longer the case; a
exited process can be undone and reopened. I considered disallowing
undoing an exited surface, but I think there is value in being able to
go back and recapture output in scrollback if you wanted to.
2025-06-09 06:51:17 -07:00
Mitchell Hashimoto e25708fc43
macos: add id to SplitTreeView to detect tree structural changes (#7547)
Fixes #7546

The comments explain what was going on here.
2025-06-08 20:18:12 -07:00
Mitchell Hashimoto e4cd90b8a0
macos: set explicit identity for split tree view based on structure
Fixes #7546

SwiftUI uses type and structure to identify views, which can lead
to issues with tree like structures where the shape and type is the same
but the content changes. This was causing #7546.

To fix this, we need to add explicit identity to the split tree view
so that SwiftUI can differentiate when it needs to redraw the view.

We don't want to blindly add Hashable to SplitTree because we don't want
to take into account all the fields. Instead, we add an explicit
"structural identity" to the SplitTreeView that can be used by SwiftUI.
2025-06-08 20:11:58 -07:00
Mitchell Hashimoto 804d270ba1
macOS: Undo/Redo for changes to windows, tabs, and splits (#7535)
This PR implements the ability to undo/redo new and closed windows,
tabs, and splits.

## Demo


https://github.com/user-attachments/assets/98601810-71b8-4adb-bfa4-bdfaa2526dc6

## Details

### Undo Timeout

Running terminal sessions _remain running_ for a configurable period of
time after close, during which time they're undoable. This is similar to
"email unsend" (since email in the traditional sense can't be unsent,
clients simply hold onto it for a period of time before sending).

This behavior is not unique to Ghostty. The first and only place I've
seen it is in iTerm2. And iTerm2 behaves similarly, although details of
our behavior and our implementation vary greatly.

The configurable period of time is done via the `undo-timeout`
configuration. The default value is 5 seconds. This feels reasonable to
be and is grounded in being the default for iTerm2 as well, so it's
probably a safe choice.

Undo can be disabled by setting `undo-timeout = 0`. 

### Future

The actions that can be potentially undone/redone can be easily expanded
in the future. Some thoughts on things that make sense to me:

- Any sort of split resizing, including equalization
- Moving tabs or splits

#### What about Linux?

I'd love to support this on Linux. I don't think any other terminal on
Linux has this kind of feature (definitely might be wrong, but I've
never seen it and I've looked at a lot of terminal emulators 😄 ). But
there's some work to be done to get there.

## TODO for the Draft PR

This is still a draft. There are some items remaining (list will update
as I go):

- [x] Undoing a closed window is sometimes buggy still and I'm not sure
why, I have to dig into this.
- [x] New window should be undoable
- [x] New tab should be undoable
- [x] Close All Windows should be undoable
- [x] I think I have to get rid of TerminalManager. Undone windows won't
be in TerminalManager's list of controllers and I think that's going to
break a lot of things.
- [x] I haven't tested this with QuickTerminal at all. I expect bugs
there but I want undo to work with splits there.
- [x] Close window with the red traffic light button doesn't trigger
undo
- [x] Closing window with multiple tabs undoes them as separate windows
2025-06-08 12:54:55 -07:00
Mitchell Hashimoto 6e85c2970b
Update iTerm2 colorschemes (#7545)
Upstream revision:
10f216f54a
2025-06-08 12:42:14 -07:00
Mitchell Hashimoto 26e1dd8f8e
macos: clear out the surface trees to prevent repeat undo
see the comment
2025-06-08 12:41:45 -07:00
Mitchell Hashimoto 3de3f48faf
macos: fix undo/redo for closing windows with multiple tabs
When closing a window that contains multiple tabs, the undo operation
now properly restores all tabs as a single tabbed window rather than
just restoring the active tab.

The implementation:
- Collects undo states from all windows in the tab group before closing
- Sorts them by their original tab index to preserve order
- Clears tab group references to avoid referencing garbage collected objects
- Restores all windows and re-adds them as tabs to the first window
- Tracks and restores which tab was focused (or focuses the last tab if none were)

AI prompts that generated this commit are below.

Each separate prompt is separated by a blank line, so this session was
made up with many prompts in a back-and-forth conversation.

> We need to update the undo/redo implementation in
> @macos/Sources/Features/Terminal/TerminalController.swift `closeWindowImmediately`
> to handle the case that multiple windows in a tab group are closed all at once,
> and to restore them as a tabbed window. To do this, I think we should collect
> all the `undoStates`, sort them by `tabIndex` (null at the end), and then on j
> restore, restore them one at a time but add them back to the same tabGroup. We
> can't use the tab group in the `undoState` because it will be garbage collected
> by then. To be sure, we should just set it to nil.

I should note at this point that the feature already worked, but the
code quality and organization wasn't up to my standards. If someone
using AI were just trying to make something work, they might be done at
this point.

I do think this is the biggest gap I worry about with AI-assisted
development: bridging between the "it works" stage at a junior quality
and the "it works and is maintainable" stage at a senior quality. I
suspect this will be a balance of LLMs getting better but also senior
code reviewers remaining highly involved in the process.

> Let's extract all the work you just did into a dedicated private method
> called `registerUndoForCloseWindow`

Manual: made some tweaks to comments, moved some lines around, didn’t change
any logic.

> I think we can pull the tabIndex directly from the undoState instead of
> storing it in a tuple.

> Instead of `var undoStates`, I think we can create a `let undoStates` and
> build and filter and sort them all in a chain of functional mappings.

> Okay, looking at your logic for restoration, the `var firstController` and
> conditionals are littly messy. Can you make your own pass at cleaning those
> up and I'll review and provide more specific guidance after.

> Excellent. Perfect. The last thing we're missing is restoring the proper
> focused window of the tab group. We should store that and make sure the
> proper window is made key. If no windows were key, then we should make the
> last one key.

> Excellent. Any more cleanups or comments you'd recommend in the places you
> changed?

Notes on the last one: it gave me a bunch of suggestions, I rejected most but
did accept some.

> Can you write me a commit message summarizing the changes?

It wrote me a part of the commit message you're reading now, but I
always manually tweak the commit message and add my own flair.
2025-06-08 08:08:01 -07:00
Mitchell Hashimoto ec043e1386
macos: red traffic light should be undoable 2025-06-08 07:00:51 -07:00
Kristófer R 6ed94b0034
move mac address length constant to file-level scope 2025-06-07 22:17:01 -04:00
Kristófer R 73e5f7e5d6
merge std.Uri.ParseError and os/hostname error sets 2025-06-07 22:12:26 -04:00
Kristófer R e4a175d24a
use explicit error set 2025-06-07 22:07:18 -04:00
Kristófer R 7760389ab8
add comptime check for platform
we only need the mac-address-as-hostname workaround on macos, so we
now have a comptime check to see if we're on macos.
2025-06-07 22:07:18 -04:00
Kristófer R 68f48b9911
name the 17 magic constant `mac_address_length` 2025-06-07 22:07:18 -04:00
Kristófer R dfdb588f58
add tests for hostnames without a path component 2025-06-07 22:07:18 -04:00
Kristófer R a24d0c9faf
re-order end-of-hostname validity check 2025-06-07 22:07:18 -04:00
Kristófer R bb07e9c026
don't rely on hard-coded schemes 2025-06-07 22:07:18 -04:00
Kristófer R 7a639a7119
use iterator syntax in for loop 2025-06-07 22:07:18 -04:00
Kristófer R e0655a7f75
Move url parsing helper to os/hostname
Also adds a test to verify that the function is working as intended.
2025-06-07 22:07:18 -04:00
Kristófer R ffe7f0d8bf
extract url parsing into its own function 2025-06-07 22:07:18 -04:00
Kristófer R 64bfaf23f9
take kitty-shell-cwd scheme into account 2025-06-07 22:07:17 -04:00
Kristófer R b66368b4d6
extract mac address validity check to function 2025-06-07 22:07:17 -04:00
Kristófer R 19ca1bfb1c
Fix modulo operation and custom Uri struct init 2025-06-07 22:07:17 -04:00
Kristófer R 0e74b8027a
pwd: fix hostname resolution on macos
When macOS's "Private WiFi address" feature is enabled it'll change the
hostname to a mac address. Mac addresses look like URIs with a hostname
and port component, e.g. 12:34:56:78:90:12 where `:12` looks like port
12. However, mac addresses can also contain letters a through f, so a
valid mac address like ab💿ef🆎cd:ef is valid, but will not be parsed
as a URI, because `:ef` is not a valid port.

This commit attempts to fix that by checking if the hostname is a valid
mac address when `std.Uri.parse()` fails and constructing a new std.Uri
struct using that information.

It's not perfect, but is equally compliant with the URI spec as std.Uri
currently is.
2025-06-07 22:07:17 -04:00
mitchellh 3b33813071 deps: Update iTerm2 color schemes 2025-06-08 00:14:39 +00:00
Mitchell Hashimoto e986beb6a7
input: parse binds containing equal signs correctly (#7544)
Since the W3C rewrite we're able to specify codepoints like `+` directly
in the config format who otherwise have special meanings. Turns out we
forgot to do the same for `=`.
2025-06-07 16:30:01 -07:00
Leah Amelia Chen ba15da4722
input: parse binds containing equal signs correctly
Since the W3C rewrite we're able to specify codepoints like `+` directly
in the config format who otherwise have special meanings. Turns out we
forgot to do the same for `=`.
2025-06-08 01:12:17 +02:00
Leah Amelia Chen 990d1cdf37
gtk/CommandPalette: prevent leaks on initialization (#7541)
* Deallocate the builder after use
* Don't hold a reference to `Command` after appending to `GListStore`
2025-06-07 23:15:16 +02:00
Mitchell Hashimoto 6f6d493763
macos: show quick terminal on undo/redo 2025-06-07 13:14:21 -07:00
Mitchell Hashimoto 6e77a5a6ca
macos: address quick terminal basic functionality with new API 2025-06-07 13:07:31 -07:00
Mitchell Hashimoto 537b5101c6
os/flatpak: fix resource leaks in FlatpakHostCommand (#7542)
This PR solves a few resource leaks in `FlatpakHostCommand`:

- Threads created by `FlatpakHostCommand.spawn` are now detached,
allowing its resources to be released.
- Errors created by various `glib`/`gio` APIs are now freed after use.
2025-06-07 12:57:34 -07:00
Mitchell Hashimoto 20744f0482
macos: fix some CI build issues 2025-06-07 12:46:15 -07:00
Mitchell Hashimoto 973a2afdde
macos: make sure we're not registering unnecessary undos 2025-06-07 12:46:15 -07:00
Mitchell Hashimoto b234cb2014
macos: only process reopen if already activated 2025-06-07 12:46:15 -07:00
Mitchell Hashimoto 396e53244d
config: add super+shift+t as a default undo too to mimic browsers 2025-06-07 12:46:15 -07:00
Mitchell Hashimoto aeede903f5
macos: undo close all windows 2025-06-07 12:46:15 -07:00
Mitchell Hashimoto d92db73f25
macos: undo new tab 2025-06-07 12:46:15 -07:00
Mitchell Hashimoto 636b1fff8a
macos: initial window shouldn't support undo 2025-06-07 12:46:15 -07:00
Mitchell Hashimoto 797c10af37
macos: undo new window 2025-06-07 12:46:15 -07:00
Mitchell Hashimoto 33d128bcff
macos: remove TerminalManager
All logic related to TerminalController is now in TerminalController.
2025-06-07 12:46:15 -07:00
Mitchell Hashimoto 3b77a16b63
Make undo/redo app-targeted so it works with no windows 2025-06-07 12:46:15 -07:00
Mitchell Hashimoto 5507ec0fc0
macos: compile errors in CI 2025-06-07 12:46:15 -07:00
Mitchell Hashimoto 966c4f98c7
apprt/glfw,gtk: noop undo/redo actions 2025-06-07 12:46:14 -07:00
Mitchell Hashimoto d2d3852026
macos: remove debug log 2025-06-07 12:46:14 -07:00
Mitchell Hashimoto 49cc88f0d3
macos: configurable undo timeout 2025-06-07 12:46:14 -07:00
Mitchell Hashimoto 3e02c0cbd5
macos: fix an incorrect bindable write during view update 2025-06-07 12:46:14 -07:00
Mitchell Hashimoto b044f4864a
add undo/redo keybindings, default them on macOS 2025-06-07 12:46:14 -07:00
Mitchell Hashimoto e1847da139
macos: more robust undo tab that goes back to the same position 2025-06-07 12:46:14 -07:00
Mitchell Hashimoto 5f74445b14
macos: basic undo tab, not quite working 2025-06-07 12:46:14 -07:00
Mitchell Hashimoto 104cc2adfe
macos: basic undo close window, not very robust yet 2025-06-07 12:46:14 -07:00
Mitchell Hashimoto f571519157
macos: setup undo responders at the AppDelegate level 2025-06-07 12:46:14 -07:00
Mitchell Hashimoto 6d32b01c64
macos: implement a custom ExpiringUndoManager, setup undo for new/close 2025-06-07 12:46:14 -07:00
Mitchell Hashimoto 493b1f5350
wip: undo 2025-06-07 12:46:13 -07:00
Mitchell Hashimoto e70a4682ac
macos: quick terminal restores previous size when exiting final surface (#7543)
This fixes a regression from the new split work last week, but it was
also probably an issue before that in a slightly different way.

With the new split work, the quick terminal was becoming unusable when
the final surface explicitly `exit`-ed, because AppKit/SwiftUI would
resize the window to a very small size and you couldn't see the new
terminal on the next toggle.

Prior to this, I think the quick terminal would've reverted to its
original size but I'm not sure (even if the user resized it manually).

This commit saves the size of the quick terminal at the point all
surfaces are exited and restores it when the quick terminal is shown the
next time with a new initial surface.
2025-06-07 12:46:04 -07:00
Mitchell Hashimoto 41ee578b7a
macos: quick terminal restores previous size when exiting final surface
This fixes a regression from the new split work last week, but it was
also probably an issue before that in a slightly different way.

With the new split work, the quick terminal was becoming unusable when
the final surface explicitly `exit`-ed, because AppKit/SwiftUI would
resize the window to a very small size and you couldn't see the new
terminal on the next toggle.

Prior to this, I think the quick terminal would've reverted to its
original size but I'm not sure (even if the user resized it manually).

This commit saves the size of the quick terminal at the point all
surfaces are exited and restores it when the quick terminal is shown the
next time with a new initial surface.
2025-06-07 12:37:44 -07:00
Leorize 53c2874667
flatpak: free GError after use 2025-06-07 14:34:55 -05:00
Leorize 42bafe9d59
flatpak: detach process tracking thread after spawn
This makes sure the underlying thread implementation know to free
resources the moment the thread is no longer necessary, preventing leaks
from not manually collecting the thread.
2025-06-07 14:34:39 -05:00
Leorize ea0766e62b
gtk/CommandPalette: prevent leaks on initialization
* Deallocate the builder after use
* Don't hold a reference to `Command` after appending to `GListStore`
2025-06-07 12:00:51 -05:00
Mitchell Hashimoto 1c7623db81
terminal: fix crash when reflowing grapheme with a spacer head (#7537)
Fixes #7536

When we're reflowing a row and we need to insert a spacer head, we must
move to the next row to insert it. Previously, we were setting a spacer
head and then copying data into that spacer head, which could lead to
corrupt data and an eventual crash.

In debug builds this triggers assertion failures but in release builds
this would lead to silent corruption and a crash later on.

The unit test shows the issue clearly but effectively you need a
multi-codepoint grapheme such as `👨‍👨‍👦‍👦` to wrap across a row by
changing the columns.
2025-06-07 06:53:01 -07:00
Mitchell Hashimoto aab00da242
terminal: fix crash when reflowing grapheme with a spacer head
Fixes #7536

When we're reflowing a row and we need to insert a spacer head, we must
move to the next row to insert it. Previously, we were setting a spacer
head and then copying data into that spacer head, which could lead to
corrupt data and an eventual crash.

In debug builds this triggers assertion failures but in release builds
this would lead to silent corruption and a crash later on.

The unit test shows the issue clearly but effectively you need a
multi-codepoint grapheme such as `👨‍👨‍👦‍👦` to wrap across a row by changing
the columns.
2025-06-06 20:37:12 -07:00
Mitchell Hashimoto 269d29624b
Add bell feature flags for audio, attention, and title actions on macOS (#7533)
Resolve #7526
2025-06-06 12:59:23 -07:00
Aaron Ruan 5f6a15abef
Add bell feature flags for audio, attention, and title actions on macOS
Signed-off-by: Aaron Ruan <i@ar212.com>
2025-06-06 23:54:34 +08:00
Mitchell Hashimoto 5b68e49847
macos: dismiss notifications on focus, application exit (#7531)
I've only recently been using programs that use user notifications
heavily and this commit addresses a number of annoyances I've
encountered.

1. Notifications dispatched while the source terminal surface is focused
are now only shown for a short time (3 seconds hardcoded) and then
automatically dismiss.

2. Notifications are dismissed when the target surface becomes focused
from an unfocused state. This dismissal happens immediately (no delay).

  3. Notifications are dismissed when the application exits.

  4. This fixes a bug where notification callbacks were modifying view
     state, but the notification center doesn't guarantee that the
     callback is called on the main thread. We now ensure that
     the callback is always called on the main thread.
2025-06-06 07:36:30 -07:00
Mitchell Hashimoto 70f030e3c2
macos: dismiss notifications on focus, application exit
I've only recently been using programs that use user notifications heavily
and this commit addresses a number of annoyances I've encountered.

  1. Notifications dispatched while the source terminal surface is
     focused are now only shown for a short time (3 seconds hardcoded)
     and then automatically dismiss.

  2. Notifications are dismissed when the target surface becomes focused
     from an unfocused state. This dismissal happens immediately (no
     delay).

  3. Notifications are dismissed when the application exits.

  4. This fixes a bug where notification callbacks were modifying view
     state, but the notification center doesn't guarantee that the
     callback is called on the main thread. We now ensure that
     the callback is always called on the main thread.
2025-06-06 07:28:32 -07:00
Mitchell Hashimoto 08101b0bc5
macos: fix hasWindowButtons logic (#7504 follow-up) (#7528)
Took another look through #7504 after the merge and realized that the
logic behind the `hasWindowButtons` property wasn't quite sound. It
would return `false` if either _at least one_ button were missing in the
`standardWindowButton(.theButton) == nil` sense, or if _all_ buttons
were hidden in the `isHidden` sense.

With this PR, the logic is rectified: `false` if _all_ buttons are
missing or hidden in any sense, otherwise `true`.

In practice, I suppose Ghostty won't ever instantiate a `TerminalWindow`
where `standardWindowButton(.theButton) == nil`, but might as well get
it right and sleep better at night.
2025-06-05 14:11:10 -07:00
Mitchell Hashimoto 2fae2eb568
macos: split directional navigation should use distance to leaf (#7527)
Fixes regression from #7523

I messed two things up around spatial navigation in the split tree that
this commit fixes:

1. The distance in the spatial tree only used a single dimension that we
were navigating. This commit now uses 2D euclidean distance from the
top-left corners of nodes. This handles the case where the nodes are
directly above or below each other better.

2. The spatial slots include split containers because they are layout
elements. But we should only navigate to leaf nodes. This was causing
the wrong navigatin to happen in some scenarios.
2025-06-05 13:54:53 -07:00
Daniel Wennberg c2c267439b macos: fix hasWindowButtons logic 2025-06-05 13:48:53 -07:00
Mitchell Hashimoto 045c84acb7
macos: split directional navigation should use distance to leaf
Fixes regression from #7523

I messed two things up around spatial navigation in the split tree
that this commit fixes:

  1. The distance in the spatial tree only used a single dimension
     that we were navigating. This commit now uses 2D euclidean
     distance from the top-left corners of nodes. This handles the case
     where the nodes are directly above or below each other better.

  2. The spatial slots include split containers because they are layout
     elements. But we should only navigate to leaf nodes. This was
     causing the wrong navigatin to happen in some scenarios.
2025-06-05 13:43:07 -07:00
Mitchell Hashimoto efc1ceab5d
macOS: New value-based split tree implementation, move split logic out of SwiftUI into AppKit (#7523)
This is a major rework of how we represent, handle, and render splits in
the macOS app.

This new PR moves the split structure into a dedicated, generic
(non-Ghostty-specific) value-type called `SplitTree<V>`. All logic
associated with splits (new split, close split, move split, etc.) is now
handled by notifications on `BaseTerminalController`. The view hierarchy
is still SwiftUI but it has no logic associated with it anymore and
purely renders a static tree of splits.

Previously, the split hierarchy was owned by AppKit in a type called
`SplitNode` (a recursive class that contained the tree structure). All
logic around creating, zooming, etc. splits was handled by notification
listeners directly within the SwiftUI hierarchy. SwiftUI managed a
significant amount of state and we heavily used bindings, publishers,
and more. The reasoning for this is mostly historical: splits date back
to when Ghostty tried to go all-in on SwiftUI. Since then, we've taken a
more balanced approach of SwiftUI for views and AppKit for data and
business logic, and this has proven a lot more maintainable.

## Spatial Navigation

Previously, focus moving was handled by traversing the tree structure.
This led to some awkward behaviors. See:
https://github.com/ghostty-org/ghostty/issues/524#issuecomment-2668396095

In this PR, we now handle focus moving spatially. This means that move
"left" means moving to the visually left split (from the top-left
corner, a future improvement would be to do it from the cursor
position).

Concretely, given the following split structure:

```
+----------+-----+
|          |  b  |
|          |     |
|   a      +-----+
|          |     |
|          |     |
|          |     |
|          |     |
|----------|  d  |
|   c      |     |
|          |     |
+----------+-----+
```

Moving "right" from `c` now moves to `d`. Previously, it would go to
`b`. On Linux, it still goes to `b`.

## Value Types

One of the major architectural shifts is moving **purely to immutable
value types.** Whenever a split property changes such as a new split,
the ratio between splits, zoomed state, etc. we _create an entirely new
`SplitTree` value_ and replace it along the entire view hierarchy. This
is in some ways wasteful, but split hierarchies are relatively small
(even the largest I've seen in practical use are dozens of splits, which
is small for a computer). And using value types lets us get rid of a ton
of change notification soup around the SwiftUI hierarchy. We can rely on
reference counting to properly clean up our closed views.

> [!NOTE]
> 
> As an aside, I think value types are going to make it a lot easier in
the future to implement features like "undo close." We can just keep a
trailing list of surface tree states and just restore them. This PR
doesn't do anything like that, but it's now possible.

## SwiftUI Simplicity

Our SwiftUI view hierarchy is dramatically simplified. See the
difference in `TerminalSplitTreeView` (new) vs `TerminalSplit` (old).
There's so much less logic in our new views (almost none!). All of it is
in the AppKit layer which is just way nicer.

## AI Notes

This PR was heavily written by AI. I reviewed every line of code that
was rewritten, and I did manually rewrite at every step of the way in
minor ways. But it was very much written in concert. Each commit usually
started as an AI agent writing the whole commit, then nudging to get
cleaned up in the right way.

One thing I found in this task was that until the last commit, I kept
the entire previous implementation around and compiling. The agent
having access to a previous working version of code during a refactor
made the code it produced as follow up in the new architecture
significantly better, despite the new architecture having major
fundamental differences in how it works!
2025-06-05 12:59:43 -07:00
Mitchell Hashimoto a2a3863ad2
macOS: Add option to hide window buttons (#7504)
Conversion of #7497 to a PR. This implements a feature requested in
#7331: an option to hide the default window buttons on macOS for a
cleaner aesthetic.

~~Builds on #7502 as it requires the same change to avoid the main
toolbar title showing on top of the tab bar.~~ EDIT: rebased on main now
that #7502 was merged.

I aligned the scope of the new option with `macos-titlebar-style`, since
they both customize titlebar elements. This means it has the same edge
case quirks: For example, if you change the setting, reload the config,
and then open a new tab, the appearance of the current window will
depend on which tab is in the foreground. I did it this way because
`macos-titlebar-style` provided an easy template for which derived
configs and functions to modify. Let me know if you want me to try
adjusting this so that a change in the setting also takes effect for
current windows/tabs, which I _think_ should be possible.

Screenshots:
* `macos-titlebar-style = transparent` (default)
![Screenshot 2025-06-01 at 18 04
56](https://github.com/user-attachments/assets/01fa3953-d2ef-4c39-a6e3-f236488dd841)
![Screenshot 2025-06-01 at 18 07
24](https://github.com/user-attachments/assets/cd463ded-a0b2-4f69-9abe-384e7eecaa27)
* `macos-titlebar-style = tabs`
![Screenshot 2025-06-01 at 17 56
35](https://github.com/user-attachments/assets/bf99d046-cdbb-4e5d-b1c5-d51bbba79007)
![Screenshot 2025-06-01 at 17 56
48](https://github.com/user-attachments/assets/098164b8-bf97-4df1-9dff-c1c17e12665d)
2025-06-05 07:46:57 -07:00
Mitchell Hashimoto 6db455eee5
fix: exit non-native fullscreen on close (#7525)
Fixes https://github.com/ghostty-org/ghostty/discussions/7159.
2025-06-05 07:36:50 -07:00
Mitchell Hashimoto 5edf0dffda
gtk/TabView: do not closeTab within close-page signal handler (#7515)
`TabView` assumes to be the sole owner of all `Tab`s within a Window. As
such, it could close the managed `Window` once all tabs are removed from
its widget.

However, during `AdwTabView::close-page` signal triggered by libadwaita,
the `Tab` to be closed will gain an another reference for the duration
of the signal, breaking `TabView.closeTab` (called via
`Tab.closeWithConfirmation`) assumptions that having no tabs meant they
are all destroyed.

This commit solves the issue by scheduling `Tab.closeWithConfirmation`
to be run after `AdwTabView::close-page` signal has finished processing.

Fixes #7426
2025-06-05 07:36:10 -07:00
Mitchell Hashimoto d4249679e3
macos: simplify some ServiceProvider code (#7508)
First, remove the always-inlined openTerminalFromPasteboard code and
combine it with openTerminal. Now that we're doing a bit of work inside
openTerminal, there's little better to having an intermediate, inlined
function.

Second, combine some type-casting operations (saving a .map() call).

Lastly, adjust some variable names because a generic `objs` or `urls`
was a little ambiguous now that we're all in one function scope.
2025-06-05 07:30:03 -07:00
Mitchell Hashimoto 2e0a23aa77
gtk: make requesting attention configurable (#7521)
Partially fixes #7520
2025-06-05 07:29:17 -07:00
Francisco Giordano 9008e21637 fix: exit non-native fullscreen on close 2025-06-05 07:25:53 -07:00
Mitchell Hashimoto c40ac6b785
input: add focus split directional commands to command palette 2025-06-05 07:11:18 -07:00
Mitchell Hashimoto 1966dfdef7
macos: moving some files around 2025-06-05 07:05:13 -07:00
Mitchell Hashimoto f8e3539b7d
macos: remove the unused resizeEvent code from SplitView 2025-06-05 07:05:13 -07:00
Mitchell Hashimoto 01fa87f2ab
macos: fix iOS builds 2025-06-05 07:05:13 -07:00
Mitchell Hashimoto 9474092f77
macos: remove the old split implementation 2025-06-05 07:05:13 -07:00
Mitchell Hashimoto 69c3c359cb
macos: resize split keybind handling 2025-06-05 07:05:13 -07:00
Mitchell Hashimoto 5299f10e13
macos: unzoom on new split and focus change 2025-06-05 07:05:13 -07:00
Mitchell Hashimoto 19a9156ae1
macos: address remaining todos 2025-06-05 07:05:13 -07:00
Mitchell Hashimoto 6c97e4a59a
macos: fix focus after closing splits 2025-06-05 07:05:13 -07:00
Mitchell Hashimoto 77458ef308
macos: rename surfaceTree2 to surfaceTree 2025-06-05 07:05:13 -07:00
Mitchell Hashimoto f1ed07caf4
macos: Remove the legacy SurfaceTree 2025-06-05 07:05:13 -07:00
Mitchell Hashimoto 22819f8a29
macos: transfer doesBorderTop 2025-06-05 07:05:12 -07:00
Mitchell Hashimoto 8b979d6dce
macos: handle surfaceTreeDidChange 2025-06-05 07:05:12 -07:00
Mitchell Hashimoto ea1ff438f8
macos: handle split zooming 2025-06-05 07:05:12 -07:00
Mitchell Hashimoto b7c01b5b4a
macos: spatial focus navigation 2025-06-05 07:05:12 -07:00
Mitchell Hashimoto ec7fd94d0f
macos: equalize splits works with new tree 2025-06-05 07:05:12 -07:00
Mitchell Hashimoto a389926ca7
macos: use surfaceTree2 needsConfirmQuit 2025-06-05 07:05:12 -07:00
Mitchell Hashimoto aef61661a0
macos: fix up command palette, focusing 2025-06-05 07:05:12 -07:00
Mitchell Hashimoto 7dcfebcd5d
macos: isSplit guarding on focus split directions works 2025-06-05 07:05:12 -07:00
Mitchell Hashimoto 0fb58298a7
macos: focus split previous/next 2025-06-05 07:05:11 -07:00
Mitchell Hashimoto b84b715ddb
macos: unify confirm close in our terminal controllers 2025-06-05 07:05:11 -07:00
Mitchell Hashimoto d1dce1e372
macos: restoration for new split tree 2025-06-05 07:05:11 -07:00
Mitchell Hashimoto 33d94521ea
macos: setup sequence for SplitTree 2025-06-05 07:05:11 -07:00
Mitchell Hashimoto 672d276276
macos: confirm close on split close 2025-06-05 07:05:11 -07:00
Mitchell Hashimoto e3bc3422dc
macos: handle split resizing 2025-06-05 07:05:11 -07:00
Mitchell Hashimoto 1707159441
new SplitTree 2025-06-05 07:05:11 -07:00
Leah Amelia Chen 77479feee6
gtk: make requesting attention configurable 2025-06-05 00:29:49 +02:00
Mitchell Hashimoto 722629f9fa
build(deps): bump namespacelabs/nscloud-cache-action from 1.2.7 to 1.2.8 (#7517)
Bumps
[namespacelabs/nscloud-cache-action](https://github.com/namespacelabs/nscloud-cache-action)
from 1.2.7 to 1.2.8.
<details>
<summary>Commits</summary>
<ul>
<li><a
href="449c929cd5"><code>449c929</code></a>
Merge pull request <a
href="https://redirect.github.com/namespacelabs/nscloud-cache-action/issues/20">#20</a>
from namespacelabs/niklas-timeout</li>
<li><a
href="a63596ed5b"><code>a63596e</code></a>
Wrap action with a timeout.</li>
<li>See full diff in <a
href="https://github.com/namespacelabs/nscloud-cache-action/compare/v1.2.7...v1.2.8">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.7&new-version=1.2.8)](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-06-04 09:07:32 -07:00
Mitchell Hashimoto f383d7b550
core: document keybind actions better (#7522)
The current documentation for actions are very sparse and would leave
someone (even including contributors) as to what exactly they do. On top
of that there are many stylistic and grammatical problems that are
simply no longer in line with our current standards, and certainly not
on par with our configuration options reference.

Hence, I've taken it upon myself to add, clarify, supplement, edit and
even rewrite the documentation for most of these actions, in a wider
effort of trying to offer better, clearer documentation for our users.
2025-06-04 09:04:16 -07:00
Leah Amelia Chen 2c8d6ba944
core: document keybind actions better
The current documentation for actions are very sparse and would leave
someone (even including contributors) as to what exactly they do.
On top of that there are many stylistic and grammatical problems that are
simply no longer in line with our current standards, and certainly not
on par with our configuration options reference.

Hence, I've taken it upon myself to add, clarify, supplement, edit and
even rewrite the documentation for most of these actions, in a wider
effort of trying to offer better, clearer documentation for our users.
2025-06-04 17:04:52 +02:00
dependabot[bot] 037d4732a6
build(deps): bump namespacelabs/nscloud-cache-action from 1.2.7 to 1.2.8
Bumps [namespacelabs/nscloud-cache-action](https://github.com/namespacelabs/nscloud-cache-action) from 1.2.7 to 1.2.8.
- [Release notes](https://github.com/namespacelabs/nscloud-cache-action/releases)
- [Commits](https://github.com/namespacelabs/nscloud-cache-action/compare/v1.2.7...v1.2.8)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-04 00:46:01 +00:00
Leorize 4e39144d39
gtk/TabView: do not closeTab within close-page signal handler
`TabView` assumes to be the sole owner of all `Tab`s within a Window.
As such, it could close the managed `Window` once all tabs are removed
from its widget.

However, during `AdwTabView::close-page` signal triggered by libadwaita,
the `Tab` to be closed will gain an another reference for the duration
of the signal, breaking `TabView.closeTab` (called via
`Tab.closeWithConfirmation`) assumptions that having no tabs meant they
are all destroyed.

This commit solves the issue by scheduling `Tab.closeWithConfirmation`
to be run after `AdwTabView::close-page` signal has finished processing.
2025-06-03 03:19:13 -05:00
Leah Amelia Chen 108fab11a5
gtk/GlobalShortcuts: don't request session with no shortcuts (#7510) 2025-06-03 09:22:20 +02:00
Mitchell Hashimoto d993588263
flatpak: rename .Devel variant to .ghostty-debug (#7511)
This is done to match against the default application id when Ghostty is
built using debug configuration, preparing the Flatpak version for D-Bus
activation support (#7433).
2025-06-02 20:09:16 -07:00
Leorize 1183ac8972
flatpak: rename .Devel variant to .ghostty-debug
This is done to match against the default application id when Ghostty is
built using debug configuration, done to prepare the Flatpak version for
D-Bus activation support.
2025-06-02 21:11:58 -05:00
Leorize 58cece07f0
gtk/GlobalShortcuts: don't request session with no shortcuts
There aren't any reason to pay the D-Bus tax if you don't use global
shortcuts.
2025-06-02 20:55:04 -05:00
Jon Parise 652f551bec macos: simplify some ServiceProvider code
First, remove the always-inlined openTerminalFromPasteboard code and
combine it with openTerminal. Now that we're doing a bit of work inside
openTerminal, there's little better to having an intermediate, inlined
function.

Second, combine some type-casting operations (saving a .map() call).

Lastly, adjust some variable names because a generic `objs` or `urls`
was a little ambiguous now that we're all in one function scope.
2025-06-02 20:11:18 -04:00
Mitchell Hashimoto aa6c349545
macos: fix small memory leak in surface tree when closing splits (#7507)
This fixes a small memory leak I found where the `SplitNode.Leaf` was
not being deinitialized properly when closing a split. It would get
deinitialized the next time a split was made or the window was closed,
so the leak wasn't big. The surface view underneath the split was also
properly deinitialized because we forced it, so again, the leak was
quite small.

But conceptually this is a big problem, because when we change the
surface tree we expect the deinit chain to propagate properly through
the whole thing, _including_ to the SurfaceView.

This fixes that by removing the `id(node)` call. I don't find this to be
necessary anymore. I don't know when that happened but we've changed
quite a lot in our split system since it was introduced. I'm also not
100% sure why the `id(node)` was causing a strong reference to begin
with... which bothers me a bit.

AI note: While I manually hunted this down, I started up Claude Code and
Codex in separate tabs to also hunt for the memory leak. They both
failed to find it and offered solutions that didn't work.
2025-06-02 14:50:02 -07:00
Mitchell Hashimoto d1f1be8833
macos: fix small memory leak in surface tree when closing splits
This fixes a small memory leak I found where the `SplitNode.Leaf` was
not being deinitialized properly when closing a split. It would get
deinitialized the next time a split was made or the window was closed,
so the leak wasn't big. The surface view underneath the split was also
properly deinitialized because we forced it, so again, the leak was
quite small.

But conceptually this is a big problem, because when we change the
surface tree we expect the deinit chain to propagate properly through
the whole thing, _including_ to the SurfaceView.

This fixes that by removing the `id(node)` call. I don't find this to be
necessary anymore. I don't know when that happened but we've changed
quite a lot in our split system since it was introduced. I'm also not
100% sure why the `id(node)` was causing a strong reference to begin
with... which bothers me a bit.

AI note: While I manually hunted this down, I started up Claude Code and
Codex in separate tabs to also hunt for the memory leak. They both
failed to find it and offered solutions that didn't work.
2025-06-02 14:12:26 -07:00
Mitchell Hashimoto 957ddd00dd
Follow-up to #7462: `var` -> `let` (#7505)
Just a quick follow-up to #7462: I noticed Swift was admonishing me
about a `var` that could be a `let`, and realized that it was I who had
failed to make that change. Apologies for the noise.
2025-06-02 12:16:41 -07:00
Daniel Wennberg 5244f8d6ac Follow-up to #7462: var -> let 2025-06-02 10:14:52 -07:00
Daniel Wennberg 232a46d2dc Add option to hide macOS traffic lights 2025-06-02 09:22:01 -07:00
Mitchell Hashimoto 3638916819
Enable reset zoom button when `macos-titlebar-style = tabs` and only one tab (#7502)
This is the conversion of #7496 into a PR. The problem was discussed in
#3288: When `macos-titlebar-style = tabs`, the reset zoom button doesn't
appear with only a single tab, i.e., no tab bar.

This fix was simply to remove an unnecessary branch, as the titlebar
style doesn't make any difference for the required logic. If the tab bar
is visible, you should unconditionally hide the titlebar's button and
rely on the per-tab buttons. If the tab bar is not visible, you should
hide or show the titlebar button depending on `surfaceIsZoomed`.

One wrinkle was that the main toolbar title started showing on top of
the tabs. Turns out it was previously not showing only because it would
always be pushed into the hidden overflow menu. With the reset zoom
button present (either hidden or visible, but always there), this no
longer happens reliably, presumably due to some cascading change in the
overflow calculations. In any case, it seems brittle to rely on this way
of concealing the main title, so I added a few lines of code to properly
hide it when the tab bar is visible.

Screenshots:
![Screenshot 2025-06-01 at 15 42
37](https://github.com/user-attachments/assets/893ba88e-a7e0-4d2f-8d08-45af4a2ba11b)
![Screenshot 2025-06-01 at 15 42
51](https://github.com/user-attachments/assets/f45db556-15a9-4655-96df-c41a34a80ec2)
![Screenshot 2025-06-01 at 15 42
58](https://github.com/user-attachments/assets/645cfe42-014c-4259-afd4-489b8ccdb311)
2025-06-02 09:18:09 -07:00
Daniel Wennberg 12a01c0460 Hide main title when covered by tabs 2025-06-02 09:10:22 -07:00
Daniel Wennberg 85beda9c49 Fix reset zoom button visibility in macOS "tabs" mode when no tabs 2025-06-02 09:09:04 -07:00
Mitchell Hashimoto 70a3d9e895
config: add launched-from to specify launch source (#7503)
Related to #7433

This extracts our "launched from desktop" logic into a config option.
The default value is detection using the same logic as before, but now
this can be overridden by the user.

This also adds the systemd and dbus activation sources from #7433.

There are a number of reasons why we decided to do this:

1. It automatically gets us caching since the configuration is only
loaded once (per reload, a rare occurrence).

2. It allows us to override the logic when testing. Previously, we had
to do more complex environment faking to get the same behavior.

3. It forces exhaustive switches in any desktop handling code, which
will make it easier to ensure valid behaviors if we introduce new launch
sources (as we are in #7433).

4. It lowers code complexity since callsites don't need to have N
`launchedFromX()` checks and can use a single value.
2025-06-02 09:07:28 -07:00
Mitchell Hashimoto 5306e7cf56
config: add launched-from to specify launch source
Related to #7433

This extracts our "launched from desktop" logic into a config option.
The default value is detection using the same logic as before, but now
this can be overridden by the user.

This also adds the systemd and dbus activation sources from #7433.

There are a number of reasons why we decided to do this:

  1. It automatically gets us caching since the configuration is only
     loaded once (per reload, a rare occurrence).

  2. It allows us to override the logic when testing. Previously, we
     had to do more complex environment faking to get the same
     behavior.

  3. It forces exhaustive switches in any desktop handling code, which
     will make it easier to ensure valid behaviors if we introduce new
     launch sources (as we are in #7433).

  4. It lowers code complexity since callsites don't need to have N
     `launchedFromX()` checks and can use a single value.
2025-06-02 08:45:02 -07:00
Leah Amelia Chen 1ff9162598
gtk(wayland,x11): refactors (#7485) 2025-05-31 08:17:11 +02:00
Mitchell Hashimoto 7e85ca3a16
gtk: clean up per-surface cgroup on close (#7487)
Fixes #6766

This ensures that during surface deinit the cgroup is removed. By the
time the surface is deinitialized, the subprocess should already be dead
so the cgroup can be safely removed. If the cgroup cannot be removed for
any reason we log a warning.

I'm still investigating whether we also need to remove the transient
cgroup we create per app but that's a lot less noisy since app startup
and shutdown is a lot more rare.
2025-05-30 19:32:32 -07:00
Mitchell Hashimoto 2b9e781933
gtk: clean up per-surface cgroup on close
Fixes #6766

This ensures that during surface deinit the cgroup is removed. By the
time the surface is deinitialized, the subprocess should already be
dead so the cgroup can be safely removed. If the cgroup cannot be
removed for any reason we log a warning.
2025-05-30 19:31:04 -07:00
Mitchell Hashimoto 84aa359984
font: rework coretext discovery sorting (#7483)
This should make the sorting more robust to fonts with questionable
metadata or atypical style names.

I was originally just going to change the scoring slightly to account
for fonts whose regular italic style is named "Regular Italic" - which
previously resulted in the Bold Italic or Thin Italic style being chosen
instead because they're shorter names, but I decided to do some better
inspection of the metadata and looser style name matching while I was
changing code here anyway.

Also adds a unit test to verify the sorting works correctly, though a
more comprehensive set of tests may be desirable in the future.

(Feel free to make any changes to the PR you feel necessary before
merging while I'm gone over the weekend.)
2025-05-30 19:30:19 -07:00
Mitchell Hashimoto 6e69893f29
font/sprite: rework `yQuads` and friends for better alignment with `draw_block` (#7488)
This improves "outer edge" alignment of octants and other elements drawn
using `yQuads` and friends with blocks drawn with `draw_block` -- this
should guarantee alignment along a continuous edge, but may result in a
1px overlap of opposing edges (such as a top half block followed by a
bottom half block with an odd cell height, they will both have the
center row filled).

This is very necessary since several block elements are needed to
complete the set of octants, since dedicated octant characters aren't
included when they would be redundant.

Fixes #7479 

<details>
<summary><b><code>Box.ppm</code> diff</b></summary>


![image](https://github.com/user-attachments/assets/aea667fd-446f-4b60-a220-cdd636093d05)

</details>

> [!NOTE]
> In the future I think we should have a unified single source of truth
for grid positions (divisions of the cell) to ensure this type of thing
can't happen with other characters, and also it would make a lot of the
code cleaner. For now this works though.
2025-05-30 19:29:45 -07:00
Qwerasd dd670f5107 font/sprite: rework `yQuads` and friends for better alignment with `draw_block`
This improves "outer edge" alignment of octants and other elements drawn
using `yQuads` and friends with blocks drawn with `draw_block` -- this
should guarantee alignment along a continuous edge, but may result in a
1px overlap of opposing edges (such as a top half block followed by a
bottom half block with an odd cell height, they will both have the
center row filled).

This is very necessary since several block elements are needed to
complete the set of octants, since dedicated octant characters aren't
included when they would be redundant.
2025-05-30 17:53:52 -06:00
Mitchell Hashimoto 5667b83328
macos: quick terminal can equalize splits (#7486)
Fixes #7480

I regret to inform the haters that an AI agent did this while I was out
getting a coffee. I only had to follow up once to ask it rename the
method to be more idiomatic. I absolutely didn't need AI to do this, but
I was leaving the office _anyways_ and figured why not. Got back and it
was done. What a time to be alive.
2025-05-30 15:24:04 -07:00
Mitchell Hashimoto fd7132db71
macos: quick terminal can equalize splits
Fixes #7480
2025-05-30 15:13:30 -07:00
Leah Amelia Chen f99c988b27
gtk(wayland): automatically bind globals 2025-05-30 23:42:48 +02:00
Leah Amelia Chen 9ded668819
gtk(wayland,x11): remove even more redundant checks 2025-05-30 23:42:42 +02:00
Leah Amelia Chen 157f50e2de
gtk: request user attention on bell (#7482)
I'm not sure if this should be enabled by default like the tab
animation, but on KDE at least this is unintrusive enough for me to
always enable by default. Alacritty appears to agree with me as well.

Fixes #7124
2025-05-30 23:33:12 +02:00
Qwerasd 34f08a450e font: rework coretext discovery sorting
This should make the sorting more robust to fonts with questionable
metadata or atypical style names.

I was originally just going to change the scoring slightly to account
for fonts whose regular italic style is named "Regular Italic" - which
previously resulted in the Bold Italic or Thin Italic style being chosen
instead because they're shorter names, but I decided to do some better
inspection of the metadata and looser style name matching while I was
changing code here anyway.

Also adds a unit test to verify the sorting works correctly, though a
more comprehensive set of tests may be desirable in the future.
2025-05-30 15:27:39 -06:00
Mitchell Hashimoto 445d88346d
config: more robust handling of font-family overwrite for CLI args (#7484)
Fixes #7481

We unfortunately don't have a great way to unit test this since our
logic relies on argv and I'm too lazy to extract it out right now.

The core issue is that we previously detected if font-families changed
by comparing lengths. This doesn't work because the CLI args can reset
and add families back to a lesser length. This caused an integer
overflow.

We can fix this by not being clever and introducing the overwrite logic
directly into the config type. I unit tested that.
2025-05-30 14:26:56 -07:00
Mitchell Hashimoto 8be5a78585
config: more robust handling of font-family overwrite for CLI args
Fixes #7481

We unfortunately don't have a great way to unit test this since our
logic relies on argv and I'm too lazy to extract it out right now.

The core issue is that we previously detected if font-families changed
by comparing lengths. This doesn't work because the CLI args can reset
and add families back to a lesser length. This caused an integer
overflow.

We can fix this by not being clever and introducing the overwrite logic
directly into the config type. I unit tested that.
2025-05-30 14:15:24 -07:00
Leah Amelia Chen bdcbb9fd42
gtk(wayland): customize keyboard interactivity for quick terminal (#7477)
Fixes #7476
2025-05-30 22:50:56 +02:00
Leah Amelia Chen 90f431005b
gtk: request user attention on bell
I'm not sure if this should be enabled by default like the tab
animation, but on KDE at least this is unintrusive enough for me to
always enable by default. Alacritty appears to agree with me as well.
2025-05-30 22:43:07 +02:00
Mitchell Hashimoto 2ad86cde69
OSC: allow multiple set/reset/report operations per OSC (#7429) 2025-05-30 13:16:57 -07:00
Leah Amelia Chen 6959fa8438
gtk(wayland): explicitly set layer name
Even though gtk4-layer-shell's documentation claims that "nobody quite
knows what it's for", some compositors (like Niri) can define custom
rules based on the layer name and it's beneficial in those cases to
define a distinct name just for our quick terminals.
2025-05-30 19:26:18 +02:00
Leah Amelia Chen dee7c835de
gtk(wayland): remove redundant check 2025-05-30 19:26:18 +02:00
Leah Amelia Chen 71a1ece7e9
gtk(wayland): gtk4-layer-shell -> layer-shell
It was getting a bit too unwieldy.
2025-05-30 19:26:18 +02:00
Leah Amelia Chen 6fac355363
gtk(wayland): fallback when on-demand mode isn't supported
This shouldn't be a real problem anymore since as of now (May 2025)
all major compositors support at least version 4, but let's do this
just in case.
2025-05-30 19:26:18 +02:00
Leah Amelia Chen 4d18c06804
gtk(wayland): customize keyboard interactivity for quick terminal
Fixes #7476
2025-05-30 19:26:11 +02:00
Mitchell Hashimoto 2f88b3bcfa
GTK: add action to show the GTK inspector (#7468)
The default keybinds for showing the GTK inspector (`ctrl+shift+i` and
`ctrl+shift+d`) don't work reliably in Ghostty due to the way Ghostty
handles input. You can show the GTK inspector by setting the environment
variable `GTK_DEBUG` to `interactive` before starting Ghostty but that's
not always convenient.

This adds a keybind action that will show the GTK inspector. Due to API
limitations toggling the GTK inspector using the keybind action is
impractical because GTK does not provide a convenient API to determine
if the GTK inspector is already showing. Thus we limit ourselves to
strictly showing the GTK inspector. To close the GTK inspector the user
must click the close button on the GTK inspector window. If the GTK
inspector window is already visible but is hidden, calling the keybind
action will not bring the GTK inspector window to the front.
2025-05-30 07:13:34 -07:00
Mitchell Hashimoto c4088f0c73
terminal: bring alt screen behaviors much closer in line with xterm (#7471)
This brings the behavior of mode 47, 1047, and 1049 much closer to
xterm's behavior. I found that our prior implementation had many
deficiencies.

For example, we weren't properly copying the cursor state back to the
primary screen from the alternate screen for modes 47 and 1047. And we
weren't saving/restoring cursor state unconditionally for mode 1049 even
if we were already in the alternate screen.

I also found that we were dangling hyperlink state on the primary screen
when we switched to alternate. xterm doesn't support hyperlinks but we
did the opposite behavior for going from alternate to primary. So one
way or the other its a bug. I'm worried this one could've maybe led to
memory corruption under the right circumstances but I wasn't able to
prove it.

These are weird, edgy behaviors that I don't think anyone expected
(evidence by there being no bug reports about them), but they are bugs
nontheless.

Many tests added.

(Btw: this flew under the radar of our "xterm audit" because that only
included sequences and not modes. I noted this in the audit issue itself
but just an FYI.)
2025-05-29 20:33:40 -07:00
Mitchell Hashimoto 9b45638c15
input: "ignore" binding action are still be processed by the OS/GUI (#7474)
Related to #7468

This changes the behavior of "ignore". Previously, Ghostty would
consider "ignore" actions consumed but do nothing. They were like a
black hole. Now, Ghostty returns `ignored` which lets the apprt forward
the event to the OS/GUI.

This enables keys that would otherwise be pty-encoded to be processed
later, such as for GTK to show the GTK inspector.
2025-05-29 16:34:03 -07:00
Mitchell Hashimoto 891b23917b
input: "ignore" binding action are still be processed by the OS/GUI
Related to #7468

This changes the behavior of "ignore". Previously, Ghostty would
consider "ignore" actions consumed but do nothing. They were like a
black hole. Now, Ghostty returns `ignored` which lets the apprt forward
the event to the OS/GUI.

This enables keys that would otherwise be pty-encoded to be processed
later, such as for GTK to show the GTK inspector.
2025-05-29 16:03:03 -07:00
Mitchell Hashimoto c5e5d61438
terminal: bring alt screen behaviors much closer in line with xterm
This brings the behavior of mode 47, 1047, and 1049 much closer to
xterm's behavior. I found that our prior implementation had many
deficiencies.

For example, we weren't properly copying the cursor state back to the
primary screen from the alternate screen for modes 47 and 1047. And we
weren't saving/restoring cursor state unconditionally for mode 1049 even
if we were already in the alternate screen.

These are weird, edgy behaviors that I don't think anyone expected
(evidence by there being no bug reports about them), but they are bugs
nontheless.

Many tests added.
2025-05-29 15:43:27 -07:00
Mitchell Hashimoto d94bcda778
build: use a libc txt file to point to correct Apple SDK (#7469)
This fixes an issue where Ghostty would not build against the macOS 15.5
SDK.

What was happening was that Zig was adding its embedded libc paths to
the clang command line, which included old headers that were
incompatible with the latest (macOS 15.5) SDK. Ghostty was adding the
newer paths but they were being overridden by the embedded libc paths.

The reason this was happening is because Zig was using its own logic to
find the libc paths and this was colliding with the paths we were
setting manually. To fix this, we now use a `libc.txt` file that
explicitly tells Zig where to find libc, and we base this on our own SDK
search logic.
2025-05-29 15:20:42 -07:00
Mitchell Hashimoto 0f1860f066
build: use a libc txt file to point to correct Apple SDK
This fixes an issue where Ghostty would not build against the macOS 15.5 SDK.

What was happening was that Zig was adding its embedded libc paths to
the clang command line, which included old headers that were
incompatible with the latest (macOS 15.5) SDK. Ghostty was adding the
newer paths but they were being overridden by the embedded libc paths.

The reason this was happening is because Zig was using its own logic to
find the libc paths and this was colliding with the paths we were
setting manually. To fix this, we now use a `libc.txt` file that
explicitly tells Zig where to find libc, and we base this on our own SDK
search logic.
2025-05-29 15:04:05 -07:00
Jeffrey C. Ollie d3cb6d0d41
GTK: add action to show the GTK inspector
The default keybinds for showing the GTK inspector (`ctrl+shift+i` and
`ctrl+shift+d`) don't work reliably in Ghostty due to the way Ghostty
handles input. You can show the GTK inspector by setting the environment
variable `GTK_DEBUG` to `interactive` before starting Ghostty but that's
not always convenient.

This adds a keybind action that will show the GTK inspector. Due to
API limitations toggling the GTK inspector using the keybind action is
impractical because GTK does not provide a convenient API to determine
if the GTK inspector is already showing. Thus we limit ourselves to
strictly showing the GTK inspector. To close the GTK inspector the user
must click the close button on the GTK inspector window. If the GTK
inspector window is already visible but is hidden, calling the keybind
action will not bring the GTK inspector window to the front.
2025-05-29 16:07:57 -05:00
Jeffrey C. Ollie 1104993c94
OSC: move some processing back inside the OSC state machine 2025-05-29 11:37:09 -05:00
Jeffrey C. Ollie f0fc82c80f
OSC: account for 32-bit systems in comptime Command size check 2025-05-29 11:37:09 -05:00
Jeffrey C. Ollie 5fb32fd8a0
OSC: add comptime check for size of OSC Command 2025-05-29 11:37:09 -05:00
Jeffrey C. Ollie bcf4d55dad
OSC: nest ColorOperation-related structs 2025-05-29 11:37:08 -05:00
Jeffrey C. Ollie fa03115f01
OSC: don't use arena during testing 2025-05-29 11:37:08 -05:00
Jeffrey C. Ollie 35384670c4
OSC: fix typo 2025-05-29 11:37:08 -05:00
Jeffrey C. Ollie e0ddc7a2fa
OSC: clean up color_operation handling 2025-05-29 11:37:08 -05:00
Jeffrey C. Ollie f2dfd9f677
OSC: improve formatting of ColorOperationSource 2025-05-29 11:37:07 -05:00
Jeffrey C. Ollie bd4d1950ce
OSC: remove unused code 2025-05-29 11:37:07 -05:00
Jeffrey C. Ollie 479fa9f809
OSC: use std.SegmentedList instead of custom data structure 2025-05-29 11:37:07 -05:00
Jeffrey C. Ollie 397a8b13e0
OSC: more tests 2025-05-29 11:37:07 -05:00
Jeffrey C. Ollie 1d9d253e4d
OSC: fix bug with buffer disappearing 2025-05-29 11:37:07 -05:00
Jeffrey C. Ollie 04e8e52171
OSC: reflow comment 2025-05-29 11:37:06 -05:00
Jeffrey C. Ollie 1288296fdc
OSC: add a datastructure to prevent some (most?) allocations 2025-05-29 11:37:06 -05:00
Jeffrey C. Ollie 5bb7492955
OSC: convert OSC 110, 111, and 112 and add more tests 2025-05-29 11:37:06 -05:00
Jeffrey C. Ollie 5ec1c15ecf
OSC: add more tests 2025-05-29 11:37:06 -05:00
Jeffrey C. Ollie 9c1abf487e
OSC: start adding structure to allow multiple color operations per OSC 2025-05-29 11:37:06 -05:00
Mitchell Hashimoto b2f3c7f309
fix: properly intialize key event in GlobalEventTap (#7462)
Fixes #7215. The issue was that `GlobalEventTap` didn't fully initialize
the key event before passing it to `ghostty_app_key`. In particular, it
didn't set the `unshifted_codepoint` field, which is needed to find a
match when calling `keybind.set.getEvent`, because `keybind.set` stores
bindings by codepoint, not physical key (i.e., the trigger to match is
`ctrl+p`, not `ctrl+key_p`, et cetera).

The fix was to make `GlobalEventTap` initialize the key event using
`event.ghosttyKeyEvent`, like it's done in `SurfaceView.keyAction` and
`AppDelegate.localEventKeyDown`.

This is my first time touching either Zig or Swift, so I'm a bit green.
In particular, I don't know if it's possible to write a test covering
this, and if so, how and where to put it. Please edit or request changes
as you see fit.
2025-05-29 08:48:10 -07:00
Daniel Wennberg d1501a4925 fix: properly intialize key event in GlobalEventTap 2025-05-27 22:33:15 -07:00
Mitchell Hashimoto 8a00aa8223
code style: use `@splat` where possible (#7461)
As of Zig 0.14.0, `@splat` can be used for array types, which eliminates
a lot of redundant syntax and makes things generally cleaner.

I've explicitly avoided applying this change in the renderer files for
now since it would just create rebasing conflicts in my renderer rework
branch which I'll be PR-ing pretty soon.
2025-05-27 21:30:23 -07:00
Qwerasd 6f7e9d5bea code style: use `@splat` where possible
As of Zig 0.14.0, `@splat` can be used for array types, which eliminates
a lot of redundant syntax and makes things generally cleaner.

I've explicitly avoided applying this change in the renderer files for
now since it would just create rebasing conflicts in my renderer rework
branch which I'll be PR-ing pretty soon.
2025-05-27 21:55:28 -06:00
Mitchell Hashimoto ad632f1068
Add support for buffer switching with CSI ? 47 h/l (#7443)
This PR adds support for handling the escape sequences CSI ? 47 h/l,
which are related to alternate screen buffer switching. This is in
response to the issue reported in
[ghostty-org/ghostty#7386](https://github.com/ghostty-org/ghostty/issues/7386).

I'm unsure where to add tests for this change. Would it make sense to
add visual tests for this behavior, or is there a preferred approach or
location for testing such functionality? I tested it locally using the
following commands:
```bash
echo -e "\e[?47h"
echo "Printed on the alt screen"
echo -e "\e[?47l"
```
2025-05-27 11:54:28 -07:00
Jonatan Borkowski 21c97aa9d6 add support for buffer switching with CSI ? 47 h/l 2025-05-27 11:48:14 -07:00
Mitchell Hashimoto d72a1511fe
Rework mouse selection logic (#7444)
This PR fixes the problem discussed in #5058 and #7434 by reworking the
selection logic in a way that better handles edge cases as well as being
generally cleaner.

This rework does change how selection behaves slightly, especially
rectangular selection, but the new behavior of rectangular selection is
more in line with other terminals I tested (Terminal.app, Kitty).

There are some TODO comments for adding unit tests- I ran out of steam
tonight, but if this PR is still open tomorrow I'll go ahead and add
them.
2025-05-27 10:12:31 -07:00
Mitchell Hashimoto ba02f0ae22
decl literal 2025-05-27 09:55:54 -07:00
Qwerasd 6aa84d0e92 test: introduce helper function for mouse selection tests
Removes a lot of repeated code and makes the test cases easier to
understand at a glance.
2025-05-27 09:38:36 -07:00
Qwerasd 4d11673318 unit test mouse selection logic
Adds many test cases for expected behavior of the selection logic, this
will allow changes to be made more confidently in the future without
fear of regressions.
2025-05-27 09:38:36 -07:00
Qwerasd ecdac8c8c1 terminal: rework selection logic in core surface
This logic is cleaner and produces better behavior when selecting by
dragging the mouse outside the bounds of the surface, previously when
doing this on the left side of the surface selections would include the
first cell of the next row, this is no longer the case.

This introduces methods on PageList.Pin which move a pin left or right
while wrapping to the prev/next row, or clamping to the ends of the row.
These need unit tests.
2025-05-27 09:38:36 -07:00
Qwerasd 58592d3f65 GTK: Don't clamp cursorpos, allow negative values
Other apprts don't do this, so this should be consistent.
2025-05-27 09:38:36 -07:00
Qwerasd 1ce6544945 Wrap comment at 80 cols 2025-05-27 09:38:36 -07:00
Mitchell Hashimoto 04db2f664b
Miscellaneous `TODO`s (#7451)
See commit messages for details.

If some of the commits in this PR have problems with them I'm perfectly
fine with the others being cherry-picked out while the problems are
addressed.

The biggest/broadest reaching changes in this PR come from converting a
lot of code to use decl literals where possible, so there are a lot of
files where only a handful of lines are modified very slightly.
2025-05-27 07:17:45 -07:00
Mitchell Hashimoto 6b1b5ca0e9
nix: update to Nix 25.05 and Zig 0.14.1 (#7447)
Update to Nix 25.05 which gets us GTK 4.18, libadwaita 1.7, and Zig
0.14.1.

Since Nix updated to Zig 0.14.1, the devshell has been switched to Zig
0.14.1 from zig-overlay as well.

Fixes #7305
2025-05-27 07:12:17 -07:00
Mitchell Hashimoto 483cb42088
Correct `$XDG_CONFIG_DIR` to `$XDG_CONFIG_HOME` (#7454)
Ghostty doesn't support `$XDG_CONFIG_DIR`, it only supports
`$XDG_CONFIG_HOME`, so the documentation was incorrect. Not to be
confused with `$XDG_CONFIG_DIRS` nor `$XDG_RUNTIME_DIR` (very
consistent…).

Furthermore, `$XDG_CONFIG_HOME` is the correct XDG path:

> <ins>$XDG_CONFIG_HOME</ins> defines the base directory relative to
which user-specific configuration files should be stored. If
<ins>$XDG_CONFIG_HOME</ins> is either not set or empty, a default equal
to <ins>$HOME</ins>/.config should be used.
> […]
> <ins>$XDG_CONFIG_DIRS</ins> defines the preference-ordered set of base
directories to search for configuration files in addition to the
<ins>$XDG_CONFIG_HOME</ins> base directory. The directories in
<ins>$XDG_CONFIG_DIRS</ins> should be separated with a colon ':'.

— [XDG Base Directory Specification § Environment variables][xdgvars]

Cross-reference:
https://github.com/ghostty-org/ghostty/discussions/7431#discussioncomment-13283139.

[xdgvars]:
https://specifications.freedesktop.org/basedir-spec/latest#variables
2025-05-27 07:10:17 -07:00
Kat 468bfce091
Correct `$XDG_CONFIG_DIR` to `$XDG_CONFIG_HOME` in theme documentation. 2025-05-27 22:40:01 +10:00
Qwerasd 2384bd69cc style: use decl literals
This commit changes a LOT of areas of the code to use decl literals
instead of redundantly referring to the type.

These changes were mostly driven by some regex searches and then manual
adjustment on a case-by-case basis.

I almost certainly missed quite a few places where decl literals could
be used, but this is a good first step in converting things, and other
instances can be addressed when they're discovered.

I tested GLFW+Metal and building the framework on macOS and tested a GTK
build on Linux, so I'm 99% sure I didn't introduce any syntax errors or
other problems with this. (fingers crossed)
2025-05-26 21:50:14 -06:00
Qwerasd 2fe2ccdbde font/sprite: use decl literals in box drawing code
Cleaner and less visual noise, easy change to make, there are many other
areas in the code which would benefit from decl literals as well, but
this is an area that benefits a lot from them and is self-contained.
2025-05-26 19:56:35 -06:00
Qwerasd 2905b47279 font: use labeled switch continue pattern for feature string parser
In this case it does result in a little repeated code for reading bytes,
but I find the control flow easier to follow, so it's worth it IMO.
2025-05-26 19:39:39 -06:00
Jeffrey C. Ollie 695e0b3e57
nix: temporarily remove snapcraft from the devshell 2025-05-26 11:43:52 -05:00
Jeffrey C. Ollie 48b6807ac9
nix: fix typos 2025-05-26 11:12:30 -05:00
Jeffrey C. Ollie 98309e3226
nix: update to Nix 25.05 and Zig 0.14.1
Update to Nix 25.05 which gets us GTK 4.18, libadwaita 1.7, and Zig 0.14.1.

Since Nix updated to Zig 0.14.1, the devshell has been switched to Zig 0.14.1
from zig-overlay as well.

Fixes #7305
2025-05-26 10:47:43 -05:00
Qwerasd 25a708ed98 terminal/style: compare packed styles directly, no cast needed
Woohoo, Zig 0.14!
2025-05-25 22:53:50 -06:00
Qwerasd 19db2e2755 CircBuf: non-allocating rotateToZero
We can call `std.mem.rotate` for this.
2025-05-25 22:25:23 -06:00
Jeffrey C. Ollie 3f6c02b49e
gtk: improve app id validation (#7442)
'g_application_id_is_valid' doesn't allow empty elements or elements
that start with digits.
This commit updates 'isValidAppId' to be more consistant with
'g_application_id_is_valid' avoiding the app id defaulting to 'GTK
Application' for app ids like '0foo.bar' or 'foo..bar'.
2025-05-25 16:11:26 -05:00
alex-huff 113c196078 gtk: use 'gio.Application.idIsValid' instead of 'isValidAppId' 2025-05-25 15:23:13 -05:00
Mitchell Hashimoto 6697dc6642
Add new and update Norwegian split translations (#7423)
This change changes the wording on the split pane functionality. The new
wording is taken from the macOS terminal app when the whole system is
translated to Norwegian.

macOS uses "Del opp vindu" and "Lukk delt vindu" for "Split Pane" and
"Close Split Pane". So instead of using "split" the verb in question is
always "del". Personally I find this translation to be better rooted in
Norwegian.

When looking at the German translation, which is often a good indicator
for Norwegian as well, one can see the same wording being used.
2025-05-25 12:27:40 -07:00
Mitchell Hashimoto 731d0f0444
Update iTerm2 colorschemes (#7435)
Upstream revision:
273a780bcd
2025-05-25 12:21:17 -07:00
alex-huff 0415a65083 gtk: improve app id validation
'g_application_id_is_valid' doesn't allow empty elements or elements
that start with digits.
This commit updates 'isValidAppId' to be more consistant with
'g_application_id_is_valid' avoiding the app id defaulting to 'GTK
Application' for app ids like '0foo.bar' or 'foo..bar'.
2025-05-25 11:43:40 -05:00
mitchellh b94d2da567 deps: Update iTerm2 color schemes 2025-05-25 00:15:05 +00:00
Mitchell Hashimoto 034c1c12ef
add cut/copy/paste keys (#7430)
The origin of these keys are old sun keyboards.
They are getting picked up by the custom (progammable) keyboard scene
(see https://github.com/manna-harbour/miryoku for a popular layout).
Support in ghosty is quite handy because it allows to bind copy/paste in
a way that doesn't overlap with ctrl-c/ctrl-v, which can have special
bindings in some terminal applications.
2025-05-24 07:17:49 -07:00
Jörg Thalheim a8651882a7 add cut/copy/paste keys
The origin of these keys are old sun keyboards.
They are getting picked up by the custom (progammable) keyboard scene
(see https://github.com/manna-harbour/miryoku for a popular layout).
Support in ghosty is quite handy because it allows to bind copy/paste in
a way that doesn't overlap with ctrl-c/ctrl-v, which can have special
bindings in some terminal applications.
2025-05-24 00:29:53 +02:00
Alan Moyano cf7e76d8f2 Adding Argentinian Spanish to CODEOWNERS 2025-05-23 17:25:14 -03:00
Alan Moyano 7bf01b97ca
Merge branch 'ghostty-org:main' into main 2025-05-23 17:21:00 -03:00
Mitchell Hashimoto 26a42fac0e
Update Turkish translations (#7408) 2025-05-23 07:15:46 -07:00
Mitchell Hashimoto 5eb32a3c47
synthetic package (#7409)
This introduces a new package `src/synthetic` for generating synthetic
data, currently primarily for benchmarking but other use cases can
emerge.

The synthetic package exports a runtime-dispatched type `Generator` that
can generate data of various types. To start, we have a bytes, utf8, and
OSC generator. The goal of each generator is to expose knobs to tune the
probabilities of various outcomes. For example, the UTF-8 generator has
a knob to tune the probability of generating 1, 2, 3, or 4-byte UTF-8
sequences.

Ultimately, the goal is to be able to collect probability data
empirically that we can then use for benchmarks so we can optimize
various parts of the codebase on real-world data shape distributions.
2025-05-23 07:15:33 -07:00
Christoffer Tønnessen ab25600b2d Add new and update Norwegian split translations
This change changes the wording on the split pane functionality. The new
wording is taken from the macOS terminal app when the whole system is
translated to Norwegian.

macOS uses "Del opp vindu" and "Lukk delt vindu" for "Split Pane" and
"Close Split Pane". So instead of using "split" the verb in question is
always "del". Personally I find this translation to be better rooted in
Norwegian.

When looking at the German translation, which is often a good indicator
for Norwegian as well, one can see the same wording being used.
2025-05-23 10:46:24 +02:00
Mitchell Hashimoto a2f52b08e5
build(deps): bump cachix/cachix-action from 15 to 16 (#7412)
Bumps [cachix/cachix-action](https://github.com/cachix/cachix-action)
from 15 to 16.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/cachix/cachix-action/releases">cachix/cachix-action's
releases</a>.</em></p>
<blockquote>
<h2>v16</h2>
<h2>What's Changed</h2>
<ul>
<li>Add a small delay to allow post-build hooks to flush through by <a
href="https://github.com/sandydoo"><code>@​sandydoo</code></a> in <a
href="https://redirect.github.com/cachix/cachix-action/pull/196">cachix/cachix-action#196</a></li>
<li>Upgraded dependencies</li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/cachix/cachix-action/compare/v15...v16">https://github.com/cachix/cachix-action/compare/v15...v16</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="0fc020193b"><code>0fc0201</code></a>
Merge pull request <a
href="https://redirect.github.com/cachix/cachix-action/issues/201">#201</a>
from cachix/bump-deps</li>
<li><a
href="9ff160dfdf"><code>9ff160d</code></a>
dist: build</li>
<li><a
href="43208f1165"><code>43208f1</code></a>
deps: pnpm update</li>
<li><a
href="177fc8ba87"><code>177fc8b</code></a>
ci: run private cache tests when secrets are available</li>
<li><a
href="9bb3a15fdb"><code>9bb3a15</code></a>
deps: devenv update</li>
<li><a
href="be5295a636"><code>be5295a</code></a>
Merge pull request <a
href="https://redirect.github.com/cachix/cachix-action/issues/197">#197</a>
from cachix/dev-restructure</li>
<li><a
href="dbbedb8579"><code>dbbedb8</code></a>
ci: split build and test scripts</li>
<li><a
href="a3f805d988"><code>a3f805d</code></a>
ci: build once with devenv</li>
<li><a
href="c48cfdb2ec"><code>c48cfdb</code></a>
ci: switch out yarn</li>
<li><a
href="9af815036c"><code>9af8150</code></a>
dist: rebuild</li>
<li>Additional commits viewable in <a
href="https://github.com/cachix/cachix-action/compare/v15...v16">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=cachix/cachix-action&package-manager=github_actions&previous-version=15&new-version=16)](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-05-21 15:22:34 -07:00
Mitchell Hashimoto 7dae4d287c
build(deps): bump namespacelabs/nscloud-cache-action from 1.2.0 to 1.2.7 (#7411)
Bumps
[namespacelabs/nscloud-cache-action](https://github.com/namespacelabs/nscloud-cache-action)
from 1.2.0 to 1.2.7.
<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.7</h2>
<h2>What's Changed</h2>
<ul>
<li>Print a warning in post if cached paths do not exist at the end. by
<a
href="https://github.com/nichtverstehen"><code>@​nichtverstehen</code></a>
in <a
href="https://redirect.github.com/namespacelabs/nscloud-cache-action/pull/19">namespacelabs/nscloud-cache-action#19</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/namespacelabs/nscloud-cache-action/compare/v1...v1.2.7">https://github.com/namespacelabs/nscloud-cache-action/compare/v1...v1.2.7</a></p>
<h2>v1.2.6</h2>
<p>No release notes provided.</p>
<h2>v1.2.5</h2>
<p>No release notes provided.</p>
<h2>v1.2.4</h2>
<p>No release notes provided.</p>
<h2>v1.2.3</h2>
<p>No release notes provided.</p>
<h2>v1.2.2</h2>
<p>No release notes provided.</p>
<h2>Add UV cache mode</h2>
<p>No release notes provided.</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="2f50e7d0f7"><code>2f50e7d</code></a>
Merge pull request <a
href="https://redirect.github.com/namespacelabs/nscloud-cache-action/issues/19">#19</a>
from namespacelabs/kirill/post</li>
<li><a
href="e9d413737a"><code>e9d4137</code></a>
Print a warning in post if cached paths do not exist at the end.</li>
<li><a
href="1d016dd6d4"><code>1d016dd</code></a>
Merge pull request <a
href="https://redirect.github.com/namespacelabs/nscloud-cache-action/issues/18">#18</a>
from namespacelabs/niklas-handle-all-warnings</li>
<li><a
href="13f8bc947a"><code>13f8bc9</code></a>
Ensure all PNPM warnings are skipped.</li>
<li><a
href="7779b07b57"><code>7779b07</code></a>
Merge pull request <a
href="https://redirect.github.com/namespacelabs/nscloud-cache-action/issues/17">#17</a>
from namespacelabs/niklas-run-on-merge</li>
<li><a
href="ea5a8440c9"><code>ea5a844</code></a>
run checks on merge queue</li>
<li><a
href="20b0b2d55d"><code>20b0b2d</code></a>
Merge pull request <a
href="https://redirect.github.com/namespacelabs/nscloud-cache-action/issues/16">#16</a>
from namespacelabs/niklas-skip-stderr</li>
<li><a
href="6d893e3fdc"><code>6d893e3</code></a>
Skip PNPM warnings in parsing.</li>
<li><a
href="17d0a826e6"><code>17d0a82</code></a>
Merge pull request <a
href="https://redirect.github.com/namespacelabs/nscloud-cache-action/issues/15">#15</a>
from namespacelabs/niklas-pnpm-only-errors</li>
<li><a
href="1bc91188ef"><code>1bc9118</code></a>
skip all PNPM warnings.</li>
<li>Additional commits viewable in <a
href="https://github.com/namespacelabs/nscloud-cache-action/compare/v1.2.0...v1.2.7">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.0&new-version=1.2.7)](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-05-21 15:22:24 -07:00
dependabot[bot] 9079561300
build(deps): bump cachix/cachix-action from 15 to 16
Bumps [cachix/cachix-action](https://github.com/cachix/cachix-action) from 15 to 16.
- [Release notes](https://github.com/cachix/cachix-action/releases)
- [Commits](https://github.com/cachix/cachix-action/compare/v15...v16)

---
updated-dependencies:
- dependency-name: cachix/cachix-action
  dependency-version: '16'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-21 21:15:50 +00:00
Mitchell Hashimoto 4a8c3df814
build(deps): bump cachix/install-nix-action from 30 to 31 (#7410)
Bumps
[cachix/install-nix-action](https://github.com/cachix/install-nix-action)
from 30 to 31.
<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</h2>
<p>Starting with v31, this action will use semantic versioning for
releases.
Major tags, like v31, will be bumped to point to the latest minor/patch
release.
This is in line with how most GitHub actions manage releases.</p>
<h2>What's Changed</h2>
<ul>
<li>nix: 2.26.3 -&gt; 2.28.2 by <a
href="https://github.com/Mic92"><code>@​Mic92</code></a> in <a
href="https://redirect.github.com/cachix/install-nix-action/pull/232">cachix/install-nix-action#232</a></li>
<li>nix: 2.24.9 -&gt; 2.25.2 by <a
href="https://github.com/Mic92"><code>@​Mic92</code></a> in <a
href="https://redirect.github.com/cachix/install-nix-action/pull/218">cachix/install-nix-action#218</a></li>
<li>ci: fix latest installer tests by <a
href="https://github.com/sandydoo"><code>@​sandydoo</code></a> in <a
href="https://redirect.github.com/cachix/install-nix-action/pull/220">cachix/install-nix-action#220</a></li>
<li>ci: add ubuntu-24.04-arm to matrix by <a
href="https://github.com/msgilligan"><code>@​msgilligan</code></a> in <a
href="https://redirect.github.com/cachix/install-nix-action/pull/221">cachix/install-nix-action#221</a></li>
<li>nix: 2.25.2 -&gt; 2.26.2 by <a
href="https://github.com/Mic92"><code>@​Mic92</code></a> in <a
href="https://redirect.github.com/cachix/install-nix-action/pull/226">cachix/install-nix-action#226</a></li>
<li>nix: 2.26.2 -&gt; 2.26.3 by <a
href="https://github.com/sandydoo"><code>@​sandydoo</code></a> in <a
href="https://redirect.github.com/cachix/install-nix-action/pull/228">cachix/install-nix-action#228</a></li>
<li>feat: Pin actions to hashes by <a
href="https://github.com/l0b0"><code>@​l0b0</code></a> in <a
href="https://redirect.github.com/cachix/install-nix-action/pull/201">cachix/install-nix-action#201</a></li>
<li>chore(deps): bump actions/checkout from 4.1.1 to 4.2.2 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/cachix/install-nix-action/pull/234">cachix/install-nix-action#234</a></li>
<li>docs: document how to provide AWS credentials to the nix-daemon by
<a href="https://github.com/sandydoo"><code>@​sandydoo</code></a> in <a
href="https://redirect.github.com/cachix/install-nix-action/pull/235">cachix/install-nix-action#235</a></li>
<li>nix: 2.28.2 -&gt; 2.28.3 by <a
href="https://github.com/Mic92"><code>@​Mic92</code></a> in <a
href="https://redirect.github.com/cachix/install-nix-action/pull/236">cachix/install-nix-action#236</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/msgilligan"><code>@​msgilligan</code></a> made
their first contribution in <a
href="https://redirect.github.com/cachix/install-nix-action/pull/221">cachix/install-nix-action#221</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/cachix/install-nix-action/compare/v30...v31">https://github.com/cachix/install-nix-action/compare/v30...v31</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/cachix/install-nix-action/blob/master/RELEASE.md">cachix/install-nix-action's
changelog</a>.</em></p>
<blockquote>
<h1>Release</h1>
<p>As of v31, releases of this action follow Semantic Versioning.</p>
<h3>Publishing a new release</h3>
<h4>Publish the release</h4>
<p>Draft <a
href="https://github.com/cachix/install-nix-action/releases">a new
release on GitHub</a>:</p>
<ul>
<li>In <code>Choose a tag</code>, create a new tag, like
<code>v31.2.1</code>, following semver.</li>
<li>Click <code>Generate release notes</code>.</li>
<li><code>Set as the latest release</code> should be selected
automatically.</li>
<li>Publish release</li>
</ul>
<h4>Update the major tag</h4>
<p>The major tag, like <code>v31</code>, allows downstream users to
opt-in to automatic non-breaking updates.</p>
<p>This process follows GitHub's own guidelines:
<a
href="https://github.com/actions/toolkit/blob/main/docs/action-versioning.md">https://github.com/actions/toolkit/blob/main/docs/action-versioning.md</a></p>
<h5>Fetch the latest tags</h5>
<pre><code>git pull --tags --force
</code></pre>
<h5>Move the tag</h5>
<pre><code>git tag -fa v31
</code></pre>
<pre><code>git push origin v31 --force
</code></pre>
<h4>Update the release notes for the major tag</h4>
<p>Find the release on GitHub: <a
href="https://github.com/cachix/install-nix-action/releases">https://github.com/cachix/install-nix-action/releases</a></p>
<p>Edit the release and click <code>Generate release notes</code>.
Edit the formatting and publish.</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="5261181216"><code>5261181</code></a>
Merge pull request <a
href="https://redirect.github.com/cachix/install-nix-action/issues/236">#236</a>
from Mic92/nix-2.28.3</li>
<li><a
href="b2b89c6cb1"><code>b2b89c6</code></a>
nix: 2.28.2 -&gt; 2.28.3</li>
<li><a
href="0c65bbe3c1"><code>0c65bbe</code></a>
Merge pull request <a
href="https://redirect.github.com/cachix/install-nix-action/issues/235">#235</a>
from cachix/docs-aws-creds</li>
<li><a
href="4f800b725c"><code>4f800b7</code></a>
docs: document how to provide AWS credentials to the nix-daemon</li>
<li><a
href="80f8d94dab"><code>80f8d94</code></a>
Merge pull request <a
href="https://redirect.github.com/cachix/install-nix-action/issues/234">#234</a>
from cachix/dependabot/github_actions/actions/checkou...</li>
<li><a
href="83772d105a"><code>83772d1</code></a>
chore(deps): bump actions/checkout from 4.1.1 to 4.2.2</li>
<li><a
href="48cf9b5849"><code>48cf9b5</code></a>
Merge pull request <a
href="https://redirect.github.com/cachix/install-nix-action/issues/201">#201</a>
from l0b0/feat/pin-actions</li>
<li><a
href="eafea807c1"><code>eafea80</code></a>
remove unused gitignores</li>
<li><a
href="9b4ef2ff2d"><code>9b4ef2f</code></a>
docs: add release notes</li>
<li><a
href="754537aaed"><code>754537a</code></a>
Merge pull request <a
href="https://redirect.github.com/cachix/install-nix-action/issues/232">#232</a>
from Mic92/nix-update</li>
<li>Additional commits viewable in <a
href="https://github.com/cachix/install-nix-action/compare/v30...v31">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=30&new-version=31)](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-05-21 14:14:50 -07:00
dependabot[bot] 56fb1cbaaf
build(deps): bump namespacelabs/nscloud-cache-action from 1.2.0 to 1.2.7
Bumps [namespacelabs/nscloud-cache-action](https://github.com/namespacelabs/nscloud-cache-action) from 1.2.0 to 1.2.7.
- [Release notes](https://github.com/namespacelabs/nscloud-cache-action/releases)
- [Commits](https://github.com/namespacelabs/nscloud-cache-action/compare/v1.2.0...v1.2.7)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-21 17:40:28 +00:00
dependabot[bot] adbf834c36
build(deps): bump cachix/install-nix-action from 30 to 31
Bumps [cachix/install-nix-action](https://github.com/cachix/install-nix-action) from 30 to 31.
- [Release notes](https://github.com/cachix/install-nix-action/releases)
- [Changelog](https://github.com/cachix/install-nix-action/blob/master/RELEASE.md)
- [Commits](https://github.com/cachix/install-nix-action/compare/v30...v31)

---
updated-dependencies:
- dependency-name: cachix/install-nix-action
  dependency-version: '31'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-21 17:40:25 +00:00
Mitchell Hashimoto f1c42c9f8c
synthetic package
This introduces a new package `src/synthetic` for generating synthetic
data, currently primarily for benchmarking but other use cases can
emerge.

The synthetic package exports a runtime-dispatched type `Generator` that
can generate data of various types. To start, we have a bytes, utf8,
and OSC generator. The goal of each generator is to expose knobs to tune the
probabilities of various outcomes. For example, the UTF-8 generator has
a knob to tune the probability of generating 1, 2, 3, or 4-byte UTF-8
sequences.

Ultimately, the goal is to be able to collect probability data
empirically that we can then use for benchmarks so we can optimize
various parts of the codebase on real-world data shape distributions.
2025-05-21 10:20:09 -07:00
Emir SARI 81647bfae6
Update Turkish translations 2025-05-21 20:06:07 +03:00
Mitchell Hashimoto 4c50a4d487
nix: don't strip if we are building a debug version of the package (#7395) 2025-05-20 06:47:27 -07:00
Mitchell Hashimoto 362d026dba
flatpak: Add --device=all permission (#7401)
Without --device=all, the sandbox gets a dedicated PTY namespace.
Commands run on the host via the HostCommand D-Bus interface receive the
file descriptors from the namespaced PTY but cannot determine its path
via ttyname(3). This breaks commands like tty(1), ps(1) and
emacsclient(1).

Add --device=all so the host PTY namespace is used when allocating TTYs.
Applications with access to org.freedesktop.Flatpak can already give
themselves arbitrary permissions, so the sandboxing benefits of
restricted device access are limited. For terminal emulators, the
consistency provided by a cross-distribution runtime and ability to
distribute directly to users is the primary benefit of shipping as a
Flatpak rather than sandboxing.
2025-05-19 21:46:06 -07:00
Liam Hupfer ae095d2262 flatpak: Add --device=all permission
Without --device=all, the sandbox gets a dedicated PTY namespace.
Commands run on the host via the HostCommand D-Bus interface receive the
file descriptors from the namespaced PTY but cannot determine its path
via ttyname(3). This breaks commands like tty(1), ps(1) and
emacsclient(1).

Add --device=all so the host PTY namespace is used when allocating TTYs.
Applications with access to org.freedesktop.Flatpak can already give
themselves arbitrary permissions, so the sandboxing benefits of
restricted device access are limited. For terminal emulators, the
primary benefit of Flatpak is the predictability of the
distro-independent target runtime rather than sandboxing.
2025-05-19 22:50:07 -05:00
Mitchell Hashimoto e2df9fa759
build: add unwind tables and frame pointers to debug/test builds (#7398)
This fixes an issue where stack traces were unreliable on some platforms
(namely aarch64-linux in a MacOS VM). I'm unsure if this is a bug in Zig
(defaults should be changed?) or what, because this isn't necessary on
other platforms, but this works around the issue.

I've unconditionally enabled this for all platforms, depending on build
mode (debug/test) and not the target. This is because I don't think
there is a downside for other platforms but if thats wrong we can fix
that quickly.

Some binaries have this unconditionally enabled regardless of build mode
(e.g. the Unicode tables generator) because having symbols in those
cases is always useful.

Some unrelated GTK test fix is also included here. I'm not sure why CI
didn't catch this (perhaps we only run tests for none-runtime) but all
tests pass locally and we can look into that elsewhere.

I also updated all our build API calls to be non-deprecated fields.
2025-05-19 19:56:22 -07:00
Mitchell Hashimoto 3d2bc3dca1
build: add unwind tables and frame pointers to debug/test builds
This fixes an issue where stack traces were unreliable on some platforms
(namely aarch64-linux in a MacOS VM). I'm unsure if this is a bug in Zig
(defaults should be changed?) or what, because this isn't necessary on
other platforms, but this works around the issue.

I've unconditionally enabled this for all platforms, depending on build
mode (debug/test) and not the target. This is because I don't think
there is a downside for other platforms but if thats wrong we can fix
that quickly.

Some binaries have this unconditionally enabled regardless of build mode
(e.g. the Unicode tables generator) because having symbols in those
cases is always useful.

Some unrelated GTK test fix is also included here. I'm not sure why CI
didn't catch this (perhaps we only run tests for none-runtime) but all
tests pass locally and we can look into that elsewhere.
2025-05-19 17:12:39 -07:00
Jeffrey C. Ollie 9ad0e4675b
nix: keep symbols if we're building a debug package
also add CI tests to make sure debug symbols exist

Co-authored-by: Mitchell Hashimoto <m@mitchellh.com>
2025-05-19 18:52:51 -05:00
Alan Moyano 5f3e5afb88 Add Argentinian Spanish translation and locale support 2025-05-19 20:32:30 -03:00
Mitchell Hashimoto dd5d2c5d0b
Add `selection-clear-on-typing` (#7394)
Fixes #7392

Docs:

> Whether to clear selected text when typing. This defaults to `true`.
> This is typical behavior for most terminal emulators as well as
> text input fields. If you set this to `false`, then the selected text
> will not be cleared when typing.
>
> "Typing" is specifically defined as any non-modifier (shift, control,
> alt, etc.) keypress that produces data to be sent to the application
> running within the terminal (e.g. the shell). Additionally, selection
> is cleared when any preedit or composition state is started (e.g.
> when typing languages such as Japanese).
>
> If this is `false`, then the selection can still be manually
> cleared by clicking once or by pressing `escape`.
2025-05-19 15:37:25 -07:00
Mitchell Hashimoto ac6aa8d395
Add `selection-clear-on-typing`
Fixes #7392

Docs:

> Whether to clear selected text when typing. This defaults to `true`.
> This is typical behavior for most terminal emulators as well as
> text input fields. If you set this to `false`, then the selected text
> will not be cleared when typing.
>
> "Typing" is specifically defined as any non-modifier (shift, control,
> alt, etc.) keypress that produces data to be sent to the application
> running within the terminal (e.g. the shell). Additionally, selection
> is cleared when any preedit or composition state is started (e.g.
> when typing languages such as Japanese).
>
> If this is `false`, then the selection can still be manually
> cleared by clicking once or by pressing `escape`.
2025-05-19 13:56:26 -07:00
Mitchell Hashimoto af293830f3
Update iTerm2 colorschemes (#7378)
Upstream revision:
f979d8b195
2025-05-19 07:13:21 -07:00
Leah Amelia Chen 60d8c42509
gtk: implement global shortcuts (#7083) 2025-05-19 08:18:28 +02:00
Leah Amelia Chen 6827dc0964
config: document `global:` support on Linux
Compiling this list of known supported and unsupported platforms has been
amazingly painful. Never change, Linux desktop.
2025-05-18 22:40:31 +02:00
Leah Amelia Chen 54dbd1990a
gtk: implement global shortcuts
It's been a lot of D-Bus related pain and suffering, but here it is.

I'm not sure about how well this is integrated inside App, but I'm fairly
proud of the standalone logic.
2025-05-18 22:40:31 +02:00
mitchellh 8a0ca1b573 deps: Update iTerm2 color schemes 2025-05-18 00:14:40 +00:00
Leah Amelia Chen b1af4a597f
gtk: implement command palette (#7167)
Closes #7156
2025-05-16 22:16:48 +02:00
Mitchell Hashimoto a6466c5ca0
macOS: use file parent dir for `openTerminal` service cwd (#7286) (#7292)
Fixes #7286

Previously, when using the "New Ghostty Window/Tab Here" macOS service
on a file, the new terminal window/tab would incorrectly open in the
user's home directory. This was because the service handler only
expected directory paths.

This commit updates the service handler to check if the provided path is
a file. If it is, the handler now uses the file's parent
directory as the working directory for the new Ghostty window or tab,
aligning with user expectations. If the path is a directory, it's used
directly as before.
2025-05-15 20:20:59 -07:00
Mitchell Hashimoto 2d29fe0494
bench: add `--mode=gen-osc` to generate synthetic OSC sequences (#7359)
cc @qwerasd205 

This commit adds a few new mode flags to the `bench-stream` program to
generator synthetic OSC sequences. The new modes are `gen-osc`,
`gen-osc-valid`, and `gen-osc-invalid`. The `gen-osc` mode generates
equal parts valid and invalid OSC sequences, while the suffixed variants
are for generating only valid or invalid sequences, respectively.

This commit also fixes our build system to actually be able to build the
benchmarks. It turns out we were just rebuilding the main Ghostty binary
for `-Demit-bench`. And, our benchmarks didn't run under Zig 0.14, which
is now fixed.

An important new design I'm working towards in this commit is to split
out synthetic data generation to a dedicated package in
`src/bench/synth` although I'm tempted to move it to `src/synth` since
it may be useful outside of benchmarks.

The synth package is a work-in-progress, but it contains a hint of
what's to come. I ultimately want to able to generate all kinds of
synthetic data with a lot of knobs to control dimensionality (e.g. in
the case of OSC sequences: valid/invalid, length, operation types,
etc.).
2025-05-15 20:19:37 -07:00
Mitchell Hashimoto e1de7a99e8
macos: add "Check for Updates" action, menu item & key-binding support (#7361)
Resolve #7325
2025-05-15 15:45:24 -07:00
Mitchell Hashimoto 5826b8b142
Gamma correct image scaling (#7368)
Fixes the gamma error noted in #7367 for both Metal and OpenGL by using
sRGB image formats for the textures.

This branch also includes the commits from #7367, so it'd probably be
best to review and merge that first.
2025-05-15 15:36:12 -07:00
Qwerasd ea79fdea11 fix(OpenGL): use sRGB texture format for gamma correct interpolation
otherwise images will be too dark when scaled
2025-05-15 12:44:44 -06:00
Qwerasd e2f3b6211f fix(Metal): use sRGB texture format for gamma correct interpolation
otherwise images will be too dark when scaled
2025-05-15 12:44:44 -06:00
Mitchell Hashimoto 1d0cb1a9b0
fix(renderer): Don't force images to grid/cell sizes. (#7367)
Also fixed Metal not interpolating scaled images.

See commit message for more details.

|`main` (Metal)|`main` (OpenGL)|Kitty|fixed (Metal)|fixed (OpenGL)|
|-|-|-|-|-|

|![image](https://github.com/user-attachments/assets/bfe09451-0a41-4952-8a55-5d7a9e5b2813)|![image](https://github.com/user-attachments/assets/70ec6775-ba00-40b7-a32d-dcaaa70671b1)|![image](https://github.com/user-attachments/assets/6d03729b-9b8e-4b25-850d-913e76f6183b)|![image](https://github.com/user-attachments/assets/aedfccf0-220c-4575-b5e4-8b467de6d5df)|![image](https://github.com/user-attachments/assets/300a080a-73f0-4c69-9603-df342767a83f)|

<sup>(Zoom in for details.)</sup>

> [!NOTE]
> This comparison reveals a separate problem we have with image scaling,
which Kitty gets right but we don't -- the interpolation is too dark
because of gamma error, we need to be interpolating in linear space but
instead we're interpolating in gamma compressed space. I'll try to
figure out the best way to resolve this.
2025-05-15 11:42:05 -07:00
Qwerasd ed207514e9 typo 2025-05-15 11:59:17 -06:00
Qwerasd 709b0214a0 fix(renderer): Don't force images to grid/cell sizes
This problem was introduced by f091a69 (PR #6675).

I've gone ahead and overhauled the placement positioning logic as well;
it was doing a lot of expensive calls before, I've significantly reduced
that.

Clipping partially off-screen images is now handled entirely by the
renderer, rather than while preparing the placement, and as such the
grid position passed to the image shader is now signed.
2025-05-15 11:41:12 -06:00
Leah Amelia Chen d6dea79bde
gtk: add option to always display the tab bar
Also fixes crashes in both vanilla GTK and Adwaita implementations of
`closeTab`, which erroneously close windows twice when there are no
more tabs left (we probably already handle it somewhere else).
2025-05-15 19:05:46 +02:00
Aaron Ruan f343e1ba46
Fix comma typo 2025-05-16 00:40:25 +08:00
Leah Amelia Chen cc65dfc90e
gtk(command_palette): focus fixes 2025-05-15 18:11:19 +02:00
Leah Amelia Chen 2800e0c99b
gtk(command_palette): address feedback related to selections
See #7173, #7175
2025-05-15 18:11:19 +02:00
Leah Amelia Chen 7293d91f10
translations(zh_CN): update 2025-05-15 18:11:19 +02:00
Leah Amelia Chen 91f811bfbf
translations: update 2025-05-15 18:11:19 +02:00
Leah Amelia Chen e97dfc2e19
gtk(command_palette): filter out certain actions 2025-05-15 18:11:19 +02:00
Leah Amelia Chen 3b013b1174
gtk: add command palette to titlebar menu 2025-05-15 18:11:19 +02:00
Leah Amelia Chen 048e4acb2c
gtk: implement command palette 2025-05-15 18:11:19 +02:00
Aaron Ruan f6d56f4f03
Handle check_for_updates as unimplemented action 2025-05-15 23:26:47 +08:00
Jeffrey C. Ollie 9ff43cd345
gtk: implement custom audio bell (#5326)
Fixes #2710 

Adds support for custom audio bell notifications.
2025-05-15 10:09:39 -05:00
Aaron Ruan 7ccc181332
macos: add "Check for Updates" action, menu item & key-binding support 2025-05-15 13:34:44 +08:00
Qwerasd 55c1ef779f fix(Metal): interpolate kitty images
uint textures can't be interpolated apparently
2025-05-14 21:12:20 -06:00
Mitchell Hashimoto a74e352726
bench: add `--mode=gen-osc` to generate synthetic OSC sequences
This commit adds a few new mode flags to the `bench-stream` program
to generator synthetic OSC sequences. The new modes are `gen-osc`,
`gen-osc-valid`, and `gen-osc-invalid`. The `gen-osc` mode generates
equal parts valid and invalid OSC sequences, while the suffixed variants
are for generating only valid or invalid sequences, respectively.

This commit also fixes our build system to actually be able to build the
benchmarks. It turns out we were just rebuilding the main Ghostty binary
for `-Demit-bench`. And, our benchmarks didn't run under Zig 0.14, which
is now fixed.

An important new design I'm working towards in this commit is to split
out synthetic data generation to a dedicated package in
`src/bench/synth` although I'm tempted to move it to `src/synth` since
it may be useful outside of benchmarks.

The synth package is a work-in-progress, but it contains a hint of
what's to come. I ultimately want to able to generate all kinds of
synthetic data with a lot of knobs to control dimensionality (e.g. in
the case of OSC sequences: valid/invalid, length, operation types,
etc.).
2025-05-14 12:26:31 -07:00
Mitchell Hashimoto a090e8eeed
url: restrict file paths regex to one slash (#7355)
Fixes https://github.com/ghostty-org/ghostty/discussions/7351.

This restricts the valid path prefixes to prevent false matches caused
by literal dot.
2025-05-14 10:32:08 -07:00
Weizhao Ouyang 528814da79 url: restrict file paths regex to one slash
This restricts the valid path prefixes to prevent false matches caused
by literal dot.

Signed-off-by: Weizhao Ouyang <o451686892@gmail.com>
2025-05-14 23:20:09 +08:00
Jeffrey C. Ollie ba08b0cce5
gtk custom bell audio: optional -> required 2025-05-13 10:01:54 -05:00
Jeffrey C. Ollie 0e8b266662
Use `std.math.clamp`
Co-authored-by: Leah Amelia Chen <github@acc.pluie.me>
2025-05-13 10:01:54 -05:00
Jeffrey C. Ollie 8d0c3c7b7c
gtk: implement custom audio for bell 2025-05-13 10:01:54 -05:00
Mitchell Hashimoto 6984b1ec48
input: add backwards compatible alias for `plus` to `+` (#7342)
From #7320
Discussion #7340

There isn't a `physical` alias because there is no physical plus key
defined for the W3C keycode spec.
2025-05-12 15:39:39 -07:00
Mitchell Hashimoto 507e808a7c
input: add backwards compatible alias for `plus` to `+`
From #7320
Discussion #7340

There isn't a `physical` alias because there is no physical plus key
defined for the W3C keycode spec.
2025-05-12 15:32:32 -07:00
Mitchell Hashimoto 7dc65adb1f
snap: Build with cpu=baseline as documented in PACKAGING.md (#7341)
Ensures baseline instruction set
2025-05-12 15:07:03 -07:00
Ken VanDine e2daf04cba snap: Build with cpu=baseline as documented in PACKAGING.md 2025-05-12 17:40:48 -04:00
Mitchell Hashimoto 00829ca2cc
macos: do not send UTF-8 PUA codepoints to key events (#7338)
Fixes #7337

AppKit encodes functional keys as PUA codepoints. We don't want to send
that down as valid text encoding for a key event because KKP uses that
in particular to change the encoding with associated text.

I think there may be a more specific solution to this by only doing this
within the KKP encoding part of KeyEncoder but that was filled with edge
cases and I didn't want to risk breaking anything else.
2025-05-12 11:45:04 -07:00
Mitchell Hashimoto ecda5ec327
macos: do not send UTF-8 PUA codepoints to key events
Fixes #7337

AppKit encodes functional keys as PUA codepoints. We don't want to send
that down as valid text encoding for a key event because KKP uses that
in particular to change the encoding with associated text.

I think there may be a more specific solution to this by only doing this
within the KKP encoding part of KeyEncoder but that was filled with edge
cases and I didn't want to risk breaking anything else.
2025-05-12 11:42:05 -07:00
Mitchell Hashimoto 6723c308be
input: bracket right was mapped to left, a typo (#7334)
From #7320
2025-05-12 10:00:17 -07:00
Mitchell Hashimoto 6c6cdf4c4f
input: bracket right was mapped to left, a typo 2025-05-12 09:57:10 -07:00
Mitchell Hashimoto 3f54601df0
Use W3C key code specification for keybindings (Breaking Change) (#7320)
Fixes #7315
Fixes #7314 
Fixes #7310 
Fixes #7309

**This PR has breaking changes, noted later.**

This changes our internal key events to match the [W3C key event code
specification](https://www.w3.org/TR/uievents-code/). With these
changes, apprts are expected to produce key codes within that spec and
everything follows from there. This gives us a standard cross-platform
keycode behavior.

Previously, due to our history, we based our key codes on GLFW and Linux
more generally (since Ghostty was on Linux first). This served us
surprisingly well through today, but has been riddled with various
issues (many fixed, but note how many bugs this PR is fixing). From a
user experience perspective, it also caused confusion about how
Ghostty's keybinds interact with keyboard layouts which led to various
complicated features like `physical:` (which is removed in this PR).

## Overview of Changes

* `physical:` is now gone. Physical keys are now specified by the W3C
key codes. Example: `ctrl+KeyA` will always match the "a" key on a US
physical layout (the name `KeyA` lining up with US keyboards is mandated
by the spec, not us). Note when we say "physical" here we mean the
keycode sent by the OS or GUI framework; these can often be overridden
using programs to remap keys at the "hardware" level but software
layouts do not do this.

* All single codepoint characters match the character produced by the
keyboard layout (i.e. are layout-dependent). So `ctrl+c` matches the
physical "c" key on a US standard keyboard with a US layout, but matches
the "i" key on a Dvorak layout. This also works for international
characters. Codepoints are case-insensitive and match via Unicode case
folding (this is how both Windows and macOS treat keyboard shortcuts).

* W3C key names replace all previous non-character names and always
match _physical keys_. For example, `ctrl+grave_accent` (Ghostty 1.1x)
is now `ctrl+backquote` to match the W3C spec. This PR maintains
backwards compatibility so the old values are aliased to the new values.

* W3C key names can be both snake case and match the spec exactly. e.g.
`KeyA` and `key_a` are both valid. This is an aesthetic choice, because
I think the capitalization is really ugly. We have tests to verify this
mapping so its officially supported.

* Because we support W3C keys, we now support significantly more media
keys such as `context_menu`, `browser_home` and so many more. These work
as long as your OS and keyboard can produce the valid key codes.

## Breaking Changes

* Key names have changed, e.g. `grave_accent` is now `backquote`. The
new names are all W3C standard. There are backwards compatible aliases,
so **old configurations will still work.** But the `+list-keybinds` CLI
will always output the new versions.

* `physical:` is gone, all W3C names are always physical and all code
points are always logical. There are backwards compatible aliases for
unambiguous keys, so **most old configurations will still work.** If
there is ambiguity, old configurations will error, but I don't expect
this to be common at all.

* Physical keybinds always take priority over logical keybinds. This was
_inconsistent_ before. Physical keybinds are relatively rare so I don't
think this will impact people but just noting this is not an explicit,
tested, documented behavior.
2025-05-12 09:18:28 -07:00
Mitchell Hashimoto 8f40d1331e
ensure `ctrl++` parses, clarify case folding docs 2025-05-12 09:08:00 -07:00
Mitchell Hashimoto 0eebebb75e
Update iTerm2 colorschemes (#7326)
Upstream revision:
93eb37fadd
2025-05-11 14:45:30 -07:00
Mitchell Hashimoto c4f1c78fcf
macOS: treat C-/ specially again to prevent beep
Fixes #7310
2025-05-11 07:15:46 -07:00
mitchellh db1608ff16 deps: Update iTerm2 color schemes 2025-05-11 00:14:21 +00:00
Mitchell Hashimoto ed1194cd75
fix tests 2025-05-10 08:51:08 -07:00
Mitchell Hashimoto 1752edd9eb
input: implement case folding for binding matching 2025-05-10 07:22:44 -07:00
Mitchell Hashimoto ca2ead9647
input: kitty add missing numpad keycodes since we support those now 2025-05-09 11:09:22 -07:00
Mitchell Hashimoto ebabdb322c
input: ignore control characters for backspace/enter/escape special case 2025-05-09 11:05:42 -07:00
Mitchell Hashimoto a26310e83f
macOS: app key is binding check should include utf-8 chars 2025-05-09 10:45:43 -07:00
Mitchell Hashimoto 293a67cd01
input: control-encode right control properly 2025-05-09 10:16:21 -07:00
Mitchell Hashimoto 54bd701ba9
input: bindings should match on single-codepoint utf-8 text too 2025-05-09 10:01:06 -07:00
Mitchell Hashimoto 5dc88bda6a
macOS: send proper UTF-8 text for more key events 2025-05-09 10:01:06 -07:00
Mitchell Hashimoto d015efc87d
clean up bindings so that they match macOS menus 2025-05-09 10:01:06 -07:00
Mitchell Hashimoto 5962696c3b
input: remove `physical_key` from the key event (all keys are physical) 2025-05-09 10:01:06 -07:00
Mitchell Hashimoto 11a623aa17
docs 2025-05-09 10:01:06 -07:00
Mitchell Hashimoto cc748305fb
input: w3c names for keys 2025-05-09 10:01:06 -07:00
Mitchell Hashimoto 1e76222f19
update docs 2025-05-09 10:01:06 -07:00
Mitchell Hashimoto 7983e0d62c
input: backwards compatibility 2025-05-09 10:01:06 -07:00
Mitchell Hashimoto ffdf86374a
apprt/gtk: build 2025-05-09 10:01:06 -07:00
Mitchell Hashimoto b991d36343
macOS: build 2025-05-09 10:01:06 -07:00
Mitchell Hashimoto 24d433333b
apprt/glfw: builds 2025-05-09 10:01:06 -07:00
Mitchell Hashimoto a3462dd2bd
input: remove translated 2025-05-09 10:01:05 -07:00
Mitchell Hashimoto 91d15c89bc
input: key enum is now aligned with W3C keyboard codes 2025-05-09 10:01:05 -07:00
Mitchell Hashimoto 7f9bb3c0e5
update PACKAGING.md to be explicit about source vs. git (#7317)
Related to #7316

I'm not going to close the issue yet because I want to also update the
website, but this should help clarify things more. I noticed the README
already makes a distinction, thankfully.
2025-05-09 08:54:02 -07:00
Mitchell Hashimoto 201ea050bd
update PACKAGING.md to be explicit about source vs. git
Related to #7316
2025-05-09 08:27:15 -07:00
Bryan Lee 800054874e
macOS: switch to using URL instead of String 2025-05-09 10:52:18 +08:00
Bryan Lee 3043012c1b
macOS: simplify path handling in `openTerminal` 2025-05-08 08:34:02 +08:00
Bryan Lee a8b450f03d
macOS: use file parent dir for `openTerminal` service cwd (#7286) 2025-05-08 08:34:02 +08:00
Mitchell Hashimoto bcff488095
core: add context menu key (#5162)
I have this key on a cheap Lenovo keyboard at work and would like to put
it to some use.
2025-05-07 13:25:18 -07:00
Jeffrey C. Ollie 9c70f8aee1 core: add context menu key 2025-05-07 13:08:38 -07:00
Jeffrey C. Ollie 73ec7e5f10
docs: fix minor grammatical error (#7295)
Fixes a small grammatical error in the config docs.
2025-05-07 14:18:50 -05:00
tangowithfoxtrot 69a744b521
docs: fix minor grammatical error 2025-05-07 11:46:36 -07:00
Jeffrey C. Ollie 0ed4b5d9c6
gtk: only allow one config error dialog at a time (#7293)
This fixes a problem introduced by #7241 that would cause multiple error
dialogs to be shown.
2025-05-07 13:36:17 -05:00
Mitchell Hashimoto c36314ca98
Allow struct/union/enum binding types to have default values (#7291)
This allows for `keybind = super+d=new_split` to now work (defaults to
"auto"). This will also let us convert void types to union/enum/struct
types in the future without breaking existing bindings.
2025-05-07 09:50:44 -07:00
Jeffrey C. Ollie 5d81a31a49
gtk: remove dead code 2025-05-07 11:12:07 -05:00
Jeffrey C. Ollie 00a2d54420
gtk: only allow one config error dialog at a time
This fixes a problem introduced by #7241 that would cause multiple error
dialogs to be shown.
2025-05-07 10:46:46 -05:00
Mitchell Hashimoto 362c5cb05f
Allow struct/union/enum binding types to have default values
This allows for `keybind = super+d=new_split` to now work (defaults to
"auto"). This will also let us convert void types to union/enum/struct
types in the future without breaking existing bindings.
2025-05-07 08:18:28 -07:00
Mitchell Hashimoto f6bb1f5e34
core: fixup callconv(.C) -> callconv(.c) (#7289)
https://ziglang.org/download/0.14.0/release-notes.html#Calling-Convention-Enhancements-and-setAlignStack-Replaced
2025-05-07 08:08:51 -07:00
Jeffrey C. Ollie e8c845b758
core: fixup callconv(.C) -> callconv(.c)
https://ziglang.org/download/0.14.0/release-notes.html#Calling-Convention-Enhancements-and-setAlignStack-Replaced
2025-05-07 08:41:09 -05:00
Mitchell Hashimoto 35c9d32e69
Add "Scroll to Selection" command (#7265)
This is mostly intended for implementing the "Jump to Selection"
(<kbd>⌘</kbd> <kbd>J</kbd>) command on macOS (but as per the TODO, the
pin still needs to be centered)

Demo: (Selected text is "10")

<table><tr>
<td><img width="965" alt="Screenshot 2025-05-03 at 9 21 55 AM"
src="https://github.com/user-attachments/assets/c37ba0b7-f622-48d2-b598-4151e85377ef"
/></td>
<td><img width="965" alt="Screenshot 2025-05-03 at 9 21 58 AM"
src="https://github.com/user-attachments/assets/650f44f9-3125-4a2a-b264-a6e8476e4fcb"
/></td>
</tr></table>
2025-05-06 16:44:21 -07:00
fn ⌃ ⌥ 071531c5c5 Add "Scroll to Selection" command 2025-05-06 16:26:22 -07:00
Mitchell Hashimoto eb7368699b
macOS: move window title handling fully to AppKit, fix command palette losing title (#7283)
Fixes #7236
Supersedes #7249

This removes all of our `focusedValue`-based tracking of the surface
title and moves it completely to the window controller. The window
controller now sets up event listeners (via Combine) when the focused
surface changes and updates the window title accordingly.

There is some complicated logic here to handle when we lose focus to
something other than a surface. In this case, we want our title to be
the last focused surface so long as it exists.

The prior `focusedValue`-based code was a relic of when Ghostty was a
full SwiftUI app. Now that we have AppKit in the mix (and have for a
couple years), we shouldn't bolt on fixes to that cruft if we can help
it.
2025-05-06 15:13:04 -07:00
Mitchell Hashimoto 2caa8a3fe1
macOS: move window title handling fully to AppKit
Fixes #7236
Supersedes #7249

This removes all of our `focusedValue`-based tracking of the surface
title and moves it completely to the window controller. The window
controller now sets up event listeners (via Combine) when the focused
surface changes and updates the window title accordingly.

There is some complicated logic here to handle when we lose focus to
something other than a surface. In this case, we want our title to be
the last focused surface so long as it exists.
2025-05-06 14:57:19 -07:00
Jeffrey C. Ollie 27cdd6d79c
gtk: require blueprint-compiler 0.16 for building (#6827)
Changes:

1. Require `blueprint-compiler` 0.16.0 (or newer) for building from a
git checkout. With #6822 distributions that can't meet that requirement
can use generated source tarballs to build.
2. Remove all `.ui` files as they are unnecessary.
3. Simplify the `Builder` interface since raw `.ui` files are no longer
used.
4. Removed build-time check of raw `.ui` files.
2025-05-06 16:06:53 -05:00
Mitchell Hashimoto 5f8a0dc4a0
termio, flatpak: support spawning terminals in cwd (#6915)
Implements path access testing for Flatpak via test spawning. This is
required since Flatpak reserves certain paths from being accessible
regardless of permissions.

Opened mostly as an RFC, this approach seems to work without any
noticeable performance impact.

Ref:
https://docs.flatpak.org/en/latest/sandbox-permissions.html#reserved-paths
2025-05-06 13:59:48 -07:00
Mitchell Hashimoto 732500b418
feat: implement toggleMaximize for macOS (#7191)
Resolve #7030
2025-05-06 13:43:57 -07:00
Leorize b6f120a749 termio, flatpak: support spawning terminals in cwd
Implements path access testing for Flatpak via test spawning. This is
required since Flatpak reserves certain paths from being accessible
regardless of permissions.

Ref: https://docs.flatpak.org/en/latest/sandbox-permissions.html#reserved-paths
2025-05-06 13:42:14 -07:00
Mitchell Hashimoto e5765dfa79
macOS: save/restore firstResponder on non-native fullscreen (#7279)
Fixes #6999
Supersedes #7201 

It appears that at some point one of the operations causes focus to move
away for non-native fullscreen. We previously relied on the delegate
method to restore this but a better approach appears to handle this
directly in the fullscreen implementations. This fixes the linked issue.

I still think long term all the `Ghostty.moveFocus` stuff is a code
smell and we should be auditing all that code to see if we can eliminate
it. But this is a step in the right direction, and removes one of those
uses.
2025-05-06 13:32:33 -07:00
Mitchell Hashimoto e2a0f439c6
macOS: save/restore firstResponder on non-native fullscreen
Fixes #6999

It appears that at some point one of the operations causes focus to move
away for non-native fullscreen. We previously relied on the delegate
method to restore this but a better approach appears to handle this
directly in the fullscreen implementations. This fixes the linked issue.

I still think long term all the `Ghostty.moveFocus` stuff is a code
smell and we should be auditing all that code to see if we can
eliminate it. But this is a step in the right direction, and removes one
of those uses.
2025-05-06 12:59:31 -07:00
Mitchell Hashimoto d0a8cb671b
macOS: handle scenario cgWindowId is nil (#7277)
Fixes #7114
Supercedes #7271

This fixes a crash that could occur with non-native fullscreen and
`fullscreen = true` set at once.

The "windowNumber" can be `<= 0` if the window "doesn't have a window
device." I don't fully know all the scenarios this is true but it is
true when the window is not visible, at least.
2025-05-06 10:50:14 -07:00
Mitchell Hashimoto 9b78917246
macOS: handle scenario cgWindowId is nil
Fixes #7114
Supercedes #7271

This fixes a crash that could occur with non-native fullscreen and
`fullscreen = true` set at once.

The "windowNumber" can be `<= 0` if the window "doesn't have a
window device." I don't fully know all the scenarios this is true but it
is true when the window is not visible, at least.
2025-05-06 10:33:56 -07:00
Mitchell Hashimoto a4bd6efcbf
ci: add flatpak JSON for iterm2 theme updates (#7275)
I forgot to add the path in the GitHub action.
2025-05-06 09:51:08 -07:00
Mitchell Hashimoto 9221d392de
ci: add flatpak JSON for iterm2 theme updates
I forgot to add the path in the GitHub action.
2025-05-06 07:20:56 -07:00
Mitchell Hashimoto 3c405a591a
update flatpak cache 2025-05-06 07:19:40 -07:00
Mitchell Hashimoto 702c3f58d9
font/freetype: introduce mutexes to ensure thread safety of Library and Face (#7238)
tl;dr: FT_New_Face and FT_Done_Face require the Library to be locked for
thread safety, and FT_Load_Glyph and FT_Render_Glyph and friends need
the face to be locked for thread safety, since we're sharing faces
across threads.

For details see comments and FreeType docs @
-
https://freetype.org/freetype2/docs/reference/ft2-library_setup.html#ft_library
-
https://freetype.org/freetype2/docs/reference/ft2-face_creation.html#ft_face

---

This might resolve the issue discussed in #7016 but I wasn't able to
reliably reproduce it in a way I could debug, so someone who was
experiencing it should probably test this PR.

Additionally I can still semi-reliably produce a crash with the GTK
apprt by setting an `all:` keybind to adjust font sizes and changing the
font size rapidly with many surfaces open with emojis on them.
Unfortunately I can't really tell what the root cause is because the
debug info is broken in QEMU.

However, I do think this is a good idea for us to be thread safe with
this stuff even if it isn't related to that problem.
2025-05-06 07:18:11 -07:00
Mitchell Hashimoto f73f7c805d
Fix removed GDK_DEBUG `gl-no-fractional` (#7233)
`gl-no-fractional` is removed from GTK v4.17.5
2025-05-06 07:17:28 -07:00
Mitchell Hashimoto 050e40a29d
Implement dark/light theme filtering in theme preview (#7248)
This pr closes https://github.com/ghostty-org/ghostty/issues/7235

Demo:


https://github.com/user-attachments/assets/88366ac7-fcdb-49e9-bed7-8deb0eebeb9e
2025-05-06 07:16:46 -07:00
Mitchell Hashimoto 7ce828253a
bash: explicitly request a login shell (#7253)
Prior to #7044, on macOS, our shell integrated command line would be
executed under `exec -l`, which caused bash to be started as a login
shell. Now that we're using direct command execution, add `--login` to
our bash command's arguments on macOS to get that same behavior.
2025-05-06 07:16:09 -07:00
Mitchell Hashimoto e2b5bfb5b0
gtk: fix comment about adwaita version (#7274) 2025-05-06 07:04:32 -07:00
Mitchell Hashimoto f13d74bcf0
improvements to the Issue Triage Discussion template (#7266)
After some time with the initial template and Discussions being created,
there are some improvements we should make to the Issue Triage template.

Most of these changes were discussed in #7012 and among helpers in the
Discord.

~~I've marked this as a Draft for now as I work with the helpers to
confirm how we want to approach a few of the outstanding changes, mostly
minor updates.~~

As always, you can test these out by [opening an Issue Triage Discussion
post on my
fork](https://github.com/taylrfnt/ghostty/discussions/new?category=issue-triage).
2025-05-06 06:57:36 -07:00
Mitchell Hashimoto b346f06a51
Update iTerm2 colorschemes (#7268)
Upstream revision:
1e4957e650
2025-05-06 06:56:49 -07:00
Jeffrey C. Ollie 1bf686d324
gtk: fix comment about adwaita version 2025-05-06 08:44:52 -05:00
taylrfnt ac11ebbb4a
update applied label to proper name
Co-authored-by: Kat <65649991+00-kat@users.noreply.github.com>
2025-05-05 21:37:49 -05:00
taylrfnt ad0d426bba
consistent spacing with tip & important highlights
Co-authored-by: Kat <65649991+00-kat@users.noreply.github.com>
2025-05-05 21:36:38 -05:00
taylrfnt d0b9242f49
replace dashes with code block backticks for additional config
Co-authored-by: Kat <65649991+00-kat@users.noreply.github.com>
2025-05-05 21:34:33 -05:00
taylrfnt f9c1b6b7cf
fixup markdown in additional config field
Co-authored-by: Kat <65649991+00-kat@users.noreply.github.com>
2025-05-05 19:28:31 -05:00
taylrfnt ad16f984cf
remove smart quotes in favor of ascii
Co-authored-by: Kat <65649991+00-kat@users.noreply.github.com>
2025-05-05 19:27:08 -05:00
taylrfnt f84367880b
Properly enclose code block backticks
Co-authored-by: Kat <65649991+00-kat@users.noreply.github.com>
2025-05-05 19:23:40 -05:00
Jon Parise 37974dba06 bash: explicitly request a login shell
Prior to #7044, on macOS, our shell integrated command line would be
executed under `exec -l`, which caused bash to be started as a login
shell. Now that we're using direct command execution, add `--login` to
our bash command's arguments on macOS to get that same behavior.
2025-05-05 10:26:37 -04:00
taylrfnt 11db0ed8ae
re-apply formatting & overwrite, not append 2025-05-04 12:17:29 -05:00
taylrfnt 8dfa6beb15
add acknowledgement for previewing format before submitting
Co-authored-by: Kat <65649991+00-kat@users.noreply.github.com>
2025-05-04 12:04:09 -05:00
taylrfnt 431116c9d8
do not ask users for a summary 2025-05-04 12:01:22 -05:00
taylrfnt 46d3de26fc
remove renderers prone to jailbreak 2025-05-04 11:59:57 -05:00
taylrfnt 233ef4f782
more updates to expected behavior placeholder
Co-authored-by: Kat <65649991+00-kat@users.noreply.github.com>
2025-05-04 11:58:50 -05:00
taylrfnt 050375cbb6
make minimum configuration more explicit
Co-authored-by: Kat <65649991+00-kat@users.noreply.github.com>
2025-05-03 21:56:08 -05:00
taylrfnt cc95475ae9
update placeholder text
remove the 'example:' prefixes and make them sound less like it's AI-generated
2025-05-03 21:48:59 -05:00
taylrfnt 1f9a4e6794
more direct naming of minimal configuration
Co-authored-by: Kat <65649991+00-kat@users.noreply.github.com>
2025-05-03 21:38:19 -05:00
taylrfnt 0bf168c834
terminal inspector no longer proper noun 2025-05-03 21:38:19 -05:00
taylrfnt 6ffb6207e7
split out expected & actual behavior fields 2025-05-03 21:38:19 -05:00
taylrfnt 9c2f8d8ad3
cleanup the input issue hint
Co-authored-by: trag1c <dev@jakubr.me>
2025-05-03 21:38:19 -05:00
taylrfnt 51b6925322
add Linux log hint 2025-05-03 21:38:19 -05:00
taylrfnt 41e3c8830f
change VT to terminal emulation
Co-authored-by: Leah Amelia Chen <hi@pluie.me>
2025-05-03 21:37:50 -05:00
taylrfnt 71f52fd198
re-order ghostty logs field 2025-05-03 20:53:00 -05:00
taylrfnt 4d27fc18eb
use log stream command instead of link to discussion
Co-authored-by: Kat <65649991+00-kat@users.noreply.github.com>
2025-05-03 20:50:04 -05:00
mitchellh abf5f18598 deps: Update iTerm2 color schemes 2025-05-04 00:14:51 +00:00
Mitchell Hashimoto b6f338065e
ci: workaround broken lxd start with snap builder (#7267)
https://discourse.ubuntu.com/t/lxd-doesn-t-start-snap-lxd-device-directory-nonexistent/59785
https://github.com/canonical/lxd-pkg-snap/pull/789

This is required until Namespace or further upstream fixes are made.
2025-05-03 15:05:33 -07:00
Mitchell Hashimoto e174599533
ci: workaround broken lxd start with snap builder
https://discourse.ubuntu.com/t/lxd-doesn-t-start-snap-lxd-device-directory-nonexistent/59785
https://github.com/canonical/lxd-pkg-snap/pull/789

This is required until Namespace or further upstream fixes are made.
2025-05-03 13:20:00 -07:00
taylrfnt 60e1a73c04
update log textarea render to display inputs in codeblock 2025-05-03 14:45:53 -05:00
taylrfnt 10dcf1dfe9
fix most of the feedback from 7012 2025-05-03 14:40:34 -05:00
Mitchell Hashimoto 040cdba707
flatpak: update GNOME runtime to 48 (#7261)
Notable dependencies updates:

- GTK 4.16.13 -> 4.18.4
- Libadwaita 1.6.6 -> 1.7.2
2025-05-03 06:57:33 -07:00
Leorize c0f41aba45
flatpak: update GNOME runtime to 48
Notable dependencies updates:

- GTK 4.16.13 -> 4.18.4
- Libadwaita 1.6.6 -> 1.7.2
2025-05-02 14:24:02 -05:00
Mitchell Hashimoto 464b85b64c
codeowners: correct shell_integration.zig filename (#7255) 2025-05-02 08:25:27 -07:00
Jon Parise b2138eeaf0 codeowners: correct shell_integration.zig filename 2025-05-02 10:59:52 -04:00
Qwerasd 5319d38366 fix(tests): correctly deinit font faces 2025-05-01 18:37:47 -06:00
Qwerasd cfedd477b2 font/freetype: introduce mutexes to ensure thread safety of Library and Face
For details see comments and FreeType docs @
https://freetype.org/freetype2/docs/reference/ft2-library_setup.html#ft_library
https://freetype.org/freetype2/docs/reference/ft2-face_creation.html#ft_face

tl;dr: FT_New_Face and FT_Done_Face require the Library to be locked for
thread safety, and FT_Load_Glyph and FT_Render_Glyph and friends need
the face to be locked for thread safety, since we're sharing faces
across threads.
2025-05-01 18:22:37 -06:00
Maciej Bartczak 418c46538c use enum for the color scheme args 2025-05-01 19:41:02 +02:00
Maciej Bartczak 0b5160e9f0 implement dark/light theme filtering in theme preview 2025-05-01 19:02:34 +02:00
Mitchell Hashimoto e79bf71f23
Binding for toggling window float on top (macOS only) (#7246)
This adds a keybinding and apprt action for #7237.
2025-05-01 09:51:09 -07:00
Mitchell Hashimoto 6e11d947e7
Binding for toggling window float on top (macOS only)
This adds a keybinding and apprt action for #7237.
2025-05-01 09:47:17 -07:00
Mitchell Hashimoto a6fd499019
macos: add float on top feature for terminal windows (#7237)
Closes #5188

**See:** 

-
https://github.com/ghostty-org/ghostty/discussions/5188#discussioncomment-12607781
-
https://github.com/ghostty-org/ghostty/discussions/5188#discussioncomment-12984898
2025-05-01 09:24:15 -07:00
Martin Hettiger f83729ba48 macos: add float on top feature for terminal windows 2025-05-01 09:13:33 -07:00
Mitchell Hashimoto 4b3a49a56e
apprt/gtk: ensure configuration is loaded on startup (#7241)
Restores the app configuration code removed in
https://github.com/ghostty-org/ghostty/pull/6792.

The was unnoticed due to `colorSchemeEvent` triggering a configuration
reload if `window-theme` deviates from the default (i.e. dark mode is
used).

Fixes https://github.com/ghostty-org/ghostty/discussions/7206
2025-05-01 08:30:22 -07:00
Leorize 0af5a291ac
apprt/gtk: ensure configuration is loaded on startup
Restores the app configuration code removed in
https://github.com/ghostty-org/ghostty/pull/6792.

The was unnoticed due to `colorSchemeEvent` triggering a
configuration reload if `window-theme` deviates from the default
(i.e. dark mode is used).

Fixes https://github.com/ghostty-org/ghostty/discussions/7206
2025-05-01 01:59:36 -05:00
Leah Amelia Chen 2b4f1f8b84
Improve the documentation for `gtk-custom-css` (#7190)
Recently when answering [a Discussion], I was reminded of when Tristan
once linked the GTK CSS documentation and said “Perhaps good to add this
to the docs of the GTK custom CSS config option”, so I decided to do
that now. I also added a few random things that I found helpful when
attempting to modify Ghostty's CSS; this information was mostly stolen
from random people on Discord or accidentally discovered.

I really do not care if this is merged or not, nor do I care if the
strings are changed considerably[^1], so I am going straight for a Pull
Request without bothering to open a Discussion, get that converted to an
Issue after a few years, then finally remember to open a Pull Request.

I only tested what this looks like in `ghostty +show-config --default
--docs`, the manpage and the HTML output; I notably did not try seeing
how it renders on the website. The links have to be in angle brackets
for the HTML output to have it rendered as URLs, but it looks odd
everywhere else; manpages have them with mathematical angle brackets,
⟨like this⟩. I also refrained from using an em (—) or en (–) dash
instead of a normal dash (-) as that does not seem to be common in the
rest of the documentation.

[a Discussion]: https://github.com/ghostty-org/ghostty/discussions/7189

[^1]: I didn't see any guidelines or standards for these strings, so
presumably these would be contested as I didn't know what to adhere to
when writing them.
2025-04-30 22:33:11 +02:00
Morgan 6f4fe56b93
Add comment about `gl-no-fractional` 2025-04-30 23:50:11 +09:00
Mitchell Hashimoto ff536e34d6
i18n: fixed the translation for Russian (#7218)
The problem was highlighted in
https://github.com/ghostty-org/ghostty/pull/7127#discussion_r2051223171

In Russian, the words
[`затем`](https://ru.wiktionary.org/wiki/%D0%B7%D0%B0%D1%82%D0%B5%D0%BC)
and [`либо`](https://ru.wiktionary.org/wiki/%D0%BB%D0%B8%D0%B1%D0%BE)
are written separately.

@zeshi09 @TicClick take a look?
2025-04-30 07:02:21 -07:00
Morgan 5291292047
Add `runtimeUntil`, fix remove GDK_DEBUG `gl-no-fractional` 2025-04-30 15:58:21 +09:00
Tim Culverhouse b3edc88010
terminal(dcs): convert all xtgettcap queries to upper (#7230)
XTGETTCAP queries are a semicolon-delimited list of hex encoded terminfo
capability names. Ghostty encodes a map using upper case hex encodings,
meaning when an application uses a lower case encoding the capability is
not found. To fix, we convert the entire list we receive in the query to
upper case prior to processing further.

Fixes: #7229
2025-04-29 19:06:25 -05:00
Tim Culverhouse 2c1ade763f
terminal(dcs): convert all xtgettcap queries to upper
XTGETTCAP queries are a semicolon-delimited list of hex encoded terminfo
capability names. Ghostty encodes a map using upper case hex encodings,
meaning when an application uses a lower case encoding the capability is
not found. To fix, we convert the entire list we receive in the query to
upper case prior to processing further.

Fixes: #7229
2025-04-29 18:42:16 -05:00
Mitchell Hashimoto 533354480a
ci: drop l10n review workflow (#7228)
*better things are coming*
2025-04-29 14:13:33 -07:00
trag1c 87107a7934
ci: drop l10n review workflow 2025-04-29 18:32:59 +02:00
Kat 4e39756501
Link to GTK CSS docs and add some useful tips to gtk-custom-css' docs.
It may not be immediately obvious how to style Ghostty despite knowing
of the existence of that configuration option; one who is more
accustomed to web development would likely be very reliant on their
browser's inspector for modifying and debugging the style of their
application. GTK CSS also differs in some important ways from the CSS
found in browsers, and hence linking to the GTK CSS documentation would
save time for anyone new to styling GTK applications.
2025-04-29 22:56:23 +10:00
Mitchell Hashimoto 9a4419ce85
macos: key input that clears preedit without text shouldn't encode (#7226)
Fixes #7225
2025-04-28 14:58:19 -07:00
Mitchell Hashimoto e5e89bcbe4
macos: key input that clears preedit without text shouldn't encode
Fixes #7225
2025-04-28 14:01:17 -07:00
Aaron Ruan 13f776d483
Rename maximize notification and refine handler 2025-04-28 10:20:29 +08:00
Danil Ovchinnikov 42913c7830 i18n: fixed the translation for Russian
Co-authored-by: TicClick <ya@ticclick.ch>
2025-04-28 04:08:04 +03:00
Mitchell Hashimoto 7daabdddef
ci: iTerm2 colorscheme update should update flatpak deps (#7214) 2025-04-27 07:50:18 -07:00
Mitchell Hashimoto 99db6b59be
Add config color palette C bindings (#7195)
C bindings to expose the color palette to Swift for macOS. Returns the
full 256 colors from the current color scheme. After fetching the
palette with `ghostty_config_get`, you can access the desired color by
its index in the list.

### Usage

Here is one way to get the palette in Swift.

```swift
import GhosttyKit

private(set) var config: ghostty_config_t? = nil {
    didSet {
        // Free the old value whenever we change
        guard let old = oldValue else { return }
        ghostty_config_free(old)
    }
}

var paletteColors: [Color] {
    var paletteList: ghostty_config_palette_s = .init()
    let key = "palette"
    
    if (!ghostty_config_get(config, &paletteList, key, UInt(key.count))) {
        return []
    }
    
    var colors: [Color] = []
    let mirror = Mirror(reflecting: paletteList.colors)
    
    for (_, element) in mirror.children {
        if let color = element as? ghostty_config_color_s {
            colors.append(Color(
                red: Double(color.r) / 255,
                green: Double(color.g) / 255,
                blue: Double(color.b) / 255
            ))
        }
    }
    
    print("Palette Colors: ", colors)
    return colors
}
```
Result (GruvboxDarkHard theme)
![CleanShot 2025-04-25 at 14 21
39](https://github.com/user-attachments/assets/a282fd8d-3e5e-4281-819c-dff00b84318f)
2025-04-27 07:14:26 -07:00
Mitchell Hashimoto f0339d5e5b
ci: iTerm2 colorscheme update should update flatpak deps 2025-04-27 07:01:52 -07:00
Mitchell Hashimoto c7b8fd1354
flatpak: update dependencies 2025-04-27 07:00:24 -07:00
Mitchell Hashimoto 17441de37f
Update iTerm2 colorschemes (#7210)
Upstream revision:
5233095e44
2025-04-27 06:53:06 -07:00
Mitchell Hashimoto d4acdf44a9
z2d 0.6.0 -> 0.6.1 for security fix (#7211)
version 0.6.0 of z2d has a security vulnerability and the author
suggests upgrading (randomly saw this in the zig discord)

https://github.com/vancluever/z2d/security/advisories/GHSA-mm4c-p35v-7hx3

I don't know enough about how ghostty uses to it to say if it could be
affected

also updates that Context no longer returns an error type this says it
was in the 0.6.0 changes which ghostty was already pinned to (it seems
like that the tag might have been updated or something im not sure) you
can see it listed as a change in 0.6.0 below
https://github.com/vancluever/z2d/blob/main/CHANGELOG.md

I'm not sure if any other changes are required I ran a `zig build` and
`zig build test` and things seem to be fine on my end

~~I'm not sure I updated the zon nix stuff correctly I just ran the
command in jcollie readme
`nix run github:jcollie/zon2nix#zon2nix -- --nix=build.zig.zon.nix
build.zig.zon`~~ looks like I should have just ran the script

ps: sorry for the direct ping mitchell (I thought this might be
important that you look at it)
2025-04-27 06:51:23 -07:00
rhodes-b ba5c773f0f update flatpak packages 2025-04-27 00:05:10 -05:00
rhodes-b b1561112d0 run the nix cache script 2025-04-27 00:03:00 -05:00
rhodes-b bbbe81efc5 z2d context no longer has err return 2025-04-26 23:51:04 -05:00
rhodes-b 0c8339d2da update z2d to 0.6.1 2025-04-26 23:39:02 -05:00
Aaron Ruan 1ec3e331de
Refactor toggleMaximize to use notifications 2025-04-27 08:48:06 +08:00
mitchellh 12f48419b6 deps: Update iTerm2 color schemes 2025-04-27 00:14:50 +00:00
Mitchell Hashimoto 38445dca2a
feat: beautify macOS command palette (#7179)
Resolve 1. of #7173
<img width="1126" alt="image"
src="https://github.com/user-attachments/assets/8904b09f-42f6-4f26-a722-c92dad8e2933"
/>

Changes made:
1. Change shortcut from `String` to `[String]` so its easier to iterate
over it.
2. Overlay background color on top of an `ultraThinMaterial` for better
aesthetic.
3. Reorganize and beautify the spacings and paddings.
4. Unhide the scrollbar.
5. Reorder the modifier keys to Control, Option, Shift and then Command.
<https://leancrew.com/all-this/2017/11/modifier-key-order/>
6. Style shortcut keys to resemble macOS menu bar items, using
corresponding symbols and fixed-width for alignment.
2025-04-25 12:01:01 -07:00
Mitchell Hashimoto 2b4d89e11f
macOS: scheme doesn't need to be state 2025-04-25 11:42:12 -07:00
Friedrich Stoltzfus 77f5fc34f1 Add config color palette C bindings
C bindings to expose the color palette to Swift for macOS.
2025-04-25 14:10:35 -04:00
Aaron Ruan 334093a9ea
feat: implement toggleMaximize for macOS 2025-04-25 15:59:44 +08:00
Aaron Ruan 1acb1715c3
replace NSVisualEffectView with ultraThinMaterial plus a background color 2025-04-25 10:42:22 +08:00
Aaron Ruan 3827ce9e4c
feat: beautify command palette 2025-04-24 12:46:38 +08:00
Mitchell Hashimoto 4e91d11a60
macOS: add descriptions for PgUp, PgDown, End, and Home keys (#7177)
Resolves #7174. The PgUp, PgDown, End, and Home keys were not being
assigned a description in the `KeyboardShortcut` extension.
2025-04-23 13:32:51 -07:00
Friedrich Stoltzfus f58fba54a0 macOS: add descriptions for PgUp, PgDown, End, and Home keys
These keys were not being assigned a description in the KeyboardShortcut
extension. This caused problems for the macOS command pallete.
2025-04-23 16:05:51 -04:00
Mitchell Hashimoto afd8d10b82
macOS: Command palette has no selection by default, selection wraps (#7175)
#7173

(1) The command palette no longer has any selection by default. If and
when we introduce most recently used commands, defaulting to that would
make sense. A selection only appears when the arrow keys are used or the
user starts typing.

(2) The selection with arrow keys now wraps, so if you press "down" on
the last option, it will wrap to the first option, and if you press "up"
on the first option, it will wrap to the last option. This matches both
VSCode and Zed.
2025-04-23 10:50:13 -07:00
Mitchell Hashimoto 9bfe4544bf
macOS: Command palette has no selection by default, selection wraps
#7173

(1) The command palette no longer has any selection by default.
If and when we introduce most recently used commands, defaulting to that
would make sense. A selection only appears when the arrow keys are used
or the user starts typing.

(2) The selection with arrow keys now wraps, so if you press "down" on
the last option, it will wrap to the first option, and if you press "up"
on the first option, it will wrap to the last option. This matches both
VSCode and Zed.
2025-04-23 10:37:20 -07:00
Mitchell Hashimoto f2c798d319
macOS: Command Pallete Improvements (#7171)
As discussed in #7165, this PR resolves two issues with the command
pallete on macOS.
1. The flashing of a command passing out of view was caused by the
`withAnimation` function. Removing this closure resolved this issue.
2. The current implementation kept the selected command anchored to the
middle of the pallete. However, most command pallates allow you to key
through the visible options, only scrolling when your selection hits the
boundary. I resolved this by removing the `anchor: .center` parameter
for the `scrollTo` command.
2025-04-23 08:35:33 -07:00
Jeffrey C. Ollie 75cc4b29fd
gtk: require blueprint-compiler 0.16 for building
Changes:

1. Require `blueprint-compiler` 0.16.0 (or newer) for building from
   a git checkout. With #6822 distributions that can't meet that
   requirement can use generated source tarballs to build.
2. Remove all `.ui` files as they are unnecessary.
3. Simplify the `Builder` interface since raw `.ui` files are no
   longer used.
4. Removed build-time check of raw `.ui` files.
2025-04-23 10:35:10 -05:00
Mitchell Hashimoto ba6ed1f3c5
snap: build from source tarball (#6831)
Eliminates the need for `blueprint-compiler`, which isn't quite new
enough on the snap builder.
2025-04-23 06:58:14 -07:00
Jeffrey C. Ollie 6bd9e35cd6
snap: build from source tarball 2025-04-23 08:10:01 -05:00
Friedrich Stoltzfus b4b2b10328 macOS: command pallete scroll improvements
Removes the withAnimation closure which caused flashing when scrolling
up or down with arrow keys. Also removes the center anchor to behave
more like other command palletes (e.g., Zed, Raycast).
2025-04-22 16:12:09 -04:00
Mitchell Hashimoto f5b5a36835
Fix flatpak packaging to a working state (#6678)
This should make testing Flatpak builds a lot easier.

To build, enter `flatpak/` directory and run:

    flatpak-builder --repo=repo builddir com.mitchellh.ghostty.yml

alternatively, using org.flatpak.Builder flatpak:

    flatpak run -p org.flatpak.Builder \
      --repo=repo \
      builddir \
      com.mitchellh.ghostty.yml

The resulting flatpak can be installed using

    flatpak install ./repo com.mitchellh.ghostty

Credit of AppStream metadata goes to @yorickpeterse.
2025-04-22 12:19:55 -07:00
Mitchell Hashimoto e6c2105a2b
ci: fix up flatpak deps 2025-04-22 12:02:24 -07:00
Mitchell Hashimoto 946cf5a375
update flatpak build hash 2025-04-22 10:57:17 -07:00
Mitchell Hashimoto d7256c71c4
ci: flatpak 2025-04-22 10:56:10 -07:00
Mitchell Hashimoto 3e81006eaa
prettier 2025-04-22 10:56:09 -07:00
Leorize 7c1e68293e flatpak: use archive for gtk4-layer-shell 2025-04-22 10:56:09 -07:00
Leorize 0473b0c3f4 metainfo: update with extra data
* Added URLs to more resources
* Fixed developer ID
* Added device compatibility information
2025-04-22 10:56:09 -07:00
Leorize 9de1aadbab flatpak: add development variant
This variant is built in Debug mode and is given a different desktop
file so it could be installed side-by-side with regular Ghostty.
2025-04-22 10:56:09 -07:00
Leorize 3232cfe138 flatpak: keep debug info for ghostty itself
Flatpak will strip them out on its own into an extension package, useful
for debugging
2025-04-22 10:56:09 -07:00
Leorize ebc169dbaf Fix flatpak packaging to a working state
This should make testing Flatpak builds a lot easier.

To build, enter `flatpak/` directory and run:

    flatpak-builder --repo=repo builddir com.mitchellh.ghostty.yml

alternatively, using org.flatpak.Builder flatpak:

    flatpak run -p org.flatpak.Builder \
      --repo=repo \
      builddir \
      com.mitchellh.ghostty.yml

The resulting flatpak can be installed using

    flatpak install ./repo com.mitchellh.ghostty

Credit of AppStream metadata goes to @yorickpeterse.
2025-04-22 10:56:09 -07:00
Mitchell Hashimoto 17b0bf585d
apprt/gtk: add menu to new tab button to create splits (#7137)
Closes: https://github.com/ghostty-org/ghostty/discussions/6828
2025-04-22 09:07:10 -07:00
Mitchell Hashimoto f36729de39
mark new strings as untranslated 2025-04-22 08:57:29 -07:00
Mitchell Hashimoto ba67c506f2
ci: extract translation check to script so we can run standalone 2025-04-22 08:55:03 -07:00
Mitchell Hashimoto 74e1c47623
macOS: Command Palette (#7153)
This introduces a command palette (inspired by @pluiedev's work in
#5681, but not using it as a base) for macOS.

The command palette is available in the `View` menu and also bindable
via `toggle_command_palette`, default binding is `cmd+shift+p` to match
VSCode.

The commands in the command palette must map to a _bindable_ action,
though they may not have an associated keybinding. This means that any
new binding actions we add in the future can be represented here and
also makes it easy in the future to add configuration to add new custom
entries to the command palette. For this initial PR, the available
commands are hardcoded (`src/input/commands.zig`).

I've noticed in other programs (VSCode, Zed), the command palette
contains pretty much _all available actions_ even if they're basically
useless in the context of a command palette. For example, Zed has the
"toggle command palette" action in the command palette and it... does
nothing (it probably should hide the palette). I followed @pluiedev's
lead and made this subjective in this PR but I wonder if we should
actually force all binding actions to be available.

There are various other improvements I'd like to make but omitted from
this PR for the sake of limiting scope:

* Instead of an entry with no matches doing nothing, we can allow users
to manually input _any_ configurable binding.
* Localization, since macOS doesn't have any yet. But for Linux when we
port this we probably have to change our strings extraction.

## Demo


https://github.com/user-attachments/assets/a2155cfb-d86b-4c1a-82b5-74ba927e4d69
2025-04-22 08:52:27 -07:00
Mitchell Hashimoto ce987ba56d
macOS: Add dock badge notification for bell events (#7118)
Resolves #7108

This PR adds visual notification badges to the Ghostty dock icon when
bell events are triggered while the application is in the background.
This complements the existing dock bounce notification, making it easier
for users to notice when a terminal needs attention.


https://github.com/user-attachments/assets/b54c881f-fea8-4085-8614-432d9e5847b9
2025-04-22 08:39:49 -07:00
Mitchell Hashimoto 5427b0b507
macOS: add description as hover tooltip 2025-04-22 08:36:17 -07:00
Mitchell Hashimoto 3e5fe5de9a
move command filtering into apprt 2025-04-22 08:33:32 -07:00
Mitchell Hashimoto 28404e946b
order commands alphabetically and preserve capitalization 2025-04-21 17:13:12 -07:00
Mitchell Hashimoto 7ef9c24e3f
renderer/opengl: reduce flickering/stretching on resize (#7155)
Fixes #2446
Supersedes #7144

Two separate issues:

1. Ensure that our screen size matches the viewport size when drawFrame
is called. By the time drawFrame is called, GTK will have updated the
OpenGL context, but our deferred screen size may still be incorrect
since we wait for the pty to update the screen size.

2. Do not clear our cells buffer when the screen size changes, instead
changing to a mechanism that only clears the buffers when we have over
50% wasted space.

/cc @adlr I added you as a coauthor.
2025-04-21 14:39:48 -07:00
Mitchell Hashimoto e5e9d43d52
renderer/opengl: reduce flickering/stretching on resize
Fixes #2446

Two separate issues:

  1. Ensure that our screen size matches the viewport size when
     drawFrame is called. By the time drawFrame is called, GTK will have
     updated the OpenGL context, but our deferred screen size may still
     be incorrect since we wait for the pty to update the screen size.

  2. Do not clear our cells buffer when the screen size changes, instead
     changing to a mechanism that only clears the buffers when we have
     over 50% wasted space.

Co-authored-by: Andrew de los Reyes <adlr@rivosinc.com>
2025-04-21 14:02:55 -07:00
Tristan Partin 1c62ddffc4 apprt/gtk: add menu to new tab button to create splits
Closes: https://github.com/ghostty-org/ghostty/discussions/6828
Signed-off-by: Tristan Partin <tristan@partin.io>
2025-04-21 13:01:37 -05:00
Mitchell Hashimoto a732bb272d
fix CI 2025-04-21 10:54:23 -07:00
Mitchell Hashimoto e33eed0216
macOS: command palette visual tweaks 2025-04-21 10:40:30 -07:00
Leah Amelia Chen 3e9b5d491c
apprt/gtk: fix typo (#7152) 2025-04-22 01:30:49 +08:00
Mitchell Hashimoto baad082438
macOS: command palette selection tweaks 2025-04-21 10:26:29 -07:00
Mitchell Hashimoto 6dad763e69
input: omit commands that are platform-specific 2025-04-21 10:20:32 -07:00
Mitchell Hashimoto 63b4cb4ead
macOS: fix responder chain 2025-04-21 10:17:02 -07:00
Tristan Partin f2fa47bca7 apprt/gtk: fix typo
I had a copy-paste error when I used right instead of up.

Signed-off-by: Tristan Partin <tristan@partin.io>
2025-04-21 12:12:54 -05:00
Mitchell Hashimoto 6d2685b5a2
add toggle command palette binding 2025-04-21 10:05:30 -07:00
Mitchell Hashimoto 8bd91e7104
macOS: hook up full action execution 2025-04-21 09:40:08 -07:00
Mitchell Hashimoto afd4ec6de2
macOS: command palette "enter" works 2025-04-21 09:32:51 -07:00
Mitchell Hashimoto 0915a7af46
macOS: extract TerminalCommandPalette 2025-04-21 09:18:46 -07:00
Mitchell Hashimoto 5fab6faf04
macOS: hook up command palette C API to actual command palette 2025-04-21 08:32:42 -07:00
Mitchell Hashimoto 8615dfb73d
libghostty: add API for getting commands 2025-04-21 08:32:05 -07:00
Mitchell Hashimoto a34134e643
input: defind Command struct and default commands 2025-04-21 08:32:05 -07:00
Mitchell Hashimoto be7fb45e9f
command palette SwiftUI view 2025-04-21 08:32:05 -07:00
Mitchell Hashimoto 40c3dbbb31
macOS: remove "r" & "c" from resize overlay (#7142)
as per [#6013](https://github.com/ghostty-org/ghostty/pull/6013) and
[#6040](https://github.com/ghostty-org/ghostty/pull/6040) but for macOS
2025-04-21 08:13:49 -07:00
Asadullah Shaikh 9709d934f0 remove "r" & "c" from resize overlay on macOS 2025-04-21 20:25:25 +05:30
Mitchell Hashimoto 8c02eea48b
macOS: get proper unshifted codepoint with ctrl pressed (#7150)
Fixes a regression where `C-S-c` stopped working properly in both legacy
and Kitty modes (although the Kitty mode side only affected alternates
and not the key itself so it probably worked fine in most programs).

The issue is that `charactersIgnoringModifiers` changes behavior if
`control` is pressed, so it doesn't really ignore all modifiers. We have
to use `characters(byApplyingModifiers:)` to get the proper unshifted
codepoint when `control` is pressed.
2025-04-21 07:52:39 -07:00
Mitchell Hashimoto 643c882597
macOS: use KeyboardShortcut rather than homegrown KeyEquivalent (#7139)
This replaces the use of our custom `Ghostty.KeyEquivalent` with the
SwiftUI `KeyboardShortcut` type. This is a more standard way to
represent keyboard shortcuts and lets us more tightly integrate with
SwiftUI/AppKit when necessary over our custom type.

This PR should have no user impact. This is just some cleanup for future
work.

Note that not all Ghostty triggers can be represented as
KeyboardShortcut values because macOS itself does not support binding
keys such as function keys (e.g. F1-F12) to KeyboardShortcuts.

This isn't an issue since all input also passes through a lower level
libghostty API which can handle all key events, we just can't show these
keyboard shortcuts on things like the menu bar. This was already true
before this commit.
2025-04-21 07:26:34 -07:00
Mitchell Hashimoto fe3b0e0ef6
Correct `change_title_prompt` → `prompt_surface_title` (#7149)
This was changed pretty late at
https://github.com/ghostty-org/ghostty/pull/4217#issuecomment-2660307923,
and I don't think anybody saw my comment at
https://github.com/ghostty-org/ghostty/pull/4217#discussion_r2045783050;
I have no idea if this change is correct and have no way to test it
either as I don't use macOS, but I'm quite suspicious of that line
having not been changed.
2025-04-21 07:25:09 -07:00
Mitchell Hashimoto 7e00f2fb7f
macOS: get proper unshifted codepoint with ctrl pressed
Fixes a regression where `C-S-c` stopped working properly in both legacy
and Kitty modes (although the Kitty mode side only affected alternates
and not the key itself so it probably worked fine in most programs).

The issue is that `charactersIgnoringModifiers` changes behavior if
`control` is pressed, so it doesn't really ignore all modifiers. We have
to use `characters(byApplyingModifiers:)` to get the proper unshifted codepoint
when `control` is pressed.
2025-04-21 07:23:24 -07:00
Mitchell Hashimoto 7d4dddb94e
Update iTerm2 colorschemes (#7140)
Upstream revision:
c5e4212e76
2025-04-21 07:11:58 -07:00
Leah Amelia Chen b13b6465f2
Remove note about default from bell-features→system's description (#7148) 2025-04-21 11:53:48 +08:00
Kat d4525f2c57
Correct remaining instances of `change_title_prompt` to `prompt_surface_title`. 2025-04-21 03:41:52 +00:00
Kat 160b26708c
Remove note about default from bell-features→system's description. 2025-04-21 03:24:05 +00:00
mitchellh 48cba761b9 deps: Update iTerm2 color schemes 2025-04-20 00:14:26 +00:00
Mitchell Hashimoto b05826ac9d
macOS: use KeyboardShortcut rather than homegrown KeyEquivalent
This replaces the use of our custom `Ghostty.KeyEquivalent` with
the SwiftUI `KeyboardShortcut` type. This is a more standard way to
represent keyboard shortcuts and lets us more tightly integrate with
SwiftUI/AppKit when necessary over our custom type.

Note that not all Ghostty triggers can be represented as
KeyboardShortcut values because macOS itself does not support
binding keys such as function keys (e.g. F1-F12) to KeyboardShortcuts.

This isn't an issue since all input also passes through a lower level
libghostty API which can handle all key events, we just can't show these
keyboard shortcuts on things like the menu bar. This was already true
before this commit.
2025-04-19 14:39:48 -07:00
Mitchell Hashimoto 4e10f972df
macOS: Do not send control characters as UTF8 keyboard text (#7136)
Fixes a regression where `ctrl+enter` was not encoding properly since
our input stack changes.
2025-04-19 07:06:39 -07:00
Mitchell Hashimoto 9beaed45f8
Revert "apprt/gtk: add menu to new tab button to create splits (#7127)"
This reverts commit 14134d61fb, reversing
changes made to 6a876ef8ec.

This causes translation failures, this should be reintroduced when the
CI check passes.
2025-04-19 07:05:38 -07:00
Mitchell Hashimoto 31b2ac4b79
macOS: Do not send control characters as UTF8 keyboard text
Fixes a regression where `ctrl+enter` was not encoding properly since
our input stack changes.
2025-04-19 06:54:36 -07:00
Tristan Partin 14134d61fb
apprt/gtk: add menu to new tab button to create splits (#7127)
Closes: https://github.com/ghostty-org/ghostty/discussions/6828
2025-04-19 01:23:18 -05:00
Tristan Partin 410761d4e3 apprt/gtk: add menu to new tab button to create splits
Closes: https://github.com/ghostty-org/ghostty/discussions/6828
Co-authored-by: Leah Amelia Chen <github@acc.pluie.me>
Signed-off-by: Tristan Partin <tristan@partin.io>
2025-04-19 01:04:57 -05:00
Mitchell Hashimoto 6a876ef8ec
macOS: A couple input regressions from 7121 (#7132)
Fixes #7131 

See individual commit messages.

I'm running them through the same tests as #7121 to verify manually that
behavior.
2025-04-18 15:35:12 -07:00
Mitchell Hashimoto e4a37dd383
macOS: only set unshifted codepoint on keyDown/Up events
Other event types trigger an AppKit assertion that doesn't crash the app
but logs some nasty stuff.
2025-04-18 15:14:38 -07:00
Mitchell Hashimoto 18d6faf597
macOS: translation mods should never have "control"
This also lets us get rid of our `C-/` special handling to prevent a
system beep.
2025-04-18 15:10:57 -07:00
Mitchell Hashimoto edb8616341
macos: translationMods should be used for consumed mods calculation
Fixes #7131
Regression from #7121

Our consumed mods should not include "alt" if `macos-option-as-alt` is
set. To do this, we need to calculate our consumed mods based on the
actual translation event mods (if available, only available during
keyDown).
2025-04-18 14:28:26 -07:00
Mitchell Hashimoto 65356c25da
macOS/libghostty: rework keyboard input handling (#7121)
This is a large refactor of the keyboard input handling code in
libghostty and macOS. Previously, libghostty did a lot of things that
felt out of scope or was repeated work due to lacking context. For
example, libghostty would do full key translation from key event to
character (including unshifted translation) as well as managing dead key
states and setting the proper preedit text.

This is all information the apprt can and should have on its own.
NSEvent on macOS already provides us with all of this information,
there's no need to redo the work. The reason we did in the first place
is mostly historical: libghostty powered our initial macOS port years
ago when we didn't have an AppKit runtime yet.

This cruft has already practically been the source of numerous issues,
e.g.
https://github.com/ghostty-org/ghostty/issues/5558, but many other hacks
along the way, too.

This commit pushes all preedit (e.g. dead key) handling and key
translation
including unshifted keys up into the caller of libghostty.

Besides code cleanup, a practical benefit of this is that key event
handling on macOS is now about 10x faster on average. That's because
we're avoiding repeated key translations as well as other unnecessary
work. This should have a meaningful impact on input latency but I didn't
measure the full end-to-end latency.

A scarier part of this commit is that key handling is not well tested
since its a GUI component. I suspect we'll have some fallout for certain
keyboard layouts or input methods, but I did my best to run through
everything I could think of.

This also fixes one bug where preedit state didn't properly clear when
changing keyboard layouts. This now does and matches the behavior
of native apps like TextEdit and Terminal.app
2025-04-18 12:06:32 -07:00
Tristan Partin 85268d4f82
apprt/gtk: refactor action callbacks to reduce code duplication (#7126)
It was getting very monotonous reading the code.
2025-04-18 13:11:12 -05:00
Tristan Partin 793c727986 apprt/gtk: refactor action callbacks to reduce code duplication
It was getting very monotonous reading the code.

Signed-off-by: Tristan Partin <tristan@partin.io>
2025-04-18 12:54:36 -05:00
Leah Amelia Chen 773506fe82
Improve Chinese (zh_CN) Translations for Natural Phrasing (#7125) 2025-04-18 23:56:12 +08:00
Bryan Lee 34ddd3d9e5
Refine Chinese translations for daily usage consistency 2025-04-18 23:34:18 +08:00
Mitchell Hashimoto 03a1c04a6e
i18n: fix spelling inconsistencies for Japanese Translations (#7122)
This pr fix spelling inconsistencies for Japanese Translations
2025-04-18 07:17:46 -07:00
Mitchell Hashimoto b63fa7dfa1
vim: fix syntax highlight on scratch buffer (#7119)
Sometimes we need detect ghostty filetype on scratch buffer.
In this case `set iskeyword` in ftplugin is not loaded.

Screenshot:
https://github.com/ibhagwan/fzf-lua/pull/1913#issuecomment-2813289819.

e.g.
```sh
nvim +'0r ~/.config/ghostty/config' +'se syntax=ghostty'
```
2025-04-18 07:17:30 -07:00
phanium 9bab900c75 vim: fix syntax highlight on scratch buffer 2025-04-18 21:50:24 +08:00
Bryan Lee 90499f0749
macOS: Add dock badge notification for bell events 2025-04-18 09:43:48 +08:00
ekusiadadus bef0d5d88e fix: spelling inconsistencies for Japanese Translations 2025-04-18 07:22:40 +09:00
Mitchell Hashimoto ded9be39c0
macOS: handle preedit text changes outside of key event 2025-04-17 14:24:12 -07:00
Mitchell Hashimoto b3cb38c3fa
macOS/libghostty: rework keyboard input handling
This is a large refactor of the keyboard input handling code in
libghostty and macOS. Previously, libghostty did a lot of things that
felt out of scope or was repeated work due to lacking context. For
example, libghostty would do full key translation from key event to
character (including unshifted translation) as well as managing dead key
states and setting the proper preedit text.

This is all information the apprt can and should have on its own.
NSEvent on macOS already provides us with all of this information,
there's no need to redo the work. The reason we did in the first place
is mostly historical: libghostty powered our initial macOS port years
ago when we didn't have an AppKit runtime yet.

This cruft has already practically been the source of numerous issues, e.g.
#5558, but many other hacks along the way, too.

This commit pushes all preedit (e.g. dead key) handling and key translation
including unshifted keys up into the caller of libghostty.

Besides code cleanup, a practical benefit of this is that key event
handling on macOS is now about 10x faster on average. That's because
we're avoiding repeated key translations as well as other unnecessary
work. This should have a meaningful impact on input latency but I didn't
measure the full end-to-end latency.

A scarier part of this commit is that key handling is not well tested
since its a GUI component. I suspect we'll have some fallout for certain
keyboard layouts or input methods, but I did my best to run through
everything I could think of.
2025-04-17 14:24:12 -07:00
Mitchell Hashimoto 2bcd76c3d9
macOS: Implement basic bell features (no sound) (#7101)
Fixes #7099

This adds basic bell features to macOS to conceptually match the GTK
implementation. When a bell is triggered, macOS will do the following:

  1. Bounce the dock icon once, if the app isn't already in focus.
2. Add a bell emoji (🔔) to the title of the surface that triggered the
bell. This emoji will be removed after the surface is focused or a
keyboard event if the surface is already focused. This behavior matches
iTerm2.

Note that neither of these respect the `system` `bell-features` config
because they're both unobtrusive (the dock icon bounces only once, the
title change is silent and similar to GTK tab attention) and unrelated
to system settings.

This doesn't add an icon badge because macOS's dockTitle.badgeLabel API
wasn't doing anything for me and I wasn't able to fully figure out
why...
2025-04-15 13:24:20 -07:00
Mitchell Hashimoto cc690eddb5
macOS: Implement basic bell features (no sound)
Fixes #7099

This adds basic bell features to macOS to conceptually match the GTK
implementation. When a bell is triggered, macOS will do the following:

  1. Bounce the dock icon once, if the app isn't already in focus.
  2. Add a bell emoji (🔔) to the title of the surface that triggered
     the bell. This emoji will be removed after the surface is focused
     or a keyboard event if the surface is already focused. This
     behavior matches iTerm2.

This doesn't add an icon badge because macOS's dockTitle.badgeLabel API
wasn't doing anything for me and I wasn't able to fully figure out
why...
2025-04-15 10:41:15 -07:00
Mitchell Hashimoto 392aab2e4a
macos: quick terminal uses padded notch mode if notch is visible (#7098)
Fixes #6612
2025-04-15 09:04:44 -07:00
Mitchell Hashimoto b77c5634f0
macos: quick terminal uses padded notch mode if notch is visible
Fixes #6612
2025-04-15 08:52:20 -07:00
Mitchell Hashimoto 62af0c0ec0
terminal: clear correct row on index operation in certain edge cases (#7093)
Fixes #7066

This fixes an issue where under certain conditions (expanded below), we
would not clear the correct row, leading to the screen having duplicate
data.

This was triggered by a page state of the following:

```
      +----------+ = PAGE 0
  ... :          :
 4305 |1ABCD00000|
 4306 |2EFGH00000|
      :^         : = PIN 0
     +-------------+ ACTIVE
 4307 |3IJKL00000| | 0
      +----------+ :
      +----------+ : = PAGE 1
    0 |          | | 1
    1 |          | | 2
      +----------+ :
     +-------------+
```

Namely, the cursor had to NOT be on the last row of the first page, but
somewhere on the first page. Then, when an `index` (LF) operation was
performed the result would look like this:

```
      +----------+ = PAGE 0
  ... :          :
 4305 |1ABCD00000|
 4306 |2EFGH00000|
     +-------------+ ACTIVE
 4307 |3IJKL00000| | 0
      :^         : : = PIN 0
      +----------+ :
      +----------+ : = PAGE 1
    0 |3IJKL00000| | 1
    1 |          | | 2
      +----------+ :
     +-------------+
```

The `3IJKL` line was duplicated. What was happening here is that we
performed the index operation correctly but failed to clear the cursor
line as expected.

This is because we were always clearing the first row in the page
instead of the row of the cursor.

Test added.
2025-04-15 07:09:18 -07:00
Mitchell Hashimoto 4aa875bbf6
ci: add logging to localization-review script (#7094)
An example of the new output (this very PR as an example):

<img
src="https://github.com/user-attachments/assets/0136238c-75d1-4bc6-8a3f-cb4b80daa512"
width="80%">

I also performed a couple of small refactors.
2025-04-14 15:56:15 -07:00
Mitchell Hashimoto da6b478fbe
terminal: clear correct row on index operation in certain edge cases
Fixes #7066

This fixes an issue where under certain conditions (expanded below), we
would not clear the correct row, leading to the screen having duplicate
data.

This was triggered by a page state of the following:

```
      +----------+ = PAGE 0
  ... :          :
 4305 |1ABCD00000|
 4306 |2EFGH00000|
      :^         : = PIN 0
     +-------------+ ACTIVE
 4307 |3IJKL00000| | 0
      +----------+ :
      +----------+ : = PAGE 1
    0 |          | | 1
    1 |          | | 2
      +----------+ :
     +-------------+
```

Namely, the cursor had to NOT be on the last row of the first page,
but somewhere on the first page. Then, when an `index` (LF) operation
was performed the result would look like this:

```
      +----------+ = PAGE 0
  ... :          :
 4305 |1ABCD00000|
 4306 |2EFGH00000|
     +-------------+ ACTIVE
 4307 |3IJKL00000| | 0
      :^         : : = PIN 0
      +----------+ :
      +----------+ : = PAGE 1
    0 |3IJKL00000| | 1
    1 |          | | 2
      +----------+ :
     +-------------+
```

The `3IJKL` line was duplicated. What was happening here is that we
performed the index operation correctly but failed to clear the cursor
line as expected.

This is because we were always clearing the first row in the page
instead of the row of the cursor.

Test added.
2025-04-14 15:54:00 -07:00
trag1c 8bc91933cd
ci: add logging to localization-review script 2025-04-14 23:58:29 +02:00
Mitchell Hashimoto 8bab8f7d64
macOS: fix quick terminal fullscreen issues (#7091)
Supersedes #7075 
Fixes #7070 

This fixes a few separate fullscreen issues with the quick terminal:

1. If we're on a fullscreen space, we can't reliably set the
`autoHideMenuBar` presentation option because macOS itself is managing
it. The fix is to use private APIs to detect we're on a fullscreen space
and avoid this.

2. If our quick terminal is fullscreen when we move spaces, we must exit
and re-enter fullscreen because the frame may change (e.g. due to
menubar changes).

3. If we aren't the frontmost app, we must avoid hiding the menu because
it has no effect and our fullscreen frame would be wrong.
2025-04-14 11:29:04 -07:00
Mitchell Hashimoto 21d09fe2e0
i18: fix minor Norwegian grammar issues (#7085)
Changes the translation of 'clipboard' to definite singular form, and
removes a misplaced verb.
2025-04-14 11:22:40 -07:00
Mitchell Hashimoto c23b389cf1
gtk: implement bell (#7087)
This PR implements a more lightweight alternative to #5326 that contains
features that I personally think Just Make Sense for the bell.

No configs, no GStreamer stuff, just sane defaults to get us started.
2025-04-14 11:19:19 -07:00
Mitchell Hashimoto d1c15dbf07
macOS: quick terminal should retain menu if not frontmost
This is a bug I noticed in the following scenario:

  1. Open Ghostty
  2. Fullscreen normal terminal window (native fullscreen)
  3. Open quick terminal
  4. Move spaces, QT follows
  5. Fullscreen the quick terminal

The result was that the menu bar would not disappear since our app is
not frontmost but we set the fullscreen frame such that we expected it.
2025-04-14 11:17:11 -07:00
Mitchell Hashimoto 453e6590e8
macOS: non-native fullscreen should not hide menu on fullscreen space
Fixes #7075

We have to use private APIs for this, I couldn't find a reliable way
otherwise.
2025-04-14 10:38:54 -07:00
Leah Amelia Chen 3a973c692a
gtk(bell): add `bell-features` config option
Co-authored-by: Jeffrey C. Ollie <jeff@ocjtech.us>
2025-04-15 00:18:05 +08:00
Leah Amelia Chen abd7d9202b
gtk(bell): mark tab as needing attention on bell 2025-04-14 23:44:13 +08:00
Leah Amelia Chen 10a591fba2
gtk(bell): use `gdk.Surface.beep` for bell
Co-authored-by: Jeffrey C. Ollie <jeff@ocjtech.us>
2025-04-14 23:44:13 +08:00
Leah Amelia Chen a0760cabd6
gtk: implement bell
Co-authored-by: Jeffrey C. Ollie <jeff@ocjtech.us>
2025-04-14 23:44:13 +08:00
cryptocode b932d35526
i18: fix minor Norwegian grammar issues
Changes the translation of 'clipboard' to definite singular form,
and removes a misplaced verb.
2025-04-14 16:29:59 +02:00
Mitchell Hashimoto 9d9d781a0b
Mouse drag while clicked should cancel any mouse link actions (#7080)
Fixes #7077

This follows pretty standard behavior across native or popular
applications on both platforms macOS and Linux. The basic behavior is
that if you do a mouse down event and then drag the mouse beyond the
current character, then any mouse up actions are canceled (beyond
emiting the event itself).

This fixes a specific scenario where you could do the following:

  1. Click anywhere (mouse down)
  2. Drag over a valid link
  3. Press command/control (to activate the link)
  4. Release the mouse button (mouse up)
  5. The link is triggered

Now, step 3 and step 5 do not happen. Links are not even highlighted in
this scenario. This matches iTerm2 on macOS which has a similar
command-to-activate-links behavior.

## Demo


https://github.com/user-attachments/assets/f79767b1-78fd-432b-af46-28194b816747
2025-04-13 19:37:13 -07:00
Mitchell Hashimoto f7394c00c1
macOS: only emit a mouse exited position if we're not dragging (#7077)
Fixes #7071

When the mouse is being actively dragged, AppKit continues to emit
mouseDragged events which will update our position appropriately. The
mouseExit event we were sending sends a synthetic (-1, -1) position
which was causing a scroll up.
2025-04-13 14:58:31 -07:00
Mitchell Hashimoto 6d3f97ec1e
Mouse drag while clicked should cancel any mouse link actions
Fixes #7077

This follows pretty standard behavior across native or popular applications
on both platforms macOS and Linux. The basic behavior is that if you
do a mouse down event and then drag the mouse beyond the current
character, then any mouse up actions are canceled (beyond emiting the
event itself).

This fixes a specific scenario where you could do the following:

  1. Click anywhere (mouse down)
  2. Drag over a valid link
  3. Press command/control (to activate the link)
  4. Release the mouse button (mouse up)
  5. The link is triggered

Now, step 3 and step 5 do not happen. Links are not even highlighted in
this scenario. This matches iTerm2 on macOS which has a similar
command-to-activate-links behavior.
2025-04-13 14:56:40 -07:00
Mitchell Hashimoto 6d80388155
macOS: only emit a mouse exited position if we're not dragging
Fixes #7071

When the mouse is being actively dragged, AppKit continues to emit
mouseDragged events which will update our position appropriately. The
mouseExit event we were sending sends a synthetic (-1, -1) position
which was causing a scroll up.
2025-04-13 12:46:39 -07:00
Mitchell Hashimoto 66636195f1
Introduce Issue Triage Template (#7012)
The helper team has been discussing some common issues we see with
Discussion submissions (missing info, duplicates, etc.), and pluie's
#6937 has been a huge step forward - this PR introduces a template for
the Issue Triage Discussion type.

The template has gone through a few revisions prior to this PR, but I am
certain there are probably a few places to be cleaned up. You can test
it out by [opening a new "Issue Triage" Discussion in my
fork](https://github.com/taylrfnt/ghostty/discussions/new?category=issue-triage).

~~Creating this as a draft for now, since I may not be able to respond
to any review comments in a timely manner.~~
2025-04-11 14:17:41 -07:00
Mitchell Hashimoto f777138590
mk_MK localization (#6902) 2025-04-11 12:52:51 -07:00
Mitchell Hashimoto deed2707a5
CODEOWNERS 2025-04-11 12:50:12 -07:00
Andrej Daskalov dcc2e9eaf8
Merge branch 'main' into mk-localization 2025-04-11 21:47:07 +02:00
Mitchell Hashimoto 74b17f68b5
i18n: add catalan translations (#6841)
Hi there!
This PR adds the Catalan translations (ca_ES.UTF-8).

Salut
2025-04-11 10:22:54 -07:00
Francesc Arpi Roca d749e1b87e i18n: fix the "deny" catalan translation 2025-04-11 10:20:53 -07:00
Francesc Arpi Roca e30feb3bfb i18n: fix string length 2025-04-11 10:20:44 -07:00
Francesc Arpi Roca a092d7ae42 i18n: add catalan translations 2025-04-11 10:20:44 -07:00
Mitchell Hashimoto 9233413126
i18n: add pt-BR (Brazilian Portuguese) translation (#6966)
With this PR now it supports the brazilian portuguese language for
ghostty, native speaker and resident, want to bring this language to
this new terminal that is starting to become very fondly to me! Any
questions about it i am free to answer.
2025-04-11 10:14:47 -07:00
Mitchell Hashimoto 24847293f2
update CODEOWNERS 2025-04-11 10:12:19 -07:00
g 7e67312c61 grammar fix and correct form for some phrases 2025-04-11 10:12:06 -07:00
g 11f5797a91 fix in lower case when required 2025-04-11 10:12:06 -07:00
Gustavo e31c8e09ed Update po/pt_BR.UTF-8.po
Co-authored-by: Kat <65649991+00-kat@users.noreply.github.com>
2025-04-11 10:12:06 -07:00
g f794afe2d8 standard file extension name 2025-04-11 10:12:06 -07:00
g 63ccdf2cff fix in capital letters 2025-04-11 10:12:06 -07:00
g c19f2aa1bc Add pt-BR translations to ghostty 2025-04-11 10:12:06 -07:00
Mitchell Hashimoto 9751f43529
Add Spanish translations (419 = Latin America) (#6940)
Hi!
I have followed the instructions and added translations for Spanish,
Country Latin America 419 according to
[this](https://localizely.com/locale-code/es-419/) and other online
sources.
In the provided links there was no references to 419, but I created it
via the suggested command:
`msginit -i po/com.mitchellh.ghostty.pot -l es_419.UTF-8 -o
"po/es_419.UTF-8.po" `
Glad to be able to contribute to this excellent product!
Cheers!
2025-04-11 10:11:26 -07:00
MiguelElGallo 5bbed046f6 add Spanish (Bolivia) translations and locale support 2025-04-11 10:09:05 -07:00
MiguelElGallo a9f9abd615 add Spanish (Latin America) locale support 2025-04-11 10:08:44 -07:00
MiguelElGallo e5de000895 add Spanish translations (419 = Latin America) for com.mitchellh.ghostty package 2025-04-11 10:08:22 -07:00
Mitchell Hashimoto 9cd3d3826a
feat: Add Turkish translations (#6898) 2025-04-11 10:01:29 -07:00
Emir SARI 913c6dc7df feat: Add Turkish translations 2025-04-11 09:57:19 -07:00
Mitchell Hashimoto 17b7920f65
Add nl_NL (Dutch) translations (#6894) 2025-04-11 09:52:33 -07:00
Mitchell Hashimoto 14cac67b98
CODEOWNERS 2025-04-11 09:51:18 -07:00
Nico Geesink b0b09bf034 Fix spell errors 2025-04-11 09:51:04 -07:00
Nico Geesink 059caef118 Use informal 'you' and change verander to wijzig 2025-04-11 09:51:04 -07:00
Nico Geesink 960fcc275f Fix typos and make sentences more fluent 2025-04-11 09:51:04 -07:00
Nico Geesink e415b6db42 Merge branch 'main' into main 2025-04-11 09:51:04 -07:00
Nico Geesink cd6a8f6a65 Fix typo 2025-04-11 09:50:44 -07:00
Nico Geesink 7db64b8e34 Add name and don't use title case 2025-04-11 09:50:44 -07:00
Nico Geesink e52aad5dea Add nl_NL (Dutch) translations 2025-04-11 09:50:44 -07:00
Mitchell Hashimoto 6899e9d984
Added Russian translation for Ghostty (#6889) 2025-04-11 09:48:50 -07:00
Mitchell Hashimoto 52ac670913
CODEOWNERS 2025-04-11 09:47:11 -07:00
blackzeshi 077ae6a098 Update po/ru_RU.UTF-8.po
Co-authored-by: TicClick <ya@ticclick.ch>
2025-04-11 09:45:55 -07:00
blackzeshi 0d226d139b Update po/ru_RU.UTF-8.po
Co-authored-by: TicClick <ya@ticclick.ch>
2025-04-11 09:45:55 -07:00
blackzeshi d0403021a4 Update po/ru_RU.UTF-8.po
2 line fixed

Co-authored-by: TicClick <ya@ticclick.ch>
2025-04-11 09:45:55 -07:00
blackzeshi f4054daf0d Update po/ru_RU.UTF-8.po
262 line about debug build fixed

Co-authored-by: TicClick <ya@ticclick.ch>
2025-04-11 09:45:55 -07:00
blackzeshi 0d23f7af31 Update po/ru_RU.UTF-8.po
248 line changed

Co-authored-by: TicClick <ya@ticclick.ch>
2025-04-11 09:45:55 -07:00
blackzeshi 2b0a81d982 Merge branch 'main' into add_russian 2025-04-11 09:45:55 -07:00
blackzeshi 91f9fdb1be some fixes to adding russian translation (i.e. emoji) 2025-04-11 09:45:37 -07:00
blackzeshi df5dd1858a add russian translation 2025-04-11 09:45:37 -07:00
Mitchell Hashimoto 444352418c
i18n: Add French translation (#6868)
Hi ! 
This is just to add a first version of a french translation !
2025-04-11 09:44:38 -07:00
Mitchell Hashimoto 5be4b0de6b
CODEOWNERS 2025-04-11 09:42:48 -07:00
Nicolas G ca336f5310 Merge branch 'main' into main 2025-04-11 09:42:12 -07:00
Kirwiisp 5ca5afb13d fix: spelling and typo 2025-04-11 09:41:49 -07:00
Kirwiisp 930079ca01 fix: spelling mistakes 2025-04-11 09:41:49 -07:00
Nicolas G 1aa16cdf6b Fix ponctuation and Warning translation
Fix: missing ponctuations on various lines.

Change "Warning" to "Attention", might change in the futur if it does not perfectly match  common practice.

Fix: Multiline on config errors dialog
2025-04-11 09:41:49 -07:00
Kirwiisp e2a8a3243c i18n: Add French translation 2025-04-11 09:41:49 -07:00
Mitchell Hashimoto 8d1a57cde3
i18n: Add Japanese translations (#6866)
This pull request adds Japanese(ja_JP.UTF-8) translations.
2025-04-11 09:39:51 -07:00
Lon Sagisawa 10a90b5b67 fix: inconsistency around space 2025-04-11 09:38:37 -07:00
Lon Sagisawa 20ef2150de i18n: Add Japanese translations 2025-04-11 09:38:37 -07:00
Mitchell Hashimoto 028759e8f6
Add Indonesian id_ID translations. (#6836)
Add the Indonesian id_ID translations.
2025-04-11 09:33:40 -07:00
Mitchell Hashimoto 7adc2954c3
update CODEOWNERS 2025-04-11 09:27:04 -07:00
halosatrio 561a0e3897 i18n: fix capitalization and some translation 2025-04-11 09:26:00 -07:00
halosatrio 1222e80eb1 i18n: add id_ID code locale 2025-04-11 09:26:00 -07:00
halosatrio d903cc9827 i18n: fix translation 2025-04-11 09:25:35 -07:00
halosatrio 02bb81ad44 i18n: add indonesian translation 2025-04-11 09:25:35 -07:00
Mitchell Hashimoto b16324ef0b
ci: add a script and workflow for requesting i18n review (#7053)
From #7052, but for some reason I couldn't push there:

> This helps get around the `CODEOWNERS` file requiring that
contributors need to have write access to the repo in order to be
requested for review. The mechanism is (for any new PR):
> 1. List the changed files
> 2. Fetch and parse the CODEOWNERS file to get a path:owner mapping
> 3. See if any changed file matches the CODEOWNERS mapping
> 4. Fetch team members for affected localization teams
> 5. Request review from individual accounts
2025-04-10 19:46:27 -04:00
trag1c f0ade53fd2 ci: add a script and workflow for requesting i18n review 2025-04-10 16:40:28 -07:00
taylrfnt 49a97a589c
fix typo - exiting to existing
Co-authored-by: Leah Amelia Chen <github@acc.pluie.me>
2025-04-10 17:45:35 -05:00
Mitchell Hashimoto d7f75b348d
config: allow commands to specify whether they shell expand or not (#7044)
Fixes #7032 

This introduces a syntax for `command` and `initial-command` that allows
the user to specify whether it should be run via `/bin/sh -c` or not.
The syntax is a prefix `direct:` or `shell:` prior to the command, with
no prefix implying a default behavior as documented.

Previously, we unconditionally ran commands via `/bin/sh -c`, primarily
to avoid having to do any shell expansion ourselves. We also leaned on
it as a crutch for PATH-expansion but this is an easy problem compared
to shell expansion.

For the principle of least surprise, this worked well for configurations
specified via the config file, and is still the default. However, these
configurations are also set via the `-e` special flag to the CLI, and it
is very much not the principle of least surprise to have the command run
via `/bin/sh -c` in that scenario since a shell has already expanded all
the arguments and given them to us in a nice separated format. But we
had no way to toggle this behavior.

This commit introduces the ability to do this, and changes the defaults
so that `-e` doesn't shell expand. Further, we also do PATH lookups
ourselves for the non-shell expanded case because thats easy (using
execvpe style extensions but implemented as part of the Zig stdlib). We
don't do path expansion (e.g. `~/`) because thats a shell expansion.

So to be clear, there are no two polar opposite behavioes here with
clear semantics:

1. Direct commands are passed to `execvpe` directly, space separated.
This will not handle quoted strings, environment variables, path
expansion (e.g. `~/`), command expansion (e.g. `$()`), etc.

2. Shell commands are passed to `/bin/sh -c` and will be shell expanded
as per the shell's rules. This will handle everything that `sh`
supports.

In doing this work, I also stumbled upon a variety of smaller
improvements that could be made:

- A number of allocations have been removed from the startup path that
only existed to add a null terminator to various strings. We now have
null terminators from the beginning since we are almost always on a
system that's going to need it anyways.

- For bash shell integration, we no longer wrap the new bash command in
a shell since we've formed a full parsed command line.

- The process of creating the command to execute by termio is now unit
tested, so we can test the various complex cases particularly on macOS
of wrapping commands in the login command.

- `xdg-terminal-exec` on Linux uses the `direct:` method by default
since it is also assumed to be executed via a shell environment.
2025-04-10 16:32:18 -04:00
Mitchell Hashimoto d4a5e5f88e
elvish: use kitty-shell-cwd:// to report pwd (#7033)
OSC 7's standard body is a percent-encoded file:// URL. There isn't an
easy way for us to percent-encode the path ($pwd) component here without
implementing a custom function.

Instead, switch to the kitty-shell-cwd:// scheme, which Kitty introduced
to ease this implementation challenge in shell scripts. It accepts the
path string verbatim, without an encoding.

In Ghostty, we accept both the file:// and kitty-shell-cwd:// schemes,
and we attempt to URI-decode them both, so in practice this is more
about the "correctness" of this protocol than a functional change. It's
also possible we might decide to treat these schemes differently in the
runtime, like Kitty does.

Also, fix the `platform:hostname` function call syntax.
2025-04-10 16:19:26 -04:00
Mitchell Hashimoto 722d41a359
config: allow commands to specify whether they shell expand or not
This introduces a syntax for `command` and `initial-command` that allows
the user to specify whether it should be run via `/bin/sh -c` or not.
The syntax is a prefix `direct:` or `shell:` prior to the command,
with no prefix implying a default behavior as documented.

Previously, we unconditionally ran commands via `/bin/sh -c`, primarily
to avoid having to do any shell expansion ourselves. We also leaned on
it as a crutch for PATH-expansion but this is an easy problem compared
to shell expansion.

For the principle of least surprise, this worked well for configurations
specified via the config file, and is still the default. However, these
configurations are also set via the `-e` special flag to the CLI, and it
is very much not the principle of least surprise to have the command run via
`/bin/sh -c` in that scenario since a shell has already expanded all the
arguments and given them to us in a nice separated format. But we had no
way to toggle this behavior.

This commit introduces the ability to do this, and changes the defaults
so that `-e` doesn't shell expand. Further, we also do PATH lookups
ourselves for the non-shell expanded case because thats easy (using
execvpe style extensions but implemented as part of the Zig stdlib). We don't
do path expansion (e.g. `~/`) because thats a shell expansion.

So to be clear, there are no two polar opposite behavioes here with
clear semantics:

  1. Direct commands are passed to `execvpe` directly, space separated.
     This will not handle quoted strings, environment variables, path
     expansion (e.g. `~/`), command expansion (e.g. `$()`), etc.

  2. Shell commands are passed to `/bin/sh -c` and will be shell expanded
     as per the shell's rules. This will handle everything that `sh`
     supports.

In doing this work, I also stumbled upon a variety of smaller
improvements that could be made:

  - A number of allocations have been removed from the startup path that
    only existed to add a null terminator to various strings. We now
    have null terminators from the beginning since we are almost always
    on a system that's going to need it anyways.

  - For bash shell integration, we no longer wrap the new bash command
    in a shell since we've formed a full parsed command line.

  - The process of creating the command to execute by termio is now unit
    tested, so we can test the various complex cases particularly on
    macOS of wrapping commands in the login command.

  - `xdg-terminal-exec` on Linux uses the `direct:` method by default
    since it is also assumed to be executed via a shell environment.
2025-04-10 13:15:14 -07:00
Leah Amelia Chen 046e92865b
gtk: fix forcing the window theme to light or dark (#7039)
Fixes #7038
2025-04-09 08:32:50 +08:00
Jeffrey C. Ollie cb1b447e8c
gtk: fix forcing the window theme to light or dark
Fixes #7038
2025-04-08 18:33:12 -05:00
Jon Parise 5b4976f6ef elvish: fix platform:hostname function call syntax 2025-04-08 10:54:26 -04:00
Jon Parise b213c157f0 elvish: use kitty-shell-cwd:// to report pwd
OSC 7's standard body is a percent-encoded file:// URL. There isn't an
easy way for us to percent-encode the path ($pwd) component here without
implementing a custom function.

Instead, switch to the kitty-shell-cwd:// scheme, which Kitty introduced
to ease this implementation challenge in shell scripts. It accepts the
path string verbatim, without an encoding.

In Ghostty, we accept both the file:// and kitty-shell-cwd:// schemes,
and we attempt to URI-decode them both, so in practice this is more
about the "correctness" of this protocol than a functional change. It's
also possible we might decide to treat these schemes differently in the
runtime, like Kitty does.
2025-04-08 10:38:57 -04:00
Mitchell Hashimoto 17ba0252e8
Update iTerm2 colorschemes (#7007)
Upstream revision:
4c57d8c11d
2025-04-07 20:31:54 -07:00
Mitchell Hashimoto dc0b9a703d
fix(kittygfx): accept commands with no control data (#7023)
This sort of command is treated as valid by Kitty so we should too. In
fact, it occurs with the example `send-png` script provided in the docs
for the protocol.
2025-04-07 20:31:41 -07:00
taylrfnt 6d36eeef3c
add the verbosity
Co-authored-by: Kat <65649991+00-kat@users.noreply.github.com>
2025-04-07 21:41:29 -05:00
taylrfnt 8a446b7776
remove the verbosity
Co-authored-by: Kat <65649991+00-kat@users.noreply.github.com>
2025-04-07 21:41:09 -05:00
taylrfnt 279a6b6f58
fix typos & make it read more naturally 2025-04-07 21:27:01 -05:00
taylrfnt 9440dbba1a
add notes abotu minimum config 2025-04-07 21:25:26 -05:00
taylrfnt a6123c0447
fix trailing whitespace 2025-04-07 20:41:48 -05:00
taylrfnt 92959bc09c
fix typo
Co-authored-by: Kat <65649991+00-kat@users.noreply.github.com>
2025-04-07 20:39:22 -05:00
taylrfnt b3c61d90f3
add note about commits 2025-04-07 20:37:57 -05:00
Jon Parise f1472362af
Use built-in functions for elvish (#7025)
Currently the elvish shell integration uses the `hostname` command, this
may not exist on all systems and is somewhat redundant to rely on when
elvish has an
[`platform:hostname`](https://elv.sh/ref/platform.html#platform:hostname)
function that can be used and will work across platform regardless of
command availability. On top of this instead of directly calling the
`pwd` function we can simply use the built-in
[`$pwd`](https://elv.sh/ref/builtin.html#$pwd) variable that elvish
gives us. This should prevent the shell integration from breaking due to
external function availability.
2025-04-07 18:09:09 -04:00
taylrfnt d3b7fe3473
make following into these for better readability 2025-04-07 15:28:31 -05:00
taylrfnt ddb85ca1b1
better discussion & issue callout in the important note
Co-authored-by: Kat <65649991+00-kat@users.noreply.github.com>
2025-04-07 15:25:54 -05:00
taylrfnt c7635d5f41
remove the please
Co-authored-by: Kat <65649991+00-kat@users.noreply.github.com>
2025-04-07 15:19:38 -05:00
Hanna a8f760c6d2
fix: undo accidental replace 2025-04-07 16:10:50 -04:00
Hanna 77f5fe2560
fix: parenthesis are unneeded around builtins 2025-04-07 16:09:43 -04:00
Hanna 9808c13796
refactor: use builtin hostname function 2025-04-07 16:02:53 -04:00
Jon Parise e73970533a
shell-integration: Fix condition for sudo (#7021)
A missing ";" meant the check for $TERMINFO was never executed.
2025-04-07 15:53:50 -04:00
Qwerasd b64f49a0d7 fix(kittygfx): accept commands with no control data
This sort of command is treated as valid by Kitty so we should too. In
fact, it occurs with the example `send-png` script provided in the docs
for the protocol.
2025-04-07 13:31:51 -06:00
Fabian Boehm df174a74f8
shell-integration: Fix condition for sudo
A missing ";" meant the check for $TERMINFO was never executed.
2025-04-07 21:20:21 +02:00
Mitchell Hashimoto 3878e46707
Fix macOS shortcut binding for `close_window` action (#7020)
Fixes #7003
2025-04-07 10:04:26 -07:00
Bryan Lee 9144f4db58
Fix macOS shortcut binding for `close_window` action 2025-04-08 00:44:53 +08:00
taylrfnt 9643e9c7a6
introduce issue triage template 2025-04-06 19:29:58 -05:00
mitchellh f6ec39a5d8 deps: Update iTerm2 color schemes 2025-04-06 00:13:30 +00:00
Mitchell Hashimoto 6f7977fef1
macos: replay control+key events that go to doCommand (#7001)
Fixes #7000

Related to #6909, the same mechanism, but it turns out some control+keys
are also handled in this same way (namely control+esc leads to "cancel"
by default, which is not what we want).
2025-04-04 22:28:20 -04:00
Mitchell Hashimoto fe0536aaaf
macos: replay control+key events that go to doCommand
Fixes #7000

Related to #6909, the same mechanism, but it turns out some control+keys
are also handled in this same way (namely control+esc leads to "cancel"
by default, which is not what we want).
2025-04-04 22:09:04 -04:00
Mitchell Hashimoto c0eaa4b158
macos: left mouse click while not focused doesn't encode to pty (#6998)
Fixes #2595

This fixes an issue where a left mouse click on a terminal while not
focused would subsequently be encoded to the pty as a mouse event. This
is atypical for macOS applications in general and wasn't something we
wanted to do.

We do, however, want to ensure our terminal gains focus when clicked
without focus. Specifically, a split. This matches iTerm2 behavior and
is rather nice. We had this behavior before but our logic to make this
work before caused the issue this commit is fixing.

I also tested this with command+click which is a common macOS shortcut
to emit a mouse event without raising the focus of the target window. In
this case, we will properly focus the split but will not encode the
mouse event to the pty. I think we actually do a _better job_ here tha
iTerm2 (but, subjective) because we do encode the pty event properly if
the split is focused whereas iTerm2 never does.
2025-04-04 19:31:22 -04:00
Mitchell Hashimoto f228933955
macos: left mouse click while not focused doesn't encode to pty
Fixes #2595

This fixes an issue where a left mouse click on a terminal while not
focused would subsequently be encoded to the pty as a mouse event. This
is atypical for macOS applications in general and wasn't something we
wanted to do.

We do, however, want to ensure our terminal gains focus when clicked
without focus. Specifically, a split. This matches iTerm2 behavior and
is rather nice. We had this behavior before but our logic to make this
work before caused the issue this commit is fixing.

I also tested this with command+click which is a common macOS shortcut
to emit a mouse event without raising the focus of the target window. In
this case, we will properly focus the split but will not encode the
mouse event to the pty. I think we actually do a _better job_ here tha
iTerm2 (but, subjective) because we do encode the pty event properly if
the split is focused whereas iTerm2 never does.
2025-04-04 19:17:03 -04:00
Mitchell Hashimoto 60da3cf6a0
shell-integration: switch to $GHOSTTY_SHELL_FEATURES (#6871)
This change consolidates all three opt-out shell integration environment
variables into a single opt-in $GHOSTTY_SHELL_FEATURES variable. Its
value is a comma-delimited list of the enabled shell feature names (e.g.
"cursor,title").

$GHOSTTY_SHELL_FEATURES is set at runtime and automatically added to the
shell environment. Its value is based on the shell-integration-features
configuration option.

$GHOSTTY_SHELL_FEATURES is only set when at least one shell feature is
enabled. It won't be set when 'shell-integration-features = false'.

$GHOSTTY_SHELL_FEATURES lists only the enabled shell feature names. We
could have alternatively gone in the opposite direction and listed the
disabled features, letting the scripts assume each feature is on by
default like we did before, but I think this explicit approach is a
little safer and easier to reason about / debug.

It also doesn't support the "no-" negation prefix used by the config
system (e.g. "cursor,no-title"). This simplifies the implementation
requirements of our (multiple) shell integration scripts, and because
$GHOSTTY_SHELL_FEATURES is derived from shell-integration-features, the
user-facing configuration interface retains that expressiveness.

$GHOSTTY_SHELL_FEATURES is intended to primarily be an internal concern:
an interface between the runtime and our shell integration scripts. It
could be used by people with particular use cases who want to manually
source those scripts, but that isn't the intended audience.

... and because the previous $GHOSTTY_SHELL_INTEGRATION_NO_* variables
were also meant to be an internal concern, this change does not include
backwards compatibility support for those names.

One last advantage of a using a single $GHOSTTY_SHELL_FEATURES variable
is that it can be easily forwarded to e.g. ssh sessions or other shell
environments.

See: #5070
2025-04-04 17:05:37 -04:00
Mitchell Hashimoto 17a19e4837
docs: use Command instead of super for macOS (#6987)
Command is the name Apple uses for this key and that's printed on the
keyboard 😉
2025-04-03 21:31:05 -04:00
Mitchell Hashimoto 970fcdf671
libghostty: Action CValue should be untagged extern union (#6992)
Fixes #6962

I believe this is an upstream bug
(https://github.com/ziglang/zig/issues/23454), where Zig is allowing
extern unions to be tagged when created via type reification. This
results in a CValue that has an extra trailing byte (the tag).

This wasn't causing any noticeable issues for Ghostty for some reason
but others using our pattern were seeing issues. And I did confirm that
our CValue was indeed tagged and was the wrong byte size. I assume Swift
was just ignoring it because it was extra data. I don't know, but we
should fix this in general for libghostty.
2025-04-03 21:14:01 -04:00
Mitchell Hashimoto e19b5a150a
libghostty: Action CValue should be untagged extern union
Fixes #6962

I believe this is an upstream bug
(https://github.com/ziglang/zig/issues/23454), where Zig is allowing
extern unions to be tagged when created via type reification. This
results in a CValue that has an extra trailing byte (the tag).

This wasn't causing any noticeable issues for Ghostty for some reason
but others using our pattern were seeing issues. And I did confirm that
our CValue was indeed tagged and was the wrong byte size. I assume Swift
was just ignoring it because it was extra data. I don't know, but we
should fix this in general for libghostty.
2025-04-03 20:57:31 -04:00
Simon Olofsson af0004eb52
docs: use Command instead of super for macOS
Command is the name Apple uses for this key and that's printed on the keyboard 😉
2025-04-03 11:03:48 +02:00
Leah Amelia Chen 6f1b22aca5
gtk(x11): fix blur regions when using >200% scaling (#6978)
See #6957

We were not considering GTK's internal scale factor that converts
between "surface coordinates" and actual device coordinates, and that
worked fine until the scale factor reached 2x (200%).

Since the code is now dependent on the scale factor (which could change
at any given moment), we also listen to scale factor changes and then
unconditionally call `winproto.syncAppearance`. Even though it's
somewhat overkill, I don't expect people to change their scale factor
dramatically all the time anyway...
2025-04-02 17:38:27 +02:00
Leah Amelia Chen 969839acf3
gtk(x11): fix blur regions when using >200% scaling
See #6957

We were not considering GTK's internal scale factor that converts between
"surface coordinates" and actual device coordinates, and that worked fine
until the scale factor reached 2x (200%).

Since the code is now dependent on the scale factor (which could change
at any given moment), we also listen to scale factor changes and then
unconditionally call `winproto.syncAppearance`. Even though it's somewhat
overkill, I don't expect people to change their scale factor dramatically
all the time anyway...
2025-04-02 17:21:28 +02:00
RubenRME a92e761c09
fix: added locale to il8n.zig 2025-03-31 12:51:19 +02:00
RubenRME 62bbad96b1
fix: fixed missing translation key at line 250 2025-03-31 12:48:51 +02:00
RubenRME 1c73f757df
lang: added Korean language file 2025-03-31 03:46:41 +02:00
Jeffrey C. Ollie 1067cd3d8a
core: update libvaxis and zf for transitive zigimg dependency (#6947) 2025-03-28 14:55:28 -05:00
Jeffrey C. Ollie 9f57a03926
core: update libvaxis and zf for transitive zigimg dependency 2025-03-28 14:31:57 -05:00
Mitchell Hashimoto 0afb922375
macos: reset the last command key state when keyDown event (#6933)
Fixes a regression from #6909
See #6887

In certain scenarios, the last command key state would linger around (I
could only see this happen with global keybinds for unknown reasons
yet). This state is only meant to have an effect within the cycle of a
single keybind and only so we can ensure an event reaches keyDown so it
should be reset if keyDown is ever sent (since, by definition at that
point, keyDown has been reached).

I'm still not happy that this is necessary and I suspect there is a
better root cause to resolve, but I'd rather get this fix in now and
figure out the root cause later.
2025-03-27 07:50:33 -07:00
Mitchell Hashimoto 99843cf54d
macos: reset the last command key state when keyDown event
Fixes a regression from #6909
See #6887

In certain scenarios, the last command key state would linger around (I
could only see this happen with global keybinds for unknown reasons
yet). This state is only meant to have an effect within the cycle of a
single keybind and only so we can ensure an event reaches keyDown so it should
be reset if keyDown is ever sent (since, by definition at that point,
keyDown has been reached).

I'm still not happy that this is necessary and I suspect there is a
better root cause to resolve, but I'd rather get this fix in now and
figure out the root cause later.
2025-03-27 07:22:05 -07:00
Jeffrey C. Ollie 1c3693c383
version bump for development (#6928) 2025-03-26 23:46:59 -05:00
Jeffrey C. Ollie 27978ef4d0
version bump for development 2025-03-26 23:29:15 -05:00
Leah Amelia Chen 494279419a
gtk: use up-to-date maximized & fullscreen state in syncAppearance (#6924)
DerivedConfig's maximize and fullscreen should only ever be used during
window creation and nowhere else.
2025-03-26 20:33:55 +01:00
Leah Amelia Chen ae3e92a3fb
gtk: use up-to-date maximized & fullscreen state in syncAppearance
DerivedConfig's maximize and fullscreen should only ever be used during
window creation and nowhere else.
2025-03-26 20:15:18 +01:00
Jeffrey C. Ollie ed4260b3c2
fix: escape characters in shell escape test (#6925)
Fix the escape.

Sorry again for the inconveniences. Let's check if the test is now green
2025-03-26 14:14:38 -05:00
Ian den Hartog 18cc119ced
fix: escape characters in shell escape test 2025-03-26 19:52:36 +01:00
Jeffrey C. Ollie 613857cf7e
fix: add ( and ) to escape characters when dropping files in gtk (#6922)
Currently when dropping files in gtk with file names that include ( or )
will generate a bash error.

With this change ( and ) will be escaped.
2025-03-26 13:38:10 -05:00
Ian den Hartog 447a889559
fix: add ( and ) to escape characters when dropping files in gtk 2025-03-26 19:30:07 +01:00
Mitchell Hashimoto 837cdf0556
Metal: fix crunchy constrained glyphs (#6914)
Fixes problem pointed out in discussion #6895, as well as adjusting the
constraint logic to account for the offset, since I noticed it was
wrong; the constraint logic now accounts for the x offset, so that the
glyph does not exceed the right edge of the constraint width when the
offset is added, and the offset is zeroed if the glyph is resized down
to fit the constraint width.

|**Before**|**After**|
|-|-|
|<img width="84" alt="image"
src="https://github.com/user-attachments/assets/9561ca40-cfa0-4aed-b192-ee15042d8cbb"
/>|<img width="82" alt="image"
src="https://github.com/user-attachments/assets/9a77ac61-f46d-41de-a859-2b394024f7bc"
/>|

<sup>Zoom in to images for detail if you can't see the
crunchiness.</sup>

> [!NOTE]
> It may be an issue that that glyph is rendered with the constrained
text mode in the first place - Kitty doesn't seem to apply constraint
logic to it, and it seems a little over-eager to do so on our part. This
is something to look in to.
2025-03-26 11:20:14 -07:00
Qwerasd e96f94d8d7 fix(Metal): improve constraint width logic to account for x offset 2025-03-25 21:14:38 -06:00
Qwerasd 6f9a362a4d fix(Metal): fix crunchy appearance of constrained glyphs
We can't use nearest neighbor filtering for sampling from the atlas
because we might not actually be doing pixel perfect sampling if the
glyph has been constrained. This will change in the future, but this
will have to be set to linear for now.
2025-03-25 20:57:08 -06:00
Mitchell Hashimoto bcff4e18f4
macos: remove special-case cmd+period handling, redispatch unhandled doCommand (#6909)
Fixes #5522

This commit re-dispatches command inputs that are unhandled by our macOS
app so they can be encoded to the pty and handled by the core libghostty
key callback system.

We've had a special case `cmd+period` handling in Ghostty for a very
long time (since well into the private beta). `cmd+period` by default
binds to "cancel" in macOS, so it doesn't encode to the pty. We don't
handle "cancel" in any meaningful way in Ghostty, so we special-cased it
to encode properly to the pty.

However, as shown in #5522, if the user rebinds `cmd+period` at the
system level to some other operation, then this is ignored and we encode
it still. This isn't desirable, we just want to work around not caring
about "cancel."

The callback path that AppKit takes for key events is a bit convoluted.
For command keys, it first calls `performKeyEquivalent`. If this returns
false (we want to continue standard processing), then it calls EITHER
`keyDown` or `doCommand(by:)`. It calls the latter if there is a
standard system command that matches the key event. For `cmd+period` by
default, this is "cancel." Unfortunately, from `doCommand` we can't say
"oops, we don't want to handle this, please continue processing." Its
too late.

So, this commit stores the last command key event from
`performKeyEquivalent` and if we reach `doCommand` for it without having
called `keyDown`, we re-dispatch the event and send it to keyDown.

I'm honestly pretty sus about this whole logic but it is scoped to only
command-keys and I couldn't trigger any adverse behavior in my testing.
It also definitely fixed #5522 as far as I could reproduce it before.
2025-03-25 15:18:54 -07:00
Mitchell Hashimoto 67f47a6e22
macos: remove special-case cmd+period handling
Fixes #5522

This commit re-dispatches command inputs that are unhandled by our macOS
app so they can be encoded to the pty and handled by the core libghostty
key callback system.

We've had a special case `cmd+period` handling in Ghostty for a very
long time (since well into the private beta). `cmd+period` by default
binds to "cancel" in macOS, so it doesn't encode to the pty. We don't
handle "cancel" in any meaningful way in Ghostty, so we special-cased it
to encode properly to the pty.

However, as shown in #5522, if the user rebinds `cmd+period` at the
system level to some other operation, then this is ignored and we encode
it still. This isn't desirable, we just want to work around not caring
about "cancel."

The callback path that AppKit takes for key events is a bit convoluted.
For command keys, it first calls `performKeyEquivalent`. If this returns
false (we want to continue standard processing), then it calls EITHER
`keyDown` or `doCommand(by:)`. It calls the latter if there is a
standard system command that matches the key event. For `cmd+period` by
default, this is "cancel." Unfortunately, from `doCommand` we can't say
"oops, we don't want to handle this, please continue processing." Its
too late.

So, this commit stores the last command key event from
`performKeyEquivalent` and if we reach `doCommand` for it without having
called `keyDown`, we re-dispatch the event and send it to keyDown.

I'm honestly pretty sus about this whole logic but it is scoped to only
command-keys and I couldn't trigger any adverse behavior in my testing.
It also definitely fixed #5522 as far as I could reproduce it before.
2025-03-25 15:03:27 -07:00
Aaron Ruan 416b617de9
fix canonicalizing some zh locales (#6885)
resolve #6870

---------

Signed-off-by: Aaron Ruan <i@ar212.com>
2025-03-25 14:46:14 +00:00
Andrej Daskalov 6c3accede8
remove extra punctuation
Co-authored-by: Kat <65649991+00-kat@users.noreply.github.com>
2025-03-25 09:53:18 +01:00
Andrej Daskalov 7915ef5661 moved mk locale to bottom of list 2025-03-25 09:48:51 +01:00
Andrej Daskalov 6e6689d825 Merge branch 'main' into mk-localization 2025-03-25 09:46:56 +01:00
Mitchell Hashimoto 5d9bee98e8
pl_PL translations (#6771)
The initial take on the `pl_PL` translation.
2025-03-24 10:43:47 -07:00
Bartosz Sokorski bf179207a1 Add pl_PL translations
Co-authored-by: chupson <chupson@chupson.dev>
Co-authored-by: trag1c <dev@jakubr.me>
2025-03-24 10:41:29 -07:00
Mitchell Hashimoto 150b7bdad1
feat: add Ukrainian translations and locale support (#6759)
Added the Ukrainian `uk_UA` translations.
2025-03-24 10:39:34 -07:00
Danylo Zalizchuk 20111048a4 fead: add new Ukrainian translations 2025-03-24 10:36:25 -07:00
Danylo Zalizchuk 36c7fda40b Merge branch 'main' of github.com:danulqua/ghostty 2025-03-24 10:36:25 -07:00
Danylo Zalizchuk 99da99cb9c Merge branch 'main' into main 2025-03-24 10:35:36 -07:00
Danylo Zalizchuk b8b5882c75 fix: removed words capitalization in the Ukrainian translations 2025-03-24 10:35:18 -07:00
Danylo Zalizchuk e6b77cf008 fix: update "Reloaded the configuration" translation 2025-03-24 10:35:18 -07:00
Danylo Zalizchuk 90a3719275 fix: reorder locales to ensure they follow ASCII ordering 2025-03-24 10:35:18 -07:00
Danylo Zalizchuk c1bf301bc7 feat: add Ukrainian translations and locale support 2025-03-24 10:34:53 -07:00
Mitchell Hashimoto 7200c87326
pkg/harfbuzz: update 8.4 => 11.0 (#6897)
This updates our bundled Harfbuzz from 8.4 to 11.0. The changes from 8
to 11 include a number of correctness and performance improvements.
Packaged releases tend to dynamically link so this won't affect existing
users, but build-from-source users hopefully get an improvement.
2025-03-24 10:26:59 -07:00
Mitchell Hashimoto 89728070e9
pkg/harfbuzz: update 8.4 => 11.0
This updates our bundled Harfbuzz from 8.4 to 11.0. The changes from 8
to 11 include a number of correctness and performance improvements.
Packaged releases tend to dynamically link so this won't affect
existing users, but build-from-source users hopefully get an
improvement.
2025-03-24 10:04:11 -07:00
Mitchell Hashimoto c1ef0c0369
pkg/glfw: update to HEAD as of 2025-03-24 (#6896)
We have always tracked a post-3.4 release, this brings us up to date.
There's no real motivation beyond this other than keeping up to date
since we're already on non-release versions anyways. The diff is
dominated by auto-generated headers from Wayland-scanner.
2025-03-24 10:01:30 -07:00
Mitchell Hashimoto 8cc5ee39d0
pkg/glfw: update to HEAD as of 2025-03-24
We have always tracked a post-3.4 release, this brings us up to date.
There's no real motivation beyond this other than keeping up to date
since we're already on non-release versions anyways.
2025-03-24 09:56:55 -07:00
Andrej Daskalov 13b94d995c added macedonian translation file 2025-03-23 14:41:07 +01:00
Jeffrey C. Ollie c58fe676ad
gtk: a couple more C cleanups (#6876) 2025-03-22 23:07:19 -05:00
Mitchell Hashimoto 68b8ba12c7
Update iTerm2 colorschemes (#6878)
Upstream revision:
8650079de4
2025-03-22 20:46:03 -07:00
mitchellh 8aab16b6e6 deps: Update iTerm2 color schemes 2025-03-23 00:13:47 +00:00
Mitchell Hashimoto b722f537e7
apprt/gtk: make GL context current in unrealize (#6877)
Fixes #6872

This commit explicitly acquires the GL context in the `unrealize` signal
handler of the GTK Surface prior to cleaning up GPU resources.

A GLArea only guarantees that the associated GdkContext is current for
the `render` signal (see the docs[1]). This is why our OpenGL renderer
"defers" various operations such as resize, font grid changing, etc.
(see the `deferred_`-prefix fields in `renderer/OpenGL.zig`). However,
we missed a spot.

The `gtk-widget::unrealize` signal is emitted when the widget is
destroyed, and it is the last chance we have to clean up our GPU
resources. But it is not guaranteed that the GL context is current at
that point, and we weren't making it current. On the NGL GTK renderer,
this was freeing GPU resources we didn't own.

As best I can understand, the old GL renderer only ever used a handful
of GL resources that were early in the ID space, so by coincidence we
were probably freeing nothing and everything was fine. But with the new
NGL renderer uses a LOT more GL resources (make a few splits and the ID
space is already in the thousands, from GTK!), so we were freeing real
resources that we didn't own, which caused rendering issues. :)

I suspect the above also resulted in VRAM memory leaks (which would be
RAM memory leaks for unified memory GPUs). This potentially relates to
#5491.

The fix is to explicitly make the GL context current in the `unrealize`
handler.

[1]: https://docs.gtk.org/gtk4/method.GLArea.make_current.html
2025-03-22 14:48:51 -07:00
Mitchell Hashimoto 9d5ce6e47d
apprt/gtk: remove gtk-gsk-renderer config
This was a hack, and is no longer required since #6877. Users can
explicitly override the GTK GSK renderer by setting the standard GTK env
var `GSK_RENDERER`.
2025-03-22 14:29:22 -07:00
Mitchell Hashimoto 36f841ee80
apprt/gtk: make GL context current in unrealize
Fixes #6872

This commit explicitly acquires the GL context in the `unrealize`
signal handler of the GTK Surface prior to cleaning up GPU resources.

A GLArea only guarantees that the associated GdkContext is current for
the `render` signal (see the docs[1]). This is why our OpenGL renderer
"defers" various operations such as resize, font grid changing, etc.
(see the `deferred_`-prefix fields in `renderer/OpenGL.zig`).
However, we missed a spot.

The `gtk-widget::unrealize` signal is emitted when the widget is
destroyed, and it is the last chance we have to clean up our GPU
resources. But it is not guaranteed that the GL context is current at
that point, and we weren't making it current. On the NGL GTK renderer,
this was freeing GPU resources we didn't own.

As best I can understand, the old GL renderer only ever used a handful
of GL resources that were early in the ID space, so by coincidence we
were probably freeing nothing and everything was fine. But with the new
NGL renderer uses a LOT more GL resources (make a few splits and the ID
space is already in the thousands, from GTK!), so we were freeing real
resources that we didn't own, which caused rendering issues. :)

I suspect the above also resulted in VRAM memory leaks (which would be
RAM memory leaks for unified memory GPUs). This potentially relates to
#5491.

The fix is to explicitly make the GL context current in the `unrealize`
handler.

[1]: https://docs.gtk.org/gtk4/method.GLArea.make_current.html
2025-03-22 14:20:01 -07:00
Jeffrey C. Ollie 1317e62722
gtk: a couple more C cleanups 2025-03-22 16:13:08 -05:00
Jon Parise cd6b850758 shell-integration: minor documentation updates 2025-03-22 15:57:55 -04:00
Jon Parise 0caba3e19f shell-integration: comptime buffer capacity 2025-03-22 15:56:05 -04:00
Jon Parise 36ff70eb7f shell-integration: use elvish's native list type
Instead of looking for individual substrings in $GHOSTTY_SHELL_FEATURES,
`str:split` it into a list of feature names and use `has-value` to
detect their presence.
2025-03-22 12:26:56 -04:00
Jon Parise 77dc5c9dd2 shell-integration: use fish's native list type
Instead of looking for individual substrings in $GHOSTTY_SHELL_FEATURES,
`string split` it into a list of feature names and use `contains` to
detect their presence.
2025-03-22 12:11:51 -04:00
Jon Parise 314d52ac3a shell-integration: switch to $GHOSTTY_SHELL_FEATURES
This change consolidates all three opt-out shell integration environment
variables into a single opt-in $GHOSTTY_SHELL_FEATURES variable. Its
value is a comma-delimited list of the enabled shell feature names (e.g.
"cursor,title").

$GHOSTTY_SHELL_FEATURES is set at runtime and automatically added to the
shell environment. Its value is based on the shell-integration-features
configuration option.

$GHOSTTY_SHELL_FEATURES is only set when at least one shell feature is
enabled. It won't be set when 'shell-integration-features = false'.

$GHOSTTY_SHELL_FEATURES lists only the enabled shell feature names. We
could have alternatively gone in the opposite direction and listed the
disabled features, letting the scripts assume each feature is on by
default like we did before, but I think this explicit approach is a
little safer and easier to reason about / debug.

It also doesn't support the "no-" negation prefix used by the config
system (e.g. "cursor,no-title"). This simplifies the implementation
requirements of our (multiple) shell integration scripts, and because
$GHOSTTY_SHELL_FEATURES is derived from shell-integration-features,
the user-facing configuration interface retains that expressiveness.

$GHOSTTY_SHELL_FEATURES is intended to primarily be an internal concern:
an interface between the runtime and our shell integration scripts. It
could be used by people with particular use cases who want to manually
source those scripts, but that isn't the intended audience.

... and because the previous $GHOSTTY_SHELL_INTEGRATION_NO_* variables
were also meant to be an internal concern, this change does not include
backwards compatibility support for those names.

One last advantage of a using a single $GHOSTTY_SHELL_FEATURES variable
is that it can be easily forwarded to e.g. ssh sessions or other shell
environments.
2025-03-22 10:16:59 -04:00
Leah Amelia Chen 747c43ffa0
gtk: clean up C remnants and `@ptrCast`s (#6862) 2025-03-21 21:35:11 +01:00
Leah Amelia Chen f659e70938
gtk: clean up C remnants and `@ptrCast`s
Some `@ptrCast`s are unavoidable in the codebase but I've gotten rid of
every one that's unnecessary.
2025-03-21 20:15:59 +01:00
Mitchell Hashimoto 4a51643043
Mention macOS' `open` in the CLI help messages (#6848)
> 3. If you want to live dangerously, open a pull request and hope for
the best.

Sure, why not!

---

This is a *super common* ask in both the GitHub Discussions and on
Discord; I thus decided to add a small(ish) note to the help output
directing users to try the open command. I did not include a note to
check the man page, as the text was already getting a bit long, but I
can change that if requested. Strings open for bike-shedding, of course.

Of course, feel free to close this if this is not a desirable change for
the project; I would appreciate a note about that though, rather than a
random unexpected close without any reason, as that would prevent any
future PRs about this from others.

As I do not use macOS, I was unable to test the appearance of the string
I edited in `main_ghostty.zig`.

On a slightly related note: are there any plans to translate the CLI's
strings? I assume they're in the same boat as the configuration parsing
errors which were [discussed in #maintainers] on [the Ghostty Discord].

[discussed in #maintainers]:
https://discord.com/channels/1005603569187160125/1337443701403815999/1352390511553417327
[the Ghostty Discord]: https://discord.org/ghostty
2025-03-21 07:21:27 -07:00
Kat 9a9bc43a9b
Mention macOS' `open` in the CLI help messages. 2025-03-21 19:16:30 +11:00
Mitchell Hashimoto 1980f9aed4
font/freetype: disable SVG glyphs, simplify color check (#6824)
We don't currently support rendering SVG glyphs so they should be
ignored when loading. Additionally, the check for whether a glyph is
colored has been simplified by just checking the pixel mode of the
rendered bitmap.

This commit also fixes a bug caused by calling the color check inside of
`renderGlyph`, which caused the bitmap to be freed creating a chance for
memory corruption and garbled glyphs. This bug was introduced by 40c1140
(#6602) and discussed in #6781.
2025-03-20 11:47:02 -07:00
Mitchell Hashimoto 141b697f9d
apprt/embedded: utf8 encoding buffer lifetime must extend beyond call (#6834)
Fixes #6821

UTF8 translation using KeymapDarwin requires a buffer and the buffer was
stack allocated in the coreKeyEvent call and returned from the function.
We need the buffer to live longer than this.

Long term, we're removing KeymapDarwin (there is a whole TODO comment in
there about how to do it), but this fixes a real problem today.
2025-03-19 21:47:13 -07:00
Mitchell Hashimoto f31f8bb782
apprt/embedded: utf8 encoding buffer lifetime must extend beyond call
Fixes #6821

UTF8 translation using KeymapDarwin requires a buffer and the buffer was
stack allocated in the coreKeyEvent call and returned from the function.
We need the buffer to live longer than this.

Long term, we're removing KeymapDarwin (there is a whole TODO comment in
there about how to do it), but this fixes a real problem today.
2025-03-19 21:36:39 -07:00
Qwerasd f0080529c4 fix(font/shape): don't require emoji presentation for grapheme parts
Also update shaper test that fails because the run iterator can't apply
that logic since `testWriteString` doesn't do proper grpaheme clustering
so the parts are actually split across multiple cells.

Several other tests are technically incorrect for the same reason but
still pass, so I've decided not to fix them here.
2025-03-19 15:09:53 -06:00
Mitchell Hashimoto 88ff566e06
ci: simplify debian 12 check (#6825)
Debian 12 CI check now relies entirely on a source tarball.
2025-03-19 13:18:41 -07:00
Mitchell Hashimoto 75045d92b4
Tweak Norwegian Bokmål translation (#6812)
This tweak is minor and fixes some grammatical errors.

I did not change `kopier` to `kopiér`, even though that is a common way
to write the word. The language council of Norway suggest writing the
word as it is written here, without the accent, but it does read weird
and allows for misunderstanding. If this was my project I would have
added the accent. Let me know if you want the accent added.

What do you think regarding the accents @Uzaaft ?
2025-03-19 13:18:05 -07:00
Mitchell Hashimoto 41130ce25f
fix: inconsistent behavior from legacy and kitty Key encoding (#5728)
this fix addresses issue occurring in nvim/vim where Backspace deletes
previous letter while in preedit state.

related to #1638

> same issue reproducible
> However, that only fixed for legacy encoding.

Unanswered Discussion
https://github.com/ghostty-org/ghostty/discussions/5312<div
type='discussions-op-text'> can be closed afterwards

tested on macos sequioa IME '2-set Korean', 'Japanese Romaji'
2025-03-19 13:03:32 -07:00
Christoffer Tønnessen 9b3bd146c6 Tweak Norwegian Bokmål translation
This tweak is minor and fixes some grammatical errors.

I did not change `kopier` to `kopiér`, even though that is a common way
to write the word. The language council of Norway suggest writing the
word as it is written here, without the accent, but it does read weird
and allows for misunderstanding. If this was my project I would have
added the accent. Let me know if you want the accent added.
2025-03-19 20:46:00 +01:00
Jeffrey C. Ollie a7a57011f0
ci: simplify debian 12 check 2025-03-19 14:44:31 -05:00
Serim Son d61e53d6d6 Kitty key encoding should not encode backspace if UTF-8 text is present
This applies the same logic from #1659 to Kitty encoding.
2025-03-19 12:43:42 -07:00
Mitchell Hashimoto 9c064216a2
build: distribute gresource c/h with source tarball (#6822)
Closes #6760 
Supersedes #6762

This introduces the concept of a "dist resource" (specifically a
`GhosttyDist.Resource` type). This is a resource that may be present in
dist tarballs but not in the source tree. If the resource is present and
we're not in a Git checkout, then we use it directly instead of
generating it. This is a generic concept we can apply to any
preprocessing we want to do that we don't want users/packagers to do.

This is used for the first time in this commit for the gresource c/h
files, which depend on a variety of external tools (blueprint-compiler,
glib-compile-resources, etc.) that we do not want to require downstream
users/packagers to have and we also do not want to worry about them
having the right versions.

This also adds a check for `distcheck` to ensure our distribution
contains all the expected files.

Note @jcollie that there may be elements of 6762 you'll want to bring
back after this.
2025-03-19 12:10:08 -07:00
Mitchell Hashimoto 7b8c2232d3
build: distribute gresource c/h with source tarball
This introduces the concept of a "dist resource" (specifically a
`GhosttyDist.Resource` type). This is a resource that may be present in
dist tarballs but not in the source tree. If the resource is present and
we're not in a Git checkout, then we use it directly instead of
generating it.

This is used for the first time in this commit for the gresource c/h
files, which depend on a variety of external tools (blueprint-compiler,
glib-compile-resources, etc.) that we do not want to require downstream
users/packagers to have and we also do not want to worry about them
having the right versions.

This also adds a check for `distcheck` to ensure our distribution
contains all the expected files.
2025-03-19 11:52:03 -07:00
Qwerasd 6f84a5d682 font/freetype: disable SVG glyphs, simplify color check
We don't currently support rendering SVG glyphs so they should be
ignored when loading. Additionally, the check for whether a glyph is
colored has been simplified by just checking the pixel mode of the
rendered bitmap.

This commit also fixes a bug caused by calling the color check inside of
`renderGlyph`, which caused the bitmap to be freed creating a chance for
memory corruption and garbled glyphs.
2025-03-19 12:43:18 -06:00
Mitchell Hashimoto bd315c8394
os: Add extra sentinel for GHOSTTY_RESOURCES_DIR (#6814)
Discover resourcesdir with `terminfo/g/ghostty`
as well as existing `terminfo/x/xterm-ghostty`.
This allows either terminfo file to be installed,
notably ncurses only provides a `terminfo/g/ghostty`.

It was brought up that the `ncurses-term` package on Fedora 42 at
<https://packages.fedoraproject.org/pkgs/ncurses/ncurses-term/fedora-42.html>
now provides a `/g/ghostty` terminfo entry which conflicts with
installing the similarly named file from ghostty's build process.
However a build with `zig build -Demit-terminfo=false` won't work as the
`x/xterm-ghostty` terminfo entry is used as a sentinel to discover the
`GHOSTTY_RESOURCES_DIR` used as a reference path for finding locale and
theme files.

```
src/Surface.zig|546 col 43| .resources_dir = global_state.resources_dir,
src/cli/list_themes.zig|112 col 22| if (global_state.resources_dir == null)
src/global.zig|38 col 5| resources_dir: ?[]const u8,
src/global.zig|173 col 14| self.resources_dir = try internal_os.resourcesDir(self.alloc);
src/global.zig|174 col 27| errdefer if (self.resources_dir) |dir| self.alloc.free(dir);
src/global.zig|177 col 18| if (self.resources_dir) |v| internal_os.i18n.init(v) catch |err| {
src/global.zig|185 col 18| if (self.resources_dir) |dir| self.alloc.free(dir);
```

We also have some comments that intend to change how the terminfo
database is discovered.

https://github.com/ghostty-org/ghostty/blob/main/src/termio/Exec.zig#L776C1-L781C60
2025-03-19 09:04:17 -07:00
Mitchell Hashimoto 403b3617f7
update translations 2025-03-19 08:54:30 -07:00
Mitchell Hashimoto 39d4cc3702
update CODEOWNERS 2025-03-19 08:52:39 -07:00
Danylo Zalizchuk 55c221c572 Merge branch 'main' into main 2025-03-19 08:52:14 -07:00
Danylo Zalizchuk 15efb913bf fix: removed words capitalization in the Ukrainian translations 2025-03-19 08:51:53 -07:00
Danylo Zalizchuk f412237106 fix: update "Reloaded the configuration" translation 2025-03-19 08:51:53 -07:00
Danylo Zalizchuk cb7180ef77 fix: reorder locales to ensure they follow ASCII ordering 2025-03-19 08:51:53 -07:00
Danylo Zalizchuk e93be23f68 feat: add Ukrainian translations and locale support 2025-03-19 08:51:11 -07:00
Mitchell Hashimoto bfec219510
Regenerate translations to fix CI (#6820)
I don't see any actual changes here, just reordering. It's using the Nix
environment so I'm not sure why this happened but it seemed to stem from
the Norwegian work originally. Fixing it back.
2025-03-19 08:39:00 -07:00
Mitchell Hashimoto e56002e149
Regenerate translations.
I don't see any actual changes here, just reordering. It's using the Nix
environment so I'm not sure why this happened but it seemed to stem from
the Norwegian work originally. Fixing it back.
2025-03-19 08:35:39 -07:00
Leah Amelia Chen 907e62aa29
Fix typo: Alejanda → Alejandra in README.md (#6817) 2025-03-19 14:03:38 +01:00
CKay9 dc21ea9998 Fix typo: Alejanda → Alejandra in README.md 2025-03-19 13:38:38 +01:00
azhn c5b1961c6b os: Add extra sentinel for GHOSTTY_RESOURCES_DIR
Discover resourcesdir with `terminfo/g/ghostty`
as well as existing `terminfo/x/xterm-ghostty`.
This allows either terminfo file to be installed,
notably ncurses only provides a `terminfo/g/ghostty`.
2025-03-19 20:49:02 +11:00
Mitchell Hashimoto bd7c5cc95f
Add Norwegian Bokmål Translations (#6731)
Pull request to add Norwegian Bokmål translations.
Asking assistance from @Uzaaft for review and help.
2025-03-18 16:04:41 -07:00
hanna 02bfa946d5 i18n: add norwegian bokmal translations 2025-03-18 15:44:46 -07:00
Mitchell Hashimoto f7999444eb
ci: zig fmt check (#6802)
This adds a CI test to ensure that all Zig files are properly formatted.
This avoids unrelated diff noise in future PRs.

This also runs `zig fmt` once to clean up all formatting issues for
future PRs.

I also introduced a new `xsm` (extra small) runner profile to use less
resources for our tiny tasks.
2025-03-18 14:39:34 -07:00
Jeffrey C. Ollie 07ec421cd3
CI: Add checks for blueprint compiler / Nix refactors (#6801)
1. Refactored Nix devshell/package to make it easier to keep
LD_LIBRARY_PATH & buildInputs in sync (plus make it easier to re-use in
other Nix environment).
2. Added a CI job to ensure that Blueprints are formatted correctly and
that they will compile using `blueprint-compiler` 0.16.0.
3. Reformatted all Blueprints with `blueprint-compiler format`.
2025-03-18 16:37:34 -05:00
Jeffrey C. Ollie 648e0a06ab
CI: Add checks for blueprint compiler / Nix refactors
1. Refactored Nix devshell/package to make it easier to keep
   LD_LIBRARY_PATH & buildInputs in sync (plus make it easier to re-use
   in other Nix environment).
2. Added a CI job to ensure that Blueprints are formatted correctly and
   that they will compile using `blueprint-compiler` 0.16.0.
3. Reformatted all Blueprints with `blueprint-compiler format`.
2025-03-18 16:12:49 -05:00
Mitchell Hashimoto 4d0bf303c6
ci: zig fmt check
This adds a CI test to ensure that all Zig files are properly formatted.
This avoids unrelated diff noise in future PRs.
2025-03-18 13:58:49 -07:00
Mitchell Hashimoto c0f5f913c9
`zig build dist` and `distcheck` for source tarballs (#6800)
This moves the source tarball creation process into the Zig build system
and follows the autotools-standard naming conventions of `dist` and
`distcheck`.

This doesn't change any of our build process otherwise. This is the
foundation for #6760 along with other source tarball tasks I have
planned (i.e. gobject bindings too).

The `dist` target creates a source tarball in the `PREFIX/dist`
directory. The tarball is named `ghostty-VERSION.tar.gz` as expected by
standard source tarball conventions.

The `distcheck` target does the same as `dist`, but also takes the
resulting tarball, extracts it, and runs tests on the extracted source
to verify the source tarball works as expected. Distcheck currently only
runs `zig build test` but in the future we can add additional checks to
run.

This commit also updates CI:

  1. Tagged releases now use the new `zig build distcheck` command.
  2. Tip releases now use the new `zig build dist` command.
3. A new test build tests that source tarball generation works on every
commit.
2025-03-18 13:21:24 -07:00
Mitchell Hashimoto bab8c28c8b
`zig build dist` and `distcheck` for source tarballs
This moves the source tarball creation process into the Zig build system
and follows the autotools-standard naming conventions of `dist` and
`distcheck`.

The `dist` target creates a source tarball in the `PREFIX/dist`
directory. The tarball is named `ghostty-VERSION.tar.gz` as expected by
standard source tarball conventions.

The `distcheck` target does the same as `dist`, but also takes the
resulting tarball, extracts it, and runs tests on the extracted source
to verify the source tarball works as expected.

This commit also updates CI:

  1. Tagged releases now use the new `zig build distcheck` command.
  2. Tip releases now use the new `zig build dist` command.
  3. A new test build tests that source tarball generation works on
     every commit.
2025-03-18 12:41:55 -07:00
Leah Amelia Chen 69590c80a1
gtk: unify gtk/adwaita version checks, use std.SemanticVersion in all cases (#6797) 2025-03-18 20:35:34 +01:00
Jeffrey C. Ollie 5bf10dce12
c804cd3dbb0274f3271736e0b8f279795bdff394 2025-03-18 14:14:50 -05:00
Jeffrey C. Ollie 0f2f0ab69f
Update Adwaita version check for Box unref (#6796)
As of Adwaita 1.5.0, the GTK Box is not being properly unref'd when the
parent window is closed. Update the conditional to account for this.

Also add a couple of missing unref()s in errdefers.

This fixes an issue where Ghostty would not properly quit after closing
the last surface.
https://github.com/ghostty-org/ghostty/discussions/3807 is related
(though I'm not sure it's the exact same problem).
2025-03-18 10:42:00 -05:00
Gregory Anders 946c0c370f Update Adwaita version check for Box unref
As of Adwaita 1.5.0, the GTK Box is not being properly unref'd when the
parent window is closed. Update the conditional to account for this.

Also add a couple of missing unref()s in errdefers.
2025-03-18 10:24:42 -05:00
Jeffrey C. Ollie ee78a3d345
gtk: remove c.zig (#6792)
It has been done.
2025-03-18 09:59:23 -05:00
Leah Amelia Chen 72017ea4d8
translations(zh_CN): update 2025-03-18 12:35:41 +01:00
Leah Amelia Chen 8c0ccfc5b3
translations: update 2025-03-18 12:35:41 +01:00
Leah Amelia Chen a773588c99
gtk: remove c.zig
It has been done.
2025-03-18 12:35:41 +01:00
Leah Amelia Chen 73341b052b
gtk: port ConfigErrorsWindow to dialogs 2025-03-18 12:35:41 +01:00
Leah Amelia Chen 1ee9c85954
gtk: port inspector & key handling to zig-gobject 2025-03-18 12:35:41 +01:00
Leah Amelia Chen e3fbbe8fe3
ci(test/translations): ignore untranslated entries 2025-03-18 12:32:55 +01:00
Leah Amelia Chen d75c5ec038
gtk: convert App to zig-gobject (#6787) 2025-03-18 09:14:19 +01:00
Jeffrey C. Ollie ee95a5f3e0
gtk: convert App to zig-gobject 2025-03-17 23:39:45 -05:00
Leah Amelia Chen 742bca713d
gtk: convert Window (and some related files) to zig-gobject (#6775) 2025-03-17 21:19:17 +01:00
Mitchell Hashimoto 899ab302e1
apprt/gtk: any preedit change should note a composing state (#6779)
Fixes #6772

When typing Korean with the fcitx5-hangful input method, moving between
graphemes does not trigger a preedit end/start cycle and instead just
clears the preexisting preedit and reuses the started state.

Every other input method we've tested up until now doesn't do this. We
need to mark composing set to "false" in "commit" because some input
methods on the contrary fail to ever call END.

What is the point of start/end events if they are just ignored depending
on the whim of the input method? Nothing. That's what. Its all a mess
that GTK should be protecting us from but it doesn't and now its the app
developer's problem. I'm frustrated because I feel like the point of an
app framework is to mask this kind of complexity from the app developer
and I'm playing whack-a-mole with input methods.

Well, here's another whack. Let's see if it works.
2025-03-17 11:59:33 -07:00
Mitchell Hashimoto 590eb60759
apprt/gtk: any preedit change should note a composing state
Fixes #6772

When typing Korean with the fcitx5-hangful input method, moving between
graphemes does not trigger a preedit end/start cycle and instead just
clears the preexisting preedit and reuses the started state.

Every other input method we've tested up until now doesn't do this. We
need to mark composing set to "false" in "commit" because some input
methods on the contrary fail to ever call END.

What is the point of start/end events if they are just ignored depending
on the whim of the input method? Nothing. That's what. Its all a mess
that GTK should be protecting us from but it doesn't and now its the app
developer's problem. I'm frustrated because I feel like the point of an
app framework is to mask this kind of complexity from the app developer
and I'm playing whack-a-mole with input methods.

Well, here's another whack. Let's see if it works.
2025-03-17 11:44:39 -07:00
Jeffrey C. Ollie daa79c3598
gtk: address review comments
1. Remove usage of C header imports for gtk x11/wayland.
2. Move X11 C header imports to winproto_x11.zig
3. Clean up long line by breaking it up into multiple steps.
2025-03-17 12:35:31 -05:00
Jeffrey C. Ollie 29322535a5
gtk: convert Window (and some related files) to zig-gobject 2025-03-17 12:06:57 -05:00
Jeffrey C. Ollie e0fe12cc05
Update Debian 12 Dockerfile (#6776)
1. Automatically detect the required Zig version rather than using a
hardcoded value.
2. Run `ghostty +version` after the build as a sanity check.
2025-03-17 11:09:47 -05:00
Jeffrey C. Ollie 1d040dd17d
debian workflow: remove unused ZIG_VERSION arg 2025-03-17 10:54:44 -05:00
Jeffrey C. Ollie 7f7191dfec
Update Debian 12 Dockerfile
1. Automatically detect the required Zig version rather than
using a hardcoded value.
2. Run `ghostty +version` after the build as a sanity check.
2025-03-17 10:41:17 -05:00
Jeffrey C. Ollie a2df8e4b86
gtk: update Tab to use zig-gobject (#6729) 2025-03-17 10:39:13 -05:00
Mitchell Hashimoto c344c320eb
Update iTerm2 colorschemes (#6755)
Upstream revision:
e348884a00
2025-03-16 07:18:30 -07:00
mitchellh 291c2f541c deps: Update iTerm2 color schemes 2025-03-16 14:17:59 +00:00
Mitchell Hashimoto f8590ce44f
scroll: translate non-precision to precision (#6750)
Some wheel mice are capable of reporting fractional wheel ticks. These
mice don't necessarily report a corresponding precision scroll start
event, at least in Wayland + GTK. We can treat all discrete (ie
non-precision) events as the number of wheel ticks - for wheel mice,
yoff will be "1.0" per tick, while precision wheel mice may report
fractional values. This unifies handling of scroll events by normalizing
all events to "pixels to scroll".

We now report `mouse-scroll-multiplier` wheel or arrow events per wheel
tick (or per accumulated cell height). This means that applications
which subscribe to mouse button events will receive (by default) three
wheel events per wheel tick. For precision scrolls, they will receive
one wheel tick per line of scroll. In my opinion, this provides the best
user experience while also allowing customization of how much a
wheel tick should scroll

Reference: https://github.com/ghostty-org/ghostty/discussions/6677
2025-03-16 07:15:34 -07:00
Mitchell Hashimoto d3424a922a
update zon2nix (#6728)
Upstream is now mostly pure Zig and the build.zig.zon.* files are
generated directly by zon2nix. The JSON file is no longer used as an
intermediate file but is retained for downstream packager usage.
2025-03-16 07:13:24 -07:00
Jeffrey C. Ollie 5cd8ebdafd
update zon2nix
Upstream is now mostly pure Zig and the build.zig.zon.* files are
generated directly by zon2nix. The JSON file is no longer used as an
intermediate file but is retained for downstream packager usage.
2025-03-16 01:09:52 -05:00
Jeffrey C. Ollie 3bc2b02303
build: update libvaxis and zf (#6752)
Fixes #6734
2025-03-15 23:42:49 -05:00
Jeffrey C. Ollie ec4d110251
build: update libvaxis and zf
Fixes #6734
2025-03-15 22:06:18 -05:00
Tim Culverhouse 2018a8fd3c
scroll: translate non-precision to precision
Some wheel mice are capable of reporting fractional wheel ticks. These
mice don't necessarily report a corresponding precision scroll start
event, at least in Wayland + GTK. We can treat all discrete (ie
non-precision) events as the number of wheel ticks - for wheel mice,
yoff will be "1.0" per tick, while precision wheel mice may report
fractional values. This unifies handling of scroll events by normalizing
all events to "pixels to scroll".

We now report `mouse-scroll-multiplier` wheel or arrow events per wheel
tick (or per accumulated cell height). This means that applications
which subscribe to mouse button events will receive (by default) three
wheel events per wheel tick. For precision scrolls, they will receive
one wheel tick per line of scroll. In my opinion, this provides the best
user experience while also allowing customization of how much a
wheel tick should scroll

Reference: https://github.com/ghostty-org/ghostty/discussions/6677
2025-03-15 21:35:39 -05:00
Jeffrey C. Ollie 4b1d1e0ed4
gtk: update Tab to use zig-gobject 2025-03-15 14:19:59 -05:00
Mitchell Hashimoto 644acdacdc
termio, flatpak: implement process watcher with xev (#6658)
This allows `termio.Exec` to track processes spawned via
`FlatpakHostCommand`, finally allowing Ghostty to function as a Flatpak.

Alongside this is a few bug fixes:

* Don't add ghostty to PATH when running in flatpak mode since it's
unreachable.
* Correctly handle exit status returned by Flatpak. Previously this was
not processed and contains extra status bits.
* Use correct type for PID returned by Flatpak.
2025-03-15 08:09:54 -07:00
Mitchell Hashimoto 791d332a25
pkg/macos: clean up for Zig 0.14, consolidate C imports into one decl (#6736)
Fixes #6727

The major change in this commit is to consolidate all the C imports in a
single decl in main.zig. This is required for Zig 0.14. Without it, the
problem in #6727 will happen. I was never able to minimize why this
happens in order to open a Zig bug.

Beyond this, I fixed the build.zig and build.zig.zon to work with Zig
0.14 so that we can test building `pkg/macos` in isolation. There are no
downstream impacting changes in the build.zig files.
2025-03-15 07:30:05 -07:00
Leorize 009b53c45e termio, flatpak: implement process watcher with xev
This allows `termio.Exec` to track processes spawned via
`FlatpakHostCommand`, finally allowing Ghostty to function as a
Flatpak.

Alongside this is a few bug fixes:

* Don't add ghostty to PATH when running in flatpak mode since it's
  unreachable.
* Correctly handle exit status returned by Flatpak. Previously this was
  not processed and contains extra status bits.
* Use correct type for PID returned by Flatpak.
2025-03-15 07:29:13 -07:00
Mitchell Hashimoto 5ad8ea6b22
pkg/macos: clean up for Zig 0.14, consolidate C imports into one decl
Fixes #6727

The major change in this commit is to consolidate all the C imports in
a single decl in main.zig. This is required for Zig 0.14. Without it,
the problem in #6727 will happen. I was never able to minimize why this
happens in order to open a Zig bug.

Beyond this, I fixed the build.zig and build.zig.zon to work with Zig
0.14 so that we can test building `pkg/macos` in isolation. There are no
downstream impacting changes in the build.zig files.
2025-03-15 07:02:53 -07:00
Leah Amelia Chen f8f9f7041a
os: fix use of deprecated splitBackwards for Flatpak (#6733) 2025-03-15 08:02:41 +01:00
Leorize 2e6a2a148f
os: fix use of deprecated splitBackwards for Flatpak 2025-03-14 23:48:59 -05:00
Mitchell Hashimoto 550edd4262
build: mark most dependencies as lazy (#6726)
Closes #6703 

Lazy dependencies are only fetched if the build script would actually
reach a usage of that dependency at runtime (when the `lazyDependency`
function is called). This can save a lot of network traffic, disk uage,
and time because we don't have to fetch and build dependencies that we
don't actually need.

Prior to this commit, Ghostty fetched almost everything for all
platforms and configurations all the time. This commit reverses that to
fetching almost nothing until it's actually needed.

There are very little downsides to doing this[1]. One downside is `zig
build --fetch` doesn't fetch lazy dependencies, but we don't rely on
this command for packaging and suggest using our custom shell script
that downloads a cached list of URLs (`build.zig.zon.txt`).

This commit doesn't cover 100% of dependencies, since some provide no
benefit to make lazy while the complexity to make them lazy is higher
(in code style typically).

Conversely, some simple dependencies are marked lazy even if they're
almost always needed if they don't introduce any real complexity to the
code, because there is very little downside to do so.

[1]: https://ziggit.dev/t/lazy-dependencies-best-dependencies/5509/5
2025-03-14 18:33:32 -07:00
Mitchell Hashimoto cfea2ea12c
build: mark most dependencies as lazy
Lazy dependencies are only fetched if the build script would actually
reach a usage of that dependency at runtime (when the `lazyDependency`
function is called). This can save a lot of network traffic, disk uage,
and time because we don't have to fetch and build dependencies that we
don't actually need.

Prior to this commit, Ghostty fetched almost everything for all
platforms and configurations all the time. This commit reverses that to
fetching almost nothing until it's actually needed.

There are very little downsides to doing this[1]. One downside is `zig
build --fetch` doesn't fetch lazy dependencies, but we don't rely on
this command for packaging and suggest using our custom shell script
that downloads a cached list of URLs (`build.zig.zon.txt`).

This commit doesn't cover 100% of dependencies, since some provide no
benefit to make lazy while the complexity to make them lazy is higher
(in code style typically).

Conversely, some simple dependencies are marked lazy even if they're
almost always needed if they don't introduce any real complexity to the
code, because there is very little downside to do so.

[1]: https://ziggit.dev/t/lazy-dependencies-best-dependencies/5509/5
2025-03-14 13:32:19 -07:00
Leah Amelia Chen 234b804872
contributing: fix link to Translator's Guide (#6712) 2025-03-14 17:29:10 +01:00
Jeffrey C. Ollie f37d1fd7ed
gtk: convert Surface to zig-gobject (#6634)
Marking this is as draft because I want to test this further before
saying that it's ready, but putting it out there for feedback.
2025-03-14 10:14:33 -05:00
Leah Amelia Chen c2aac45848
fix: Use builtin `source_env_if_exists` for sourcing `.envrc.local` (#6717) 2025-03-14 13:33:37 +01:00
Uzair Aftab b497400be6
fix: ignore `.envrc.local` 2025-03-14 13:15:29 +01:00
Uzair Aftab ec5066988e
fix: Use builtin `source_env_if_exists` for sourcing `.envrc.local` 2025-03-14 13:11:05 +01:00
Leah Amelia Chen 4ab3754a59
feat: source local .envrc if it exists (#6715) 2025-03-14 12:14:19 +01:00
Uzair Aftab b9ea32b8ce
Update .envrc
Co-authored-by: Kat <65649991+00-kat@users.noreply.github.com>
2025-03-14 12:08:37 +01:00
Uzair Aftab 69dfc8870d
fix: use bashism in `.envrc`
Co-authored-by: Leah Amelia Chen <github@acc.pluie.me>
2025-03-14 12:00:25 +01:00
Uzair Aftab 09d538b620
feat: source `.envrc.local` if it exists
Co-authored-by: Kat <65649991+00-kat@users.noreply.github.com>
2025-03-14 11:50:56 +01:00
Leah Amelia Chen 07b653bd71
contributing: link to po/README_CONTRIBUTORS.md 2025-03-14 08:46:06 +01:00
Leah Amelia Chen e8101c1136
contributing: fix link to Translator's Guide
For some reason it pointed to the Contributor's Guide instead...
2025-03-14 08:44:04 +01:00
Mitchell Hashimoto 8eacde92e6
Replace mach-glfw with pkg/glfw (#6708)
Closes #6702

This removes our mach-glfw dependency and replaces it with an in-tree
pkg/glfw that includes both the source for compiling glfw as well as the
Zig bindings. This matches the pattern from our other packages.

This is based on the upstream mach-glfw work and therefore includes the
original license and copyright information.

The reasoning is stated in the issue but to summarize for the commit:

  - mach-glfw is no longer maintained, so we have to take ownership
- mach-glfw depended on some large blobs of header files to enable
cross-compilation but this isn't something we actually care about, so we
can (and do) drop the blobs
- mach-glfw blobs were hosted on mach hosts. given mach-glfw is
unmaintained, we can't rely on this hosting
- mach-glfw relied on a "glfw" package which was owned by another person
to be Zig 0.14 compatible, but we no longer need to rely on this
  - mach-glfw builds were outdated based on latest Zig practices
2025-03-13 21:18:41 -07:00
Mitchell Hashimoto 221f905a1c
pkg/glfw
Closes #6702

This removes our mach-glfw dependency and replaces it with an in-tree
pkg/glfw that includes both the source for compiling glfw as well as the
Zig bindings. This matches the pattern from our other packages.

This is based on the upstream mach-glfw work and therefore includes the
original license and copyright information.

The reasoning is stated in the issue but to summarize for the commit:

  - mach-glfw is no longer maintained, so we have to take ownership
  - mach-glfw depended on some large blobs of header files to enable
    cross-compilation but this isn't something we actually care about,
    so we can (and do) drop the blobs
  - mach-glfw blobs were hosted on mach hosts. given mach-glfw is
    unmaintained, we can't rely on this hosting
  - mach-glfw relied on a "glfw" package which was owned by another
    person to be Zig 0.14 compatible, but we no longer need to rely on
    this
  - mach-glfw builds were outdated based on latest Zig practices
2025-03-13 20:52:33 -07:00
Mitchell Hashimoto 73c7943fff
CODEOWNERS: add localization teams (#6704) 2025-03-13 10:19:29 -07:00
Mitchell Hashimoto d8497d9b16
CODEOWNERS: add localization teams 2025-03-13 10:07:27 -07:00
Mitchell Hashimoto ef0ff94c75
translations: add German translation (#6601)
This PR adds a translation for German `de_DE`.

Additionally it excludes all `*.po` files from the typos CI action.

Some comments on the decisions I made (open to discuss them):

- I choosed to use `du` instead of `Sie` as this seems appropriate
  to me.
- I added `Window` (`Fenster` in German) to all split commands
  as it appears more naturally to me.
2025-03-13 10:05:27 -07:00
Jeffrey C. Ollie 572fc8b5d7
gtk: convert Surface to zig-gobject 2025-03-13 12:04:10 -05:00
Mitchell Hashimoto 1f6b1d75eb
Fix aspect ratio when rendering images with kitty protocol (#6675)
Fixes https://github.com/ghostty-org/ghostty/issues/6673

<img width="914" alt="image"
src="https://github.com/user-attachments/assets/010a1304-0d46-46ec-9a82-87a8d8fbea1b"
/>
2025-03-13 09:50:19 -07:00
Mitchell Hashimoto aeada3f1a8
Zig 0.14 (#6699)
Closes #5744 

This gets Ghostty onto Zig 0.14. The goal of this PR is to focus only on
Zig 0.14 _compatibility_. I plan to open a number of subsequent issues
for future improvements I'd like to tackle, as noted in #5744.

I did run some basic benchmarks on a Zig 0.13 vs 0.14 build and didn't
notice any statistically significant changes. All our scrolling
benchmarks on vtebench got consistently 1 or 2ms faster but that may
just be noise. The good news is nothing got consistently slower (nothing
got slower at all on any runs!).

The Git history here is kind of nasty, I'm going to squash it.
2025-03-13 09:36:09 -07:00
Mitchell Hashimoto f1f9db8b96
Update PACKAGING to note Zig 0.14 requirement 2025-03-13 09:18:34 -07:00
Mitchell Hashimoto a542e63582
pkg/gtk4-layer-shell: disable ubsan 2025-03-13 09:14:37 -07:00
Mitchell Hashimoto bdb66984b6
for iOS simulator builds for apple M1 as base CPU model 2025-03-13 07:13:13 -07:00
Mitchell Hashimoto 6613a695f0
nix 2025-03-12 16:30:22 -07:00
Mitchell Hashimoto b96a5d702b
fix mach-glfw on windows 2025-03-12 16:29:17 -07:00
Mitchell Hashimoto 66c83648c8
ci: debian 12 build should use zig 0.14 2025-03-12 16:29:17 -07:00
Mitchell Hashimoto 1dbeba7065
ci: update snap to Zig 0.14 2025-03-12 16:29:17 -07:00
Mitchell Hashimoto fc21444f2d
fix windows 2025-03-12 16:29:17 -07:00
Mitchell Hashimoto 907ed239a1
update typos 2025-03-12 16:29:17 -07:00
Mitchell Hashimoto b123b14686
update zig2nix 2025-03-12 15:56:24 -07:00
Mitchell Hashimoto 99bde549af
fix /usr/lib issues 2025-03-12 15:46:15 -07:00
Mitchell Hashimoto 1f6aa0e90d
apprt/glfw: move darwin enabled const out to top-level 2025-03-12 12:53:15 -07:00
Mitchell Hashimoto 18084a3e61
update gobject, fix compiler errors 2025-03-12 12:32:50 -07:00
Mitchell Hashimoto 816ff8cef0
fix tests building on Linux 2025-03-12 11:29:13 -07:00
Mitchell Hashimoto 2e45a4c7a3
fix typos 2025-03-12 11:23:11 -07:00
Mitchell Hashimoto 3116a1b92c
bundle ubsan rt 2025-03-12 11:07:15 -07:00
Mitchell Hashimoto 601acf4059
pkg/highway: upgrade to fix compilation issues on LLVM18 2025-03-12 11:03:54 -07:00
Mitchell Hashimoto 7e9be00924
working on macos 2025-03-12 10:15:14 -07:00
Mitchell Hashimoto 43467690f3
test 2025-03-12 10:04:17 -07:00
Mitchell Hashimoto 2408d4c6a9
more fixes 2025-03-12 09:59:24 -07:00
Mitchell Hashimoto 0f4d2bb237
Lots of 0.14 changes 2025-03-12 09:55:52 -07:00
Mitchell Hashimoto 86d3f18707
pkg/oniguruma: fix build 2025-03-12 09:10:17 -07:00
Bryan Lee 2f814b37e8
Add unit tests for kitty image aspect ratio calculation 2025-03-12 22:44:17 +08:00
Mitchell Hashimoto bd848a27d2
update all packages to new hash for caching 2025-03-12 07:30:01 -07:00
Bryan Lee f091a69790
Fix aspect ratio when rendering images with kitty protocol 2025-03-12 15:06:06 +08:00
Mitchell Hashimoto 2466de4556
pkg: update to new build.zig.zon format and hash values 2025-03-11 15:00:47 -07:00
Mitchell Hashimoto 251caeb22a
Zig 0.14 fixes 2025-03-11 14:53:30 -07:00
Mitchell Hashimoto 3abbe6d3ba
nix: must not inject xcrun into PATH on macOS 2025-03-11 14:49:01 -07:00
Mitchell Hashimoto 7e2286eb8c
Zig 0.14 2025-03-11 14:39:04 -07:00
Leah Amelia Chen 95daca616d
core: refactor RepeatablePath into separate files and add Path (#6622)
Slims down `Config.zig` and makes some of the code reusable in Path.
2025-03-10 09:14:25 +01:00
Leah Amelia Chen 14b66e93d1
pkg(gtk4-layer-shell): Enable using system-installed headers for dynamic linking (#6624)
I noticed we weren't doing system-integration against the pkgconfig for
gtk4-layer-shell. This behaviour differed from how we handled system
integration for existing deps in `pkg/` (oniguruma, fontconfig).

Refactored `pkg/gtk4-layer-shell/build.zig` referencing
`pkg/oniguruma/build.zig` to use pkgconfig names in system integration.
Previously we used to libname `libgtk4-layer-shell.so`
(`gtk4-layer-shell`) instead of pkgconfig name `gtk4-layer-shell-0.pc`
which meant system integration still relied on fetching the C-headers
via `zig fetch` instead of system C-headers.

I've tested this with a `--system` build where the relevant
`.zig-cache/p/<hash of gtk4-layer-shell>` is stubbed to an empty
directory and `pkgconfig(gtk4-layer-shell-0)` is installed instead on
fedora linux.
2025-03-10 09:11:42 +01:00
Mitchell Hashimoto 0ecee3ee92
Fix passing EnvMap for Flatpak builds (#6647)
When using -Dflatpak=true the EnvMap was passed as the incorrect type.
2025-03-09 18:39:54 -07:00
Mitchell Hashimoto 57d0a4d2e7
font(freetype): constrain emoji to cell width (#6602)
When scaling emoji (with freetype), we would unilaterally scale the
bitmap to fit within the `cell_height`. For narrow fonts, this would
result in a horizontal overflow:


![image](https://github.com/user-attachments/assets/87b9f952-6f12-40b2-bbed-5bfe948f45b4)

Modify the glyph rendering such that we scale to fit within the cell
width. After doing so, the above image looks like:


![image](https://github.com/user-attachments/assets/c75bfa51-4730-4179-b032-c3afa7840d65)

The emoji glyph is noticeably smaller because we have constrained the
height further than before, but fits perfectly within two cells. I am
using Victor Mono as my font, which is pretty narrow. The effect would
be even more pronounced on something like Iosevka.
2025-03-09 18:34:34 -07:00
Mitchell Hashimoto 480b1a9805
macOS: only set LANGUAGE for app bundle, do not inherit in termio env (#6648)
Fixes #6633

For macOS, we set LANGUAGE to the priority list of preferred languages
for the app bundle, using the GNU gettext priority list format (colon
separated list of language codes).

This previously was inherited by the termio env. At first, this was by
design, but this has inherent flaws. Namely, the priority list format is
a GNU gettext specific format, and programs that use alternate gettext
implementations (like musl or Python) do not understand it and actually
do the wrong thing (not their fault!).

This change removes the inheritance of LANGUAGE in the termio env. To
make it extra safe, we only do set and unset LANGUAGE when we know we
launch from an app bundle. That was always the desired behavior but this
makes it more explicit.
2025-03-09 17:08:55 -07:00
Mitchell Hashimoto ebffe299ce
macOS: only set LANGUAGE for app bundle, do not inherit in termio env
Fixes #6633

For macOS, we set LANGUAGE to the priority list of preferred languages
for the app bundle, using the GNU gettext priority list format (colon
separated list of language codes).

This previously was inherited by the termio env. At first, this was by
design, but this has inherent flaws. Namely, the priority list format is
a GNU gettext specific format, and programs that use alternate gettext
implementations (like musl or Python) do not understand it and actually
do the wrong thing (not their fault!).

This change removes the inheritance of LANGUAGE in the termio env. To
make it extra safe, we only do set and unset LANGUAGE when we know we
launch from an app bundle. That was always the desired behavior but this
makes it more explicit.
2025-03-09 18:17:38 -05:00
Yorick Peterse 300f4544ef Fix passing EnvMap for Flatpak builds
When using -Dflatpak=true the EnvMap was passed as the incorrect type.
2025-03-09 23:46:24 +01:00
Jeffrey C. Ollie 843cc83f42
gtk: implement quick-terminal-size (#6629)
Fixes #2384 on GTK

I'm not exactly sure how to deal with centered quick terminals so I
opted to make them similar to either top/bottom or left/right quick
terminals based on the monitor's orientation (portrait/landscape). This
may not be the right approach, so I'd like to hear more thoughts about
this.
2025-03-09 09:51:04 -05:00
Mitchell Hashimoto 78f16d040d
macOS: disable setting LANGUAGE for now until bug is fixed
See: https://github.com/ghostty-org/ghostty/discussions/6633

This is temporary while we figure this out.
2025-03-09 07:25:55 -07:00
Jeffrey C. Ollie 6767493428
core: move RepeatablePath to separate file and enable Path as config type
Slim down Config.zig by moving RepeatablePath to a separate file and
enable the use of Path as it's own config type.
2025-03-09 09:18:01 -05:00
Jeffrey C. Ollie bb3dad1309
core: all paths referenced from the CLI must be expanded 2025-03-09 09:17:57 -05:00
Mitchell Hashimoto d3fd2b02e7
terminal: remove redundant assertIntegrity from clearPrompt (#6630)
clearCells() always asserts its page's integrity after finishing its
work (via a `defer`). We don't need to re-assert the page's integrity
immediately thereafter.
2025-03-08 14:37:23 -08:00
Mitchell Hashimoto 5efa2a6ca1
macOS: Set LANGUAGE env var based on macOS preferred language list (#6628)
Sets the LANGUAGE environment variable based on the preferred languages
as reported by NSLocale.

macOS has a concept of preferred languages separate from the system
locale. The set of preferred languages is a list in priority order of
what translations the user prefers. A user can have, for example,
"fr_FR" as their locale but "en" as their preferred language. This would
mean that they want to use French units, date formats, etc. but they
prefer English translations.

gettext uses the LANGUAGE environment variable to override only
translations and a priority order can be specified by separating the
languages with colons. For example, "en:fr" would mean that English
translations are preferred but if they are not available then French
translations should be used.

To further complicate things, Apple reports the languages in BCP-47
format which is not compatible with gettext's POSIX locale format so we
have to canonicalize them. To canonicalize the languages we use an
internal function from libintl. This isn't normally available but since
we compile from source on macOS we can use it. This isn't necessary for
other platforms.

This logic is only run if the user didn't explicitly request a specific
locale, so it should really only affect macOS app launches. From the CLI
the environment will have a locale unless the user really explicitly
clears it out.
2025-03-08 14:36:58 -08:00
Leah Amelia Chen a0080ddad7
gtk: implement quick-terminal-size
Fixes #2384 on GTK

I'm not exactly sure how to deal with centered quick terminals so I opted
to make them similar to either top/bottom or left/right quick terminals
based on the monitor's orientation (portrait/landscape). This may not be
the right approach, so I'd like to hear more thoughts about this.
2025-03-08 22:36:24 +01:00
Jon Parise b0b2de01f5 terminal: remove redundant assertIntegrity from clearPrompt
clearCells() always asserts its page's integrity after finishing its
work (via a `defer`). We don't need to re-assert the page's integrity
immediately thereafter.
2025-03-08 16:36:14 -05:00
Mitchell Hashimoto b48fcf33f7
macOS: Set LANGUAGE env var based on macOS preferred language list
Sets the LANGUAGE environment variable based on the preferred languages
as reported by NSLocale.

macOS has a concept of preferred languages separate from the system
locale. The set of preferred languages is a list in priority order
of what translations the user prefers. A user can have, for example,
"fr_FR" as their locale but "en" as their preferred language. This would
mean that they want to use French units, date formats, etc. but they
prefer English translations.

gettext uses the LANGUAGE environment variable to override only
translations and a priority order can be specified by separating
the languages with colons. For example, "en:fr" would mean that
English translations are preferred but if they are not available
then French translations should be used.

To further complicate things, Apple reports the languages in BCP-47
format which is not compatible with gettext's POSIX locale format so
we have to canonicalize them. To canonicalize the languages we use
an internal function from libintl. This isn't normally available but
since we compile from source on macOS we can use it. This isn't
necessary for other platforms.
2025-03-08 12:54:39 -08:00
azhn 35aab1a302 build: use pkgconfig name for gtk4-layer-shell system integration
By linking using the pkg-config name we gain the compiler flags in pkgconf
for linking, specifically the -I <headers> to include system-installed
headers. This allows the gtk4-layer-shell pkg to not require the source
files specified in the `pkg/gtk4-layer-shell/build.zig.zon`.

pkg(gtk4-layer-shell): Refactor to allow dynamic linking

Refactored `pkg/gtk4-layer-shell/build.zig` to have similar structure
to `pkg/oniguruma/build.zig`.

Now dynamic link using pkgconfig, this adds pkgconfig compiler flags.
So we are now using system-installed headers to resolve @cInclude().
2025-03-09 02:46:33 +11:00
Robin Pfäffle c67c7da582 translations(german): fix fuzzy translations 2025-03-08 09:24:54 +01:00
Robin Pfäffle 9d86bdfe72 translations: add `de_DE` to locales 2025-03-08 08:23:33 +01:00
Robin Pfäffle abb97fa574
translations(german): update `de_DE` strings 2025-03-08 08:11:43 +01:00
Robin Pfäffle 7e268b9a43
ci: typos ignore `*.po` files 2025-03-08 08:11:43 +01:00
Robin Pfäffle d2931b5d8f
translations(german): address review comments 2025-03-08 08:11:41 +01:00
Robin Pfäffle 2ef11fb65f
translations(german): add missing warning indicator 2025-03-08 08:08:51 +01:00
Robin Pfäffle d511b3601d
translations: add German translation 2025-03-08 08:08:51 +01:00
Mitchell Hashimoto e03e98e106
Groundwork for cross-platform i18n with libintl for libghostty/macOS (#6619)
This builds on @pluiedev's excellent #6004.

## Background: The macOS (and libghostty consumer) Plan

Broadly, the decision I've come to is that for cross-platform
translations (i.e. strings shared across libghostty), we will be using
gettext and libghostty will export helper methods to call those (e.g.
`ghostty_translate` in this PR for singular forms). To be clear, **this
only applies to strings owned by libghostty**. For application-level
strings such as macOS-specific menu items and so on, we still have
choice but will likely using native features.

The reason for this is because converting gettext translations (`po`) to
native formats (Xcode String Catalog, `.strings`/`.stringsdict`) is
nightmare level, in particular for plural forms. I don't see a robust
path to doing it. And if we don't convert and don't use gettext, then
translators would have to maintain an identical translation in multiple
locations. To make matters worse, the macOS translation formats require
Apple-tooling for now unless you want to edit raw JSON.

Leveraging gettext lets us share translations across platforms and take
advantage of proven tech.

## PR Contents

**`pkg/libintl` builds and statically links libintl for macOS.** macOS
doesn't ship libintl with the system while Linux generally does with
libc, so we need to build this ourselves. This makes gettext available
to macOS. libintl is LGPL and we remain in compliance with that despite
static linking because our build process is fully open source, so
downstream consumers can modify our build scripts to replace it if they
wanted to.

~~**`src/os/locale.zig` now sets the `LANGUAGE` environment variable on
macOS based on the app's preferred languages.** macOS lets you configure
the system locale separate from preferred language. We previously relied
solely on `NSLocale.currentLocale`, but this only represents the system
locale. We now also look at `NSLocale.preferredLanguages` (a list in
priority order) and if we support a given language we set `LANGUAGE` so
gettext translates properly. Notably, the above lets us debug
translations in Xcode by setting alternate languages for debug builds
only.~~ Removed this for a future PR since it was problematic.

**`build.zig` unconditionally builds binary `mo` files** since they're
required for all apprts now.

**The macOS app bundles the translation strings.** This includes our
GTK-specific translation strings but the size of these is so small it
isn't worth the complexity of splitting up into multiple `pot`s at this
time, I think.

**i18n APIs moved to `src/os` from `src/apprt/gtk`.** Since these are
now cross-platform/cross-apprt, they're a core API. The only notable
change here is that `_` now maps to `dgettext` and explicitly specifies
our domain so that it's library-friendly. The GTK apprt calls
`initGlobalDomain` so that blueprint translations still work.

## Next Steps

This PR is all groundwork. The macOS app doesn't leverage any of this
yet, although I've verified it all works (e.g. calling the
`ghostty_translate` API from Swift).

For next steps, we need to have a use case for cross-platform
translations and the first one I was looking at was configuration error
messages and other core strings.
2025-03-07 14:51:12 -08:00
Mitchell Hashimoto dcb8440b52
os: remove the preferredLanguages lookup 2025-03-07 13:43:00 -08:00
Mitchell Hashimoto 7eddf98269
Fix typos 2025-03-07 13:42:00 -08:00
Mitchell Hashimoto da731e6caa
typo i81n -> i18n 2025-03-07 13:42:00 -08:00
Mitchell Hashimoto 79a9ddf66f
build: pure libghostty builds need to build translations 2025-03-07 13:42:00 -08:00
Mitchell Hashimoto e8a988f6d3
os: i18n unsupported on windows 2025-03-07 13:42:00 -08:00
Mitchell Hashimoto c7681e8fd7
apprt/gtk: use the new global i18n API 2025-03-07 13:42:00 -08:00
Mitchell Hashimoto cff092f4c6
nix: update hashes 2025-03-07 13:42:00 -08:00
Mitchell Hashimoto 3ebd5b839f
update translating readme 2025-03-07 13:42:00 -08:00
Mitchell Hashimoto be839cb681
update our gitattributes with new generated files 2025-03-07 13:42:00 -08:00
Mitchell Hashimoto 3c49bc5086
os: locale automatically sets LANGUAGE based on macOS preferred 2025-03-07 13:42:00 -08:00
Mitchell Hashimoto edf619205c
add ghostty_translate C API 2025-03-07 13:42:00 -08:00
Mitchell Hashimoto 238573d42e
i18n: export proper _ function 2025-03-07 13:42:00 -08:00
Mitchell Hashimoto 4cf127a064
build: i18n should emit mo on every platform 2025-03-07 13:42:00 -08:00
Mitchell Hashimoto e8c20b5501
pkg/libintl: fix missing symbols 2025-03-07 13:42:00 -08:00
Mitchell Hashimoto cb8085ab72
global state initializes i18n 2025-03-07 13:42:00 -08:00
Mitchell Hashimoto dd95f727ec
build: add libintl for macOS builds 2025-03-07 13:41:59 -08:00
Mitchell Hashimoto 67488754d5
pkg/libintl 2025-03-07 13:41:59 -08:00
Leah Amelia Chen 4a215a9518
gtk: use AdwAlertDialog for close dialogs, fix incorrect close dialogs (#5741)
AdwAlertDialog is the recommended way to do alert/message dialogs
starting from libadwaita 1.5, and is much easier to manage than
GtkMessageDialog. (The latter is also deprecated since GTK 4.10, but
this PR does not migrate it to use GtkAlertDialog, mostly because of its
obtuse interface and that we'll remove the GtkMessageDialog code anyway
in 1.2 when we remove non-Adwaita builds.)

We also had two bugs where tabs with only one split would display the
"close surface" confirmation dialog, and windows would do the same when
closed via the "Close Window" menu item or by the `close_window` keybind
action. (The "close window" dialog only appears when the user clicks on
the close button on the titlebar.) Initially I was very confused by
this, but it turns out that we don't have any apprt action related to
closing a window, and it was simply closing surfaces...
2025-03-07 20:46:23 +01:00
Leah Amelia Chen b25da6b9c4
core: update zig2nix to use explicit Zig version from Nix (#6617)
This will avoid build breakage in the near future as Zig 0.14 is coming
to Nix.
2025-03-07 20:42:13 +01:00
Jeffrey C. Ollie 3ba4864f6c
core: update zig2nix to use explicit Zig version from Nix
This will avoid build breakage in the near future as Zig 0.14 is coming
to Nix.
2025-03-07 11:46:30 -06:00
Leah Amelia Chen 77e16770cc
gtk: build gtk4-layer-shell ourselves (#6614)
As of now `gtk4-layer-shell` is unavailable on recent, stable releases
of many distros (Debian 12, Ubuntu 24.04, openSUSE Leap & Tumbleweed,
etc.) and outdated on many others (Nixpkgs 24.11/unstable, Fedora 41,
etc.) This is inconvenient for our users and severely limits where the
quick terminal can be used. As a result we then build gtk4-layer-shell
ourselves by default unless `--system` or `-fsys=gtk4-layer-shell` are
specified. This also allows me to add an idiomatic Zig API on top of the
library and avoiding adding even more raw C code in the GTK apprt.

Since we now build gtk4-layer-shell it should be theoretically available
on all Linux systems we target. As such, the `-Dgtk-layer-shell` build
option has been removed. This is somewhat of an experimental change as I
don't know if gtk4-layer-shell works perfectly across all distros, and
we can always add the option back if need be.
2025-03-07 18:19:49 +01:00
Leah Amelia Chen cd442eb9e2
gtk: build gtk4-layer-shell ourselves
As of now `gtk4-layer-shell` is unavailable on recent, stable releases
of many distros (Debian 12, Ubuntu 24.04, openSUSE Leap & Tumbleweed, etc.)
and outdated on many others (Nixpkgs 24.11/unstable, Fedora 41, etc.)
This is inconvenient for our users and severely limits where the quick
terminal can be used. As a result we then build gtk4-layer-shell ourselves
by default unless `--system` or `-fsys=gtk4-layer-shell` are specified.
This also allows me to add an idiomatic Zig API on top of the library
and avoiding adding even more raw C code in the GTK apprt.

Since we now build gtk4-layer-shell it should be theoretically available
on all Linux systems we target. As such, the `-Dgtk-layer-shell` build
option has been removed. This is somewhat of an experimental change as
I don't know if gtk4-layer-shell works perfectly across all distros, and
we can always add the option back if need be.
2025-03-07 17:52:06 +01:00
Leah Amelia Chen 6c00c36d62
config: make quick-terminal-autohide=false on Linux (#6613)
See diff for explanation
2025-03-07 17:36:05 +01:00
Leah Amelia Chen 9ed76729ab
gtk: add separate close_window apprt action
For *some* reason we have a binding for close_window but it merely closes
the surface and not the entire window. That is not only misleading but
also just wrong. Now we make a separate apprt action for close_window
that would make it show a close confirmation prompt identical to as if
the user had clicked the (X) button on the window titlebar.
2025-03-06 20:32:38 +01:00
Leah Amelia Chen b4bfdb2c44
translation: update template & zh_CN strings 2025-03-06 20:32:30 +01:00
Leah Amelia Chen 23d2d4ec70
gtk: use AdwAlertDialog for close dialogs 2025-03-06 20:32:30 +01:00
Tim Culverhouse 40c1140f7d
font(freetype): constrain emoji to 2 cells wide
When scaling emoji, scale so that they entirely fit within 2 cells. The
previous behavior was to scale to fill vertically, however with fonts
which are narrow this would result in horizontal overflow.
2025-03-06 10:46:58 -06:00
Tim Culverhouse 27c4fd76f3
renderer(OpenGL): pass cell_width to glyph renderer
When adding a glyph, we didn't pass the expected width to the glyph
renderer. This can be helpful when scaling emoji, as will happen in the
next commit.
2025-03-06 09:59:24 -06:00
Tim Culverhouse 22ed08cfd8
chore: zig fmt 2025-03-06 09:59:24 -06:00
Leah Amelia Chen 260a90cbf0
config: make quick-terminal-autohide=false on Linux
See diff for explanation
2025-03-06 12:38:23 +01:00
Leah Amelia Chen e07b6fdf6b
gtk: implement quick terminal slide & autohide (#6090) 2025-03-05 23:20:03 +01:00
Leah Amelia Chen 44d4990eb2
gtk: implement quick-terminal-autohide 2025-03-05 21:51:35 +01:00
Leah Amelia Chen 58b0434092
docs: update information about quick terminal support on Linux 2025-03-05 21:37:49 +01:00
Jeffrey C. Ollie d6bd7b56b3
gtk: implement sensitive content reveal on paste confirmation (#6054)
Fixes https://github.com/ghostty-org/ghostty/issues/4947 for gtk
This PR implements the senstive content hiding when displaying the paste
confirmation dialog in secure input mode.

Following changes are implemented:
- in the blueprint for each dialog add a show/hide button that is not
visible by default, and a Revealer that is revealed by default
- save the `secure_input` action value for each surface in the GTK apprt
- pass the value when initializing the paste confirmation dialog
- in the dialog code, alter the visibility of the content and
reveal/hide buttons based on secure input flag value

Demo:


https://github.com/user-attachments/assets/c91cbd3d-ed3b-464d-b4cf-e51fe7aa23b7

I feel like this is already a nearly full implementation, but I'm
leaving this as a draft for now, since i need to look into blueprints
for Adwaita 1.2, and verify if it behaves properly when the dialog is in
not-sensitive input mode and in OSC52 mode.
2025-03-05 14:27:13 -06:00
Leah Amelia Chen 8f7425f78c
gtk: implement quick terminal slide animation
Yet another protocol that as far as I know only KWin implements.
Oh well, might as well let KDE users such as myself enjoy it OOTB
2025-03-05 21:13:13 +01:00
Maciej Bartczak bd617c52e9 code review:
- implement blueprints for Adwaita 1.2
- use postifx notation for casting gtk widgets
- fix formatting
2025-03-05 21:03:02 +01:00
Maciej Bartczak f71b294697 gtk: new approach to reveal/hide buttons 2025-03-05 21:03:02 +01:00
Maciej Bartczak 7123d4e055 gtk: blur the content view instead of using a Revealer widget 2025-03-05 21:03:02 +01:00
Maciej Bartczak 1f695c2646 gtk: implement sensitive content reveal mechanism when showing paste confirmation in secure input mode 2025-03-05 21:02:58 +01:00
Jeffrey C. Ollie 58adaffcb9
gtk: don't modify horizontal alignment on menus that have arrows (#6087)
Setting the horizontal alignment to start on popover menus that have
arrows results in visual anomalies:


![image](https://github.com/user-attachments/assets/fef279a3-73cf-4717-9b32-605ccd48c934)

From Discord:

https://discord.com/channels/1005603569187160125/1346819853612482571
2025-03-05 13:42:50 -06:00
Jeffrey C. Ollie 8f62901218
gtk: don't modify horizontal alignment on menus that have arrows 2025-03-05 13:28:57 -06:00
Leah Amelia Chen 2f65f01fc8
gtk: add localization support, take 3 (#6004)
This is my third (!) attempt at implementing localization support. By
leveraging GTK builder to do most of the `gettext` calls, I can avoid
the whole mess about missing symbols on non-glibc platforms.

Added some documentation too for contributors and translators, just for
good measure.

Supersedes #5214, resolves the GTK half of #2357
2025-03-05 20:12:52 +01:00
Mitchell Hashimoto 66e8d91957
Make `equalize_splits` action only affect current window (#6080)
Fixes #6064 


https://github.com/user-attachments/assets/bbf393be-de98-41eb-aaad-3a185705ed4c
2025-03-04 07:36:00 -08:00
Ken VanDine fd6e4fd615
fix: Generate pixbuf loader cache on start if needed, fixes #6066 (#6079)
This fix ensures the correct pixbuf loaders are used, not mixing in
libraries from the host.
2025-03-04 09:38:23 -05:00
Bryan Lee 423bc1971b
Make `equalize_splits` action only affect current window 2025-03-04 22:37:32 +08:00
Ken VanDine 2c6e6ad680 fix: Generate pixbuf loader cache on start if needed, fixes #6066 2025-03-04 08:50:11 -05:00
Leah Amelia Chen 6373399e59
os: deprioritize GHOSTTY_RESOURCES_DIR for debug builds
When one develops Ghostty while using Ghostty it could lead to an
interesting conundrum: the freshly built Ghostty would use the parent
Ghostty's resources, which would be stale and not reflect any new
changes to resources. This is especially bad for translators, since
their translations would not be reflected in the newly built Ghostty
if they happen to run it under older Ghostty, which is not only
counterintuitive and also painful in terms of workflow.

Now, on debug builds we always try to use the terminfo detection method
first in order to locate the zig-out/share/ghostty folder, and only fall
back to GHOSTTY_RESOURCES_DIR if the executable is for some reason no
longer in zig-out. You can test this behavior by manually moving the
Ghostty executable out of zig-out, and then launching it with and without
Ghostty.
2025-03-03 10:19:58 +01:00
Mitchell Hashimoto 6b1a017a86 build: some style changes, namely we should create steps only in root 2025-03-03 10:19:58 +01:00
Leah Amelia Chen e252932bde
translations: add basic Chinese translation 2025-03-03 10:19:58 +01:00
Leah Amelia Chen 9c97084ad0
gtk: extract translations from Zig source code 2025-03-03 10:19:58 +01:00
Leah Amelia Chen 5851bad4a0
ci: add check that ensures POT files are up to date 2025-03-03 10:19:58 +01:00
Leah Amelia Chen 9360afd29f
gtk: add localization support, take 3
This is my third (!) attempt at implementing localization support.
By leveraging GTK builder to do most of the `gettext` calls, I
can avoid the whole mess about missing symbols on non-glibc platforms.

Added some documentation too for contributors and translators,
just for good measure.
2025-03-03 10:19:58 +01:00
Tim Culverhouse ee8ae196ee
input: legacy encoding never encodes text for command mods on macOS (#6057)
Fixes #5929
Replaces #5984

On macOS, native applications typically never encode any text for key
events that use the command key. This is because the command key is used
for key equivalents and "commands" and should not be used for text
input.

This can be verified with apps like TextEdit but also terminals like
Terminal.app officially but also iTerm2 unofficially. Anything such as
`Cmd+b` or `Cmd+Shift+b` will not produce any text input.

Cross-platform terminals generally don't follow this, for example Kitty
performs CSI-u encoding and Alacritty and WezTerm encode the text as-is
(i.e. `Cmd+b` will produce `b`).

On Linux, the super key (command-equivalent) does produce text input.
For example, `Super+b` will produce `b` in Gnome Console, Foot, and all
the cross-platform terminals mentioned above.

In the interest of matching the behavior of native macOS applications,
we should not encode text for command key events on macOS. We continue
to encode text for the super key on non-macOS platforms. This matches
the behaviors appropriately on each platform.
2025-03-02 16:21:02 -06:00
Mitchell Hashimoto a646aee6bd
CODEOWNERS: terminal team should own input encoding (#6058) 2025-03-02 13:56:37 -08:00
Mitchell Hashimoto 28e20f3015
CODEOWNERS: terminal team should own input encoding 2025-03-02 13:54:35 -08:00
Mitchell Hashimoto f93eb0b27f
input: legacy encoding never encodes text for command mods on macOS
Fixes #5929
Replaces #5984

On macOS, native applications typically never encode any text for
key events that use the command key. This is because the command key
is used for key equivalents and "commands" and should not be used
for text input.

This can be verified with apps like TextEdit but also terminals like
Terminal.app officially but also iTerm2 unofficially. Anything such as
`Cmd+b` or `Cmd+Shift+b` will not produce any text input.

Cross-platform terminals generally don't follow this, for example Kitty
performs CSI-u encoding and Alacritty and WezTerm encode the text as-is
(i.e. `Cmd+b` will produce `b`).

On Linux, the super key (command-equivalent) does produce text input.
For example, `Super+b` will produce `b` in Gnome Console, Foot, and
all the cross-platform terminals mentioned above.

In the interest of matching the behavior of native macOS applications,
we should not encode text for command key events on macOS. We continue
to encode text for the super key on non-macOS platforms.
2025-03-02 13:53:20 -08:00
Mitchell Hashimoto 82326508b1
macos: set title of terminal window immediately if configured (#6056)
Fixes #5934 for macOS

If a `title` config is set, this change sets the title immediately on
windowDidLoad to ensure that the window appears with the correct title
right away.

If there is any reason to set another title, the `set_title` apprt
action will come on another event loop tick (due to our usage of
notifications) but that's okay since that's already how it works. This
is just to say that setting this here won't break any shell integration
or anything.
2025-03-02 13:48:33 -08:00
Mitchell Hashimoto 8d395c094b
macos: set title of terminal window immediately if configured
Fixes #5934 for macOS

If a `title` config is set, this change sets the title immediately on
windowDidLoad to ensure that the window appears with the correct title
right away.

If there is any reason to set another title, the `set_title` apprt
action will come on another event loop tick (due to our usage of
notifications) but that's okay since that's already how it works. This
is just to say that setting this here won't break any shell integration
or anything.
2025-03-02 13:27:40 -08:00
Mitchell Hashimoto fc893ae7e3
core!: modify scroll behavior (#6052)
Modify the scroll behavior to better match other terminals, as well as
provide a
better overall experience. Before this PR, ghostty would scale
non-precision
scroll events dependent on the screen size. This is in line with kitty,
but no
other terminal. Ghostty also was the only terminal to send *more than
one* wheel
event.

```
 # 50% Screen height
| terminal   | arrows keys sent| wheels events sent|
|------------|-----------------|-------------------|
| alacritty  |        3        |          1        |
| foot       |        3        |          1        |
| xterm      |        5        |          1        |
| kitty      |        3        |          1        |
| ghostty    |        2        |          2        |

 # 100% Screen height
| terminal   | arrows keys sent| wheels events sent|
|------------|-----------------|-------------------|
| alacritty  |        3        |          1        |
| foot       |        3        |          1        |
| xterm      |        5        |          1        |
| kitty      |        5        |          1        |
| ghostty    |        3        |          3        |
```

This PR modifies Ghostty to behave like foot and alacritty.

For an improved user experience, we only use the configured multiplier
for
non-precision scrolls. This multiplier now *only applies* to viewport
scrolling
and alternate scroll mode. The default value has been updated to 3.0.

GTK also now supports precision scrolling.
2025-03-02 13:15:45 -08:00
Tim Culverhouse 30a49d0458
fixup! config: default mouse-scroll-multiplier to 3.0 2025-03-02 08:46:11 -06:00
Tim Culverhouse 68a2478317
gtk: enable non-discrete scrolling
Remove the flag which reports all scrolls as discrete scrolls. This
enables precision scrolling in GTK. We have to track a flag between
continuous scroll events.
2025-03-02 08:36:47 -06:00
Tim Culverhouse c1e87e7122
scroll: only use multiplier for non-precision scrolls
Precision scrolls don't require a multiplier to behave nicely. However,
wheel scrolls feel extremely slow without one. We apply the multiplier
to wheel scrolls only
2025-03-02 08:35:25 -06:00
Tim Culverhouse 6e751d2d7e
config: default mouse-scroll-multiplier to 3.0
Make Ghostty behave like other terminals by multiplying scrolls by 3.0.
This only affects when we are reporting arrow keys (alternate scroll
mode) or when we are scrolling the scrollback.
2025-03-02 08:03:09 -06:00
Tim Culverhouse dbba3f1a60
scroll: don't use multiplier for wheel events
When we report mouse scroll wheel events, they should not be multiplied.
Refactor the scrollCallback to only use a multiplier for viewport or
alternate scroll reports.
2025-03-02 08:02:47 -06:00
Tim Culverhouse 34388ab5df
surface: calculate scroll amount directly from yoff/xoff for non-precision scrolls
Calculate the scroll amount for non-precision scrolls as a direct
multiple of yoff. This fixes an issue where Ghostty sends scroll wheel
events (or arrow keys if in alternate scroll mode) that are variable,
dependent on the screen size. I checked multiple terminals, and each
responds to a single wheel click by sending only a single wheel / arrow
key - independent of screen size.

```sh
printf "\x1b[?1049h"
printf "\x1b[?1007h"

cat -v

```

Using the above procedure, with varying screen sizes:

```
 # 50% Screen height
| terminal   | arrows keys sent| wheels events sent|
|------------|-----------------|-------------------|
| alacritty  |        3        |          1        |
| foot       |        3        |          1        |
| xterm      |        5        |          1        |
| kitty      |        3        |          1        |
| ghostty    |        2        |          2        |

 # 100% Screen height
| terminal   | arrows keys sent| wheels events sent|
|------------|-----------------|-------------------|
| alacritty  |        3        |          1        |
| foot       |        3        |          1        |
| xterm      |        5        |          1        |
| kitty      |        5        |          1        |
| ghostty    |        3        |          3        |
```

Both ghostty and kitty scale the number of arrow keys sent in proportion
to the screen size. However, when mouse reporting is on, only ghostty
does this.

This commit makes Ghostty behave like foot, and more generally removes
the dependence on screen size.
2025-03-02 08:02:47 -06:00
Mitchell Hashimoto 8721f2ae51
Update iTerm2 colorschemes (#6047)
Upstream revision:
e21d5ffd19
2025-03-01 20:42:22 -08:00
mitchellh 29447b60b3 deps: Update iTerm2 color schemes 2025-03-02 00:13:13 +00:00
Mitchell Hashimoto e2b5584a8d
Add note to configuration that some settings might require a restart (#6033)
This adds a note in the default config to note that may require a
restart. Also adds a note with the window-padding-x and window-padding-y
to indicate a restart will be required to update existing windows.

I ran into this while updating one of the existing values in the default
config file. `window-padding-x` The value defaulted to 2 so figured it
was safe to assume and just uncomment it and try reloading the config.

Doing that doesn't work only restarting will make it take effect for the
main window ( or of course more tricky opening new windows and killing
off the old one )

https://github.com/ghostty-org/ghostty/discussions/6022
2025-03-01 13:57:25 -08:00
Aaron Ogle e7a9d6a81d Update config template with a note about a restart possibly being required 2025-03-01 13:55:10 -08:00
Jeffrey C. Ollie b342909e10
GTK: do not check for terminal area focus when setting window title (#6032)
Fixes https://github.com/ghostty-org/ghostty/issues/5940
The mentioned problem occurs because when creating a new tab through the
tab overview we do not have focus on the terminal area widget, it does
not matter if we have a custom title set or not.
I think it is just safe to remove this check from the code. I've tested
the change and I don't really see a valid use case in which we would not
want to set the window title even if we don't have focus on the terminal
area.
2025-03-01 12:10:13 -06:00
Leah Amelia Chen df62d45b36
gtk: update URLWidget to use zig-gobject (#6042) 2025-03-01 18:40:27 +01:00
Jeffrey C. Ollie 5d5a632a89
gtk: update URLWidget to use zig-gobject
Also move URLWidget to a separate file to cut down on the size of
Surface.zig.
2025-03-01 10:02:16 -06:00
Jeffrey C. Ollie ed647caa2e
apprt/gtk: remove non-ascii characters from resize overlay (#6040)
It is possible that fonts people are using don't contain these
characters as evidenced by users in the Discord.
2025-03-01 08:54:31 -06:00
Maciej Bartczak a3cd7c6f02 gtk: update the window title when grabbing tab focus 2025-03-01 13:25:25 +01:00
Tristan Partin 0e6c26bbfe apprt/gtk: remove non-ascii characters from resize overlay
It is possible that fonts people are using don't contain these
characters as evidenced by users in the Discord.

Signed-off-by: Tristan Partin <tristan@partin.io>
2025-03-01 00:37:01 -06:00
Mitchell Hashimoto efc1b10bfd
Introduce `reset_window_size` keybinding and apprt action (#6038)
Related to #6035

This implements the keybind/action portion of #5974 so that this can
have a binding and so that other apprts can respond to this and
implement it this way.
2025-02-28 19:02:10 -08:00
Mitchell Hashimoto 17cae57f51
Introduce `reset_window_size` keybinding and apprt action
Related to #6035

This implements the keybind/action portion of #5974 so that this can
have a binding and so that other apprts can respond to this and
implement it this way.
2025-02-28 15:31:17 -08:00
Mitchell Hashimoto c6485b9fd5
"Return to Default Size" implementation (#5974)
## Added Support for "Return To Default Size"

This update introduces support for the **"Return To Default Size"**
feature.

### Fixes  
- Resolves [#1328](https://github.com/ghostty-org/ghostty/issues/1328)

### Screenshots  

| Description | Screenshot |
|------------|------------|
| **Ghostty** | <img width="1084" alt="Screenshot 2025-02-24 at 21 15
38"
src="https://github.com/user-attachments/assets/4657ccdb-9c7a-4884-873c-bbe0f30f9400"
/> |
| **After changing window size** | <img width="1155" alt="Screenshot
2025-02-24 at 21 16 00"
src="https://github.com/user-attachments/assets/9b3931f2-1c4b-4f86-8d56-8892bd5675cc"
/> |
| **Native Terminal App (for reference)** | <img width="630"
alt="Screenshot 2025-02-24 at 21 16 20"
src="https://github.com/user-attachments/assets/ae049931-b74d-4246-a9e7-d9be079b1a24"
/> |
2025-02-28 15:06:24 -08:00
Mitchell Hashimoto afb154ee5d
macos: store default size as computed property 2025-02-28 14:51:56 -08:00
Leah Amelia Chen 5accc069fb
gtk: implement quick terminal (#6027) 2025-02-28 23:31:39 +01:00
Mikhail Borisov 8838ebf02a Refactor to use height/width from ghostty configuration 2025-02-28 14:17:46 -08:00
Mikhail Borisov f73c1a2c59 "Return to Default Size" implementation
Added support for "Return To Default Size"
2025-02-28 14:17:46 -08:00
Mitchell Hashimoto 9681009650
apprt initial_size is sent whenever the grid size changes (#6034)
As noted in the comments, this is so that apprt's can always know what
the default size of a window would be so they can utilize this for
"return to default size" actions.

The initial size shouldn't be treated as a "resize" event and was
already documented as such. Prior to this commit the docs already noted
that the initial size may be sent multiple times but only the first time
during initialization should be used as a resize.

Therefore, this shouldn't impact prior behavior. I've verified this with
the apprts.
2025-02-28 10:43:55 -08:00
Mitchell Hashimoto b0f1f19da0
apprt initial_size is sent whenever the grid size changes
As noted in the comments, this is so that apprt's can always know what
the default size of a window would be so they can utilize this for
"return to default size" actions.

The initial size shouldn't be treated as a "resize" event and was
already documented as such. Prior to this commit the docs already noted
that the initial size may be sent multiple times but only the first time
during initialization should be used as a resize.

Therefore, this shouldn't impact prior behavior. I've verified this with
the apprts.
2025-02-28 10:07:36 -08:00
Leah Amelia Chen a85651fe4f
gtk: implement quick terminal
Using `gtk4-layer-shell` still seems like the path of least resistance,
and to my delight it pretty much Just Works. Hurrah!

This implementation could do with some further polish (e.g. animations,
which can be implemented via libadwaita's animations API, and global
shortcuts), but as a MVP it works well enough.

It even supports tabs!

Fixes #4624.
2025-02-28 18:04:42 +01:00
Mitchell Hashimoto 1cfe7027e5
Fix Terminal Inspector option turns inactive if toggled in the Quick Terminal (#6024)
Fixed: [2475](https://github.com/ghostty-org/ghostty/issues/2475)

The problem actually existed because of the responder chain, as
previously pointed out in the report (thanks to @mitchellh).

When we first click on Toggle Terminal Inspector:
* the responder chain goes to _toggleTerminalInspector_
(_SurfaceView_AppKit_ implementation).
When we click the second toggleTerminalInspector:
* it tries to find the next responder, but the one available is
_TerminalController_. (if we remove this method from there, the bug will
reproduce even without quick mode)

**Problem**:
TerminalController not available during quick terminal, so there's no
way to toggle inspector
**Solution**:
We add toggleTerminalInspector to the _QuickTerminalController_:
selector, as we did with other similar methods.
2025-02-28 07:09:00 -08:00
Mikhail Borisov 744240c009 Fix Terminal Inspector option turns inactive if toggled in the Quick Terminal 2025-02-28 00:38:29 +01:00
Mitchell Hashimoto ef88d1cba9
feat: respect maximize config on macOS (#5962)
Resolve #5928
2025-02-27 15:25:17 -08:00
Aaron Ruan 5a5478abe1 feat: respect maximize config on macOS
Signed-off-by: Aaron Ruan <i@ar212.com>
2025-02-27 15:10:39 -08:00
Qwerasd a1437e5579
fix(Metal): force a full rebuild in `setFontGrid` (#6008)
This was causing garbled text due to a non-rebuilt rows referencing an
outdated atlas when the DPI changed but not the grid dimensions, which
could be caused by a variety of things such as the quick terminal
slide-in, dpi scaling changes on sleep/wake, moving windows between
displays because of closing/opening the laptop lid, etc.

Fixes #2731
2025-02-27 09:43:47 -05:00
Jeffrey C. Ollie 31df9d5576
gtk: work around oversized drag handle for GtkPaned (#6000)
Improves #3020.

Based on recommendation from upstream Gtk issue:
https://gitlab.gnome.org/GNOME/gtk/-/issues/4484#note_2362002

Without this, it's not possible to select the first character on the
right-hand side of a split.
2025-02-27 08:42:17 -06:00
Jeffrey C. Ollie ef7f8cb3da
gtk: use language-neutral arrows for resize overlays (#6013)
The meaning of "c" and "r" can be somewhat cryptic to non-native English
speakers as it may not be immediately obvious that "c" stands for
"columns", and "r" stands for "rows". I propose replacing them with
left-right and up-down double-headed arrows that convey the same
meaning, but in a truly language-neutral manner.

Related to #2357
2025-02-27 08:25:12 -06:00
David Wales 63ea1ab32e gtk: work around oversized drag handle for GtkPaned
Improves #3020.

Based on recommendation from upstream Gtk issue:
https://gitlab.gnome.org/GNOME/gtk/-/issues/4484#note_2362002

Without this, it's not possible to select the first character on the
right-hand side of a split.
2025-02-27 19:17:37 +11:00
Leah Amelia Chen cdfa028521
gtk: use language-neutral arrows for resize overlays
The meaning of "c" and "r" can be somewhat cryptic to non-native English
speakers as it may not be immediately obvious that "c" stands for "columns",
and "r" stands for "rows". I propose replacing them with left-right and
up-down double-headed arrows that convey the same meaning, but in a
truly language-neutral manner.

Related to #2357
2025-02-27 08:38:06 +01:00
Jeffrey C. Ollie c7938af7be
gtk: convert Split.zig to gobject (#6012) 2025-02-26 22:38:51 -06:00
Jeffrey C. Ollie 78a98e01fc
gtk: convert Split.zig to gobject 2025-02-26 19:22:02 -06:00
Jeffrey C. Ollie d85ed8275e
gtk: convert cgroup operations to gobject (#6009) 2025-02-26 18:28:53 -06:00
Jeffrey C. Ollie 6581b9cf41
gtk: convert cgroup operations to gobject 2025-02-26 16:26:44 -06:00
Leah Amelia Chen 12ba5d89f0
apprt/gtk: subscribe to AdwStyleManager::dark for ColorScheme (#6007) 2025-02-26 20:38:50 +01:00
Qwerasd 16a61c43dd fix(Metal): force a full rebuild in `setFontGrid`
This was causing garbled text due to a non-rebuilt rows referencing an
outdated atlas when the DPI changed but not the grid dimensions, which
could be caused by a variety of things such as the quick terminal
slide-in, dpi scaling changes on sleep/wake, moving windows between
displays because of closing/opening the laptop lid, etc.
2025-02-26 14:11:05 -05:00
Tristan Partin acbb1d3bd4 apprt/gtk: subscribe to AdwStyleManager::dark for ColorScheme
Signed-off-by: Tristan Partin <tristan@partin.io>
2025-02-26 13:03:12 -06:00
Jeffrey C. Ollie dec14f3096
gtk: switch dbus operations in src/apprt/gtk/App.zig to zig-gobject (#5996) 2025-02-26 11:17:47 -06:00
Jeffrey C. Ollie 5fdb732798
gtk: switch dbus operations in src/apprt/gtk/App.zig to zig-gobject 2025-02-25 22:52:57 -06:00
Leah Amelia Chen 4e5e4a7c2f
gtk: switch clipboard confirmation to zig-gobject and blueprints (#5968) 2025-02-25 23:28:56 +01:00
Mitchell Hashimoto c068390634
Fix elvish sudo integration and update documentation (#5992)
Elvish integration is broken when running `sudo`, because the function
`sudo-with-terminfo` uses `command` command, which is not implemented in
Elvish. Changing it to `external` command should fix possible error when
bypassing aliases, functions and builtins, like `command` does in Bash.
Discussion about this issue: #5979 

Also I updated documentation about Elvish integration to provide fix
when using `use ghostty-integration` outside of Ghostty with `rc.elv`.
2025-02-25 13:57:31 -08:00
Yappaholic 3cac06a70a Fix elvish sudo integration and update documentation 2025-02-25 23:17:00 +03:00
Jeffrey C. Ollie 62dcddb315
gtk: fix missing defer 2025-02-25 13:46:50 -06:00
Jeffrey C. Ollie 0638eca633
gtk: use versioned directories to store blueprint files 2025-02-25 13:30:44 -06:00
Jeffrey C. Ollie c6b049b12b
gtk: fix properties on close confirmation text view 2025-02-25 13:30:44 -06:00
Jeffrey C. Ollie 3f847de964
gtk: switch clipboard confirmation to zig-gobject and blueprints
Note that for Debian 12, the blueprints must be compiled on a distro
with a newer version of `blueprint-compiler` and the raw UI XML
committed to git. Debian 12 includes `blueprint-compiler` 0.6.0 which
doesn't support compiling `adw.MessageDialog` even though the version of
`libadwaita` supports it.
2025-02-25 13:30:44 -06:00
Mitchell Hashimoto 9972eeb673
Create a snap packaging subsystem (#5987)
This team is responsible for snap packaging.
2025-02-25 10:54:29 -08:00
Mitchell Hashimoto 166362d349
Create a snap packaging subsystem
This team is responsible for snap packaging.
2025-02-25 10:21:55 -08:00
Mitchell Hashimoto 0b7df7511a
Fix empty keybind setting (#5977)
Fixes https://github.com/ghostty-org/ghostty/issues/5936.

Extracts the default keybind setting to an `init` function. Add logic to
call `init` in `parseIntoField` if it is defined for the type.
2025-02-25 09:06:11 -08:00
David Mo df9de1523c fix test 2025-02-25 11:53:01 -05:00
Leah Amelia Chen 22f3e60dcf
gtk: convert window actions to use zig-gobject (#5978) 2025-02-25 16:44:09 +01:00
David Mo af2d710000 rename `setToDefault` to `init` 2025-02-25 10:15:58 -05:00
Jeffrey C. Ollie 3d08b1c4aa
gtk: cast to application window 2025-02-25 08:19:52 -06:00
David Mo 22d99f2533 add test for `setToDefault` 2025-02-24 23:39:01 -05:00
David Mo 8fadb54e65 set default keybinds when parsing empty keybind config 2025-02-24 23:31:49 -05:00
David Mo 0321aec68f create default keybinds function 2025-02-24 23:27:49 -05:00
Jeffrey C. Ollie d284146621
gtk: convert window actions to use zig-gobject 2025-02-24 22:07:16 -06:00
Mitchell Hashimoto 92340f8fb0
fix(macos): prevent performing newTab shortcut on QuickTerminalWindow… (#5955)
Fixes #5939
2025-02-24 15:32:39 -08:00
McNight b4349d3226 fix(macos): make showNoNewTabAlert method private #5939 2025-02-25 00:18:02 +01:00
McNight 1254c6b981 fix(macos): address MR feedback #5939 2025-02-25 00:17:01 +01:00
Mitchell Hashimoto ce8bfe45ed
Docs change: Note instead of simple text and Removing two times showing info. (#5920)
In docs option reference, for macos-icon info. It is showing two times
similar thing. And Note looks good instead of just text because it wont
work without `custom-style`. So a Big Note is a good highlight.
2025-02-24 09:41:26 -08:00
Jeffrey C. Ollie e1e1539e4f
kitty: delete stray log line (#5969) 2025-02-24 11:30:22 -06:00
Jeffrey C. Ollie 9bcf554139
gtk: instruct users to install blueprint-compiler (#5970)
There's been *far* too many people who aren't aware of the new
dependency, and that is partly our fault: a "FileNotFound" error is
quite obtuse, unless you religiously follow every PR and every commit
made to the repository. Instead of shepherding everyone who runs into
this manually, we should offer better signposting.
2025-02-24 11:25:56 -06:00
Leah Amelia Chen 1dc375dd0e
gtk: instruct users to install blueprint-compiler
There's been *far* too many people who aren't aware of the new dependency,
and that is partly our fault: a "FileNotFound" error is quite obtuse,
unless you religiously follow every PR and every commit made to the
repository. Instead of shepherding everyone who runs into this manually,
we should offer better signposting.
2025-02-24 18:10:18 +01:00
Jeffrey C. Ollie f4f36a9a98
kitty: delete stray log line 2025-02-24 11:05:37 -06:00
Mitchell Hashimoto 71ae51b4b3
kitty images: add delete by range operations (#5957)
Fixes #5937

Implement [deleting Kitty image
ranges](https://sw.kovidgoyal.net/kitty/graphics-protocol/#deleting-images).
2025-02-24 07:14:11 -08:00
Jeffrey C. Ollie 61f41e5c01
nix: include libxml2 in nativeBuildInputs for xmllint (#5959) 2025-02-23 15:56:08 -06:00
Jeffrey C. Ollie 2ef042978d
nix: include libxml2 in nativeBuildInputs for xmllint 2025-02-23 15:17:18 -06:00
Leah Amelia Chen a52c603f16
gtk: ensure that the content scale is always positive (#5954) 2025-02-23 21:27:09 +01:00
Jeffrey C. Ollie da10269d3f
gtk: handle other nonsensical values returned by gtk_widget_get_scale_factor 2025-02-23 13:18:00 -06:00
Jeffrey C. Ollie ac7029256a
gtk: better document what to do if gtk-xft-dpi <= 0 2025-02-23 13:04:47 -06:00
Jeffrey C. Ollie 995959dce4
kitty images: add delete by range operations
Fixes #5937

Implement [deleting Kitty image ranges](https://sw.kovidgoyal.net/kitty/graphics-protocol/#deleting-images).
2025-02-23 12:57:24 -06:00
McNight aa4aaa200f fix(macos): prevent performing newTab shortcut on QuickTerminalWindow #5939 2025-02-23 19:34:27 +01:00
Jeffrey C. Ollie bc2acdd060
gtk: ensure that the content scale is always positive
Fixes #5927

This doesn't fix the underlying reason that GTK sometimes reports
content scales as negative. If GTK reports a negative scale, we ignore
that and use 1.0 for the scale.
2025-02-23 11:02:59 -06:00
Mitchell Hashimoto 2f63f840de
terminal: increase CSI max params to 24 to accept Kakoune sequence (#5949)
See #5930

Kakoune sends a real SGR sequence with 17 parameters. Our previous max
was 16 so we threw away the entire sequence. This commit increases the
max rather than fundamentally addressing limitations.

Practically, it took us this long to witness a real world sequence that
exceeded our previous limit. We may need to revisit this in the future,
but this is an easy fix for now.

In the future, as the comment states in this diff, we should probably
look into a rare slow path where we heap allocate to accept up to some
larger size (but still would need a cap to avoid DoS). For now,
increasing to 24 slightly increases our memory usage but shouldn't
result in any real world issues.
2025-02-23 07:12:38 -08:00
Tristan Partin eaeb6a620f
gtk: switch menus to use blueprints instead of raw builder ui (#5944) 2025-02-22 23:30:56 -06:00
Tristan Partin 65c65b9c97
gtk: fix menu separator colors (again) (#5945) 2025-02-22 23:30:30 -06:00
Mitchell Hashimoto dad2cf887b
add macos default config path to manpages (#5942)
This should resolve #5938.

I tested this locally using `zig build -D=emit-docs=true` and confirmed
that the mdgen process provided the new manpages in
`zig-out/share/man/man*`, respectively.

Let me know if this needs any changes, I tried to keep this as similar
as possible to the existing manpages (both format and content).
2025-02-22 20:53:34 -08:00
Mitchell Hashimoto 22c506b03e
terminal: increase CSI max params to 24 to accept Kakoune sequence
See #5930

Kakoune sends a real SGR sequence with 17 parameters. Our previous max
was 16 so we through away the entire sequence. This commit increases the
max rather than fundamentally addressing limitations.

Practically, it took us this long to witness a real world sequence that
exceeded our previous limit. We may need to revisit this in the future,
but this is an easy fix for now.

In the future, as the comment states in this diff, we should probably
look into a rare slow path where we heap allocate to accept up to some
larger size (but still would need a cap to avoid DoS). For now,
increasing to 24 slightly increases our memory usage but shouldn't
result in any real world issues.
2025-02-22 20:43:44 -08:00
Jeffrey C. Ollie 427da79a02
gtk: fix menu separator colors (again) 2025-02-22 20:23:16 -06:00
Jeffrey C. Ollie a8b6b96fbd
gtk: switch menus to use blueprints instead of raw builder ui 2025-02-22 20:21:41 -06:00
Tristan Partin e7cbb7fd16
gtk: update ResizeOverlay for zig-gobject (#5941)
Also switch to a "DerivedConfig" model so that we aren't referring to a
global copy of the config.
2025-02-22 20:07:20 -06:00
Jeffrey C. Ollie bdf0f27d1a
gtk: fix the alignment of the context menu (#5943)
This aligns the top left of the context menu with the right-click
location, rather than the top center.
2025-02-22 18:37:41 -06:00
Jeffrey C. Ollie 0af256b57a
gtk: fix the alignment of the context menu
This aligns the top left of the context menu with the right-click
location, rather than the top center.
2025-02-22 18:23:30 -06:00
taylrfnt 398add17f1
actually change it in both places 2025-02-22 18:00:37 -06:00
taylrfnt eec150d4cd
mention default loc precendence over XDG 2025-02-22 17:58:05 -06:00
taylrfnt 573fe7348b
add macos default config path to manpages 2025-02-22 17:46:30 -06:00
Jeffrey C. Ollie f1134640c5
gtk: update ResizeOverlay for zig-gobject
Also switch to a "DerivedConfig" model so that we aren't referring to a
global copy of the config.
2025-02-22 17:42:09 -06:00
Jeffrey C. Ollie 5131f8a71c
GTK: propagate config updates to the GTK apprt surfaces (#5866)
This will be needed to the convert GTK apprt surfaces to a DerivedConfig
model rather than accessing the global config stored in the app. It's a
no-op for now, but I have a PR in the works to update the resize overlay
that will take advantage of this.
2025-02-22 17:19:13 -06:00
Jeffrey C. Ollie 867982a2ff
Gtk: change title prompt (#5905)
This PR implements the title change functionality for the GTK app and
closes https://github.com/ghostty-org/ghostty/issues/5769

Demo:


https://github.com/user-attachments/assets/cad611b3-b7bf-40ac-8d0f-11d2095fe525

For now I came up with a basic UI that i believe is sufficient, but I'm
open to feedback and happy to iterate on it further.

https://github.com/ghostty-org/ghostty/issues/5769#issuecomment-2660341107
- Regarding Mitchell's comment I checked Gnome Console and I could not
find a similar feature.
2025-02-22 17:00:40 -06:00
Jeffrey C. Ollie bde5b963d0
gtk: fix Builder api changes 2025-02-22 16:39:12 -06:00
Maciej Bartczak 5d80db2ef8
code review: fix log format 2025-02-22 16:39:12 -06:00
Jeffrey C. Ollie 32a62ff862
snap: add libxml2-utils (for xmllint) to snap 2025-02-22 16:33:22 -06:00
Jeffrey C. Ollie d4bcac0150
snap: add blueprint-compiler to snap 2025-02-22 16:33:22 -06:00
Jeffrey C. Ollie 51dc1e2e8c
gtk: fix typos 2025-02-22 16:33:22 -06:00
Jeffrey C. Ollie 4f3c4037aa
gtk: get 'Change Title' working with older distros 2025-02-22 16:33:20 -06:00
Maciej Bartczak 7c19dd5a33
format the blueprint file using `blueprint-compiler format` 2025-02-22 16:32:52 -06:00
Maciej Bartczak 8758295647
code review:
- move responses definition to the blueprint, use translatable strings
- minor changes in the response callback
2025-02-22 16:32:52 -06:00
Maciej Bartczak 1ee8dfc99c
code review:
- remove unnecessary @ptrCast
- set the default focus to the text entry field
2025-02-22 16:32:52 -06:00
Maciej Bartczak cd287b4161
- remove the unused dialog context struct
- set the current title in the input buffer
- fix formatting
2025-02-22 16:32:50 -06:00
Maciej Bartczak 454a53b3f1
code review:
- remove the menu entry defined in code
2025-02-22 16:32:23 -06:00
Maciej Bartczak 6189f5d09e
code review:
- use blueprint for the dialog content
- use zig-gobject bindings
- make the enum values lowercase
2025-02-22 16:31:32 -06:00
Maciej Bartczak dcd17c6ac4
set the ok widget to be activated by default 2025-02-22 16:30:57 -06:00
Maciej Bartczak 3542778d84
free the terminal title when destroy is run 2025-02-22 16:30:57 -06:00
Maciej Bartczak 95fc5ad1e9
remove outdated comment 2025-02-22 16:30:57 -06:00
Maciej Bartczak cc9c45de2a
fix the edge case when user tries to revert the title to default and hasn't set a title before 2025-02-22 16:30:57 -06:00
Maciej Bartczak 5e9908af27
make the change of the title persistent & allow the user to restore to a default one 2025-02-22 16:30:56 -06:00
Maciej Bartczak 6b75ca40ca
Implement a prompt that allows the user to set the title 2025-02-22 16:30:55 -06:00
Jeffrey C. Ollie 3f715c296a
gtk: update menus to use popovers and builder ui files (#5781)
Menus (context menus and the window hamburger menu) now use popovers and
are defined using GTK builder UI files. This is a bit more "modern" and
reduces the amount of code to define menus.
2025-02-22 14:54:06 -06:00
Mitchell Hashimoto e307f1a373
Allow whitespace in ColorList values (#5925)
The following formats are now all valid:

```zig
macos-icon-screen-color = #00FF00,#FF1000,#00FFFF
macos-icon-screen-color = #00FF00, #FF1000, #00FFFF
macos-icon-screen-color = #00FF00 ,#FF1000 ,#00FFFF
macos-icon-screen-color =  #00FF00 , #FF1000  , #00FFFF
```

Fixes #5918
2025-02-22 12:18:54 -08:00
Mitchell Hashimoto 726ac36612
Add support for whitespace in color and palette parsing (#5926)
Resolves #5921
2025-02-22 07:25:18 -08:00
Mitchell Hashimoto ce62b5cc5e
Clarify configuration of `macos-icon-screen-color`'s gradient (#5923)
From #5863, cc @vollink.

I'm not sure what the hard-wrap limit for comments is (70?), so I've
tried to match the paragraph I've edited.
2025-02-22 07:13:08 -08:00
Bryan Lee 1b6b029e0d
Add test cases for whitespace handling for ColorList 2025-02-22 22:11:35 +08:00
Bryan Lee 2383e4d90d
Add support for whitespace in color and palette parsing 2025-02-22 22:05:05 +08:00
Bryan Lee 7c6375f744
Allow whitespace after commas in ColorList values 2025-02-22 20:53:27 +08:00
Kat 6770ad3736 Clarify configuration of `macos-icon-screen-color`'s gradient. 2025-02-22 17:14:08 +11:00
Ronit Gandhi a262da92bf using only note instead of both for docs. 2025-02-22 10:49:27 +05:30
Mitchell Hashimoto 870b74f4da
macOS: Fix new window focus when created from quick terminal (#5834)
## Root Cause

The issue has two aspects:

1. The window creation process didn't explicitly force focus on the new
window after showing it.
2. More fundamentally, we were relying on `NSApp.isActive` to determine
whether to activate the application, which is problematic because:
- When creating a window from quick terminal, the application is already
"active" but this active state is owned by the quick terminal
- The [`NSApp.isActive`
check](4cfe5522db/macos/Sources/Features/Terminal/TerminalManager.swift (L100))
doesn't accurately reflect our intent - creating a new window is an
explicit user action that should always result in that window gaining
focus

## Solution

Removing the `NSApp.isActive` check.

```swift
// Before
if !NSApp.isActive {
    NSApp.activate(ignoringOtherApps: true)
}

// After
NSApp.activate(ignoringOtherApps: true)
```

Fixes #5688
2025-02-21 15:50:00 -08:00
Mitchell Hashimoto c1fb9a33f7
Fix barely visible new tab button on macOS (#5897)
Resolve #5894 and #4288
2025-02-21 15:47:33 -08:00
Aaron Ruan 4291e1c5d7 fix: use surfaceConfig.backgroundColor to determine if the theme is light or dark
Signed-off-by: Aaron Ruan <i@ar212.com>
2025-02-21 15:32:24 -08:00
Mitchell Hashimoto b5ecd7b6be
Update libxev to use dynamic backend, support Linux configurability (#5916)
Related to #3224

Previously, Ghostty used a static API for async event handling: io_uring
on Linux, kqueue on macOS. This commit changes the backend to be dynamic
on Linux so that epoll will be used if io_uring isn't available, or if
the user explicitly chooses it.

This introduces a new config `async-backend` (default "auto") which can
be set by the user to change the async backend in use. This is a
best-effort setting: if the user requests io_uring but it isn't
available, Ghostty will fall back to something that is and that choice
is up to us.

Basic benchmarking both in libxev and Ghostty (vtebench) show no
noticeable performance differences introducing the dynamic API, nor
choosing epoll over io_uring.

For platforms that don't have multiple choices (currently macOS), the
dynamic API is literally the static API so there should be no
performance or behavioral changes whatsoever.
2025-02-21 15:18:59 -08:00
Mitchell Hashimoto d532a6e260
Update libxev to use dynamic backend, support Linux configurability
Related to #3224

Previously, Ghostty used a static API for async event handling: io_uring
on Linux, kqueue on macOS. This commit changes the backend to be dynamic
on Linux so that epoll will be used if io_uring isn't available, or if
the user explicitly chooses it.

This introduces a new config `async-backend` (default "auto") which can
be set by the user to change the async backend in use. This is a
best-effort setting: if the user requests io_uring but it isn't
available, Ghostty will fall back to something that is and that choice
is up to us.

Basic benchmarking both in libxev and Ghostty (vtebench) show no
noticeable performance differences introducing the dynamic API, nor
choosing epoll over io_uring.
2025-02-21 15:04:37 -08:00
Jeffrey C. Ollie 2697061e5b
gtk: fix comment in Window.updateConfig 2025-02-18 23:28:10 -06:00
Jeffrey C. Ollie d1fa933006
gtk: forward config updates to GTK apprt surfaces 2025-02-18 23:18:47 -06:00
Jeffrey C. Ollie 2d5a07c795
gtk: fix build on debian 12 2025-02-18 17:10:54 -06:00
Jeffrey C. Ollie b3f994a9d2
gtk: use builder ui files and popovers for menus 2025-02-18 17:10:51 -06:00
Jeffrey C. Ollie 38908e0126
gtk: apply all window appearance changes in syncAppearance (#5404)
The GTK side of appearance code is kind of a mess with several different
functions all having the responsibility of interacting with each other
and setting the appropriate window appearance. It should solely be the
responsibility of the `syncAppearance` function to apply appearance
changes, with other callbacks/functions calling it instead: much like
what we already do for the macOS apprt.

~~I also took the time to refactor the libadwaita version checks since
calling `versionAtLeast(0, 0, 0)` does get old after a while. Now almost
all checks are given human-readable names and contributors need not
memorize what the relevant version checks all are.~~ Moved to another PR
2025-02-18 16:36:07 -06:00
Leah Amelia Chen 8eaa901aec
config: update reload ability information for several keys
Several keys are now able to affect existing windows (especially
window-decoration, whose config documentation got a greater overhaul)
2025-02-18 10:09:41 +01:00
Leah Amelia Chen aa2dbe2919
gtk: apply all window appearance changes in syncAppearance
The GTK side of appearance code is kind of a mess with several different
functions all having the responsibility of interacting with each other
and setting the appropriate window appearance. It should solely be the
responsibility of the `syncAppearance` function to apply appearance
changes, with other callbacks/functions calling it instead: much like
what we already do for the macOS apprt.
2025-02-18 10:09:41 +01:00
Bryan Lee c9f8732e5c
Fix new window focus when quick terminal is open 2025-02-18 10:50:01 +08:00
Jeffrey C. Ollie da32534e8a
gtk: fix closing window when last tab is closed (#5837)
Causes windows to not close and leave behind a "corpse" if they are not
the last window or we are running in single instance mode.

![image](https://github.com/user-attachments/assets/5f6860c2-7807-4ff1-9cad-d32dd4bc348b)
2025-02-17 11:37:51 -06:00
Jeffrey C. Ollie 3dbbbdee0b
gtk: fix closing window when last tab is closed 2025-02-17 11:15:16 -06:00
Mitchell Hashimoto 16c6903706
Vertically center title when `macos-titlebar-style = tabs` (#5777)
Fix #3868 
<img width="812" alt="Frame 14"
src="https://github.com/user-attachments/assets/1fe78a13-ed8f-46e5-b4d4-69ecefdbdc22"
/>
2025-02-17 07:44:22 -08:00
Mitchell Hashimoto 3253df3d54
Equalize Splits invalid keybind (#5646)
refer to #4007

there are also quite a few posts about this in the discord help section

Basically for some reason for the equal key shift is not a typical
modifier where it would be the original key + shift modifier but it
actually just changes equal to respond as the plus key this is the only
key on the keyboard I can see exhibit this behavior

it seems all 3 major operating systems report the key this way (mac,
linux, and windows)
2025-02-17 07:41:42 -08:00
Aaron Ruan 830a117555 fix: vertically center toolbar title more accurately
Signed-off-by: Aaron Ruan <i@ar212.com>
2025-02-17 07:30:14 -08:00
rhodes-b 768b0a79cb dont use shift+equal combo 2025-02-17 07:26:32 -08:00
Mitchell Hashimoto 429c8ab277
fix: [snap] Don't set GDK_PIXBUF_MODULE_FILE, it causes the icon loader (#5820)
This fixes loading the tab-new-symbolic icon in the snap package
2025-02-16 20:45:22 -08:00
Ken VanDine 76bd002aa4 fix: [snap] Don't set GDK_PIXBUF_MODULE_FILE, it causes the icon loader 2025-02-16 23:18:16 -05:00
Jeffrey C. Ollie 246f4baf7c
gtk: rename notebook to TabView and switch to gobject (#5795) 2025-02-16 17:43:46 -06:00
Mitchell Hashimoto 1013ba63ee
[macOS] feat: Add "Split Left" and "Split Up" actions to menubar (#5807)
Fixes #5779
2025-02-16 12:37:11 -08:00
mbrown379 b1df97b33f Add Split Left and Split Up to menu 2025-02-16 15:14:02 -05:00
Jeffrey C. Ollie 25b93ceb55
gtk: disable shortcuts in tab view 2025-02-16 13:56:15 -06:00
Jeffrey C. Ollie 497a1b6f8f
gtk: prevent double free when closing window 2025-02-16 13:56:15 -06:00
Jeffrey C. Ollie bf7e9603d2
gtk: rename notebook to TabView and switch to gobject 2025-02-16 13:56:15 -06:00
Mitchell Hashimoto 2e7ed98dfd
build: fix colorscheme update (#5797) 2025-02-16 08:39:39 -08:00
Jeffrey C. Ollie 36e6ed3339
build: fix colorscheme update 2025-02-15 23:39:40 -06:00
Jeffrey C. Ollie 9a5bc65034
gtk: fix building on Debian 12 (#5791)
`std.debug.assert(x)` _is not_ the same as `if (!x) unreachable` because
the function call is not `inline`. Since it's not inline the Zig
compiler will try to compile any code that might otherwise be
unreachable.

Also, added a CI test that compiles Ghostty in a Debian 12 container to
ensure that regressions do not happen.
2025-02-15 18:31:39 -06:00
Mitchell Hashimoto 8ad2ae6ab4
Update iTerm2 colorschemes (#5793)
Upstream revision:
efb1bb1843
2025-02-15 16:26:58 -08:00
mitchellh fe11efff63 deps: Update iTerm2 color schemes 2025-02-16 00:13:20 +00:00
Jeffrey C. Ollie b0d68324a6
gtk: fix multiple build args in docker build 2025-02-15 18:11:42 -06:00
Jeffrey C. Ollie fb35d10981
gtk: add Zig version as arg to Debian 12 build 2025-02-15 18:01:07 -06:00
Jeffrey C. Ollie 191b19f9a5
gtk: add debian build to list of required checks 2025-02-15 17:58:25 -06:00
Jeffrey C. Ollie c7b3cbd397
gtk: only test Debian 12 builds on amd64 2025-02-15 17:57:19 -06:00
Jeffrey C. Ollie 0ce1342263
gtk: fix building on Debian 12
`std.debug.assert(x)` _is not_ the same as `if (!x) unreachable`
because the function call is not `inline`. Since it's not inline the
Zig compiler will try to compile any code that might otherwise be
unreachable.

Also, added a CI test that compiles Ghostty in a Debian 12 container to
ensure that regressions do not happen.
2025-02-15 16:53:53 -06:00
Mitchell Hashimoto 6d8db4b380
[macOS] feat: Add setting to hide icon from dock/cmd-tab (#5122)
Resolves #4538 

Adds boolean configuration option `macos-hidden` which toggles the
NSApp's activation policy appropriately on config change.
2025-02-15 11:00:32 -08:00
Albert Dong d7a82f212a Add setting to hide icon from dock/cmd-tab 2025-02-15 10:45:27 -08:00
Mitchell Hashimoto aeccbd266a
Added snap packaging (#3931)
Added snap packaging, fixes #3153

If whoever registered the name in the snap store could add me as a
collaborator, I can handle getting it released in the store, setup
automated builds, and request the necessary classic permissions in the
store.
2025-02-15 09:24:36 -08:00
Thom Dickson ac9f8ba9b1 wip: allow directional split movement 2025-02-15 10:14:21 -06:00
Mitchell Hashimoto baa47ff24e
ci: test requires build-snap 2025-02-15 07:24:25 -08:00
Mitchell Hashimoto 818bc779b3
apprt/gtk: unset snap env vars 2025-02-15 07:22:21 -08:00
Mitchell Hashimoto 88a6b542b3
ci: move snap testing into our big test workflow 2025-02-15 07:20:55 -08:00
Mitchell Hashimoto 494273cf08
ci: snap workflow requires git history 2025-02-15 07:10:31 -08:00
Mitchell Hashimoto 03d1240999
nix: use snapcraft only on Linux 2025-02-15 07:07:23 -08:00
Ken VanDine b551e106a8 Comment out refresh-mode, the store rejects this. Needs fixing in
review-tools
2025-02-15 07:06:40 -08:00
Ken VanDine 0c3b873dde Merge remote-tracking branch 'origin/add_snap_package' into add_snap_package 2025-02-15 07:06:40 -08:00
Ken VanDine d3623393a6 More environment handling to ensure reliability across distros 2025-02-15 07:06:40 -08:00
Ken VanDine 2adee4290a Improved rpath handling for ghostty 2025-02-15 07:06:40 -08:00
Ken VanDine 94e2982d4b Allow snap to refresh while running 2025-02-15 07:06:40 -08:00
Ken VanDine 238b0faf5c Simplified setting snap version 2025-02-15 07:06:40 -08:00
Ken VanDine 927f626d9a Merge remote-tracking branch 'upstream/main' into add_snap_package 2025-02-15 07:06:40 -08:00
Ken VanDine bd6a133e95 Updated stage packages 2025-02-15 07:06:40 -08:00
Ken VanDine 1c41cf236f Merge branch 'ghostty-org:main' into add_snap_package 2025-02-15 07:06:40 -08:00
Ken VanDine a831df903d Merge branch 'ghostty-org:main' into add_snap_package 2025-02-15 07:06:40 -08:00
Ken VanDine ff5c1001c6 Per PR review feedback, this is the more "ziggy" way of doing the check for environment variable. 2025-02-15 07:06:40 -08:00
Ken VanDine e4cf81c2ba Clean up environment variable while launching the shell 2025-02-15 07:06:40 -08:00
Ken VanDine cb5379ab1d Unset environment varies set by the snap 2025-02-15 07:06:40 -08:00
Ken VanDine 7e5c57a848 Only export XDG_CONFIG_HOME and XDG_DATA_HOME if they aren't already set 2025-02-15 07:06:40 -08:00
Ken VanDine 5841a4f958 Stage libglib2.0-0t64 to insure we don't mix in the host's lib 2025-02-15 07:06:40 -08:00
Ken VanDine 725488e1a2 Improved environment handling to ensure the snap will work across
distros and unset all SNAP environment variables that could leak at
runtime
2025-02-15 07:06:40 -08:00
Ken VanDine 0acf82bb9c Use patch-rpath which improves our cross distro support 2025-02-15 07:06:40 -08:00
Mitchell Hashimoto 9944fd5958
ci: temporary apt installs required for namespace 2025-02-15 07:06:40 -08:00
Ken VanDine e7d4daa7c1 Removed duplicated stage-packages 2025-02-15 07:06:40 -08:00
Ken VanDine 5de0e775cb Don't stage shells 2025-02-15 07:06:40 -08:00
Ken VanDine 301fdff58f enable-patchelf is more repliable for classic snaps 2025-02-15 07:06:40 -08:00
Ken VanDine 99c7abb43a Set GHOSTTY_RESOURCES_DIR 2025-02-15 07:06:40 -08:00
Ken VanDine a85de40710 Exit with error if building for unsupported arch 2025-02-15 07:06:40 -08:00
Ken VanDine e174fb2748 no-patchelf for DRI and tidy up the mesa bits 2025-02-15 07:06:40 -08:00
Ken VanDine 403eab2cf0 Stage gnome-text-editor to open configuration, this makes it more
reliable across more distros as a classic snap.
2025-02-15 07:06:40 -08:00
Ken VanDine bdafc2227c Drop patchelf 2025-02-15 07:06:40 -08:00
Ken VanDine c9cafd3051 Enable patch-elf for libs part 2025-02-15 07:06:40 -08:00
Ken VanDine 48f94e6fcc Stage more depends to ensure we aren't getting leaks from the host 2025-02-15 07:06:40 -08:00
Ken VanDine 43b2e43a11 EGL fixes, ensure necessary env variables are set to isolate
dependencies from the host
2025-02-15 07:06:40 -08:00
Ken VanDine 8dffe3450c CRAFT_TARGET_ARCH is deprecated, use CRAFT_ARCH_BUILD_FOR 2025-02-15 07:06:40 -08:00
Ken VanDine ae953b5f10 Ensure LD_LIBRARY_PATH is set appropriately 2025-02-15 07:06:40 -08:00
Mitchell Hashimoto c7635201ab
Add snap to nix, add arm64 builders 2025-02-15 07:06:40 -08:00
Ken VanDine c35ca1e87f Set a more meaningful version for the snap 2025-02-15 07:06:40 -08:00
Ken VanDine d06d6796c5 Changed shebang in launcher script 2025-02-15 07:06:40 -08:00
Ken VanDine e6c9dc7040 Only run snap workflow on push and PR 2025-02-15 07:06:40 -08:00
Ken VanDine 5d0dde57f9 Don't stage shells 2025-02-15 07:06:40 -08:00
Ken VanDine d0108416d0 enable-patchelf is more repliable for classic snaps 2025-02-15 07:06:40 -08:00
Ken VanDine 71297870cf Set GHOSTTY_RESOURCES_DIR 2025-02-15 07:06:40 -08:00
Ken VanDine fcde494440 Install bash-completion 2025-02-15 07:06:40 -08:00
Ken VanDine b7bd8444c7 Exit with error if building for unsupported arch 2025-02-15 07:06:40 -08:00
Ken VanDine 2b2b3c5b3b Set source-type for launcher dir 2025-02-15 07:06:40 -08:00
Ken VanDine 818c81282b Added snap build workflow 2025-02-15 07:06:40 -08:00
Ken VanDine f0842c5599 Added snap packaging 2025-02-15 07:06:40 -08:00
Jeffrey C. Ollie 2d0940f6ae
gtk: require libadwaita (#5749)
This commit removes support for building without libadwaita. (Y'all knew
that I just had this sitting in my back pocket). This will need some
serious review to ensure that we haven't lost any functionality.
2025-02-15 09:04:11 -06:00
Tim Culverhouse f1f1120749
termio: use modified backend (#5776)
In Termio.init, we make a copy of backend and modify it by calling
initTerminal. However, we used the original in the struct definition.
This lead to the pty being opened with a size 0,0.
2025-02-14 22:57:50 -06:00
Mitchell Hashimoto c1ff382e97
core: add `env` config option (#5309)
Fixes #5257

Specify environment variables to pass to commands launched in a terminal
surface. The format is `env=KEY=VALUE`.

`env = foo=bar`
`env = bar=baz`

Setting `env` to an empty string will reset the entire map to default
(empty).

`env =`

Setting a key to an empty string will remove that particular key and
corresponding value from the map.

`env = foo=bar`
`env = foo=`

will result in `foo` not being passed to the launched commands. Setting
a key multiple times will overwrite previous entries.

`env = foo=bar`
`env = foo=baz`

will result in `foo=baz` being passed to the launched commands.

These environment variables _will not_ be passed to commands run by
Ghostty for other purposes, like `open` or `xdg-open` used to open URLs
in your browser.
2025-02-14 20:55:51 -08:00
Tim Culverhouse 29f25ae474
termio: prevent responses to non-query OSC 21 sequences (#5770)
The Ghostty implementation of OSC 21 (Kitty color protocol) currently
responds to *all* OSC 21 sequences. It should not respond to a set, nor
a reset command. Fix the implementation so that we only respond if a
query was received.
2025-02-14 22:50:03 -06:00
Jeffrey C. Ollie c7971b562e core: add `env` config option
Fixes #5257

Specify environment variables to pass to commands launched in a terminal
surface. The format is `env=KEY=VALUE`.

`env = foo=bar`
`env = bar=baz`

Setting `env` to an empty string will reset the entire map to default
(empty).

`env =`

Setting a key to an empty string will remove that particular key and
corresponding value from the map.

`env = foo=bar`
`env = foo=`

will result in `foo` not being passed to the launched commands.
Setting a key multiple times will overwrite previous entries.

`env = foo=bar`
`env = foo=baz`

will result in `foo=baz` being passed to the launched commands.

These environment variables _will not_ be passed to commands run by Ghostty
for other purposes, like `open` or `xdg-open` used to open URLs in your
browser.
2025-02-14 20:50:01 -08:00
Tim Culverhouse b7009202ce
termio: use modified backend
In Termio.init, we make a copy of backend and modify it by calling
initTerminal. However, we used the original in the struct definition.
This lead to the pty being opened with a size 0,0.
2025-02-14 22:44:27 -06:00
Jeffrey C. Ollie 25c5ecf553
gtk: require libadwaita
This commit removes support for building without libadwaita.
2025-02-14 21:49:51 -06:00
Tim Culverhouse 09fbf096d3
termio: prevent responses to non-query OSC 21 sequences
The Ghostty implementation of OSC 21 (Kitty color protocol) currently
responds to *all* OSC 21 sequences. It should not respond to a set, nor
a reset command. Fix the implementation so that we only respond if a
query was received.
2025-02-14 18:55:26 -06:00
Mitchell Hashimoto b975f1e860
cli: disable +boo on non-desktop platforms due to lack of tty 2025-02-14 15:14:05 -08:00
Mitchell Hashimoto 8c4b0f815d
prettier 2025-02-14 14:54:59 -08:00
Mitchell Hashimoto 4e8e2d9796
nix: snapcraft should only be installed on Linux 2025-02-14 14:52:36 -08:00
Ken VanDine 90ce5b75f1 Simplified setting snap version 2025-02-14 14:52:08 -08:00
Ken VanDine fd9cbde3d8 Merge remote-tracking branch 'upstream/main' into add_snap_package 2025-02-14 14:52:08 -08:00
Ken VanDine b0edda4b69 Updated stage packages 2025-02-14 14:52:08 -08:00
Ken VanDine bbd279bb4f Merge branch 'ghostty-org:main' into add_snap_package 2025-02-14 14:52:08 -08:00
Ken VanDine bdbf30dc96 Merge branch 'ghostty-org:main' into add_snap_package 2025-02-14 14:52:08 -08:00
Ken VanDine a111b3f96f Per PR review feedback, this is the more "ziggy" way of doing the check for environment variable. 2025-02-14 14:52:08 -08:00
Ken VanDine f239df59ca Clean up environment variable while launching the shell 2025-02-14 14:52:08 -08:00
Ken VanDine c036eb2444 Unset environment varies set by the snap 2025-02-14 14:52:08 -08:00
Ken VanDine cee189de11 Only export XDG_CONFIG_HOME and XDG_DATA_HOME if they aren't already set 2025-02-14 14:52:08 -08:00
Ken VanDine d2f82b2e40 Stage libglib2.0-0t64 to insure we don't mix in the host's lib 2025-02-14 14:52:08 -08:00
Ken VanDine 3e669fc4bb Improved environment handling to ensure the snap will work across
distros and unset all SNAP environment variables that could leak at
runtime
2025-02-14 14:52:08 -08:00
Ken VanDine 1a5b69181f Use patch-rpath which improves our cross distro support 2025-02-14 14:52:08 -08:00
Mitchell Hashimoto 55c5b8b72f
ci: temporary apt installs required for namespace 2025-02-14 14:52:08 -08:00
Ken VanDine 5e77a973b2 Removed duplicated stage-packages 2025-02-14 14:52:08 -08:00
Ken VanDine 9c81cd323d Don't stage shells 2025-02-14 14:52:08 -08:00
Ken VanDine 78446008c4 enable-patchelf is more repliable for classic snaps 2025-02-14 14:52:08 -08:00
Ken VanDine e09d8455a1 Set GHOSTTY_RESOURCES_DIR 2025-02-14 14:52:08 -08:00
Ken VanDine 1dcea3b11f Exit with error if building for unsupported arch 2025-02-14 14:52:08 -08:00
Ken VanDine 9d62c31f44 no-patchelf for DRI and tidy up the mesa bits 2025-02-14 14:52:08 -08:00
Ken VanDine 0272ad9edb Stage gnome-text-editor to open configuration, this makes it more
reliable across more distros as a classic snap.
2025-02-14 14:52:08 -08:00
Ken VanDine f3829072f3 Drop patchelf 2025-02-14 14:52:08 -08:00
Ken VanDine 2b6b7c19d2 Enable patch-elf for libs part 2025-02-14 14:52:08 -08:00
Ken VanDine 3a9d61d6e4 Stage more depends to ensure we aren't getting leaks from the host 2025-02-14 14:52:08 -08:00
Ken VanDine 6d8b3973e4 EGL fixes, ensure necessary env variables are set to isolate
dependencies from the host
2025-02-14 14:52:08 -08:00
Ken VanDine aa4d9809c3 CRAFT_TARGET_ARCH is deprecated, use CRAFT_ARCH_BUILD_FOR 2025-02-14 14:52:08 -08:00
Ken VanDine ec8e7d9d86 Ensure LD_LIBRARY_PATH is set appropriately 2025-02-14 14:52:08 -08:00
Mitchell Hashimoto f1f23e1c7d
Add snap to nix, add arm64 builders 2025-02-14 14:52:08 -08:00
Ken VanDine 2e0e8af1ad Set a more meaningful version for the snap 2025-02-14 14:52:08 -08:00
Ken VanDine 53f1b4bc15 Changed shebang in launcher script 2025-02-14 14:52:08 -08:00
Ken VanDine eae420a241 Only run snap workflow on push and PR 2025-02-14 14:52:08 -08:00
Ken VanDine bf49784b7d Don't stage shells 2025-02-14 14:52:08 -08:00
Ken VanDine b6a3b98828 enable-patchelf is more repliable for classic snaps 2025-02-14 14:52:08 -08:00
Ken VanDine eb0816c2c4 Set GHOSTTY_RESOURCES_DIR 2025-02-14 14:52:08 -08:00
Ken VanDine 30fa18390f Install bash-completion 2025-02-14 14:52:08 -08:00
Ken VanDine f51789b17a Exit with error if building for unsupported arch 2025-02-14 14:52:08 -08:00
Ken VanDine 97b104cf9d Set source-type for launcher dir 2025-02-14 14:52:08 -08:00
Ken VanDine a7d1029e5c Added snap build workflow 2025-02-14 14:52:08 -08:00
Ken VanDine aed30502bd Added snap packaging 2025-02-14 14:52:08 -08:00
Mitchell Hashimoto 56efaf0c82
[macOS] feat: add `bring_all_to_front` keybinding (#5006)
Can't consider the feature complete until the Linux (GTK) implementation
:/ .

Fixes #4704
2025-02-14 14:49:28 -08:00
Mitchell Hashimoto 686b6a2971
cli: add +boo command (#4876)
Add a `+boo` command to show the animation from the website. The data
for the frames is compressed during the build process. This build step
was added to the SharedDeps object because it is used in both
libghostty and in binaries.

The compression is done as follows:

- All files are concatenated together using \x01 as a combining byte
- The files are compressed to a cached build file
- A zig file is written to stdout which `@embedFile`s the compressed
  file and exposes it to the importer
- A new anonymous module "framedata" is added in the SharedDeps object

Any file can import framedata and access the compressed bytes via
`framedata.compressed`. In the `boo` command, we decompress the slice
and
split it into frames for use in the animation.

The overall addition to the binary size is 348k.
2025-02-14 14:47:51 -08:00
Tim Culverhouse 9cb297202b cli: add +boo command
Add a `+boo` command to show the animation from the website. The data
for the frames is compressed during the build process. This build step
was added to the SharedDeps object because it is used in both
libghostty and in binaries.

The compression is done as follows:
- All files are concatenated together using \x01 as a combining byte
- The files are compressed to a cached build file
- A zig file is written to stdout which `@embedFile`s the compressed
  file and exposes it to the importer
- A new anonymous module "framedata" is added in the SharedDeps object

Any file can import framedata and access the compressed bytes via
`framedata.compressed`. In the `boo` command, we decompress the file and
split it into frames for use in the animation.

The overall addition to the binary size is 348k.
2025-02-14 14:46:18 -08:00
Damien Mehala a0f243691a feat: add `bring_all_to_front` keybinding
Resolves #4704.
2025-02-14 14:41:49 -08:00
Mitchell Hashimoto cdfea4bc7e
feat: add save instruction to +list-themes (#4902)
Close #4731 

<img width="1164" alt="image"
src="https://github.com/user-attachments/assets/50cb96cc-5192-424f-9ec6-1a150ae7f98b"
/>
2025-02-14 13:47:46 -08:00
Aaron Ruan 5c1f85e861 Merge branch 'ghostty-org:main' into list-theme-save 2025-02-14 13:44:33 -08:00
Aaron Ruan 2da7d77feb add save instruction to +list-themes
Signed-off-by: Aaron Ruan <aaron212cn@outlook.com>
2025-02-14 13:44:33 -08:00
Mitchell Hashimoto 1121ea9d6c
Add tab title renaming feature to macos (#4217)
Tries to resolve #2509 partially by enabling tab title renaming feature
for MacOS.

* Used the existing set_title action
* Added the set_title action to Bindings so that a keybind can be set
for this feature (defaulted this to cmd+i -- same as iTerm2)
* 3 ways to trigger this feature: "Set Title" option in the right-click
menu for the window, "Set Title" option in the "View" menu in the title
bar, and the keybind (cmd+i default)
* Prevented esc sequences from the different programs from resetting the
tab title once it is set manually using a new state var called
`titleSetManually` in the SurfaceView
* The input box is a basic native macos dialog with "OK" and "Cancel".
Leaving the title text box empty resets the title to automatic / from
the `title` property in the config

**Demo**:


https://github.com/user-attachments/assets/5cacc389-4486-46c4-8cd5-dda347e9c663


Need some feedback. Thanks!
2025-02-14 13:37:29 -08:00
Aswin M Prabhu a581955b9b Add tab title rename feature to macos 2025-02-14 13:29:36 -08:00
Mitchell Hashimoto 228b4dbd60
build: mirror most of our direct dependencies (#5765)
This adds a new script `update-mirror.sh` which generates the proper
blob format for R2 (or any blob storage) to mirror all of our
dependencies.

It doesn't automate updating build.zig.zon but on an ongoing basis this
should be easy to do manually, and we can strive to automate it in the
future.

I omitted iTerm2 color themes because we auto-update that via CI and
updating all of the machinery to send it to our mirror and so on is a
pain. Additionally, this doesn't mirror transitive dependencies because
Zig doesn't have a way to fetch those from a mirror instead (unless you
pre-generate a full cache like packagers but that's not practical for
day to day development).

It's hugely beneficial just to get most of our dependencies mirrored.
2025-02-14 11:34:08 -08:00
Mitchell Hashimoto 8231ebb770
build: mirror most of our direct dependencies
This adds a new script `update-mirror.sh` which generates the proper
blob format for R2 (or any blob storage) to mirror all of our
dependencies.

It doesn't automate updating build.zig.zon but on an ongoing basis this
should be easy to do manually, and we can strive to automate it in the
future.

I omitted iTerm2 color themes because we auto-update that via CI and
updating all of the machinery to send it to our mirror and so on is a
pain. Additionally, this doesn't mirror transitive dependencies because
Zig doesn't have a way to fetch those from a mirror instead (unless you
pre-generate a full cache like packagers but that's not practical for
day to day development).

It's hugely beneficial just to get most of our dependencies mirrored.
2025-02-14 10:06:15 -08:00
Mitchell Hashimoto 95e6a27393
build: generate a build.zig.zon.txt file for easy zig fetch scripting (#5764)
This fixes a regression in 1.1.1/1.1.2 where our PACKAGING docs mention
using `fetch-zig-cache.sh` but it was removed. This commit adds it back,
generating its contents from the build.zig.zon file (via zon2nix which
we use for our Nix packaging).

For packagers, there are no dependency changes: you still need Zig and
POSIX sh. For release time, Ghostty has a new dependency on `jq` but
otherwise the release process is the same. The check-zig-cache.sh script
is updated to generate the new build.zig.zon.txt file.
2025-02-14 09:24:07 -08:00
Jeffrey C. Ollie f32ad5216b build: generate a build.zig.zon.txt file for easy zig fetch scripting
This fixes a regression in 1.1.1/1.1.2 where our PACKAGING docs mention
using `fetch-zig-cache.sh` but it was removed. This commit adds it back,
generating its contents from the build.zig.zon file (via zon2nix which
we use for our Nix packaging).

For packagers, there are no dependency changes: you still need Zig and
POSIX sh. For release time, Ghostty has a new dependency on `jq` but
otherwise the release process is the same. The check-zig-cache.sh script
is updated to generate the new build.zig.zon.txt file.
2025-02-14 09:23:51 -08:00
Mitchell Hashimoto 56b244973f
Add back `fetch-zig-cache.sh` for packaging (#5762)
See the comment on more details, which also covers when and how we can
remove this.
2025-02-14 08:07:28 -08:00
Mitchell Hashimoto cdd287c88b
Add back `fetch-zig-cache.sh` for packaging
See the comment on more details, which also covers when and how we can
remove this.
2025-02-14 07:23:26 -08:00
Mitchell Hashimoto 315df0ab3f
macos: add `padded-notch` option for `macos-non-native-fullscreen` (#5750)
Finishes #378
Supercedes #4159

This adds a new enum value for `macos-non-native-fullscreen`:
`padded-notch`. This value will add padding to the top of the window to
account for the notch on applicable devices while still hiding the menu.

This value is preferred over "visible-menu" by some people because for
screens without a notch, the window will take up the full height.

The plan in the future is that we may color the padded area when a notch
is present. In this commit it appears as transparent.

EDIT: Hah, the video below is pretty useless since the screen recording
software omits the notch. 😄


https://github.com/user-attachments/assets/4b1e84dd-3b3a-44a8-a83b-0f51e44f6cf8
2025-02-13 21:09:29 -08:00
Mitchell Hashimoto ac7aa757bd
macos: add `padded-notch` option for `macos-non-native-fullscreen`
Finishes #378
Supercedes #4159

This adds a new enum value for `macos-non-native-fullscreen`:
`padded-notch`. This value will add padding to the top of the window to
account for the notch on applicable devices while still hiding the
menu.

This value is preferred over "visible-menu" by some people because for
screens without a notch, the window will take up the full height.

The plan in the future is that we may color the padded area when a notch
is present. In this commit it appears as transparent.
2025-02-13 20:27:42 -08:00
Mitchell Hashimoto 52a5069dec
up versions for development 2025-02-13 15:31:14 -08:00
1265 changed files with 177654 additions and 54780 deletions

64
.agents/commands/gh-issue Executable file
View File

@ -0,0 +1,64 @@
#!/usr/bin/env nu
# A command to generate an agent prompt to diagnose and formulate
# a plan for resolving a GitHub issue.
#
# IMPORTANT: This command is prompted to NOT write any code and to ONLY
# produce a plan. You should still be vigilant when running this but that
# is the expected behavior.
#
# The `<issue>` parameter can be either an issue number or a full GitHub
# issue URL.
def main [
issue: any, # Ghostty issue number or URL
--repo: string = "ghostty-org/ghostty" # GitHub repository in the format "owner/repo"
] {
# TODO: This whole script doesn't handle errors very well. I actually
# don't know Nu well enough to know the proper way to handle it all.
let issueData = gh issue view $issue --json author,title,number,body,comments | from json
let comments = $issueData.comments | each { |comment|
$"
### Comment by ($comment.author.login)
($comment.body)
" | str trim
} | str join "\n\n"
$"
Deep-dive on this GitHub issue. Find the problem and generate a plan.
Do not write code. Explain the problem clearly and propose a comprehensive plan
to solve it.
# ($issueData.title) \(($issueData.number)\)
## Description
($issueData.body)
## Comments
($comments)
## Your Tasks
You are an experienced software developer tasked with diagnosing issues.
1. Review the issue context and details.
2. Examine the relevant parts of the codebase. Analyze the code thoroughly
until you have a solid understanding of how it works.
3. Explain the issue in detail, including the problem and its root cause.
4. Create a comprehensive plan to solve the issue. The plan should include:
- Required code changes
- Potential impacts on other parts of the system
- Necessary tests to be written or updated
- Documentation updates
- Performance considerations
- Security implications
- Backwards compatibility \(if applicable\)
- Include the reference link to the source issue and any related discussions
4. Think deeply about all aspects of the task. Consider edge cases, potential
challenges, and best practices for addressing the issue. Review the plan
with the oracle and adjust it based on its feedback.
**ONLY CREATE A PLAN. DO NOT WRITE ANY CODE.** Your task is to create
a thorough, comprehensive strategy for understanding and resolving the issue.
" | str trim
}

75
.agents/commands/review-branch Executable file
View File

@ -0,0 +1,75 @@
#!/usr/bin/env nu
# A command to review the changes made in the current Git branch.
#
# IMPORTANT: This command is prompted to NOT write any code and to ONLY
# produce a review summary. You should still be vigilant when running this
# but that is the expected behavior.
#
# The optional `<issue>` parameter can be an issue number, PR number,
# or a full GitHub URL to provide additional context.
def main [
issue?: any, # Optional GitHub issue/PR number or URL for context
] {
let issueContext = if $issue != null {
let data = gh issue view $issue --json author,title,number,body,comments | from json
let comments = if ($data.comments? != null) {
$data.comments | each { |comment|
let author = if ($comment.author?.login? != null) { $comment.author.login } else { "unknown" }
$"
### Comment by ($author)
($comment.body)
" | str trim
} | str join "\n\n"
} else {
""
}
$"
## Source Issue: ($data.title) \(#($data.number)\)
### Description
($data.body)
### Comments
($comments)
"
} else {
""
}
$"
# Branch Review
Inspect the changes made in this Git branch. Identify any possible issues
and suggest improvements. Do not write code. Explain the problems clearly
and propose a brief plan for addressing them.
($issueContext)
## Your Tasks
You are an experienced software developer with expertise in code review.
Review the change history between the current branch and its
base branch. Analyze all relevant code for possible issues, including but
not limited to:
- Code quality and readability
- Code style that matches or mimics the rest of the codebase
- Potential bugs or logical errors
- Edge cases that may not be handled
- Performance considerations
- Security vulnerabilities
- Backwards compatibility \(if applicable\)
- Test coverage and effectiveness
For test coverage, consider if the changes are in an area of the codebase
that is testable. If so, check if there are appropriate tests added or
modified. Consider if the code itself should be modified to be more
testable.
Think deeply about the implications of the changes here and proposed.
Consult the oracle if you have access to it.
**ONLY CREATE A SUMMARY. DO NOT WRITE ANY CODE.**
" | str trim
}

View File

@ -1,6 +1,6 @@
root = true
[*.{sh,bash}]
[*.{sh,bash,elv}]
indent_size = 2
indent_style = space

2
.envrc
View File

@ -4,3 +4,5 @@ if has nix; then
watch_file nix/{devShell,package,wraptest}.nix
use flake
fi
source_env_if_exists .envrc.local

7
.gitattributes vendored
View File

@ -1,7 +1,14 @@
build.zig.zon.nix linguist-generated=true
build.zig.zon.txt linguist-generated=true
build.zig.zon.json linguist-generated=true
vendor/** linguist-vendored
website/** linguist-documentation
pkg/breakpad/vendor/** linguist-vendored
pkg/cimgui/vendor/** linguist-vendored
pkg/glfw/wayland-headers/** linguist-vendored
pkg/libintl/config.h linguist-generated=true
pkg/libintl/libintl.h linguist-generated=true
pkg/simdutf/vendor/** linguist-vendored
src/font/nerd_font_attributes.zig linguist-generated=true
src/font/nerd_font_codepoint_tables.py linguist-generated=true
src/terminal/res/** linguist-vendored

View File

@ -0,0 +1,162 @@
labels: ["needs-confirmation"]
body:
- type: markdown
attributes:
value: |
> [!IMPORTANT]
> Please read through [the Discussion rules](https://github.com/ghostty-org/ghostty/discussions/6937), review [the FAQs](https://ghostty.org/docs/help#common-issues-and-solutions), and check for both existing [Discussions](https://github.com/ghostty-org/ghostty/discussions?discussions_q=) and [Issues](https://github.com/ghostty-org/ghostty/issues?q=sort%3Areactions-desc) prior to opening a new Discussion.
- type: markdown
attributes:
value: "# Issue Details"
- type: textarea
attributes:
label: Issue Description
description: |
Provide a detailed description of the issue. Include relevant information, such as:
- The feature or configuration option you encounter the issue with.
- Screenshots, screen recordings, or other supporting media (as needed).
- If this is a regression of an existing issue that was closed or resolved, please include the previous item reference (Discussion, Issue, PR, commit) in your description.
> [!TIP]
> **Not sure what information to include?**
> Here are some recommendations:
> - **Input issues:** include your keyboard layout, a screenshot of logged keystrokes from the terminal inspector's "Keyboard" tab (Linux: <kbd>ctrl</kbd>+<kbd>shift</kbd>+<kbd>i</kbd>; MacOS: <kbd>cmd</kbd>+<kbd>alt</kbd>+<kbd>i</kbd>), input method, Linux input method engine (IBus, Fcitx 5, or none) and its version.
> - **Font issues:** include the problematic character(s), the output of `ghostty +show-face` for these character(s), and if they work in other applications.
> - **Terminal emulation issues (including image rendering issues):** attach an [asciinema](https://docs.asciinema.org/getting-started/) cast file, shell script, or text file for reproduction.
> - **Renderer issues:** (Linux) include your OpenGL version, graphics card, driver version.
> - **Crashes:** (macOS) include the [Sentry UUID](https://github.com/ghostty-org/ghostty?tab=readme-ov-file#crash-reports); (Linux) try to reproduce using a debug build and provide the stack trace.
placeholder: |
When using SSH to connect to my remote Linux machine from my local macOS device in Ghostty, I try to run `clear`, and the screen does not clear. Instead, I see the following error message printed to the terminal: `Error opening terminal: xterm-ghostty.`
validations:
required: true
- type: textarea
attributes:
label: Expected Behavior
description: |
Describe how you expect Ghostty to behave in this situation. Include any relevant documentation links.
placeholder: |
The screen is cleared and the prompt is redrawn at the top of the window.
validations:
required: true
- type: textarea
attributes:
label: Actual Behavior
description: |
Describe how Ghostty actually behaves in this situation. If it is not immediately obvious how the actual behavior differs from the expected behavior described above, please be sure to mention the deviation specifically.
placeholder: |
The screen is not cleared, and an error is printed: `Error opening terminal: xterm-ghostty`.
validations:
required: true
- type: textarea
attributes:
label: Reproduction Steps
description: |
Provide a detailed set of step-by-step instructions for reproducing this issue.
placeholder: |
1. Open Ghostty.
2. Connect to a remote server via SSH.
3. Try to execute `clear`.
4. Observe `xterm-ghostty` error message above.
validations:
required: true
- type: textarea
attributes:
label: Ghostty Logs
description: |
Provide any captured Ghostty logs or stacktraces during your issue reproduction in this field. On Linux, logs can be found by running `ghostty` from the command-line; on macOS, logs can be viewed with `sudo log stream --level debug --predicate 'subsystem=="com.mitchellh.ghostty"'` from another terminal emulator.
render: text
- type: textarea
attributes:
label: Ghostty Version
description: Paste the output of `ghostty +version` here.
placeholder: |
Ghostty 1.1.3
Version
- version: 1.1.3
- channel: stable
Build Config
- Zig version: 0.13.0
- build mode : builtin.OptimizeMode.ReleaseFast
- app runtime: apprt.Runtime.none
- font engine: font.main.Backend.coretext
- renderer : renderer.Metal
- libxev : main.Backend.kqueue
render: text
validations:
required: true
- type: input
attributes:
label: OS Version Information
description: |
Please tell us what operating system (name and version) you are using.
placeholder: Ubuntu 24.04.1 (Noble Numbat)
validations:
required: true
- type: dropdown
attributes:
label: (Linux only) Display Server
description: |
If you run Linux, please tell us if you use X11 or Wayland. If you aren't sure, you can determine this by running `[ -z "$WAYLAND_DISPLAY" ] && echo X11 || echo Wayland`.
options:
- X11
- Wayland
- Other
validations:
required: false
- type: input
attributes:
label: (Linux only) Desktop Environment/Window Manager
description: |
If you run Linux, please tell us what Desktop Environment/Window Manager you are using (include the name and version).
placeholder: GNOME 47.4
validations:
required: false
- type: textarea
attributes:
label: Minimal Ghostty Configuration
description: |
Please provide the **minimum** configuration needed to reproduce this issue. If you can still reproduce the issue with one of the lines removed, do not include that line. If and **only** if you are not able to determine this, paste the contents of your Ghostty configuration file here.
placeholder: |
font-family = CommitMono Nerd Font
font-family-bold = CommitMono Nerd Font
font-family-italic = CommitMono Nerd Font
font-family-bold-italic = CommitMono Nerd Font
font-feature = +cv07
font-size = 16
font-thicken = true
theme = catppuccin-mocha
render: ini
validations:
required: true
- type: textarea
attributes:
label: Additional Relevant Configuration
description: |
If your issue involves other programs, tools, or applications in addition to Ghostty (e.g. Neovim, tmux, Zellij, etc.), please provide the minimum configuration and versions needed for all relevant programs to reproduce the issue here. If you use custom CSS or shaders for Ghostty, also include them here, if applicable to your issue.
placeholder: |
#### `tmux.conf` (tmux 3.5a)
```
set -g default-terminal "tmux-256color"
set-option -sa terminal-overrides ",xterm*:Tc"
set -g base-index 1
setw -g pane-base-index 1
```
validations:
required: false
- type: markdown
attributes:
value: |
# User Acknowledgements
> [!TIP]
> Use these links to review the existing Ghostty [Discussions](https://github.com/ghostty-org/ghostty/discussions?discussions_q=) and [Issues](https://github.com/ghostty-org/ghostty/issues?q=sort%3Areactions-desc).
- type: checkboxes
attributes:
label: "I acknowledge that:"
options:
- label: I have reviewed the FAQ and confirm that my issue is NOT among them.
required: true
- label: I have searched the Ghostty repository (both open and closed Discussions and Issues) and confirm this is not a duplicate of an existing issue or discussion.
required: true
- label: I have checked the "Preview" tab on all text fields to ensure that everything looks right, and have wrapped all configuration and code in code blocks with a group of three backticks (` ``` `) on separate lines.
required: true

4
.github/pinact.yml vendored Normal file
View File

@ -0,0 +1,4 @@
version: 3
ignore_actions:
- name: "DeterminateSystems/nix-installer-action"
ref: "main"

14
.github/scripts/check-translations.sh vendored Executable file
View File

@ -0,0 +1,14 @@
#!/bin/sh
old_pot=$(mktemp)
cp po/com.mitchellh.ghostty.pot "$old_pot"
zig build update-translations
# Compare previous POT to current POT
msgcmp "$old_pot" po/com.mitchellh.ghostty.pot --use-untranslated
# Compare all other POs to current POT
for f in po/*.po; do
# Ignore untranslated entries
msgcmp --use-untranslated "$f" po/com.mitchellh.ghostty.pot;
done

19
.github/scripts/ghostty-tip vendored Executable file
View File

@ -0,0 +1,19 @@
#!/usr/bin/env nu
# Check if a given commit SHA has a corresponding tip release.
#
# This does not validate that the commit SHA is valid for the
# Ghostty repository, only that a tip release exists for it.
def main [
commit: string, # The full length commit SHA
] {
let url = $"https://tip.files.ghostty.org/($commit)/ghostty-macos-universal.zip"
try {
http head $url
exit 0
} catch {
print -e $"The SHA ($commit) does not have a corresponding tip release."
exit 1
}
}

View File

@ -10,7 +10,7 @@ jobs:
timeout-minutes: 10
steps:
- name: Remove old artifacts
uses: c-hive/gha-remove-artifacts@v1
uses: c-hive/gha-remove-artifacts@44fc7acaf1b3d0987da0e8d4707a989d80e9554b # v1.4.0
with:
age: "1 week"
skip-tags: true

50
.github/workflows/flatpak.yml vendored Normal file
View File

@ -0,0 +1,50 @@
on:
workflow_dispatch:
inputs:
source-run-id:
description: run id of the workflow that generated the artifact
required: true
type: string
source-artifact-id:
description: source tarball built during build-dist
required: true
type: string
name: Flatpak
jobs:
build:
if: github.repository == 'ghostty-org/ghostty'
name: "Flatpak"
container:
image: ghcr.io/flathub-infra/flatpak-github-actions:gnome-47
options: --privileged
strategy:
fail-fast: false
matrix:
variant:
- arch: x86_64
runner: namespace-profile-ghostty-md
- arch: aarch64
runner: namespace-profile-ghostty-md-arm64
runs-on: ${{ matrix.variant.runner }}
steps:
- name: Download Source Tarball Artifacts
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
run-id: ${{ inputs.source-run-id }}
artifact-ids: ${{ inputs.source-artifact-id }}
github-token: ${{ github.token }}
- name: Extract tarball
run: |
mkdir dist
tar --verbose --extract --strip-components 1 --directory dist --file ghostty-source.tar.gz
- uses: flatpak/flatpak-github-actions/flatpak-builder@92ae9851ad316786193b1fd3f40c4b51eb5cb101 # v6.6
with:
bundle: com.mitchellh.ghostty
manifest-path: dist/flatpak/com.mitchellh.ghostty.yml
cache-key: flatpak-builder-${{ github.sha }}
arch: ${{ matrix.variant.arch }}
verbose: true

View File

@ -15,7 +15,7 @@ jobs:
name: Milestone Update
steps:
- name: Set Milestone for PR
uses: hustcer/milestone-action@v2
uses: hustcer/milestone-action@dcd6c3742acc1846929c054251c64cccd555a00d # v3.0
if: github.event.pull_request.merged == true
with:
action: bind-pr # `bind-pr` is the default action
@ -24,7 +24,7 @@ jobs:
# Bind milestone to closed issue that has a merged PR fix
- name: Set Milestone for Issue
uses: hustcer/milestone-action@v2
uses: hustcer/milestone-action@dcd6c3742acc1846929c054251c64cccd555a00d # v3.0
if: github.event.issue.state == 'closed'
with:
action: bind-issue

View File

@ -1,5 +1,10 @@
on: [push, pull_request]
name: Nix
concurrency:
group: ${{ github.workflow }}-${{ github.ref_name != 'main' && github.ref || github.run_id }}
cancel-in-progress: true
jobs:
required:
name: "Required Checks: Nix"
@ -34,18 +39,18 @@ jobs:
ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Setup Cache
uses: namespacelabs/nscloud-cache-action@v1.2.0
uses: namespacelabs/nscloud-cache-action@446d8f390563cd54ca27e8de5bdb816f63c0b706 # v1.2.21
with:
path: |
/nix
/zig
- name: Setup Nix
uses: cachix/install-nix-action@v30
uses: cachix/install-nix-action@4e002c8ec80594ecd40e759629461e26c8abed15 # v31.9.0
with:
nix_path: nixpkgs=channel:nixos-unstable
- uses: cachix/cachix-action@v15
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
with:
name: ghostty
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"

View File

@ -28,7 +28,7 @@ jobs:
echo "Version is valid: ${{ github.event.inputs.version }}"
- name: Exract the Version
- name: Extract the Version
id: extract_version
run: |
VERSION=${{ github.event.inputs.version }}
@ -64,7 +64,7 @@ jobs:
mkdir blob
mv appcast.xml blob/appcast.xml
- name: Upload Appcast to R2
uses: ryand56/r2-upload-action@latest
uses: ryand56/r2-upload-action@b801a390acbdeb034c5e684ff5e1361c06639e7c # v1
with:
r2-account-id: ${{ secrets.CF_R2_RELEASE_ACCOUNT_ID }}
r2-access-key-id: ${{ secrets.CF_R2_RELEASE_AWS_KEY }}

View File

@ -1,351 +0,0 @@
on:
workflow_dispatch: {}
name: Release PR
jobs:
sentry-dsym-debug:
runs-on: namespace-profile-ghostty-sm
needs: [build-macos-debug]
steps:
- uses: actions/checkout@v4
- name: Install sentry-cli
run: |
curl -sL https://sentry.io/get-cli/ | bash
- name: Download dSYM
run: |
GHOSTTY_COMMIT_LONG=$(git rev-parse HEAD)
curl -L https://pr.files.ghostty.dev/${GHOSTTY_COMMIT_LONG}/ghostty-macos-universal-debug-dsym.zip > dsym.zip
- name: Upload dSYM to Sentry
env:
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
run: |
sentry-cli dif upload --project ghostty --wait dsym.zip
sentry-dsym:
runs-on: namespace-profile-ghostty-sm
needs: [build-macos]
steps:
- uses: actions/checkout@v4
- name: Install sentry-cli
run: |
curl -sL https://sentry.io/get-cli/ | bash
- name: Download dSYM
run: |
GHOSTTY_COMMIT_LONG=$(git rev-parse HEAD)
curl -L https://pr.files.ghostty.dev/${GHOSTTY_COMMIT_LONG}/ghostty-macos-universal-dsym.zip > dsym.zip
- name: Upload dSYM to Sentry
env:
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
run: |
sentry-cli dif upload --project ghostty --wait dsym.zip
build-macos:
runs-on: namespace-profile-ghostty-macos
timeout-minutes: 90
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
# Important so that build number generation works
fetch-depth: 0
# Install Nix and use that to run our tests so our environment matches exactly.
- uses: cachix/install-nix-action@v30
with:
nix_path: nixpkgs=channel:nixos-unstable
- uses: cachix/cachix-action@v15
with:
name: ghostty
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
# Setup Sparkle
- name: Setup Sparkle
env:
SPARKLE_VERSION: 2.6.4
run: |
mkdir -p .action/sparkle
cd .action/sparkle
curl -L https://github.com/sparkle-project/Sparkle/releases/download/${SPARKLE_VERSION}/Sparkle-for-Swift-Package-Manager.zip > sparkle.zip
unzip sparkle.zip
echo "$(pwd)/bin" >> $GITHUB_PATH
# Load Build Number
- name: Build Number
run: |
echo "GHOSTTY_BUILD=$(git rev-list --count head)" >> $GITHUB_ENV
echo "GHOSTTY_COMMIT=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
echo "GHOSTTY_COMMIT_LONG=$(git rev-parse HEAD)" >> $GITHUB_ENV
# GhosttyKit is the framework that is built from Zig for our native
# Mac app to access. Build this in release mode.
- name: Build GhosttyKit
run: nix develop -c zig build -Doptimize=ReleaseSafe
# The native app is built with native XCode tooling. This also does
# codesigning. IMPORTANT: this must NOT run in a Nix environment.
# Nix breaks xcodebuild so this has to be run outside.
- name: Build Ghostty.app
run: |
cd macos
sudo xcode-select -s /Applications/Xcode_16.0.app
xcodebuild -target Ghostty -configuration Release
# We inject the "build number" as simply the number of commits since HEAD.
# This will be a monotonically always increasing build number that we use.
- name: Update Info.plist
env:
SPARKLE_KEY_PUB: ${{ secrets.PROD_MACOS_SPARKLE_KEY_PUB }}
run: |
# Version Info
/usr/libexec/PlistBuddy -c "Set :GhosttyCommit $GHOSTTY_COMMIT" "macos/build/Release/Ghostty.app/Contents/Info.plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $GHOSTTY_BUILD" "macos/build/Release/Ghostty.app/Contents/Info.plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString $GHOSTTY_COMMIT" "macos/build/Release/Ghostty.app/Contents/Info.plist"
# Updater
/usr/libexec/PlistBuddy -c "Set :SUPublicEDKey $SPARKLE_KEY_PUB" "macos/build/Release/Ghostty.app/Contents/Info.plist"
/usr/libexec/PlistBuddy -c "Delete :SUEnableAutomaticChecks" "macos/build/Release/Ghostty.app/Contents/Info.plist"
- name: Codesign app bundle
env:
MACOS_CERTIFICATE: ${{ secrets.PROD_MACOS_CERTIFICATE }}
MACOS_CERTIFICATE_PWD: ${{ secrets.PROD_MACOS_CERTIFICATE_PWD }}
MACOS_CERTIFICATE_NAME: ${{ secrets.PROD_MACOS_CERTIFICATE_NAME }}
MACOS_CI_KEYCHAIN_PWD: ${{ secrets.PROD_MACOS_CI_KEYCHAIN_PWD }}
run: |
# Turn our base64-encoded certificate back to a regular .p12 file
echo $MACOS_CERTIFICATE | base64 --decode > certificate.p12
# We need to create a new keychain, otherwise using the certificate will prompt
# with a UI dialog asking for the certificate password, which we can't
# use in a headless CI environment
security create-keychain -p "$MACOS_CI_KEYCHAIN_PWD" build.keychain
security default-keychain -s build.keychain
security unlock-keychain -p "$MACOS_CI_KEYCHAIN_PWD" build.keychain
security import certificate.p12 -k build.keychain -P "$MACOS_CERTIFICATE_PWD" -T /usr/bin/codesign
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$MACOS_CI_KEYCHAIN_PWD" build.keychain
# Codesign Sparkle. Some notes here:
# - The XPC services aren't used since we don't sandbox Ghostty,
# but since they're part of the build, they still need to be
# codesigned.
# - The binaries in the "Versions" folders need to NOT be symlinks.
/usr/bin/codesign --verbose -f -s "$MACOS_CERTIFICATE_NAME" -o runtime "macos/build/Release/Ghostty.app/Contents/Frameworks/Sparkle.framework/Versions/B/XPCServices/Downloader.xpc"
/usr/bin/codesign --verbose -f -s "$MACOS_CERTIFICATE_NAME" -o runtime "macos/build/Release/Ghostty.app/Contents/Frameworks/Sparkle.framework/Versions/B/XPCServices/Installer.xpc"
/usr/bin/codesign --verbose -f -s "$MACOS_CERTIFICATE_NAME" -o runtime "macos/build/Release/Ghostty.app/Contents/Frameworks/Sparkle.framework/Versions/B/Autoupdate"
/usr/bin/codesign --verbose -f -s "$MACOS_CERTIFICATE_NAME" -o runtime "macos/build/Release/Ghostty.app/Contents/Frameworks/Sparkle.framework/Versions/B/Updater.app"
/usr/bin/codesign --verbose -f -s "$MACOS_CERTIFICATE_NAME" -o runtime "macos/build/Release/Ghostty.app/Contents/Frameworks/Sparkle.framework"
# Codesign the app bundle
/usr/bin/codesign --verbose -f -s "$MACOS_CERTIFICATE_NAME" -o runtime --entitlements "macos/Ghostty.entitlements" macos/build/Release/Ghostty.app
- name: "Notarize app bundle"
env:
PROD_MACOS_NOTARIZATION_APPLE_ID: ${{ secrets.PROD_MACOS_NOTARIZATION_APPLE_ID }}
PROD_MACOS_NOTARIZATION_TEAM_ID: ${{ secrets.PROD_MACOS_NOTARIZATION_TEAM_ID }}
PROD_MACOS_NOTARIZATION_PWD: ${{ secrets.PROD_MACOS_NOTARIZATION_PWD }}
run: |
# Store the notarization credentials so that we can prevent a UI password dialog
# from blocking the CI
echo "Create keychain profile"
xcrun notarytool store-credentials "notarytool-profile" --apple-id "$PROD_MACOS_NOTARIZATION_APPLE_ID" --team-id "$PROD_MACOS_NOTARIZATION_TEAM_ID" --password "$PROD_MACOS_NOTARIZATION_PWD"
# We can't notarize an app bundle directly, but we need to compress it as an archive.
# Therefore, we create a zip file containing our app bundle, so that we can send it to the
# notarization service
echo "Creating temp notarization archive"
ditto -c -k --keepParent "macos/build/Release/Ghostty.app" "notarization.zip"
# Here we send the notarization request to the Apple's Notarization service, waiting for the result.
# This typically takes a few seconds inside a CI environment, but it might take more depending on the App
# characteristics. Visit the Notarization docs for more information and strategies on how to optimize it if
# you're curious
echo "Notarize app"
xcrun notarytool submit "notarization.zip" --keychain-profile "notarytool-profile" --wait
# Finally, we need to "attach the staple" to our executable, which will allow our app to be
# validated by macOS even when an internet connection is not available.
echo "Attach staple"
xcrun stapler staple "macos/build/Release/Ghostty.app"
# Zip up the app
- name: Zip App
run: |
cd macos/build/Release
zip -9 -r --symlinks ../../../ghostty-macos-universal.zip Ghostty.app
zip -9 -r --symlinks ../../../ghostty-macos-universal-dsym.zip Ghostty.app.dSYM/
# Update Blob Storage
- name: Prep R2 Storage
run: |
mkdir blob
mkdir -p blob/${GHOSTTY_COMMIT_LONG}
cp ghostty-macos-universal.zip blob/${GHOSTTY_COMMIT_LONG}/ghostty-macos-universal.zip
cp ghostty-macos-universal-dsym.zip blob/${GHOSTTY_COMMIT_LONG}/ghostty-macos-universal-dsym.zip
- name: Upload to R2
uses: ryand56/r2-upload-action@latest
with:
r2-account-id: ${{ secrets.CF_R2_PR_ACCOUNT_ID }}
r2-access-key-id: ${{ secrets.CF_R2_PR_AWS_KEY }}
r2-secret-access-key: ${{ secrets.CF_R2_PR_SECRET_KEY }}
r2-bucket: ghostty-pr
source-dir: blob
destination-dir: ./
build-macos-debug:
runs-on: namespace-profile-ghostty-macos
timeout-minutes: 90
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
# Important so that build number generation works
fetch-depth: 0
# Install Nix and use that to run our tests so our environment matches exactly.
- uses: cachix/install-nix-action@v30
with:
nix_path: nixpkgs=channel:nixos-unstable
- uses: cachix/cachix-action@v15
with:
name: ghostty
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
# Setup Sparkle
- name: Setup Sparkle
env:
SPARKLE_VERSION: 2.5.1
run: |
mkdir -p .action/sparkle
cd .action/sparkle
curl -L https://github.com/sparkle-project/Sparkle/releases/download/${SPARKLE_VERSION}/Sparkle-for-Swift-Package-Manager.zip > sparkle.zip
unzip sparkle.zip
echo "$(pwd)/bin" >> $GITHUB_PATH
# Load Build Number
- name: Build Number
run: |
echo "GHOSTTY_BUILD=$(git rev-list --count head)" >> $GITHUB_ENV
echo "GHOSTTY_COMMIT=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
echo "GHOSTTY_COMMIT_LONG=$(git rev-parse HEAD)" >> $GITHUB_ENV
# GhosttyKit is the framework that is built from Zig for our native
# Mac app to access. Build this in release mode.
- name: Build GhosttyKit
run: nix develop -c zig build -Doptimize=Debug
# The native app is built with native XCode tooling. This also does
# codesigning. IMPORTANT: this must NOT run in a Nix environment.
# Nix breaks xcodebuild so this has to be run outside.
- name: Build Ghostty.app
run: |
cd macos
sudo xcode-select -s /Applications/Xcode_16.0.app
xcodebuild -target Ghostty -configuration Release
# We inject the "build number" as simply the number of commits since HEAD.
# This will be a monotonically always increasing build number that we use.
- name: Update Info.plist
env:
SPARKLE_KEY_PUB: ${{ secrets.PROD_MACOS_SPARKLE_KEY_PUB }}
run: |
# Version Info
/usr/libexec/PlistBuddy -c "Set :GhosttyCommit $GHOSTTY_COMMIT" "macos/build/Release/Ghostty.app/Contents/Info.plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $GHOSTTY_BUILD" "macos/build/Release/Ghostty.app/Contents/Info.plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString $GHOSTTY_COMMIT" "macos/build/Release/Ghostty.app/Contents/Info.plist"
# Updater
/usr/libexec/PlistBuddy -c "Set :SUPublicEDKey $SPARKLE_KEY_PUB" "macos/build/Release/Ghostty.app/Contents/Info.plist"
/usr/libexec/PlistBuddy -c "Delete :SUEnableAutomaticChecks" "macos/build/Release/Ghostty.app/Contents/Info.plist"
- name: Codesign app bundle
env:
MACOS_CERTIFICATE: ${{ secrets.PROD_MACOS_CERTIFICATE }}
MACOS_CERTIFICATE_PWD: ${{ secrets.PROD_MACOS_CERTIFICATE_PWD }}
MACOS_CERTIFICATE_NAME: ${{ secrets.PROD_MACOS_CERTIFICATE_NAME }}
MACOS_CI_KEYCHAIN_PWD: ${{ secrets.PROD_MACOS_CI_KEYCHAIN_PWD }}
run: |
# Turn our base64-encoded certificate back to a regular .p12 file
echo $MACOS_CERTIFICATE | base64 --decode > certificate.p12
# We need to create a new keychain, otherwise using the certificate will prompt
# with a UI dialog asking for the certificate password, which we can't
# use in a headless CI environment
security create-keychain -p "$MACOS_CI_KEYCHAIN_PWD" build.keychain
security default-keychain -s build.keychain
security unlock-keychain -p "$MACOS_CI_KEYCHAIN_PWD" build.keychain
security import certificate.p12 -k build.keychain -P "$MACOS_CERTIFICATE_PWD" -T /usr/bin/codesign
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$MACOS_CI_KEYCHAIN_PWD" build.keychain
# Codesign Sparkle. Some notes here:
# - The XPC services aren't used since we don't sandbox Ghostty,
# but since they're part of the build, they still need to be
# codesigned.
# - The binaries in the "Versions" folders need to NOT be symlinks.
/usr/bin/codesign --verbose -f -s "$MACOS_CERTIFICATE_NAME" -o runtime "macos/build/Release/Ghostty.app/Contents/Frameworks/Sparkle.framework/Versions/B/XPCServices/Downloader.xpc"
/usr/bin/codesign --verbose -f -s "$MACOS_CERTIFICATE_NAME" -o runtime "macos/build/Release/Ghostty.app/Contents/Frameworks/Sparkle.framework/Versions/B/XPCServices/Installer.xpc"
/usr/bin/codesign --verbose -f -s "$MACOS_CERTIFICATE_NAME" -o runtime "macos/build/Release/Ghostty.app/Contents/Frameworks/Sparkle.framework/Versions/B/Autoupdate"
/usr/bin/codesign --verbose -f -s "$MACOS_CERTIFICATE_NAME" -o runtime "macos/build/Release/Ghostty.app/Contents/Frameworks/Sparkle.framework/Versions/B/Updater.app"
/usr/bin/codesign --verbose -f -s "$MACOS_CERTIFICATE_NAME" -o runtime "macos/build/Release/Ghostty.app/Contents/Frameworks/Sparkle.framework"
# Codesign the app bundle
/usr/bin/codesign --verbose -f -s "$MACOS_CERTIFICATE_NAME" -o runtime --entitlements "macos/Ghostty.entitlements" macos/build/Release/Ghostty.app
- name: "Notarize app bundle"
env:
PROD_MACOS_NOTARIZATION_APPLE_ID: ${{ secrets.PROD_MACOS_NOTARIZATION_APPLE_ID }}
PROD_MACOS_NOTARIZATION_TEAM_ID: ${{ secrets.PROD_MACOS_NOTARIZATION_TEAM_ID }}
PROD_MACOS_NOTARIZATION_PWD: ${{ secrets.PROD_MACOS_NOTARIZATION_PWD }}
run: |
# Store the notarization credentials so that we can prevent a UI password dialog
# from blocking the CI
echo "Create keychain profile"
xcrun notarytool store-credentials "notarytool-profile" --apple-id "$PROD_MACOS_NOTARIZATION_APPLE_ID" --team-id "$PROD_MACOS_NOTARIZATION_TEAM_ID" --password "$PROD_MACOS_NOTARIZATION_PWD"
# We can't notarize an app bundle directly, but we need to compress it as an archive.
# Therefore, we create a zip file containing our app bundle, so that we can send it to the
# notarization service
echo "Creating temp notarization archive"
ditto -c -k --keepParent "macos/build/Release/Ghostty.app" "notarization.zip"
# Here we send the notarization request to the Apple's Notarization service, waiting for the result.
# This typically takes a few seconds inside a CI environment, but it might take more depending on the App
# characteristics. Visit the Notarization docs for more information and strategies on how to optimize it if
# you're curious
echo "Notarize app"
xcrun notarytool submit "notarization.zip" --keychain-profile "notarytool-profile" --wait
# Finally, we need to "attach the staple" to our executable, which will allow our app to be
# validated by macOS even when an internet connection is not available.
echo "Attach staple"
xcrun stapler staple "macos/build/Release/Ghostty.app"
# Zip up the app
- name: Zip App
run: |
cd macos/build/Release
zip -9 -r --symlinks ../../../ghostty-macos-universal-debug.zip Ghostty.app
zip -9 -r --symlinks ../../../ghostty-macos-universal-debug-dsym.zip Ghostty.app.dSYM/
# Update Blob Storage
- name: Prep R2 Storage
run: |
mkdir blob
mkdir -p blob/${GHOSTTY_COMMIT_LONG}
cp ghostty-macos-universal-debug.zip blob/${GHOSTTY_COMMIT_LONG}/ghostty-macos-universal-debug.zip
cp ghostty-macos-universal-debug-dsym.zip blob/${GHOSTTY_COMMIT_LONG}/ghostty-macos-universal-debug-dsym.zip
- name: Upload to R2
uses: ryand56/r2-upload-action@latest
with:
r2-account-id: ${{ secrets.CF_R2_PR_ACCOUNT_ID }}
r2-access-key-id: ${{ secrets.CF_R2_PR_AWS_KEY }}
r2-secret-access-key: ${{ secrets.CF_R2_PR_SECRET_KEY }}
r2-bucket: ghostty-pr
source-dir: blob
destination-dir: ./

View File

@ -39,7 +39,7 @@ jobs:
echo "Version is valid: ${{ github.event.inputs.version }}"
- name: Exract the Version
- name: Extract the Version
id: extract_version
run: |
if [[ "${{ github.event_name }}" == "push" ]]; then
@ -56,7 +56,7 @@ jobs:
fi
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
# Important so that build number generation works
fetch-depth: 0
@ -77,22 +77,33 @@ jobs:
needs: [setup]
env:
GHOSTTY_VERSION: ${{ needs.setup.outputs.version }}
ZIG_LOCAL_CACHE_DIR: /zig/local-cache
ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: cachix/install-nix-action@v30
- name: Setup Cache
uses: namespacelabs/nscloud-cache-action@446d8f390563cd54ca27e8de5bdb816f63c0b706 # v1.2.21
with:
path: |
/nix
/zig
- uses: cachix/install-nix-action@4e002c8ec80594ecd40e759629461e26c8abed15 # v31.9.0
with:
nix_path: nixpkgs=channel:nixos-unstable
- uses: cachix/cachix-action@v15
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
with:
name: ghostty
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
- name: Create Tarball
run: |
git archive --format=tgz --prefix="ghostty-${GHOSTTY_VERSION}/" -o "ghostty-${GHOSTTY_VERSION}.tar.gz" HEAD
git archive --format=tgz --prefix=ghostty-source/ -o ghostty-source.tar.gz HEAD
rm -rf zig-out/dist
nix develop -c zig build distcheck
cp zig-out/dist/ghostty-${GHOSTTY_VERSION}.tar.gz .
cp zig-out/dist/ghostty-${GHOSTTY_VERSION}.tar.gz ghostty-source.tar.gz
- name: Sign Tarball
run: |
@ -102,7 +113,7 @@ jobs:
nix develop -c minisign -S -m "ghostty-source.tar.gz" -s minisign.key < minisign.password
- name: Upload artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: source-tarball
path: |-
@ -113,7 +124,7 @@ jobs:
build-macos:
needs: [setup]
runs-on: namespace-profile-ghostty-macos
runs-on: namespace-profile-ghostty-macos-tahoe
timeout-minutes: 90
env:
GHOSTTY_VERSION: ${{ needs.setup.outputs.version }}
@ -121,22 +132,25 @@ jobs:
GHOSTTY_COMMIT: ${{ needs.setup.outputs.commit }}
steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: cachix/install-nix-action@v30
- uses: DeterminateSystems/nix-installer-action@main
with:
nix_path: nixpkgs=channel:nixos-unstable
- uses: cachix/cachix-action@v15
determinate: true
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
with:
name: ghostty
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
- name: XCode Select
run: sudo xcode-select -s /Applications/Xcode_16.0.app
run: sudo xcode-select -s /Applications/Xcode_26.0.app
- name: Xcode Version
run: xcodebuild -version
- name: Setup Sparkle
env:
SPARKLE_VERSION: 2.6.4
SPARKLE_VERSION: 2.7.3
run: |
mkdir -p .action/sparkle
cd .action/sparkle
@ -151,6 +165,7 @@ jobs:
nix develop -c \
zig build \
-Doptimize=ReleaseFast \
-Demit-macos-app=false \
-Dversion-string=${GHOSTTY_VERSION}
# The native app is built with native XCode tooling. This also does
@ -221,14 +236,16 @@ jobs:
- name: "Notarize DMG"
env:
PROD_MACOS_NOTARIZATION_APPLE_ID: ${{ secrets.PROD_MACOS_NOTARIZATION_APPLE_ID }}
PROD_MACOS_NOTARIZATION_TEAM_ID: ${{ secrets.PROD_MACOS_NOTARIZATION_TEAM_ID }}
PROD_MACOS_NOTARIZATION_PWD: ${{ secrets.PROD_MACOS_NOTARIZATION_PWD }}
APPLE_NOTARIZATION_ISSUER: ${{ secrets.APPLE_NOTARIZATION_ISSUER }}
APPLE_NOTARIZATION_KEY_ID: ${{ secrets.APPLE_NOTARIZATION_KEY_ID }}
APPLE_NOTARIZATION_KEY: ${{ secrets.APPLE_NOTARIZATION_KEY }}
run: |
# Store the notarization credentials so that we can prevent a UI password dialog
# from blocking the CI
echo "Create keychain profile"
xcrun notarytool store-credentials "notarytool-profile" --apple-id "$PROD_MACOS_NOTARIZATION_APPLE_ID" --team-id "$PROD_MACOS_NOTARIZATION_TEAM_ID" --password "$PROD_MACOS_NOTARIZATION_PWD"
echo "$APPLE_NOTARIZATION_KEY" > notarization_key.p8
xcrun notarytool store-credentials "notarytool-profile" --key notarization_key.p8 --key-id "$APPLE_NOTARIZATION_KEY_ID" --issuer "$APPLE_NOTARIZATION_ISSUER"
rm notarization_key.p8
# Here we send the notarization request to the Apple's Notarization service, waiting for the result.
# This typically takes a few seconds inside a CI environment, but it might take more depending on the App
@ -252,7 +269,7 @@ jobs:
zip -9 -r --symlinks ../../../ghostty-macos-universal-dsym.zip Ghostty.app.dSYM/
- name: Upload artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: macos
path: |-
@ -269,7 +286,7 @@ jobs:
curl -sL https://sentry.io/get-cli/ | bash
- name: Download macOS Artifacts
uses: actions/download-artifact@v4
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
name: macos
@ -281,7 +298,7 @@ jobs:
appcast:
needs: [setup, build-macos]
runs-on: namespace-profile-ghostty-macos
runs-on: namespace-profile-ghostty-macos-tahoe
env:
GHOSTTY_VERSION: ${{ needs.setup.outputs.version }}
GHOSTTY_BUILD: ${{ needs.setup.outputs.build }}
@ -289,16 +306,16 @@ jobs:
GHOSTTY_COMMIT_LONG: ${{ needs.setup.outputs.commit_long }}
steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Download macOS Artifacts
uses: actions/download-artifact@v4
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
name: macos
- name: Setup Sparkle
env:
SPARKLE_VERSION: 2.6.4
SPARKLE_VERSION: 2.7.3
run: |
mkdir -p .action/sparkle
cd .action/sparkle
@ -323,7 +340,7 @@ jobs:
mv appcast_new.xml appcast.xml
- name: Upload artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: sparkle
path: |-
@ -340,17 +357,17 @@ jobs:
GHOSTTY_VERSION: ${{ needs.setup.outputs.version }}
steps:
- name: Download macOS Artifacts
uses: actions/download-artifact@v4
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
name: macos
- name: Download Sparkle Artifacts
uses: actions/download-artifact@v4
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
name: sparkle
- name: Download Source Tarball Artifacts
uses: actions/download-artifact@v4
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
name: source-tarball
@ -370,7 +387,7 @@ jobs:
mv Ghostty.dmg blob/${GHOSTTY_VERSION}/Ghostty.dmg
mv appcast.xml blob/${GHOSTTY_VERSION}/appcast-staged.xml
- name: Upload to R2
uses: ryand56/r2-upload-action@latest
uses: ryand56/r2-upload-action@b801a390acbdeb034c5e684ff5e1361c06639e7c # v1.4
with:
r2-account-id: ${{ secrets.CF_R2_RELEASE_ACCOUNT_ID }}
r2-access-key-id: ${{ secrets.CF_R2_RELEASE_AWS_KEY }}

View File

@ -15,11 +15,58 @@ concurrency:
cancel-in-progress: false
jobs:
setup:
if: |
github.event_name == 'workflow_dispatch' ||
(
github.repository_owner == 'ghostty-org' &&
github.ref_name == 'main'
)
runs-on: namespace-profile-ghostty-sm
outputs:
should_skip: ${{ steps.check.outputs.should_skip }}
build: ${{ steps.extract_build_info.outputs.build }}
commit: ${{ steps.extract_build_info.outputs.commit }}
commit_long: ${{ steps.extract_build_info.outputs.commit_long }}
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
# Important so that build number generation works
fetch-depth: 0
- uses: cachix/install-nix-action@4e002c8ec80594ecd40e759629461e26c8abed15 # v31.9.0
with:
nix_path: nixpkgs=channel:nixos-unstable
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
with:
name: ghostty
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
- name: Extract build info
id: extract_build_info
run: |
GHOSTTY_BUILD=$(git rev-list --count HEAD)
GHOSTTY_COMMIT=$(git rev-parse --short HEAD)
GHOSTTY_COMMIT_LONG=$(git rev-parse HEAD)
echo "build=$GHOSTTY_BUILD" >> $GITHUB_OUTPUT
echo "commit=$GHOSTTY_COMMIT" >> $GITHUB_OUTPUT
echo "commit_long=$GHOSTTY_COMMIT_LONG" >> $GITHUB_OUTPUT
- name: Check if tip already exists
id: check
run: |
GHOSTTY_COMMIT_LONG=$(git rev-parse HEAD)
if nix develop -c nu .github/scripts/ghostty-tip $GHOSTTY_COMMIT_LONG; then
echo "Tip release already exists for commit $GHOSTTY_COMMIT_LONG"
echo "should_skip=true" >> $GITHUB_OUTPUT
else
echo "No tip release found for commit $GHOSTTY_COMMIT_LONG"
echo "should_skip=false" >> $GITHUB_OUTPUT
fi
tag:
runs-on: namespace-profile-ghostty-sm
needs: [build-macos]
needs: [setup, build-macos]
if: needs.setup.outputs.should_skip != 'true'
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Tip Tag
run: |
git config user.name "github-actions[bot]"
@ -29,9 +76,12 @@ jobs:
sentry-dsym-debug-slow:
runs-on: namespace-profile-ghostty-sm
needs: [build-macos-debug-slow]
needs: [setup, build-macos-debug-slow]
if: needs.setup.outputs.should_skip != 'true'
env:
GHOSTTY_COMMIT_LONG: ${{ needs.setup.outputs.commit_long }}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Install sentry-cli
run: |
@ -39,7 +89,6 @@ jobs:
- name: Download dSYM
run: |
GHOSTTY_COMMIT_LONG=$(git rev-parse HEAD)
curl -L https://tip.files.ghostty.dev/${GHOSTTY_COMMIT_LONG}/ghostty-macos-universal-debug-slow-dsym.zip > dsym.zip
- name: Upload dSYM to Sentry
@ -50,9 +99,12 @@ jobs:
sentry-dsym-debug-fast:
runs-on: namespace-profile-ghostty-sm
needs: [build-macos-debug-fast]
needs: [setup, build-macos-debug-fast]
if: needs.setup.outputs.should_skip != 'true'
env:
GHOSTTY_COMMIT_LONG: ${{ needs.setup.outputs.commit_long }}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Install sentry-cli
run: |
@ -60,7 +112,6 @@ jobs:
- name: Download dSYM
run: |
GHOSTTY_COMMIT_LONG=$(git rev-parse HEAD)
curl -L https://tip.files.ghostty.dev/${GHOSTTY_COMMIT_LONG}/ghostty-macos-universal-debug-fast-dsym.zip > dsym.zip
- name: Upload dSYM to Sentry
@ -71,9 +122,12 @@ jobs:
sentry-dsym:
runs-on: namespace-profile-ghostty-sm
needs: [build-macos]
needs: [setup, build-macos]
if: needs.setup.outputs.should_skip != 'true'
env:
GHOSTTY_COMMIT_LONG: ${{ needs.setup.outputs.commit_long }}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Install sentry-cli
run: |
@ -81,7 +135,6 @@ jobs:
- name: Download dSYM
run: |
GHOSTTY_COMMIT_LONG=$(git rev-parse HEAD)
curl -L https://tip.files.ghostty.dev/${GHOSTTY_COMMIT_LONG}/ghostty-macos-universal-dsym.zip > dsym.zip
- name: Upload dSYM to Sentry
@ -91,34 +144,49 @@ jobs:
sentry-cli dif upload --project ghostty --wait dsym.zip
source-tarball:
needs: [setup]
if: |
${{
needs.setup.outputs.should_skip != 'true' &&
(
github.event_name == 'workflow_dispatch' ||
(
github.event.workflow_run.conclusion == 'success' &&
github.repository_owner == 'ghostty-org' &&
github.ref_name == 'main'
)
}}
)
runs-on: namespace-profile-ghostty-md
env:
ZIG_LOCAL_CACHE_DIR: /zig/local-cache
ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
steps:
- uses: actions/checkout@v4
- uses: cachix/install-nix-action@v30
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Setup Cache
uses: namespacelabs/nscloud-cache-action@446d8f390563cd54ca27e8de5bdb816f63c0b706 # v1.2.21
with:
path: |
/nix
/zig
- uses: cachix/install-nix-action@4e002c8ec80594ecd40e759629461e26c8abed15 # v31.9.0
with:
nix_path: nixpkgs=channel:nixos-unstable
- uses: cachix/cachix-action@v15
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
with:
name: ghostty
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
- name: Create Tarball
run: git archive --format=tgz --prefix=ghostty-source/ -o ghostty-source.tar.gz HEAD
run: |
rm -rf zig-out/dist
nix develop -c zig build distcheck
cp zig-out/dist/*.tar.gz ghostty-source.tar.gz
- name: Sign Tarball
run: |
echo -n "${{ secrets.MINISIGN_KEY }}" > minisign.key
echo -n "${{ secrets.MINISIGN_PASSWORD }}" > minisign.password
nix develop -c minisign -S -m ghostty-source.tar.gz -s minisign.key < minisign.password
- name: Update Release
uses: softprops/action-gh-release@v2
uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b # v2.5.0
with:
name: 'Ghostty Tip ("Nightly")'
prerelease: true
@ -130,41 +198,49 @@ jobs:
token: ${{ secrets.GH_RELEASE_TOKEN }}
build-macos:
needs: [setup]
if: |
${{
needs.setup.outputs.should_skip != 'true' &&
(
github.event_name == 'workflow_dispatch' ||
(
github.event.workflow_run.conclusion == 'success' &&
github.repository_owner == 'ghostty-org' &&
github.ref_name == 'main'
)
}}
)
runs-on: namespace-profile-ghostty-macos
runs-on: namespace-profile-ghostty-macos-tahoe
timeout-minutes: 90
env:
GHOSTTY_BUILD: ${{ needs.setup.outputs.build }}
GHOSTTY_COMMIT: ${{ needs.setup.outputs.commit }}
GHOSTTY_COMMIT_LONG: ${{ needs.setup.outputs.commit_long }}
steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
# Important so that build number generation works
fetch-depth: 0
# Install Nix and use that to run our tests so our environment matches exactly.
- uses: cachix/install-nix-action@v30
# TODO(tahoe): https://github.com/NixOS/nix/issues/13342
- uses: DeterminateSystems/nix-installer-action@main
with:
nix_path: nixpkgs=channel:nixos-unstable
- uses: cachix/cachix-action@v15
determinate: true
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
with:
name: ghostty
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
- name: XCode Select
run: sudo xcode-select -s /Applications/Xcode_16.0.app
run: sudo xcode-select -s /Applications/Xcode_26.0.app
- name: Xcode Version
run: xcodebuild -version
# Setup Sparkle
- name: Setup Sparkle
env:
SPARKLE_VERSION: 2.6.4
SPARKLE_VERSION: 2.7.3
run: |
mkdir -p .action/sparkle
cd .action/sparkle
@ -172,17 +248,10 @@ jobs:
unzip sparkle.zip
echo "$(pwd)/bin" >> $GITHUB_PATH
# Load Build Number
- name: Build Number
run: |
echo "GHOSTTY_BUILD=$(git rev-list --count head)" >> $GITHUB_ENV
echo "GHOSTTY_COMMIT=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
echo "GHOSTTY_COMMIT_LONG=$(git rev-parse HEAD)" >> $GITHUB_ENV
# GhosttyKit is the framework that is built from Zig for our native
# Mac app to access. Build this in release mode.
- name: Build GhosttyKit
run: nix develop -c zig build -Doptimize=ReleaseFast
run: nix develop -c zig build -Doptimize=ReleaseFast -Demit-macos-app=false
# The native app is built with native XCode tooling. This also does
# codesigning. IMPORTANT: this must NOT run in a Nix environment.
@ -253,14 +322,16 @@ jobs:
- name: "Notarize DMG"
env:
PROD_MACOS_NOTARIZATION_APPLE_ID: ${{ secrets.PROD_MACOS_NOTARIZATION_APPLE_ID }}
PROD_MACOS_NOTARIZATION_TEAM_ID: ${{ secrets.PROD_MACOS_NOTARIZATION_TEAM_ID }}
PROD_MACOS_NOTARIZATION_PWD: ${{ secrets.PROD_MACOS_NOTARIZATION_PWD }}
APPLE_NOTARIZATION_ISSUER: ${{ secrets.APPLE_NOTARIZATION_ISSUER }}
APPLE_NOTARIZATION_KEY_ID: ${{ secrets.APPLE_NOTARIZATION_KEY_ID }}
APPLE_NOTARIZATION_KEY: ${{ secrets.APPLE_NOTARIZATION_KEY }}
run: |
# Store the notarization credentials so that we can prevent a UI password dialog
# from blocking the CI
echo "Create keychain profile"
xcrun notarytool store-credentials "notarytool-profile" --apple-id "$PROD_MACOS_NOTARIZATION_APPLE_ID" --team-id "$PROD_MACOS_NOTARIZATION_TEAM_ID" --password "$PROD_MACOS_NOTARIZATION_PWD"
echo "$APPLE_NOTARIZATION_KEY" > notarization_key.p8
xcrun notarytool store-credentials "notarytool-profile" --key notarization_key.p8 --key-id "$APPLE_NOTARIZATION_KEY_ID" --issuer "$APPLE_NOTARIZATION_ISSUER"
rm notarization_key.p8
# Here we send the notarization request to the Apple's Notarization service, waiting for the result.
# This typically takes a few seconds inside a CI environment, but it might take more depending on the App
@ -285,7 +356,7 @@ jobs:
# Update Release
- name: Release
uses: softprops/action-gh-release@v2
uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b # v2.5.0
with:
name: 'Ghostty Tip ("Nightly")'
prerelease: true
@ -298,6 +369,9 @@ jobs:
# Create our appcast for Sparkle
- name: Generate Appcast
if: |
github.repository_owner == 'ghostty-org' &&
github.ref_name == 'main'
env:
SPARKLE_KEY: ${{ secrets.PROD_MACOS_SPARKLE_KEY }}
run: |
@ -317,7 +391,7 @@ jobs:
cp Ghostty.dmg blob/${GHOSTTY_COMMIT_LONG}/Ghostty.dmg
- name: Upload to R2
uses: ryand56/r2-upload-action@latest
uses: ryand56/r2-upload-action@b801a390acbdeb034c5e684ff5e1361c06639e7c # v1.4
with:
r2-account-id: ${{ secrets.CF_R2_TIP_ACCOUNT_ID }}
r2-access-key-id: ${{ secrets.CF_R2_TIP_AWS_KEY }}
@ -329,13 +403,19 @@ jobs:
# Now upload our appcast. This ensures that the appcast never
# gets out of sync with the binaries.
- name: Prep R2 Storage for Appcast
if: |
github.repository_owner == 'ghostty-org' &&
github.ref_name == 'main'
run: |
rm -r blob
mkdir blob
cp appcast_new.xml blob/appcast.xml
- name: Upload Appcast to R2
uses: ryand56/r2-upload-action@latest
if: |
github.repository_owner == 'ghostty-org' &&
github.ref_name == 'main'
uses: ryand56/r2-upload-action@b801a390acbdeb034c5e684ff5e1361c06639e7c # v1.4
with:
r2-account-id: ${{ secrets.CF_R2_TIP_ACCOUNT_ID }}
r2-access-key-id: ${{ secrets.CF_R2_TIP_AWS_KEY }}
@ -344,42 +424,57 @@ jobs:
source-dir: blob
destination-dir: ./
- name: Echo Release URLs
run: |
echo "Release URLs:"
echo " App Bundle: https://tip.files.ghostty.org/${GHOSTTY_COMMIT_LONG}/ghostty-macos-universal.zip"
echo " Debug Symbols: https://tip.files.ghostty.org/${GHOSTTY_COMMIT_LONG}/ghostty-macos-universal-dsym.zip"
echo " DMG: https://tip.files.ghostty.org/${GHOSTTY_COMMIT_LONG}/Ghostty.dmg"
build-macos-debug-slow:
needs: [setup]
if: |
${{
needs.setup.outputs.should_skip != 'true' &&
(
github.event_name == 'workflow_dispatch' ||
(
github.event.workflow_run.conclusion == 'success' &&
github.repository_owner == 'ghostty-org' &&
github.ref_name == 'main'
)
}}
)
runs-on: namespace-profile-ghostty-macos
runs-on: namespace-profile-ghostty-macos-tahoe
timeout-minutes: 90
env:
GHOSTTY_BUILD: ${{ needs.setup.outputs.build }}
GHOSTTY_COMMIT: ${{ needs.setup.outputs.commit }}
GHOSTTY_COMMIT_LONG: ${{ needs.setup.outputs.commit_long }}
steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
# Important so that build number generation works
fetch-depth: 0
# Install Nix and use that to run our tests so our environment matches exactly.
- uses: cachix/install-nix-action@v30
# TODO(tahoe): https://github.com/NixOS/nix/issues/13342
- uses: DeterminateSystems/nix-installer-action@main
with:
nix_path: nixpkgs=channel:nixos-unstable
- uses: cachix/cachix-action@v15
determinate: true
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
with:
name: ghostty
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
- name: XCode Select
run: sudo xcode-select -s /Applications/Xcode_16.0.app
run: sudo xcode-select -s /Applications/Xcode_26.0.app
- name: Xcode Version
run: xcodebuild -version
# Setup Sparkle
- name: Setup Sparkle
env:
SPARKLE_VERSION: 2.5.1
SPARKLE_VERSION: 2.7.3
run: |
mkdir -p .action/sparkle
cd .action/sparkle
@ -387,17 +482,10 @@ jobs:
unzip sparkle.zip
echo "$(pwd)/bin" >> $GITHUB_PATH
# Load Build Number
- name: Build Number
run: |
echo "GHOSTTY_BUILD=$(git rev-list --count head)" >> $GITHUB_ENV
echo "GHOSTTY_COMMIT=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
echo "GHOSTTY_COMMIT_LONG=$(git rev-parse HEAD)" >> $GITHUB_ENV
# GhosttyKit is the framework that is built from Zig for our native
# Mac app to access. Build this in release mode.
- name: Build GhosttyKit
run: nix develop -c zig build -Doptimize=Debug
run: nix develop -c zig build -Doptimize=Debug -Demit-macos-app=false
# The native app is built with native XCode tooling. This also does
# codesigning. IMPORTANT: this must NOT run in a Nix environment.
@ -457,14 +545,16 @@ jobs:
- name: "Notarize app bundle"
env:
PROD_MACOS_NOTARIZATION_APPLE_ID: ${{ secrets.PROD_MACOS_NOTARIZATION_APPLE_ID }}
PROD_MACOS_NOTARIZATION_TEAM_ID: ${{ secrets.PROD_MACOS_NOTARIZATION_TEAM_ID }}
PROD_MACOS_NOTARIZATION_PWD: ${{ secrets.PROD_MACOS_NOTARIZATION_PWD }}
APPLE_NOTARIZATION_ISSUER: ${{ secrets.APPLE_NOTARIZATION_ISSUER }}
APPLE_NOTARIZATION_KEY_ID: ${{ secrets.APPLE_NOTARIZATION_KEY_ID }}
APPLE_NOTARIZATION_KEY: ${{ secrets.APPLE_NOTARIZATION_KEY }}
run: |
# Store the notarization credentials so that we can prevent a UI password dialog
# from blocking the CI
echo "Create keychain profile"
xcrun notarytool store-credentials "notarytool-profile" --apple-id "$PROD_MACOS_NOTARIZATION_APPLE_ID" --team-id "$PROD_MACOS_NOTARIZATION_TEAM_ID" --password "$PROD_MACOS_NOTARIZATION_PWD"
echo "$APPLE_NOTARIZATION_KEY" > notarization_key.p8
xcrun notarytool store-credentials "notarytool-profile" --key notarization_key.p8 --key-id "$APPLE_NOTARIZATION_KEY_ID" --issuer "$APPLE_NOTARIZATION_ISSUER"
rm notarization_key.p8
# We can't notarize an app bundle directly, but we need to compress it as an archive.
# Therefore, we create a zip file containing our app bundle, so that we can send it to the
@ -493,7 +583,7 @@ jobs:
# Update Release
- name: Release
uses: softprops/action-gh-release@v2
uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b # v2.5.0
with:
name: 'Ghostty Tip ("Nightly")'
prerelease: true
@ -510,7 +600,7 @@ jobs:
cp ghostty-macos-universal-debug-slow.zip blob/${GHOSTTY_COMMIT_LONG}/ghostty-macos-universal-debug-slow.zip
cp ghostty-macos-universal-debug-slow-dsym.zip blob/${GHOSTTY_COMMIT_LONG}/ghostty-macos-universal-debug-slow-dsym.zip
- name: Upload to R2
uses: ryand56/r2-upload-action@latest
uses: ryand56/r2-upload-action@b801a390acbdeb034c5e684ff5e1361c06639e7c # v1.4
with:
r2-account-id: ${{ secrets.CF_R2_TIP_ACCOUNT_ID }}
r2-access-key-id: ${{ secrets.CF_R2_TIP_AWS_KEY }}
@ -519,42 +609,56 @@ jobs:
source-dir: blob
destination-dir: ./
- name: Echo Release URLs
run: |
echo "Release URLs:"
echo " App Bundle: https://tip.files.ghostty.org/${GHOSTTY_COMMIT_LONG}/ghostty-macos-universal-debug-slow.zip"
echo " Debug Symbols: https://tip.files.ghostty.org/${GHOSTTY_COMMIT_LONG}/ghostty-macos-universal-debug-slow-dsym.zip"
build-macos-debug-fast:
needs: [setup]
if: |
${{
needs.setup.outputs.should_skip != 'true' &&
(
github.event_name == 'workflow_dispatch' ||
(
github.event.workflow_run.conclusion == 'success' &&
github.repository_owner == 'ghostty-org' &&
github.ref_name == 'main'
)
}}
)
runs-on: namespace-profile-ghostty-macos
runs-on: namespace-profile-ghostty-macos-tahoe
timeout-minutes: 90
env:
GHOSTTY_BUILD: ${{ needs.setup.outputs.build }}
GHOSTTY_COMMIT: ${{ needs.setup.outputs.commit }}
GHOSTTY_COMMIT_LONG: ${{ needs.setup.outputs.commit_long }}
steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
# Important so that build number generation works
fetch-depth: 0
# Install Nix and use that to run our tests so our environment matches exactly.
- uses: cachix/install-nix-action@v30
# TODO(tahoe): https://github.com/NixOS/nix/issues/13342
- uses: DeterminateSystems/nix-installer-action@main
with:
nix_path: nixpkgs=channel:nixos-unstable
- uses: cachix/cachix-action@v15
determinate: true
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
with:
name: ghostty
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
- name: XCode Select
run: sudo xcode-select -s /Applications/Xcode_16.0.app
run: sudo xcode-select -s /Applications/Xcode_26.0.app
- name: Xcode Version
run: xcodebuild -version
# Setup Sparkle
- name: Setup Sparkle
env:
SPARKLE_VERSION: 2.5.1
SPARKLE_VERSION: 2.7.3
run: |
mkdir -p .action/sparkle
cd .action/sparkle
@ -562,17 +666,10 @@ jobs:
unzip sparkle.zip
echo "$(pwd)/bin" >> $GITHUB_PATH
# Load Build Number
- name: Build Number
run: |
echo "GHOSTTY_BUILD=$(git rev-list --count head)" >> $GITHUB_ENV
echo "GHOSTTY_COMMIT=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
echo "GHOSTTY_COMMIT_LONG=$(git rev-parse HEAD)" >> $GITHUB_ENV
# GhosttyKit is the framework that is built from Zig for our native
# Mac app to access. Build this in release mode.
- name: Build GhosttyKit
run: nix develop -c zig build -Doptimize=ReleaseSafe
run: nix develop -c zig build -Doptimize=ReleaseSafe -Demit-macos-app=false
# The native app is built with native XCode tooling. This also does
# codesigning. IMPORTANT: this must NOT run in a Nix environment.
@ -632,14 +729,16 @@ jobs:
- name: "Notarize app bundle"
env:
PROD_MACOS_NOTARIZATION_APPLE_ID: ${{ secrets.PROD_MACOS_NOTARIZATION_APPLE_ID }}
PROD_MACOS_NOTARIZATION_TEAM_ID: ${{ secrets.PROD_MACOS_NOTARIZATION_TEAM_ID }}
PROD_MACOS_NOTARIZATION_PWD: ${{ secrets.PROD_MACOS_NOTARIZATION_PWD }}
APPLE_NOTARIZATION_ISSUER: ${{ secrets.APPLE_NOTARIZATION_ISSUER }}
APPLE_NOTARIZATION_KEY_ID: ${{ secrets.APPLE_NOTARIZATION_KEY_ID }}
APPLE_NOTARIZATION_KEY: ${{ secrets.APPLE_NOTARIZATION_KEY }}
run: |
# Store the notarization credentials so that we can prevent a UI password dialog
# from blocking the CI
echo "Create keychain profile"
xcrun notarytool store-credentials "notarytool-profile" --apple-id "$PROD_MACOS_NOTARIZATION_APPLE_ID" --team-id "$PROD_MACOS_NOTARIZATION_TEAM_ID" --password "$PROD_MACOS_NOTARIZATION_PWD"
echo "$APPLE_NOTARIZATION_KEY" > notarization_key.p8
xcrun notarytool store-credentials "notarytool-profile" --key notarization_key.p8 --key-id "$APPLE_NOTARIZATION_KEY_ID" --issuer "$APPLE_NOTARIZATION_ISSUER"
rm notarization_key.p8
# We can't notarize an app bundle directly, but we need to compress it as an archive.
# Therefore, we create a zip file containing our app bundle, so that we can send it to the
@ -668,7 +767,7 @@ jobs:
# Update Release
- name: Release
uses: softprops/action-gh-release@v2
uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b # v2.5.0
with:
name: 'Ghostty Tip ("Nightly")'
prerelease: true
@ -685,7 +784,7 @@ jobs:
cp ghostty-macos-universal-debug-fast.zip blob/${GHOSTTY_COMMIT_LONG}/ghostty-macos-universal-debug-fast.zip
cp ghostty-macos-universal-debug-fast-dsym.zip blob/${GHOSTTY_COMMIT_LONG}/ghostty-macos-universal-debug-fast-dsym.zip
- name: Upload to R2
uses: ryand56/r2-upload-action@latest
uses: ryand56/r2-upload-action@b801a390acbdeb034c5e684ff5e1361c06639e7c # v1.4
with:
r2-account-id: ${{ secrets.CF_R2_TIP_ACCOUNT_ID }}
r2-access-key-id: ${{ secrets.CF_R2_TIP_AWS_KEY }}
@ -693,3 +792,9 @@ jobs:
r2-bucket: ghostty-tip
source-dir: blob
destination-dir: ./
- name: Echo Release URLs
run: |
echo "Release URLs:"
echo " App Bundle: https://tip.files.ghostty.org/${GHOSTTY_COMMIT_LONG}/ghostty-macos-universal-debug-fast.zip"
echo " Debug Symbols: https://tip.files.ghostty.org/${GHOSTTY_COMMIT_LONG}/ghostty-macos-universal-debug-fast-dsym.zip"

59
.github/workflows/snap.yml vendored Normal file
View File

@ -0,0 +1,59 @@
on:
workflow_dispatch:
inputs:
source-run-id:
description: run id of the workflow that generated the artifact
required: true
type: string
source-artifact-id:
description: source tarball built during build-dist
required: true
type: string
name: Snap
jobs:
build:
strategy:
fail-fast: false
matrix:
os:
[namespace-profile-ghostty-snap, namespace-profile-ghostty-snap-arm64]
runs-on: ${{ matrix.os }}
timeout-minutes: 45
env:
ZIG_LOCAL_CACHE_DIR: /zig/local-cache
ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
steps:
- name: Download Source Tarball Artifacts
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
run-id: ${{ inputs.source-run-id }}
artifact-ids: ${{ inputs.source-artifact-id }}
github-token: ${{ github.token }}
- name: Extract tarball
run: |
mkdir dist
tar --verbose --extract --strip-components 1 --directory dist --file ghostty-source.tar.gz
- name: Setup Cache
uses: namespacelabs/nscloud-cache-action@446d8f390563cd54ca27e8de5bdb816f63c0b706 # v1.2.21
with:
path: |
/nix
/zig
- run: sudo apt install -y udev
- run: sudo systemctl start systemd-udevd
# Workaround until this is fixed: https://github.com/canonical/lxd-pkg-snap/pull/789
- run: |
_LXD_SNAP_DEVCGROUP_CONFIG="/var/lib/snapd/cgroup/snap.lxd.device"
sudo mkdir -p /var/lib/snapd/cgroup
echo 'self-managed=true' | sudo tee "${_LXD_SNAP_DEVCGROUP_CONFIG}"
- uses: snapcore/action-build@3bdaa03e1ba6bf59a65f84a751d943d549a54e79 # v1.3.0
with:
path: dist

File diff suppressed because it is too large Load Diff

View File

@ -17,32 +17,53 @@ jobs:
ZIG_GLOBAL_CACHE_DIR: /zig/global-cache
steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
fetch-depth: 0
- name: Setup Cache
uses: namespacelabs/nscloud-cache-action@v1.2.0
uses: namespacelabs/nscloud-cache-action@446d8f390563cd54ca27e8de5bdb816f63c0b706 # v1.2.21
with:
path: |
/nix
/zig
- name: Setup Nix
uses: cachix/install-nix-action@v30
uses: cachix/install-nix-action@4e002c8ec80594ecd40e759629461e26c8abed15 # v31.9.0
with:
nix_path: nixpkgs=channel:nixos-unstable
- uses: cachix/cachix-action@v15
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
with:
name: ghostty
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
- name: Run zig fetch
id: zig_fetch
- name: Download colorschemes
id: download
env:
GH_TOKEN: ${{ github.token }}
run: |
UPSTREAM_REV="$(curl "https://api.github.com/repos/mbadolato/iTerm2-Color-Schemes/commits/master" | jq -r '.sha')"
nix develop -c zig fetch --save="iterm2_themes" "https://github.com/mbadolato/iTerm2-Color-Schemes/archive/$UPSTREAM_REV.tar.gz"
echo "upstream_rev=$UPSTREAM_REV" >> "$GITHUB_OUTPUT"
# Get the latest release from iTerm2-Color-Schemes
RELEASE_INFO=$(gh api repos/mbadolato/iTerm2-Color-Schemes/releases/latest)
TAG_NAME=$(echo "$RELEASE_INFO" | jq -r '.tag_name')
FILENAME="ghostty-themes-${TAG_NAME}.tgz"
mkdir -p upload
curl -L -o "upload/${FILENAME}" "https://github.com/mbadolato/iTerm2-Color-Schemes/releases/download/${TAG_NAME}/ghostty-themes.tgz"
echo "tag_name=$TAG_NAME" >> $GITHUB_OUTPUT
echo "filename=$FILENAME" >> $GITHUB_OUTPUT
- name: Upload to R2
uses: ryand56/r2-upload-action@b801a390acbdeb034c5e684ff5e1361c06639e7c # v1.4
with:
r2-account-id: ${{ secrets.CF_R2_DEPS_ACCOUNT_ID }}
r2-access-key-id: ${{ secrets.CF_R2_DEPS_AWS_KEY }}
r2-secret-access-key: ${{ secrets.CF_R2_DEPS_SECRET_KEY }}
r2-bucket: ghostty-deps
source-dir: upload
destination-dir: ./
- name: Run zig fetch
run: |
nix develop -c zig fetch --save="iterm2_themes" "https://deps.files.ghostty.org/${{ steps.download.outputs.filename }}"
- name: Update zig cache hash
run: |
@ -58,7 +79,7 @@ jobs:
run: nix build .#ghostty
- name: Create pull request
uses: peter-evans/create-pull-request@v7
uses: peter-evans/create-pull-request@98357b18bf14b5342f975ff684046ec3b2a07725 # v8.0.0
with:
title: Update iTerm2 colorschemes
base: main
@ -67,6 +88,9 @@ jobs:
add-paths: |
build.zig.zon
build.zig.zon.nix
build.zig.zon.txt
build.zig.zon.json
flatpak/zig-packages.json
body: |
Upstream revision: https://github.com/mbadolato/iTerm2-Color-Schemes/tree/${{ steps.zig_fetch.outputs.upstream_rev }}
Upstream release: https://github.com/mbadolato/iTerm2-Color-Schemes/releases/tag/${{ steps.download.outputs.tag_name }}
labels: dependencies

7
.gitignore vendored
View File

@ -5,17 +5,22 @@
.DS_Store
.vscode/
.direnv/
.envrc.local
.flatpak-builder/
zig-cache/
.zig-cache/
zig-out/
/result*
/.nixos-test-history
example/*.wasm
test/ghostty
test/cases/**/*.actual.png
flatpak/builddir/
flatpak/repo/
glad.zip
/Box_test.ppm
/Box_test_diff.ppm
/ghostty.qcow2
/build.zig.zon2json-lock
vgcore.*

View File

@ -11,6 +11,9 @@ zig-out/
# macos is managed by XCode GUI
macos/
# produced by Icon Composer on macOS
images/Ghostty.icon/icon.json
# website dev run
website/.next

34
AGENTS.md Normal file
View File

@ -0,0 +1,34 @@
# Agent Development Guide
A file for [guiding coding agents](https://agents.md/).
## Commands
- **Build:** `zig build`
- **Test (Zig):** `zig build test`
- **Test filter (Zig)**: `zig build test -Dtest-filter=<test name>`
- **Formatting (Zig)**: `zig fmt .`
- **Formatting (other)**: `prettier -w .`
## Directory Structure
- Shared Zig core: `src/`
- C API: `include`
- macOS app: `macos/`
- GTK (Linux and FreeBSD) app: `src/apprt/gtk`
## libghostty-vt
- Build: `zig build lib-vt`
- Build Wasm Module: `zig build lib-vt -Dtarget=wasm32-freestanding`
- Test: `zig build test-lib-vt`
- Test filter: `zig build test-lib-vt -Dtest-filter=<test name>`
- When working on libghostty-vt, do not build the full app.
- For C only changes, don't run the Zig tests. Build all the examples.
## macOS App
- Do not use `xcodebuild`
- Use `zig build` to build the macOS app and any shared Zig code
- Use `zig build run` to build and run the macOS app
- Run Xcode tests using `zig build test`

View File

@ -78,9 +78,19 @@
# the GTK apprt. Also includes X11/Wayland integrations and general
# Linux support.
#
# - @ghostty-org/localization/* - Anything related to localization
# for a specific locale.
#
# - @ghosty-org/localization/manager - Manage all localization tasks
# and tooling. They are not responsible for any specific locale but
# are responsible for the overall localization process and tooling.
#
# - @ghostty-org/macos - The Ghostty macOS app and any macOS-specific
# features, configurations, etc.
#
# - @ghostty-org/packaging/snap - Ghostty snap packaging
# (https://snapcraft.io/ghostty)
#
# - @ghostty-org/renderer - Ghostty rendering subsystem, including the
# rendering abstractions as well as specific renderers like OpenGL
# and Metal.
@ -138,12 +148,45 @@
# Shell
/src/shell-integration/ @ghostty-org/shell
/src/termio/shell-integration.zig @ghostty-org/shell
/src/termio/shell_integration.zig @ghostty-org/shell
# Terminal
/src/simd/ @ghostty-org/terminal
/src/input/KeyEncoder.zig @ghostty-org/terminal
/src/terminal/ @ghostty-org/terminal
/src/terminfo/ @ghostty-org/terminal
/src/termio/ @ghostty-org/terminal
/src/unicode/ @ghostty-org/terminal
/src/Surface.zig @ghostty-org/terminal
/src/surface_mouse.zig @ghostty-org/terminal
# Localization
/po/README_TRANSLATORS.md @ghostty-org/localization
/po/com.mitchellh.ghostty.pot @ghostty-org/localization
/po/ca_ES.UTF-8.po @ghostty-org/ca_ES
/po/de_DE.UTF-8.po @ghostty-org/de_DE
/po/es_BO.UTF-8.po @ghostty-org/es_BO
/po/es_AR.UTF-8.po @ghostty-org/es_AR
/po/fr_FR.UTF-8.po @ghostty-org/fr_FR
/po/hu_HU.UTF-8.po @ghostty-org/hu_HU
/po/id_ID.UTF-8.po @ghostty-org/id_ID
/po/ja_JP.UTF-8.po @ghostty-org/ja_JP
/po/mk_MK.UTF-8.po @ghostty-org/mk_MK
/po/nb_NO.UTF-8.po @ghostty-org/nb_NO
/po/nl_NL.UTF-8.po @ghostty-org/nl_NL
/po/pl_PL.UTF-8.po @ghostty-org/pl_PL
/po/pt_BR.UTF-8.po @ghostty-org/pt_BR
/po/ru_RU.UTF-8.po @ghostty-org/ru_RU
/po/tr_TR.UTF-8.po @ghostty-org/tr_TR
/po/uk_UA.UTF-8.po @ghostty-org/uk_UA
/po/zh_CN.UTF-8.po @ghostty-org/zh_CN
/po/ga_IE.UTF-8.po @ghostty-org/ga_IE
/po/ko_KR.UTF-8.po @ghostty-org/ko_KR
/po/he_IL.UTF-8.po @ghostty-org/he_IL
/po/it_IT.UTF-8.po @ghostty-org/it_IT
/po/lt_LT.UTF-8.po @ghostty-org/lt_LT
/po/zh_TW.UTF-8.po @ghostty-org/zh_TW
/po/hr_HR.UTF-8.po @ghostty-org/hr_HR
# Packaging - Snap
/snap/ @ghostty-org/snap

View File

@ -1,9 +1,9 @@
# Ghostty Development Process
# Contributing to Ghostty
This document describes the development process for Ghostty. It is intended for
anyone considering opening an **issue** or **pull request**. If in doubt,
please open a [discussion](https://github.com/ghostty-org/ghostty/discussions);
we can always convert that to an issue later.
This document describes the process of contributing to Ghostty. It is intended
for anyone considering opening an **issue**, **discussion** or **pull request**.
For people who are interested in developing Ghostty and technical details behind
it, please check out our ["Developing Ghostty"](HACKING.md) document as well.
> [!NOTE]
>
@ -13,33 +13,188 @@ we can always convert that to an issue later.
> time to fixing bugs, maintaining features, and reviewing code, I do kindly
> ask you spend a few minutes reading this document. Thank you. ❤️
## AI Assistance Notice
> [!IMPORTANT]
>
> The Ghostty project allows AI-**assisted** _code contributions_, which
> must be properly disclosed in the pull request.
If you are using any kind of AI assistance while contributing to Ghostty,
**this must be disclosed in the pull request**, along with the extent to
which AI assistance was used (e.g. docs only vs. code generation).
The submitter must have also tested the pull request on all impacted
platforms, and it's **highly discouraged** to code for an unfamiliar platform
with AI assistance alone: if you only have a macOS machine, do **not** ask AI
to write the equivalent GTK code, and vice versa — someone else with more
expertise will eventually get to it and do it for you.
> [!WARNING]
> **Note that AI _assistance_ does not equal AI _generation_**. We require
> a significant amount of human accountability, involvement and interaction
> even within AI-assisted contributions. Contributors are required to be able
> to understand the AI-assisted output, reason with it and answer critical
> questions about it. Should a PR see no visible human accountability and
> involvement, or it is so broken that it requires significant rework to be
> acceptable, **we reserve the right to close it without hesitation**.
**In addition, we currently restrict AI assistance to code changes only.**
No AI-generated media, e.g. artwork, icons, videos and other assets is
allowed, as it goes against the methodology and ethos behind Ghostty.
While AI-assisted code can help with productive prototyping, creative
inspiration and even automated bugfinding, we have currently found zero
benefit to AI-generated assets. Instead, we are far more interested and
invested in funding professional work done by human designers and artists.
If you intend to submit AI-generated assets to Ghostty, sorry,
we are not interested.
Likewise, all community interactions, including all comments on issues and
discussions and all PR titles and descriptions **must be composed by a human**.
Community moderators and Ghostty maintainers reserve the right to mark
AI-generated responses as spam or disruptive content, and ban users who have
been repeatedly caught relying entirely on LLMs during interactions.
> [!NOTE]
> If your English isn't the best and you are currently relying on an LLM to
> translate your responses, don't fret — usually we maintainers will be able
> to understand your messages well enough. We'd like to encourage real humans
> to interact with each other more, and the positive impact of genuine,
> responsive yet imperfect human interaction more than makes up for any
> language barrier.
>
> Please write your responses yourself, to the best of your ability.
> If you do feel the need to polish your sentences, however, please use
> dedicated translation software rather than an LLM.
>
> We greatly appreciate it. Thank you. ❤️
Minor exceptions to this policy include trivial AI-generated tab completion
functionality, as it usually does not impact the quality of the code and
do not need to be disclosed, and commit titles and messages, which are often
generated by AI coding agents.
An example disclosure:
> This PR was written primarily by Claude Code.
Or a more detailed disclosure:
> I consulted ChatGPT to understand the codebase but the solution
> was fully authored manually by myself.
An example of a **problematic** disclosure (not having tested all platforms):
> I used Amp to code both macOS and GTK UIs, but I have not yet tested
> the GTK UI as I don't have a Linux setup.
Failure to disclose this is first and foremost rude to the human operators
on the other end of the pull request, but it also makes it difficult to
determine how much scrutiny to apply to the contribution.
In a perfect world, AI assistance would produce equal or higher quality
work than any human. That isn't the world we live in today, and in most cases
it's generating slop. I say this despite being a fan of and using them
successfully myself (with heavy supervision)!
Please be respectful to maintainers and disclose AI assistance.
## Quick Guide
**I'd like to contribute!**
### I'd like to contribute
All issues are actionable. Pick one and start working on it. Thank you.
If you need help or guidance, comment on the issue. Issues that are extra
friendly to new contributors are tagged with "contributor friendly".
[All issues are actionable](#issues-are-actionable). Pick one and start
working on it. Thank you. If you need help or guidance, comment on the issue.
Issues that are extra friendly to new contributors are tagged with
["contributor friendly"].
**I have a bug!**
["contributor friendly"]: https://github.com/ghostty-org/ghostty/issues?q=is%3Aissue%20is%3Aopen%20label%3A%22contributor%20friendly%22
1. Search the issue tracker and discussions for similar issues.
2. If you don't have steps to reproduce, open a discussion.
3. If you have steps to reproduce, open an issue.
### I'd like to translate Ghostty to my language
**I have an idea for a feature!**
We have written a [Translator's Guide](po/README_TRANSLATORS.md) for
everyone interested in contributing translations to Ghostty.
Translations usually do not need to go through the process of issue triage
and you can submit pull requests directly, although please make sure that
our [Style Guide](po/README_TRANSLATORS.md#style-guide) is followed before
submission.
1. Open a discussion.
### I have a bug! / Something isn't working
**I've implemented a feature!**
First, search the issue tracker and discussions for similar issues. Tip: also
search for [closed issues] and [discussions] — your issue might have already
been fixed!
1. If there is an issue for the feature, open a pull request.
> [!NOTE]
>
> If there is an _open_ issue or discussion that matches your problem,
> **please do not comment on it unless you have valuable insight to add**.
>
> GitHub has a very _noisy_ set of default notification settings which
> sends an email to _every participant_ in an issue/discussion every time
> someone adds a comment. Instead, use the handy upvote button for discussions,
> and/or emoji reactions on both discussions and issues, which are a visible
> yet non-disruptive way to show your support.
If your issue hasn't been reported already, open an ["Issue Triage"] discussion
and make sure to fill in the template **completely**. They are vital for
maintainers to figure out important details about your setup.
> [!WARNING]
>
> A _very_ common mistake is to file a bug report either as a Q&A or a Feature
> Request. **Please don't do this.** Otherwise, maintainers would have to ask
> for your system information again manually, and sometimes they will even ask
> you to create a new discussion because of how few detailed information is
> required for other discussion types compared to Issue Triage.
>
> Because of this, please make sure that you _only_ use the "Issue Triage"
> category for reporting bugs — thank you!
[closed issues]: https://github.com/ghostty-org/ghostty/issues?q=is%3Aissue%20state%3Aclosed
[discussions]: https://github.com/ghostty-org/ghostty/discussions?discussions_q=is%3Aclosed
["Issue Triage"]: https://github.com/ghostty-org/ghostty/discussions/new?category=issue-triage
### I have an idea for a feature
Like bug reports, first search through both issues and discussions and try to
find if your feature has already been requested. Otherwise, open a discussion
in the ["Feature Requests, Ideas"] category.
["Feature Requests, Ideas"]: https://github.com/ghostty-org/ghostty/discussions/new?category=feature-requests-ideas
### I've implemented a feature
1. If there is an issue for the feature, open a pull request straight away.
2. If there is no issue, open a discussion and link to your branch.
3. If you want to live dangerously, open a pull request and hope for the best.
3. If you want to live dangerously, open a pull request and
[hope for the best](#pull-requests-implement-an-issue).
**I have a question!**
### I have a question which is neither a bug report nor a feature request
1. Open a discussion or use Discord.
Open an [Q&A discussion], or join our [Discord Server] and ask away in the
`#help` forum channel.
Do not use the `#terminals` or `#development` channels to ask for help —
those are for general discussion about terminals and Ghostty development
respectively. If you do ask a question there, you will be redirected to
`#help` instead.
> [!NOTE]
> If your question is about a missing feature, please open a discussion under
> the ["Feature Requests, Ideas"] category. If Ghostty is behaving
> unexpectedly, use the ["Issue Triage"] category.
>
> The "Q&A" category is strictly for other kinds of discussions and do not
> require detailed information unlike the two other categories, meaning that
> maintainers would have to spend the extra effort to ask for basic information
> if you submit a bug report under this category.
>
> Therefore, please **pay attention to the category** before opening
> discussions to save us all some time and energy. Thank you!
[Q&A discussion]: https://github.com/ghostty-org/ghostty/discussions/new?category=q-a
[Discord Server]: https://discord.gg/ghostty
## General Patterns
@ -86,6 +241,32 @@ pull request will be accepted with a high degree of certainty.
> working on Ghostty.** If you're a user reporting an issue, you can
> ignore the rest of this document.
## Including and Updating Translations
See the [Contributor's Guide](po/README_CONTRIBUTORS.md) for more details.
## Checking for Memory Leaks
While Zig does an amazing job of finding and preventing memory leaks,
Ghostty uses many third-party libraries that are written in C. Improper usage
of those libraries or bugs in those libraries can cause memory leaks that
Zig cannot detect by itself.
### On Linux
On Linux the recommended tool to check for memory leaks is Valgrind. The
recommended way to run Valgrind is via `zig build`:
```sh
zig build run-valgrind
```
This builds a Ghostty executable with Valgrind support and runs Valgrind
with the proper flags to ensure we're suppressing known false positives.
You can combine the same build args with `run-valgrind` that you can with
`run`, such as specifying additional configurations after a trailing `--`.
## Input Stack Testing
The input stack is the part of the codebase that starts with a
@ -245,7 +426,7 @@ recreated the next time you run the VM.
We welcome the contribution of new VM definitions, as long as they meet the following criteria:
1. The should be different enough from existing VM definitions that they represent a distinct
1. They should be different enough from existing VM definitions that they represent a distinct
user (and developer) experience.
2. There's a significant Ghostty user population that uses a similar environment.
3. The VMs can be built using only packages from the current stable NixOS release.
@ -257,3 +438,60 @@ We welcome the contribution of new VM definitions, as long as they meet the foll
2. VMs should not expose any services to the network, or run any remote access
software like SSH daemons, VNC or RDP.
3. VMs should auto-login using the "ghostty" user.
## Nix VM Integration Tests
Several Nix VM tests are provided by the project for testing Ghostty in a "live"
environment rather than just unit tests.
Running these requires a working Nix installation, either Nix on your
favorite Linux distribution, NixOS, or macOS with nix-darwin installed. Further
requirements for macOS are detailed below.
### Linux
1. Check out the Ghostty source and change to the directory.
2. Run `nix run .#check.<system>.<test-name>.driver`. `<system>` should be
`x86_64-linux` or `aarch64-linux` (even on macOS, this launches a Linux
VM, not a macOS one). `<test-name>` should be one of the tests defined in
`nix/tests.nix`. The test will build and then launch. Depending on the speed
of your system, this can take a while. Eventually though the test should
complete. Hopefully successfully, but if not error messages should be printed
out that can be used to diagnose the issue.
3. To run _all_ of the tests, run `nix flake check`.
### macOS
1. To run the VMs on macOS you will need to enable the Linux builder in your `nix-darwin`
config. This _should_ be as simple as adding `nix.linux-builder.enable=true` to your
configuration and then rebuilding. See [this](https://nixcademy.com/posts/macos-linux-builder/)
blog post for more information about the Linux builder and how to tune the performance.
2. Once the Linux builder has been enabled, you should be able to follow the Linux instructions
above to launch a test.
### Interactively Running Test VMs
To run a test interactively, run `nix run
.#check.<system>.<test-name>.driverInteractive`. This will load a Python console
that can be used to manage the test VMs. In this console run `start_all()` to
start the VM(s). The VMs should boot up and a window should appear showing the
VM's console.
For more information about the Nix test console, see [the NixOS manual](https://nixos.org/manual/nixos/stable/index.html#sec-call-nixos-test-outside-nixos)
### SSH Access to Test VMs
Some test VMs are configured to allow outside SSH access for debugging. To
access the VM, use a command like the following:
```
ssh -o StrictHostKeyChecking=accept-new -o UserKnownHostsFile=/dev/null -p 2222 root@192.168.122.1
ssh -o StrictHostKeyChecking=accept-new -o UserKnownHostsFile=/dev/null -p 2222 ghostty@192.168.122.1
```
The SSH options are important because the SSH host keys will be regenerated
every time the test is started. Without them, your personal SSH known hosts file
will become difficult to manage. The port that is needed to access the VM may
change depending on the test.
None of the users in the VM have passwords so do not expose these VMs to the Internet.

92
Doxyfile Normal file
View File

@ -0,0 +1,92 @@
# Doxyfile 1.13.2
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = "libghostty"
PROJECT_LOGO = images/gnome/64.png
INPUT = include/ghostty
INPUT_ENCODING = UTF-8
RECURSIVE = YES
FILE_PATTERNS = *.h
EXAMPLE_PATH = example
EXAMPLE_RECURSIVE = YES
EXAMPLE_PATTERNS = *
FULL_PATH_NAMES = NO
STRIP_FROM_INC_PATH = include
SOURCE_BROWSER = YES
INLINE_SOURCES = NO
REFERENCES_RELATION = YES
REFERENCED_BY_RELATION = YES
#---------------------------------------------------------------------------
# Preprocessor
#---------------------------------------------------------------------------
# Enable preprocessing to handle #ifdef guards
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = YES
EXPAND_ONLY_PREDEF = YES
PREDEFINED = __wasm__
#---------------------------------------------------------------------------
# C API Optimization
#---------------------------------------------------------------------------
# Optimize output for C API documentation
OPTIMIZE_OUTPUT_FOR_C = YES
TYPEDEF_HIDES_STRUCT = YES
HIDE_SCOPE_NAMES = YES
# Clean path names
FULL_PATH_NAMES = NO
STRIP_FROM_PATH = .
STRIP_FROM_INC_PATH = include
# Hide undocumented and internal APIs
HIDE_UNDOC_MEMBERS = YES
HIDE_UNDOC_CLASSES = YES
EXTRACT_ALL = NO
INTERNAL_DOCS = NO
EXTRACT_PRIVATE = NO
EXTRACT_LOCAL_CLASSES = NO
#---------------------------------------------------------------------------
# HTML Output
#---------------------------------------------------------------------------
GENERATE_HTML = YES
HTML_OUTPUT = zig-out/share/ghostty/doc/libghostty
HTML_EXTRA_STYLESHEET = dist/doxygen/ghostty.css
HTML_EXTRA_FILES = dist/doxygen/favicon.png \
dist/doxygen/mobile-nav.js
HTML_COLORSTYLE = DARK
HTML_CODE_FOLDING = NO
HTML_HEADER = dist/doxygen/header.html
LAYOUT_FILE = DoxygenLayout.xml
GENERATE_TREEVIEW = YES
HTML_DYNAMIC_SECTIONS = YES
SEARCHENGINE = YES
ALPHABETICAL_INDEX = YES
HTML_TIMESTAMP = NO
DISABLE_INDEX = NO
FULL_SIDEBAR = NO
#---------------------------------------------------------------------------
# Graphs and Diagrams
#---------------------------------------------------------------------------
HAVE_DOT = NO
#---------------------------------------------------------------------------
# Man Output
#---------------------------------------------------------------------------
GENERATE_MAN = YES
MAN_OUTPUT = zig-out/share/man
MAN_EXTENSION = .3
MAN_LINKS = YES
#---------------------------------------------------------------------------
# Other Output
#---------------------------------------------------------------------------
GENERATE_LATEX = NO

247
DoxygenLayout.xml Normal file
View File

@ -0,0 +1,247 @@
<?xml version="1.0" encoding="UTF-8"?>
<doxygenlayout version="2.0">
<!-- Generated by doxygen 1.14.0 -->
<!-- Navigation index tabs for HTML output -->
<navindex>
<tab type="mainpage" visible="yes" title=""/>
<tab type="pages" visible="yes" title="" intro=""/>
<tab type="topics" visible="yes" title="" intro=""/>
<tab type="modules" visible="yes" title="API Groups" intro="">
<tab type="modulelist" visible="yes" title="" intro=""/>
<tab type="modulemembers" visible="yes" title="" intro=""/>
</tab>
<tab type="structs" visible="yes" title="Data Types" intro="">
<tab type="structlist" visible="yes" title="" intro=""/>
<tab type="structindex" visible="$ALPHABETICAL_INDEX" title=""/>
</tab>
<tab type="files" visible="yes" title="C Headers" intro="">
<tab type="filelist" visible="yes" title="" intro=""/>
<tab type="globals" visible="yes" title="" intro=""/>
</tab>
<tab type="examples" visible="yes" title="" intro=""/>
</navindex>
<!-- Layout definition for a class page -->
<class>
<briefdescription visible="yes"/>
<includes visible="$SHOW_HEADERFILE"/>
<inheritancegraph visible="yes"/>
<collaborationgraph visible="yes"/>
<memberdecl>
<nestedclasses visible="yes" title=""/>
<publictypes visible="yes" title=""/>
<services visible="yes" title=""/>
<interfaces visible="yes" title=""/>
<publicslots visible="yes" title=""/>
<signals visible="yes" title=""/>
<publicmethods visible="yes" title=""/>
<publicstaticmethods visible="yes" title=""/>
<publicattributes visible="yes" title=""/>
<publicstaticattributes visible="yes" title=""/>
<protectedtypes visible="yes" title=""/>
<protectedslots visible="yes" title=""/>
<protectedmethods visible="yes" title=""/>
<protectedstaticmethods visible="yes" title=""/>
<protectedattributes visible="yes" title=""/>
<protectedstaticattributes visible="yes" title=""/>
<packagetypes visible="yes" title=""/>
<packagemethods visible="yes" title=""/>
<packagestaticmethods visible="yes" title=""/>
<packageattributes visible="yes" title=""/>
<packagestaticattributes visible="yes" title=""/>
<properties visible="yes" title=""/>
<events visible="yes" title=""/>
<privatetypes visible="yes" title=""/>
<privateslots visible="yes" title=""/>
<privatemethods visible="yes" title=""/>
<privatestaticmethods visible="yes" title=""/>
<privateattributes visible="yes" title=""/>
<privatestaticattributes visible="yes" title=""/>
<friends visible="yes" title=""/>
<related visible="yes" title="" subtitle=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription visible="yes" title=""/>
<memberdef>
<inlineclasses visible="yes" title=""/>
<typedefs visible="yes" title=""/>
<enums visible="yes" title=""/>
<services visible="yes" title=""/>
<interfaces visible="yes" title=""/>
<constructors visible="yes" title=""/>
<functions visible="yes" title=""/>
<related visible="yes" title=""/>
<variables visible="yes" title=""/>
<properties visible="yes" title=""/>
<events visible="yes" title=""/>
</memberdef>
<allmemberslink visible="yes"/>
<usedfiles visible="$SHOW_USED_FILES"/>
<authorsection visible="yes"/>
</class>
<!-- Layout definition for a namespace page -->
<namespace>
<briefdescription visible="yes"/>
<memberdecl>
<nestednamespaces visible="yes" title=""/>
<constantgroups visible="yes" title=""/>
<interfaces visible="yes" title=""/>
<classes visible="yes" title=""/>
<concepts visible="yes" title=""/>
<structs visible="yes" title=""/>
<exceptions visible="yes" title=""/>
<typedefs visible="yes" title=""/>
<sequences visible="yes" title=""/>
<dictionaries visible="yes" title=""/>
<enums visible="yes" title=""/>
<functions visible="yes" title=""/>
<variables visible="yes" title=""/>
<properties visible="yes" title=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription visible="yes" title=""/>
<memberdef>
<inlineclasses visible="yes" title=""/>
<typedefs visible="yes" title=""/>
<sequences visible="yes" title=""/>
<dictionaries visible="yes" title=""/>
<enums visible="yes" title=""/>
<functions visible="yes" title=""/>
<variables visible="yes" title=""/>
<properties visible="yes" title=""/>
</memberdef>
<authorsection visible="yes"/>
</namespace>
<!-- Layout definition for a concept page -->
<concept>
<briefdescription visible="yes"/>
<includes visible="$SHOW_HEADERFILE"/>
<definition visible="yes" title=""/>
<detaileddescription visible="yes" title=""/>
<authorsection visible="yes"/>
</concept>
<!-- Layout definition for a file page -->
<file>
<briefdescription visible="yes"/>
<includes visible="$SHOW_INCLUDE_FILES"/>
<includegraph visible="yes"/>
<includedbygraph visible="yes"/>
<sourcelink visible="yes"/>
<memberdecl>
<interfaces visible="yes" title=""/>
<classes visible="yes" title=""/>
<structs visible="yes" title=""/>
<exceptions visible="yes" title=""/>
<namespaces visible="yes" title=""/>
<concepts visible="yes" title=""/>
<constantgroups visible="yes" title=""/>
<defines visible="yes" title=""/>
<typedefs visible="yes" title=""/>
<sequences visible="yes" title=""/>
<dictionaries visible="yes" title=""/>
<enums visible="yes" title=""/>
<functions visible="yes" title=""/>
<variables visible="yes" title=""/>
<properties visible="yes" title=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription visible="yes" title=""/>
<memberdef>
<inlineclasses visible="yes" title=""/>
<defines visible="yes" title=""/>
<typedefs visible="yes" title=""/>
<sequences visible="yes" title=""/>
<dictionaries visible="yes" title=""/>
<enums visible="yes" title=""/>
<functions visible="yes" title=""/>
<variables visible="yes" title=""/>
<properties visible="yes" title=""/>
</memberdef>
<authorsection/>
</file>
<!-- Layout definition for a group page -->
<group>
<briefdescription visible="yes"/>
<detaileddescription visible="yes" title=""/>
<memberdecl>
<nestedgroups visible="yes" title=""/>
<typedefs visible="yes" title=""/>
<enums visible="yes" title=""/>
<enumvalues visible="no" title=""/>
<functions visible="yes" title=""/>
<variables visible="yes" title=""/>
<defines visible="yes" title=""/>
<modules visible="yes" title=""/>
<dirs visible="yes" title=""/>
<files visible="yes" title=""/>
<namespaces visible="yes" title=""/>
<concepts visible="yes" title=""/>
<classes visible="yes" title=""/>
<sequences visible="yes" title=""/>
<dictionaries visible="yes" title=""/>
<signals visible="yes" title=""/>
<publicslots visible="yes" title=""/>
<protectedslots visible="yes" title=""/>
<privateslots visible="yes" title=""/>
<events visible="yes" title=""/>
<properties visible="yes" title=""/>
<friends visible="yes" title=""/>
<membergroups visible="yes"/>
</memberdecl>
<memberdef>
<pagedocs/>
<inlineclasses visible="yes" title=""/>
<typedefs visible="yes" title=""/>
<enums visible="yes" title=""/>
<enumvalues visible="yes" title=""/>
<functions visible="yes" title=""/>
<variables visible="yes" title=""/>
<defines visible="yes" title=""/>
<sequences visible="yes" title=""/>
<dictionaries visible="yes" title=""/>
<signals visible="yes" title=""/>
<publicslots visible="yes" title=""/>
<protectedslots visible="yes" title=""/>
<privateslots visible="yes" title=""/>
<events visible="yes" title=""/>
<properties visible="yes" title=""/>
<friends visible="yes" title=""/>
</memberdef>
<groupgraph visible="yes"/>
<authorsection visible="yes"/>
</group>
<!-- Layout definition for a C++20 module page -->
<module>
<briefdescription visible="yes"/>
<exportedmodules visible="yes"/>
<memberdecl>
<concepts visible="yes" title=""/>
<classes visible="yes" title=""/>
<enums visible="yes" title=""/>
<typedefs visible="yes" title=""/>
<functions visible="yes" title=""/>
<variables visible="yes" title=""/>
<membergroups visible="yes" title=""/>
</memberdecl>
<detaileddescription visible="yes" title=""/>
<memberdecl>
<files visible="yes"/>
</memberdecl>
</module>
<!-- Layout definition for a directory page -->
<directory>
<briefdescription visible="yes"/>
<directorygraph visible="yes"/>
<memberdecl>
<dirs visible="yes"/>
<files visible="yes"/>
</memberdecl>
<detaileddescription visible="yes" title=""/>
</directory>
</doxygenlayout>

383
HACKING.md Normal file
View File

@ -0,0 +1,383 @@
# Developing Ghostty
This document describes the technical details behind Ghostty's development.
If you'd like to open any pull requests or would like to implement new features
into Ghostty, please make sure to read our ["Contributing to Ghostty"](CONTRIBUTING.md)
document first.
To start development on Ghostty, you need to build Ghostty from a Git checkout,
which is very similar in process to [building Ghostty from a source tarball](http://ghostty.org/docs/install/build). One key difference is that obviously
you need to clone the Git repository instead of unpacking the source tarball:
```shell
git clone https://github.com/ghostty-org/ghostty
cd ghostty
```
> [!NOTE]
>
> Ghostty may require [extra dependencies](#extra-dependencies)
> when building from a Git checkout compared to a source tarball.
> Tip versions may also require a different version of Zig or other toolchains
> (e.g. the Xcode SDK on macOS) compared to stable versions — make sure to
> follow the steps closely!
When you're developing Ghostty, it's very likely that you will want to build a
_debug_ build to diagnose issues more easily. This is already the default for
Zig builds, so simply run `zig build` **without any `-Doptimize` flags**.
There are many more build steps than just `zig build`, some of which are listed
here:
| Command | Description |
| ------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `zig build run` | Runs Ghostty |
| `zig build run-valgrind` | Runs Ghostty under Valgrind to [check for memory leaks](#checking-for-memory-leaks) |
| `zig build test` | Runs unit tests (accepts `-Dtest-filter=<filter>` to only run tests whose name matches the filter) |
| `zig build update-translations` | Updates Ghostty's translation strings (see the [Contributor's Guide on Localizing Ghostty](po/README_CONTRIBUTORS.md)) |
| `zig build dist` | Builds a source tarball |
| `zig build distcheck` | Builds and validates a source tarball |
## Extra Dependencies
Building Ghostty from a Git checkout on Linux requires some additional
dependencies:
- `blueprint-compiler` (version 0.16.0 or newer)
macOS users don't require any additional dependencies.
## Xcode Version and SDKs
Building the Ghostty macOS app requires that Xcode, the macOS SDK,
the iOS SDK, and Metal Toolchain are all installed.
A common issue is that the incorrect version of Xcode is either
installed or selected. Use the `xcode-select` command to
ensure that the correct version of Xcode is selected:
```shell-session
sudo xcode-select --switch /Applications/Xcode.app
```
> [!IMPORTANT]
>
> Main branch development of Ghostty requires **Xcode 26 and the macOS 26 SDK**.
>
> You do not need to be running on macOS 26 to build Ghostty, you can
> still use Xcode 26 on macOS 15 stable.
## AI and Agents
If you're using AI assistance with Ghostty, Ghostty provides an
[AGENTS.md file](https://github.com/ghostty-org/ghostty/blob/main/AGENTS.md)
read by most of the popular AI agents to help produce higher quality
results.
We also provide commands in `.agents/commands` that have some vetted
prompts for common tasks that have been shown to produce good results.
We provide these to help reduce the amount of time a contributor has to
spend prompting the AI to get good results, and hopefully to lower the slop
produced.
- `/gh-issue <number/url>` - Produces a prompt for diagnosing a GitHub
issue, explaining the problem, and suggesting a plan for resolving it.
Requires `gh` to be installed with read-only access to Ghostty.
> [!WARNING]
>
> All AI assistance usage [must be disclosed](https://github.com/ghostty-org/ghostty/blob/main/CONTRIBUTING.md#ai-assistance-notice)
> and we expect contributors to understand the code that is produced and
> be able to answer questions about it. If you don't understand the
> code produced, feel free to disclose that, but if it has problems, we
> may ask you to fix it and close the issue. It isn't a maintainers job to
> review a PR so broken that it requires significant rework to be acceptable.
## Logging
Ghostty can write logs to a number of destinations. On all platforms, logging to
`stderr` is available. Depending on the platform and how Ghostty was launched,
logs sent to `stderr` may be stored by the system and made available for later
retrieval.
On Linux if Ghostty is launched by the default `systemd` user service, you can use
`journald` to see Ghostty's logs: `journalctl --user --unit app-com.mitchellh.ghostty.service`.
On macOS logging to the macOS unified log is available and enabled by default.
Use the system `log` CLI to view Ghostty's logs: `sudo log stream --level debug --predicate 'subsystem=="com.mitchellh.ghostty"'`.
Ghostty's logging can be configured in two ways. The first is by what
optimization level Ghostty is compiled with. If Ghostty is compiled with `Debug`
optimizations debug logs will be output to `stderr`. If Ghostty is compiled with
any other optimization the debug logs will not be output to `stderr`.
Ghostty also checks the `GHOSTTY_LOG` environment variable. It can be used
to control which destinations receive logs. Ghostty currently defines two
destinations:
- `stderr` - logging to `stderr`.
- `macos` - logging to macOS's unified log (has no effect on non-macOS platforms).
Combine values with a comma to enable multiple destinations. Prefix a
destination with `no-` to disable it. Enabling and disabling destinations
can be done at the same time. Setting `GHOSTTY_LOG` to `true` will enable all
destinations. Setting `GHOSTTY_LOG` to `false` will disable all destinations.
## Linting
### Prettier
Ghostty's docs and resources (not including Zig code) are linted using
[Prettier](https://prettier.io) with out-of-the-box settings. A Prettier CI
check will fail builds with improper formatting. Therefore, if you are
modifying anything Prettier will lint, you may want to install it locally and
run this from the repo root before you commit:
```
prettier --write .
```
Make sure your Prettier version matches the version of Prettier in [devShell.nix](https://github.com/ghostty-org/ghostty/blob/main/nix/devShell.nix).
Nix users can use the following command to format with Prettier:
```
nix develop -c prettier --write .
```
### Alejandra
Nix modules are formatted with [Alejandra](https://github.com/kamadorueda/alejandra/). An Alejandra CI check
will fail builds with improper formatting.
Nix users can use the following command to format with Alejandra:
```
nix develop -c alejandra .
```
Non-Nix users should install Alejandra and use the following command to format with Alejandra:
```
alejandra .
```
Make sure your Alejandra version matches the version of Alejandra in [devShell.nix](https://github.com/ghostty-org/ghostty/blob/main/nix/devShell.nix).
### Updating the Zig Cache Fixed-Output Derivation Hash
The Nix package depends on a [fixed-output
derivation](https://nix.dev/manual/nix/stable/language/advanced-attributes.html#adv-attr-outputHash)
that manages the Zig package cache. This allows the package to be built in the
Nix sandbox.
Occasionally (usually when `build.zig.zon` is updated), the hash that
identifies the cache will need to be updated. There are jobs that monitor the
hash in CI, and builds will fail if it drifts.
To update it, you can run the following in the repository root:
```
./nix/build-support/check-zig-cache.sh --update
```
This will write out the `nix/zigCacheHash.nix` file with the updated hash
that can then be committed and pushed to fix the builds.
## Including and Updating Translations
See the [Contributor's Guide](po/README_CONTRIBUTORS.md) for more details.
## Checking for Memory Leaks
While Zig does an amazing job of finding and preventing memory leaks,
Ghostty uses many third-party libraries that are written in C. Improper usage
of those libraries or bugs in those libraries can cause memory leaks that
Zig cannot detect by itself.
### On Linux
On Linux the recommended tool to check for memory leaks is Valgrind. The
recommended way to run Valgrind is via `zig build`:
```sh
zig build run-valgrind
```
This builds a Ghostty executable with Valgrind support and runs Valgrind
with the proper flags to ensure we're suppressing known false positives.
You can combine the same build args with `run-valgrind` that you can with
`run`, such as specifying additional configurations after a trailing `--`.
## Input Stack Testing
The input stack is the part of the codebase that starts with a
key event and ends with text encoding being sent to the pty (it
does not include _rendering_ the text, which is part of the
font or rendering stack).
If you modify any part of the input stack, you must manually verify
all the following input cases work properly. We unfortunately do
not automate this in any way, but if we can do that one day that'd
save a LOT of grief and time.
Note: this list may not be exhaustive, I'm still working on it.
### Linux IME
IME (Input Method Editors) are a common source of bugs in the input stack,
especially on Linux since there are multiple different IME systems
interacting with different windowing systems and application frameworks
all written by different organizations.
The following matrix should be tested to ensure that all IME input works
properly:
1. Wayland, X11
2. ibus, fcitx, none
3. Dead key input (e.g. Spanish), CJK (e.g. Japanese), Emoji, Unicode Hex
4. ibus versions: 1.5.29, 1.5.30, 1.5.31 (each exhibit slightly different behaviors)
> [!NOTE]
>
> This is a **work in progress**. I'm still working on this list and it
> is not complete. As I find more test cases, I will add them here.
#### Dead Key Input
Set your keyboard layout to "Spanish" (or another layout that uses dead keys).
1. Launch Ghostty
2. Press `'`
3. Press `a`
4. Verify that `á` is displayed
Note that the dead key may or may not show a preedit state visually.
For ibus and fcitx it does but for the "none" case it does not. Importantly,
the text should be correct when it is sent to the pty.
We should also test canceling dead key input:
1. Launch Ghostty
2. Press `'`
3. Press escape
4. Press `a`
5. Verify that `a` is displayed (no diacritic)
#### CJK Input
Configure fcitx or ibus with a keyboard layout like Japanese or Mozc. The
exact layout doesn't matter.
1. Launch Ghostty
2. Press `Ctrl+Shift` to switch to "Hiragana"
3. On a US physical layout, type: `konn`, you should see `こん` in preedit.
4. Press `Enter`
5. Verify that `こん` is displayed in the terminal.
We should also test switching input methods while preedit is active, which
should commit the text:
1. Launch Ghostty
2. Press `Ctrl+Shift` to switch to "Hiragana"
3. On a US physical layout, type: `konn`, you should see `こん` in preedit.
4. Press `Ctrl+Shift` to switch to another layout (any)
5. Verify that `こん` is displayed in the terminal as committed text.
## Nix Virtual Machines
Several Nix virtual machine definitions are provided by the project for testing
and developing Ghostty against multiple different Linux desktop environments.
Running these requires a working Nix installation, either Nix on your
favorite Linux distribution, NixOS, or macOS with nix-darwin installed. Further
requirements for macOS are detailed below.
VMs should only be run on your local desktop and then powered off when not in
use, which will discard any changes to the VM.
The VM definitions provide minimal software "out of the box" but additional
software can be installed by using standard Nix mechanisms like `nix run nixpkgs#<package>`.
### Linux
1. Check out the Ghostty source and change to the directory.
2. Run `nix run .#<vmtype>`. `<vmtype>` can be any of the VMs defined in the
`nix/vm` directory (without the `.nix` suffix) excluding any file prefixed
with `common` or `create`.
3. The VM will build and then launch. Depending on the speed of your system, this
can take a while, but eventually you should get a new VM window.
4. The Ghostty source directory should be mounted to `/tmp/shared` in the VM. Depending
on what UID and GID of the user that you launched the VM as, `/tmp/shared` _may_ be
writable by the VM user, so be careful!
### macOS
1. To run the VMs on macOS you will need to enable the Linux builder in your `nix-darwin`
config. This _should_ be as simple as adding `nix.linux-builder.enable=true` to your
configuration and then rebuilding. See [this](https://nixcademy.com/posts/macos-linux-builder/)
blog post for more information about the Linux builder and how to tune the performance.
2. Once the Linux builder has been enabled, you should be able to follow the Linux instructions
above to launch a VM.
### Custom VMs
To easily create a custom VM without modifying the Ghostty source, create a new
directory, then create a file called `flake.nix` with the following text in the
new directory.
```
{
inputs = {
nixpkgs.url = "nixpkgs/nixpkgs-unstable";
ghostty.url = "github:ghostty-org/ghostty";
};
outputs = {
nixpkgs,
ghostty,
...
}: {
nixosConfigurations.custom-vm = ghostty.create-gnome-vm {
nixpkgs = nixpkgs;
system = "x86_64-linux";
overlay = ghostty.overlays.releasefast;
# module = ./configuration.nix # also works
module = {pkgs, ...}: {
environment.systemPackages = [
pkgs.btop
];
};
};
};
}
```
The custom VM can then be run with a command like this:
```
nix run .#nixosConfigurations.custom-vm.config.system.build.vm
```
A file named `ghostty.qcow2` will be created that is used to persist any changes
made in the VM. To "reset" the VM to default delete the file and it will be
recreated the next time you run the VM.
### Contributing new VM definitions
#### VM Acceptance Criteria
We welcome the contribution of new VM definitions, as long as they meet the following criteria:
1. They should be different enough from existing VM definitions that they represent a distinct
user (and developer) experience.
2. There's a significant Ghostty user population that uses a similar environment.
3. The VMs can be built using only packages from the current stable NixOS release.
#### VM Definition Criteria
1. VMs should be as minimal as possible so that they build and launch quickly.
Additional software can be added at runtime with a command like `nix run nixpkgs#<package name>`.
2. VMs should not expose any services to the network, or run any remote access
software like SSH daemons, VNC or RDP.
3. VMs should auto-login using the "ghostty" user.

View File

@ -1,6 +1,6 @@
MIT License
Copyright (c) 2024 Mitchell Hashimoto
Copyright (c) 2024 Mitchell Hashimoto, Ghostty contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -22,7 +22,7 @@ vendor/glad/include/glad/glad.h: vendor/glad/include/glad/gl.h
clean:
rm -rf \
zig-out zig-cache \
zig-out .zig-cache \
macos/build \
macos/GhosttyKit.xcframework
.PHONY: clean

View File

@ -4,13 +4,12 @@ Ghostty relies on downstream package maintainers to distribute Ghostty to
end-users. This document provides guidance to package maintainers on how to
package Ghostty for distribution.
> [!NOTE]
> [!IMPORTANT]
>
> While Ghostty went through an extensive private beta testing period,
> packaging Ghostty is immature and may require additional build script
> tweaks and documentation improvement. I'm extremely motivated to work with
> package maintainers to improve the packaging process. Please open issues
> to discuss any packaging issues you encounter.
> This document is only accurate for the Ghostty source alongside it.
> **Do not use this document for older or newer versions of Ghostty!** If
> you are reading this document in a different version of Ghostty, please
> find the `PACKAGING.md` file alongside that version.
## Source Tarballs
@ -23,13 +22,6 @@ https://release.files.ghostty.org/VERSION/ghostty-VERSION.tar.gz
https://release.files.ghostty.org/VERSION/ghostty-VERSION.tar.gz.minisig
```
> [!NOTE]
>
> **Version 1.0.0 the filename is `ghostty-source.tar.gz`.** Future
> versions will use the `ghostty-VERSION.tar.gz` format since it is more
> typical for source tarballs. But for version 1.0.0, the filename is
> `ghostty-source.tar.gz`.
Signature files are signed with
[minisign](https://jedisct1.github.io/minisign/)
using the following public key:
@ -44,6 +36,19 @@ Use the `ghostty-source.tar.gz` asset and _not the GitHub auto-generated
source tarball_. These tarballs are generated for every commit to
the `main` branch and are not associated with a specific version.
> [!WARNING]
>
> Source tarballs are _not the same_ as a Git checkout. Source tarballs
> contain some preprocessed files that allow building Ghostty with less
> dependencies. If you are building Ghostty from a Git checkout, the
> steps below are the same but they may require additional dependencies
> not listed here. See the `README.md` for more information on building
> from a Git checkout.
>
> For everyone except Ghostty developers, please use the source tarballs.
> We generate tip source tarballs for users following the development
> branch.
## Zig Version
[Zig](https://ziglang.org) is required to build Ghostty. Prior to Zig 1.0,
@ -55,7 +60,7 @@ To find the version of Zig required to build Ghostty, check the `required_zig`
constant in `build.zig`. You don't need to know Zig to extract this information.
This version will always be an official released version of Zig.
For example, at the time of writing this document, Ghostty requires Zig 0.13.0.
For example, at the time of writing this document, Ghostty requires Zig 0.14.0.
## Building Ghostty
@ -117,11 +122,3 @@ relevant to package maintainers:
often necessary for system packages to specify a specific minimum Linux
version, glibc, etc. Run `zig targets` to a get a full list of available
targets.
> [!WARNING]
>
> **The GLFW runtime is not meant for distribution.** The GLFW runtime
> (`-Dapp-runtime=glfw`) is meant for development and testing only. It is
> missing many features, has known memory leak scenarios, known crashes,
> and more. Please do not package the GLFW-based Ghostty runtime for
> distribution.

115
README.md
View File

@ -13,7 +13,9 @@
·
<a href="https://ghostty.org/docs">Documentation</a>
·
<a href="#developing-ghostty">Developing</a>
<a href="CONTRIBUTING.md">Contributing</a>
·
<a href="HACKING.md">Developing</a>
</p>
</p>
@ -49,6 +51,14 @@ See the [download page](https://ghostty.org/download) on the Ghostty website.
See the [documentation](https://ghostty.org/docs) on the Ghostty website.
## Contributing and Developing
If you have any ideas, issues, etc. regarding Ghostty, or would like to
contribute to Ghostty through pull requests, please check out our
["Contributing to Ghostty"](CONTRIBUTING.md) document. Those who would like
to get involved with Ghostty's development as well should also read the
["Developing Ghostty"](HACKING.md) document for more technical details.
## Roadmap and Status
The high-level ambitious plan for the project, in order:
@ -134,16 +144,23 @@ In addition to being a standalone terminal emulator, Ghostty is a
C-compatible library for embedding a fast, feature-rich terminal emulator
in any 3rd party project. This library is called `libghostty`.
This goal is not hypothetical! The macOS app is a `libghostty` consumer.
Due to the scope of this project, we're breaking libghostty down into
separate actually libraries, starting with `libghostty-vt`. The goal of
this project is to focus on parsing terminal sequences and maintaining
terminal state. This is covered in more detail in this
[blog post](https://mitchellh.com/writing/libghostty-is-coming).
`libghostty-vt` is already available and usable today for Zig and C and
is compatible for macOS, Linux, Windows, and WebAssembly. At the time of
writing this, the API isn't stable yet and we haven't tagged an official
release, but the core logic is well proven (since Ghostty uses it) and
we're working hard on it now.
The ultimate goal is not hypothetical! The macOS app is a `libghostty` consumer.
The macOS app is a native Swift app developed in Xcode and `main()` is
within Swift. The Swift app links to `libghostty` and uses the C API to
render terminals.
This step encompasses expanding `libghostty` support to more platforms
and more use cases. At the time of writing this, `libghostty` is very
Mac-centric -- particularly around rendering -- and we have work to do to
expand this to other platforms.
## Crash Reports
Ghostty has a built-in crash reporter that will generate and save crash
@ -183,86 +200,4 @@ SENTRY_DSN=https://e914ee84fd895c4fe324afa3e53dac76@o4507352570920960.ingest.us.
> purposely contain sensitive information, but it does contain the full
> stack memory of each thread at the time of the crash. This information
> is used to rebuild the stack trace but can also contain sensitive data
> depending when the crash occurred.
## Developing Ghostty
See the documentation on the Ghostty website for
[building Ghostty from source](http://ghostty.org/docs/install/build).
For development, omit the `-Doptimize` flag to build a debug build.
On Linux or macOS, you can use `zig build -Dapp-runtime=glfw run` for a quick
GLFW-based app for a faster development cycle while developing core
terminal features. Note that this app is missing many features and is also
known to crash in certain scenarios, so it is only meant for development
tasks.
Other useful commands:
- `zig build test` for running unit tests.
- `zig build test -Dtest-filter=<filter>` for running a specific subset of those unit tests
- `zig build run -Dconformance=<name>` runs a conformance test case from
the `conformance` directory. The `name` is the name of the file. This runs
in the current running terminal emulator so if you want to check the
behavior of this project, you must run this command in Ghostty.
### Linting
#### Prettier
Ghostty's docs and resources (not including Zig code) are linted using
[Prettier](https://prettier.io) with out-of-the-box settings. A Prettier CI
check will fail builds with improper formatting. Therefore, if you are
modifying anything Prettier will lint, you may want to install it locally and
run this from the repo root before you commit:
```
prettier --write .
```
Make sure your Prettier version matches the version of Prettier in [devShell.nix](https://github.com/ghostty-org/ghostty/blob/main/nix/devShell.nix).
Nix users can use the following command to format with Prettier:
```
nix develop -c prettier --write .
```
#### Alejandra
Nix modules are formatted with [Alejandra](https://github.com/kamadorueda/alejandra/). An Alejandra CI check
will fail builds with improper formatting.
Nix users can use the following command to format with Alejanda:
```
nix develop -c alejandra .
```
Non-Nix users should install Alejandra and use the following command to format with Alejandra:
```
alejandra .
```
Make sure your Alejandra version matches the version of Alejandra in [devShell.nix](https://github.com/ghostty-org/ghostty/blob/main/nix/devShell.nix).
#### Updating the Zig Cache Fixed-Output Derivation Hash
The Nix package depends on a [fixed-output
derivation](https://nix.dev/manual/nix/stable/language/advanced-attributes.html#adv-attr-outputHash)
that manages the Zig package cache. This allows the package to be built in the
Nix sandbox.
Occasionally (usually when `build.zig.zon` is updated), the hash that
identifies the cache will need to be updated. There are jobs that monitor the
hash in CI, and builds will fail if it drifts.
To update it, you can run the following in the repository root:
```
./nix/build-support/check-zig-cache-hash.sh --update
```
This will write out the `nix/zigCacheHash.nix` file with the updated hash
that can then be committed and pushed to fix the builds.
> depending on when the crash occurred.

21
TODO.md
View File

@ -1,21 +0,0 @@
Performance:
- Loading fonts on startups should probably happen in multiple threads
Correctness:
- test wrap against wraptest: https://github.com/mattiase/wraptest
- automate this in some way
- Charsets: UTF-8 vs. ASCII mode
- we only support UTF-8 input right now
- need fallback glyphs if they're not supported
- can effect a crash using `vttest` menu `3 10` since it tries to parse
ASCII as UTF-8.
Mac:
- Preferences window
Major Features:
- Bell

338
build.zig
View File

@ -1,106 +1,320 @@
const std = @import("std");
const assert = std.debug.assert;
const builtin = @import("builtin");
const buildpkg = @import("src/build/main.zig");
const appVersion = @import("build.zig.zon").version;
const minimumZigVersion = @import("build.zig.zon").minimum_zig_version;
comptime {
buildpkg.requireZig("0.13.0");
buildpkg.requireZig(minimumZigVersion);
}
pub fn build(b: *std.Build) !void {
const config = try buildpkg.Config.init(b);
// This defines all the available build options (e.g. `-D`). If you
// want to know what options are available, you can run `--help` or
// you can read `src/build/Config.zig`.
// Ghostty resources like terminfo, shell integration, themes, etc.
const resources = try buildpkg.GhosttyResources.init(b, &config);
const config = try buildpkg.Config.init(b, appVersion);
const test_filters = b.option(
[][]const u8,
"test-filter",
"Filter for test. Only applies to Zig tests.",
) orelse &[0][]const u8{};
// Ghostty dependencies used by many artifacts.
const deps = try buildpkg.SharedDeps.init(b, &config);
// The modules exported for Zig consumers of libghostty. If you're
// writing a Zig program that uses libghostty, read this file.
const mod = try buildpkg.GhosttyZig.init(
b,
&config,
&deps,
);
// All our steps which we'll hook up later. The steps are shown
// up here just so that they are more self-documenting.
const libvt_step = b.step("lib-vt", "Build libghostty-vt");
const run_step = b.step("run", "Run the app");
const run_valgrind_step = b.step(
"run-valgrind",
"Run the app under valgrind",
);
const test_step = b.step("test", "Run tests");
const test_lib_vt_step = b.step(
"test-lib-vt",
"Run libghostty-vt tests",
);
const test_valgrind_step = b.step(
"test-valgrind",
"Run tests under valgrind",
);
const translations_step = b.step(
"update-translations",
"Update translation files",
);
// Ghostty resources like terminfo, shell integration, themes, etc.
const resources = try buildpkg.GhosttyResources.init(b, &config, &deps);
const i18n = if (config.i18n) try buildpkg.GhosttyI18n.init(b, &config) else null;
// Ghostty executable, the actual runnable Ghostty program.
const exe = try buildpkg.GhosttyExe.init(b, &config, &deps);
if (config.emit_helpgen) deps.help_strings.install();
// Ghostty docs
const docs = try buildpkg.GhosttyDocs.init(b, &deps);
if (config.emit_docs) {
const docs = try buildpkg.GhosttyDocs.init(b, &deps);
docs.install();
} else if (config.target.result.os.tag.isDarwin()) {
// If we aren't emitting docs we need to emit a placeholder so
// our macOS xcodeproject builds since it expects the `share/man`
// directory to exist to copy into the app bundle.
docs.installDummy(b.getInstallStep());
}
// Ghostty webdata
if (config.emit_webdata) {
const webdata = try buildpkg.GhosttyWebdata.init(b, &deps);
webdata.install();
}
const webdata = try buildpkg.GhosttyWebdata.init(b, &deps);
if (config.emit_webdata) webdata.install();
// Ghostty bench tools
if (config.emit_bench) {
const bench = try buildpkg.GhosttyBench.init(b, &deps);
bench.install();
const bench = try buildpkg.GhosttyBench.init(b, &deps);
if (config.emit_bench) bench.install();
// Ghostty dist tarball
const dist = try buildpkg.GhosttyDist.init(b, &config);
{
const step = b.step("dist", "Build the dist tarball");
step.dependOn(dist.install_step);
const check_step = b.step("distcheck", "Install and validate the dist tarball");
check_step.dependOn(dist.check_step);
check_step.dependOn(dist.install_step);
}
// If we're not building libghostty, then install the exe and resources.
// libghostty (internal, big)
const libghostty_shared = try buildpkg.GhosttyLib.initShared(
b,
&deps,
);
const libghostty_static = try buildpkg.GhosttyLib.initStatic(
b,
&deps,
);
// libghostty-vt
const libghostty_vt_shared = shared: {
if (config.target.result.cpu.arch.isWasm()) {
break :shared try buildpkg.GhosttyLibVt.initWasm(
b,
&mod,
);
}
break :shared try buildpkg.GhosttyLibVt.initShared(
b,
&mod,
);
};
libghostty_vt_shared.install(libvt_step);
libghostty_vt_shared.install(b.getInstallStep());
// Helpgen
if (config.emit_helpgen) deps.help_strings.install();
// Runtime "none" is libghostty, anything else is an executable.
if (config.app_runtime != .none) {
exe.install();
resources.install();
}
// Libghostty
//
// Note: libghostty is not stable for general purpose use. It is used
// heavily by Ghostty on macOS but it isn't built to be reusable yet.
// As such, these build steps are lacking. For example, the Darwin
// build only produces an xcframework.
if (config.app_runtime == .none) {
if (config.target.result.isDarwin()) darwin: {
if (!config.emit_xcframework) break :darwin;
// Build the xcframework
const xcframework = try buildpkg.GhosttyXCFramework.init(b, &deps);
xcframework.install();
// The xcframework build always installs resources because our
// macOS xcode project contains references to them.
if (config.emit_exe) {
exe.install();
resources.install();
if (i18n) |v| v.install();
}
} else {
// Libghostty
//
// Note: libghostty is not stable for general purpose use. It is used
// heavily by Ghostty on macOS but it isn't built to be reusable yet.
// As such, these build steps are lacking. For example, the Darwin
// build only produces an xcframework.
// If we aren't emitting docs we need to emit a placeholder so
// our macOS xcodeproject builds.
if (!config.emit_docs) {
var wf = b.addWriteFiles();
const path = "share/man/.placeholder";
const placeholder = wf.add(path, "emit-docs not true so no man pages");
b.getInstallStep().dependOn(&b.addInstallFile(placeholder, path).step);
}
} else {
const libghostty_shared = try buildpkg.GhosttyLib.initShared(b, &deps);
const libghostty_static = try buildpkg.GhosttyLib.initStatic(b, &deps);
// We shouldn't have this guard but we don't currently
// build on macOS this way ironically so we need to fix that.
if (!config.target.result.os.tag.isDarwin()) {
libghostty_shared.installHeader(); // Only need one header
libghostty_shared.install("libghostty.so");
libghostty_static.install("libghostty.a");
}
}
// Run runs the Ghostty exe
{
const run_cmd = b.addRunArtifact(exe.exe);
// macOS only artifacts. These will error if they're initialized for
// other targets.
if (config.target.result.os.tag.isDarwin()) {
// Ghostty xcframework
const xcframework = try buildpkg.GhosttyXCFramework.init(
b,
&deps,
config.xcframework_target,
);
if (config.emit_xcframework) {
xcframework.install();
// The xcframework build always installs resources because our
// macOS xcode project contains references to them.
resources.install();
if (i18n) |v| v.install();
}
// Ghostty macOS app
const macos_app = try buildpkg.GhosttyXcodebuild.init(
b,
&config,
.{
.xcframework = &xcframework,
.docs = &docs,
.i18n = if (i18n) |v| &v else null,
.resources = &resources,
},
);
if (config.emit_macos_app) {
macos_app.install();
}
}
// Run step
run: {
if (config.app_runtime != .none) {
const run_cmd = b.addRunArtifact(exe.exe);
if (b.args) |args| run_cmd.addArgs(args);
// Set the proper resources dir so things like shell integration
// work correctly. If we're running `zig build run` in Ghostty,
// this also ensures it overwrites the release one with our debug
// build.
run_cmd.setEnvironmentVariable(
"GHOSTTY_RESOURCES_DIR",
b.getInstallPath(.prefix, "share/ghostty"),
);
run_step.dependOn(&run_cmd.step);
break :run;
}
assert(config.app_runtime == .none);
// On macOS we can run the macOS app. For "run" we always force
// a native-only build so that we can run as quickly as possible.
if (config.target.result.os.tag.isDarwin()) {
const xcframework_native = try buildpkg.GhosttyXCFramework.init(
b,
&deps,
.native,
);
const macos_app_native_only = try buildpkg.GhosttyXcodebuild.init(
b,
&config,
.{
.xcframework = &xcframework_native,
.docs = &docs,
.i18n = if (i18n) |v| &v else null,
.resources = &resources,
},
);
// Run uses the native macOS app
run_step.dependOn(&macos_app_native_only.open.step);
// If we have no test filters, install the tests too
if (test_filters.len == 0) {
macos_app_native_only.addTestStepDependencies(test_step);
}
}
}
// Valgrind
if (config.app_runtime != .none) {
// We need to rebuild Ghostty with a baseline CPU target.
const valgrind_exe = exe: {
var valgrind_config = config;
valgrind_config.target = valgrind_config.baselineTarget();
break :exe try buildpkg.GhosttyExe.init(
b,
&valgrind_config,
&deps,
);
};
const run_cmd = b.addSystemCommand(&.{
"valgrind",
"--leak-check=full",
"--num-callers=50",
b.fmt("--suppressions={s}", .{b.pathFromRoot("valgrind.supp")}),
"--gen-suppressions=all",
});
run_cmd.addArtifactArg(valgrind_exe.exe);
if (b.args) |args| run_cmd.addArgs(args);
const run_step = b.step("run", "Run the app");
run_step.dependOn(&run_cmd.step);
run_valgrind_step.dependOn(&run_cmd.step);
}
// Zig module tests
{
const mod_vt_test = b.addTest(.{
.root_module = mod.vt,
.filters = test_filters,
});
const mod_vt_test_run = b.addRunArtifact(mod_vt_test);
test_lib_vt_step.dependOn(&mod_vt_test_run.step);
const mod_vt_c_test = b.addTest(.{
.root_module = mod.vt_c,
.filters = test_filters,
});
const mod_vt_c_test_run = b.addRunArtifact(mod_vt_c_test);
test_lib_vt_step.dependOn(&mod_vt_c_test_run.step);
}
// Tests
{
const test_step = b.step("test", "Run all tests");
const test_filter = b.option([]const u8, "test-filter", "Filter for test");
// Full unit tests
const test_exe = b.addTest(.{
.name = "ghostty-test",
.root_source_file = b.path("src/main.zig"),
.target = config.target,
.filter = test_filter,
.filters = test_filters,
.root_module = b.createModule(.{
.root_source_file = b.path("src/main.zig"),
.target = config.baselineTarget(),
.optimize = .Debug,
.strip = false,
.omit_frame_pointer = false,
.unwind_tables = .sync,
}),
// Crash on x86_64 without this
.use_llvm = true,
});
if (config.emit_test_exe) b.installArtifact(test_exe);
_ = try deps.add(test_exe);
{
if (config.emit_test_exe) b.installArtifact(test_exe);
_ = try deps.add(test_exe);
const test_run = b.addRunArtifact(test_exe);
test_step.dependOn(&test_run.step);
}
// Normal test running
const test_run = b.addRunArtifact(test_exe);
test_step.dependOn(&test_run.step);
// Normal tests always test our libghostty modules
//test_step.dependOn(test_lib_vt_step);
// Valgrind test running
const valgrind_run = b.addSystemCommand(&.{
"valgrind",
"--leak-check=full",
"--num-callers=50",
b.fmt("--suppressions={s}", .{b.pathFromRoot("valgrind.supp")}),
"--gen-suppressions=all",
});
valgrind_run.addArtifactArg(test_exe);
test_valgrind_step.dependOn(&valgrind_run.step);
}
// update-translations does what it sounds like and updates the "pot"
// files. These should be committed to the repo.
if (i18n) |v| {
translations_step.dependOn(v.update_step);
} else {
try translations_step.addError("cannot update translations when i18n is disabled", .{});
}
}

View File

@ -1,90 +1,124 @@
.{
.name = "ghostty",
.version = "1.1.2",
.name = .ghostty,
.version = "1.3.0-dev",
.paths = .{""},
.fingerprint = 0x64407a2a0b4147e5,
.minimum_zig_version = "0.15.2",
.dependencies = .{
// Zig libs
.libxev = .{
.url = "https://github.com/mitchellh/libxev/archive/31eed4e337fed7b0149319e5cdbb62b848c24fbd.tar.gz",
.hash = "1220ebf88622c4d502dc59e71347e4d28c47e033f11b59aff774ae5787565c40999c",
},
.mach_glfw = .{
.url = "https://github.com/mitchellh/mach-glfw/archive/37c2995f31abcf7e8378fba68ddcf4a3faa02de0.tar.gz",
.hash = "12206ed982e709e565d536ce930701a8c07edfd2cfdce428683f3f2a601d37696a62",
// mitchellh/libxev
.url = "https://deps.files.ghostty.org/libxev-34fa50878aec6e5fa8f532867001ab3c36fae23e.tar.gz",
.hash = "libxev-0.0.0-86vtc4IcEwCqEYxEYoN_3KXmc6A9VLcm22aVImfvecYs",
.lazy = true,
},
.vaxis = .{
.url = "git+https://github.com/rockorager/libvaxis/?ref=main#6d729a2dc3b934818dffe06d2ba3ce02841ed74b",
.hash = "12200df4ebeaed45de26cb2c9f3b6f3746d8013b604e035dae658f86f586c8c91d2f",
// rockorager/libvaxis
.url = "https://deps.files.ghostty.org/vaxis-7dbb9fd3122e4ffad262dd7c151d80d863b68558.tar.gz",
.hash = "vaxis-0.5.1-BWNV_LosCQAGmCCNOLljCIw6j6-yt53tji6n6rwJ2BhS",
.lazy = true,
},
.z2d = .{
.url = "git+https://github.com/vancluever/z2d?ref=v0.4.0#4638bb02a9dc41cc2fb811f092811f6a951c752a",
.hash = "12201f0d542e7541cf492a001d4d0d0155c92f58212fbcb0d224e95edeba06b5416a",
// vancluever/z2d
.url = "https://deps.files.ghostty.org/z2d-0.9.0-j5P_Hu-WFgA_JEfRpiFss6gdvcvS47cgOc0Via2eKD_T.tar.gz",
.hash = "z2d-0.9.0-j5P_Hu-WFgA_JEfRpiFss6gdvcvS47cgOc0Via2eKD_T",
.lazy = true,
},
.zig_objc = .{
.url = "https://github.com/mitchellh/zig-objc/archive/9b8ba849b0f58fe207ecd6ab7c147af55b17556e.tar.gz",
.hash = "1220e17e64ef0ef561b3e4b9f3a96a2494285f2ec31c097721bf8c8677ec4415c634",
// mitchellh/zig-objc
.url = "https://deps.files.ghostty.org/zig_objc-f356ed02833f0f1b8e84d50bed9e807bf7cdc0ae.tar.gz",
.hash = "zig_objc-0.0.0-Ir_Sp5gTAQCvxxR7oVIrPXxXwsfKgVP7_wqoOQrZjFeK",
.lazy = true,
},
.zig_js = .{
.url = "https://github.com/mitchellh/zig-js/archive/d0b8b0a57c52fbc89f9d9fecba75ca29da7dd7d1.tar.gz",
.hash = "12205a66d423259567764fa0fc60c82be35365c21aeb76c5a7dc99698401f4f6fefc",
// mitchellh/zig-js
.url = "https://deps.files.ghostty.org/zig_js-04db83c617da1956ac5adc1cb9ba1e434c1cb6fd.tar.gz",
.hash = "zig_js-0.0.0-rjCAV-6GAADxFug7rDmPH-uM_XcnJ5NmuAMJCAscMjhi",
.lazy = true,
},
.ziglyph = .{
.url = "https://deps.files.ghostty.org/ziglyph-b89d43d1e3fb01b6074bc1f7fc980324b04d26a5.tar.gz",
.hash = "12207831bce7d4abce57b5a98e8f3635811cfefd160bca022eb91fe905d36a02cf25",
.uucode = .{
// jacobsandlund/uucode
.url = "https://deps.files.ghostty.org/uucode-31655fba3c638229989cc524363ef5e3c7b580c1.tar.gz",
.hash = "uucode-0.1.0-ZZjBPicPTQDlG6OClzn2bPu7ICkkkyWrTB6aRsBr-A1E",
},
.zig_wayland = .{
.url = "https://deps.files.ghostty.org/zig-wayland-fbfe3b4ac0b472a27b1f1a67405436c58cbee12d.tar.gz",
.hash = "12209ca054cb1919fa276e328967f10b253f7537c4136eb48f3332b0f7cf661cad38",
// codeberg ifreund/zig-wayland
.url = "https://deps.files.ghostty.org/zig_wayland-1b5c038ec10da20ed3a15b0b2a6db1c21383e8ea.tar.gz",
.hash = "wayland-0.5.0-dev-lQa1khrMAQDJDwYFKpdH3HizherB7sHo5dKMECfvxQHe",
.lazy = true,
},
.zf = .{
.url = "git+https://github.com/natecraddock/zf/?ref=main#ed99ca18b02dda052e20ba467e90b623c04690dd",
.hash = "1220edc3b8d8bedbb50555947987e5e8e2f93871ca3c8e8d4cc8f1377c15b5dd35e8",
// natecraddock/zf
.url = "https://deps.files.ghostty.org/zf-3c52637b7e937c5ae61fd679717da3e276765b23.tar.gz",
.hash = "zf-0.10.3-OIRy8RuJAACKA3Lohoumrt85nRbHwbpMcUaLES8vxDnh",
.lazy = true,
},
.gobject = .{
.url = "https://github.com/ianprime0509/zig-gobject/releases/download/v0.2.2/bindings-gnome47.tar.zst",
.hash = "12208d70ee791d7ef7e16e1c3c9c1127b57f1ed066a24f87d57fc9f730c5dc394b9d",
// https://github.com/ghostty-org/zig-gobject based on zig_gobject
// Temporary until we generate them at build time automatically.
.url = "https://deps.files.ghostty.org/gobject-2025-11-08-23-1.tar.zst",
.hash = "gobject-0.3.0-Skun7ANLnwDvEfIpVmohcppXgOvg_I6YOJFmPIsKfXk-",
.lazy = true,
},
// C libs
.cimgui = .{ .path = "./pkg/cimgui" },
.fontconfig = .{ .path = "./pkg/fontconfig" },
.freetype = .{ .path = "./pkg/freetype" },
.harfbuzz = .{ .path = "./pkg/harfbuzz" },
.highway = .{ .path = "./pkg/highway" },
.libpng = .{ .path = "./pkg/libpng" },
.macos = .{ .path = "./pkg/macos" },
.oniguruma = .{ .path = "./pkg/oniguruma" },
.opengl = .{ .path = "./pkg/opengl" },
.sentry = .{ .path = "./pkg/sentry" },
.simdutf = .{ .path = "./pkg/simdutf" },
.utfcpp = .{ .path = "./pkg/utfcpp" },
.wuffs = .{ .path = "./pkg/wuffs" },
.zlib = .{ .path = "./pkg/zlib" },
.cimgui = .{ .path = "./pkg/cimgui", .lazy = true },
.fontconfig = .{ .path = "./pkg/fontconfig", .lazy = true },
.freetype = .{ .path = "./pkg/freetype", .lazy = true },
.gtk4_layer_shell = .{ .path = "./pkg/gtk4-layer-shell", .lazy = true },
.harfbuzz = .{ .path = "./pkg/harfbuzz", .lazy = true },
.highway = .{ .path = "./pkg/highway", .lazy = true },
.libintl = .{ .path = "./pkg/libintl", .lazy = true },
.libpng = .{ .path = "./pkg/libpng", .lazy = true },
.macos = .{ .path = "./pkg/macos", .lazy = true },
.oniguruma = .{ .path = "./pkg/oniguruma", .lazy = true },
.opengl = .{ .path = "./pkg/opengl", .lazy = true },
.sentry = .{ .path = "./pkg/sentry", .lazy = true },
.simdutf = .{ .path = "./pkg/simdutf", .lazy = true },
.utfcpp = .{ .path = "./pkg/utfcpp", .lazy = true },
.wuffs = .{ .path = "./pkg/wuffs", .lazy = true },
.zlib = .{ .path = "./pkg/zlib", .lazy = true },
// Shader translation
.glslang = .{ .path = "./pkg/glslang" },
.spirv_cross = .{ .path = "./pkg/spirv-cross" },
.glslang = .{ .path = "./pkg/glslang", .lazy = true },
.spirv_cross = .{ .path = "./pkg/spirv-cross", .lazy = true },
// Wayland
.wayland = .{
.url = "https://deps.files.ghostty.org/wayland-9cb3d7aa9dc995ffafdbdef7ab86a949d0fb0e7d.tar.gz",
.hash = "12202cdac858abc52413a6c6711d5026d2d3c8e13f95ca2c327eade0736298bb021f",
.hash = "N-V-__8AAKrHGAAs2shYq8UkE6bGcR1QJtLTyOE_lcosMn6t",
.lazy = true,
},
.wayland_protocols = .{
.url = "https://deps.files.ghostty.org/wayland-protocols-258d8f88f2c8c25a830c6316f87d23ce1a0f12d9.tar.gz",
.hash = "12201a57c6ce0001aa034fa80fba3e1cd2253c560a45748f4f4dd21ff23b491cddef",
.hash = "N-V-__8AAKw-DAAaV8bOAAGqA0-oD7o-HNIlPFYKRXSPT03S",
.lazy = true,
},
.plasma_wayland_protocols = .{
.url = "git+https://github.com/KDE/plasma-wayland-protocols?ref=main#db525e8f9da548cffa2ac77618dd0fbe7f511b86",
.hash = "12207e0851c12acdeee0991e893e0132fc87bb763969a585dc16ecca33e88334c566",
.url = "https://deps.files.ghostty.org/plasma_wayland_protocols-12207e0851c12acdeee0991e893e0132fc87bb763969a585dc16ecca33e88334c566.tar.gz",
.hash = "N-V-__8AAKYZBAB-CFHBKs3u4JkeiT4BMvyHu3Y5aaWF3Bbs",
.lazy = true,
},
// Fonts
.jetbrains_mono = .{
.url = "https://deps.files.ghostty.org/JetBrainsMono-2.304.tar.gz",
.hash = "N-V-__8AAIC5lwAVPJJzxnCAahSvZTIlG-HhtOvnM1uh-66x",
.lazy = true,
},
.nerd_fonts_symbols_only = .{
.url = "https://deps.files.ghostty.org/NerdFontsSymbolsOnly-3.4.0.tar.gz",
.hash = "N-V-__8AAMVLTABmYkLqhZPLXnMl-KyN38R8UVYqGrxqO26s",
.lazy = true,
},
// Other
.apple_sdk = .{ .path = "./pkg/apple-sdk" },
.iterm2_themes = .{
.url = "https://github.com/mbadolato/iTerm2-Color-Schemes/archive/db227d159adc265818f2e898da0f70ef8d7b580e.tar.gz",
.hash = "12203d2647e5daf36a9c85b969e03f422540786ce9ea624eb4c26d204fe1f46218f3",
.url = "https://github.com/mbadolato/iTerm2-Color-Schemes/releases/download/release-20251201-150531-bfb3ee1/ghostty-themes.tgz",
.hash = "N-V-__8AANFEAwCzzNzNs3Gaq8pzGNl2BbeyFBwTyO5iZJL-",
.lazy = true,
},
},
}

124
build.zig.zon.bak Normal file
View File

@ -0,0 +1,124 @@
.{
.name = .ghostty,
.version = "1.3.0-dev",
.paths = .{""},
.fingerprint = 0x64407a2a0b4147e5,
.minimum_zig_version = "0.15.2",
.dependencies = .{
// Zig libs
.libxev = .{
// mitchellh/libxev
.url = "https://deps.files.ghostty.org/libxev-34fa50878aec6e5fa8f532867001ab3c36fae23e.tar.gz",
.hash = "libxev-0.0.0-86vtc4IcEwCqEYxEYoN_3KXmc6A9VLcm22aVImfvecYs",
.lazy = true,
},
.vaxis = .{
// rockorager/libvaxis
.url = "https://github.com/rockorager/libvaxis/archive/7dbb9fd3122e4ffad262dd7c151d80d863b68558.tar.gz",
.hash = "vaxis-0.5.1-BWNV_LosCQAGmCCNOLljCIw6j6-yt53tji6n6rwJ2BhS",
.lazy = true,
},
.z2d = .{
// vancluever/z2d
.url = "https://github.com/vancluever/z2d/archive/refs/tags/v0.9.0.tar.gz",
.hash = "z2d-0.9.0-j5P_Hu-WFgA_JEfRpiFss6gdvcvS47cgOc0Via2eKD_T",
.lazy = true,
},
.zig_objc = .{
// mitchellh/zig-objc
.url = "https://deps.files.ghostty.org/zig_objc-f356ed02833f0f1b8e84d50bed9e807bf7cdc0ae.tar.gz",
.hash = "zig_objc-0.0.0-Ir_Sp5gTAQCvxxR7oVIrPXxXwsfKgVP7_wqoOQrZjFeK",
.lazy = true,
},
.zig_js = .{
// mitchellh/zig-js
.url = "https://deps.files.ghostty.org/zig_js-04db83c617da1956ac5adc1cb9ba1e434c1cb6fd.tar.gz",
.hash = "zig_js-0.0.0-rjCAV-6GAADxFug7rDmPH-uM_XcnJ5NmuAMJCAscMjhi",
.lazy = true,
},
.uucode = .{
// jacobsandlund/uucode
.url = "https://github.com/jacobsandlund/uucode/archive/31655fba3c638229989cc524363ef5e3c7b580c1.tar.gz",
.hash = "uucode-0.1.0-ZZjBPicPTQDlG6OClzn2bPu7ICkkkyWrTB6aRsBr-A1E",
},
.zig_wayland = .{
// codeberg ifreund/zig-wayland
.url = "https://deps.files.ghostty.org/zig_wayland-1b5c038ec10da20ed3a15b0b2a6db1c21383e8ea.tar.gz",
.hash = "wayland-0.5.0-dev-lQa1khrMAQDJDwYFKpdH3HizherB7sHo5dKMECfvxQHe",
.lazy = true,
},
.zf = .{
// natecraddock/zf
.url = "https://github.com/natecraddock/zf/archive/3c52637b7e937c5ae61fd679717da3e276765b23.tar.gz",
.hash = "zf-0.10.3-OIRy8RuJAACKA3Lohoumrt85nRbHwbpMcUaLES8vxDnh",
.lazy = true,
},
.gobject = .{
// https://github.com/ghostty-org/zig-gobject based on zig_gobject
// Temporary until we generate them at build time automatically.
.url = "https://github.com/ghostty-org/zig-gobject/releases/download/0.7.0-2025-11-08-23-1/ghostty-gobject-0.7.0-2025-11-08-23-1.tar.zst",
.hash = "gobject-0.3.0-Skun7ANLnwDvEfIpVmohcppXgOvg_I6YOJFmPIsKfXk-",
.lazy = true,
},
// C libs
.cimgui = .{ .path = "./pkg/cimgui", .lazy = true },
.fontconfig = .{ .path = "./pkg/fontconfig", .lazy = true },
.freetype = .{ .path = "./pkg/freetype", .lazy = true },
.gtk4_layer_shell = .{ .path = "./pkg/gtk4-layer-shell", .lazy = true },
.harfbuzz = .{ .path = "./pkg/harfbuzz", .lazy = true },
.highway = .{ .path = "./pkg/highway", .lazy = true },
.libintl = .{ .path = "./pkg/libintl", .lazy = true },
.libpng = .{ .path = "./pkg/libpng", .lazy = true },
.macos = .{ .path = "./pkg/macos", .lazy = true },
.oniguruma = .{ .path = "./pkg/oniguruma", .lazy = true },
.opengl = .{ .path = "./pkg/opengl", .lazy = true },
.sentry = .{ .path = "./pkg/sentry", .lazy = true },
.simdutf = .{ .path = "./pkg/simdutf", .lazy = true },
.utfcpp = .{ .path = "./pkg/utfcpp", .lazy = true },
.wuffs = .{ .path = "./pkg/wuffs", .lazy = true },
.zlib = .{ .path = "./pkg/zlib", .lazy = true },
// Shader translation
.glslang = .{ .path = "./pkg/glslang", .lazy = true },
.spirv_cross = .{ .path = "./pkg/spirv-cross", .lazy = true },
// Wayland
.wayland = .{
.url = "https://deps.files.ghostty.org/wayland-9cb3d7aa9dc995ffafdbdef7ab86a949d0fb0e7d.tar.gz",
.hash = "N-V-__8AAKrHGAAs2shYq8UkE6bGcR1QJtLTyOE_lcosMn6t",
.lazy = true,
},
.wayland_protocols = .{
.url = "https://deps.files.ghostty.org/wayland-protocols-258d8f88f2c8c25a830c6316f87d23ce1a0f12d9.tar.gz",
.hash = "N-V-__8AAKw-DAAaV8bOAAGqA0-oD7o-HNIlPFYKRXSPT03S",
.lazy = true,
},
.plasma_wayland_protocols = .{
.url = "https://deps.files.ghostty.org/plasma_wayland_protocols-12207e0851c12acdeee0991e893e0132fc87bb763969a585dc16ecca33e88334c566.tar.gz",
.hash = "N-V-__8AAKYZBAB-CFHBKs3u4JkeiT4BMvyHu3Y5aaWF3Bbs",
.lazy = true,
},
// Fonts
.jetbrains_mono = .{
.url = "https://deps.files.ghostty.org/JetBrainsMono-2.304.tar.gz",
.hash = "N-V-__8AAIC5lwAVPJJzxnCAahSvZTIlG-HhtOvnM1uh-66x",
.lazy = true,
},
.nerd_fonts_symbols_only = .{
.url = "https://deps.files.ghostty.org/NerdFontsSymbolsOnly-3.4.0.tar.gz",
.hash = "N-V-__8AAMVLTABmYkLqhZPLXnMl-KyN38R8UVYqGrxqO26s",
.lazy = true,
},
// Other
.apple_sdk = .{ .path = "./pkg/apple-sdk" },
.iterm2_themes = .{
.url = "https://github.com/mbadolato/iTerm2-Color-Schemes/releases/download/release-20251201-150531-bfb3ee1/ghostty-themes.tgz",
.hash = "N-V-__8AANFEAwCzzNzNs3Gaq8pzGNl2BbeyFBwTyO5iZJL-",
.lazy = true,
},
},
}

177
build.zig.zon.json generated Normal file
View File

@ -0,0 +1,177 @@
{
"N-V-__8AALw2uwF_03u4JRkZwRLc3Y9hakkYV7NKRR9-RIZJ": {
"name": "breakpad",
"url": "https://deps.files.ghostty.org/breakpad-b99f444ba5f6b98cac261cbb391d8766b34a5918.tar.gz",
"hash": "sha256-bMqYlD0amQdmzvYQd8Ca/1k4Bj/heh7+EijlQSttatk="
},
"N-V-__8AAIrfdwARSa-zMmxWwFuwpXf1T3asIN7s5jqi9c1v": {
"name": "fontconfig",
"url": "https://deps.files.ghostty.org/fontconfig-2.14.2.tar.gz",
"hash": "sha256-O6LdkhWHGKzsXKrxpxYEO1qgVcJ7CB2RSvPMtA3OilU="
},
"N-V-__8AAKLKpwC4H27Ps_0iL3bPkQb-z6ZVSrB-x_3EEkub": {
"name": "freetype",
"url": "https://deps.files.ghostty.org/freetype-1220b81f6ecfb3fd222f76cf9106fecfa6554ab07ec7fdc4124b9bb063ae2adf969d.tar.gz",
"hash": "sha256-QnIB9dUVFnDQXB9bRb713aHy592XHvVPD+qqf/0quQw="
},
"N-V-__8AADcZkgn4cMhTUpIz6mShCKyqqB-NBtf_S2bHaTC-": {
"name": "gettext",
"url": "https://deps.files.ghostty.org/gettext-0.24.tar.gz",
"hash": "sha256-yRhQPVk9cNr0hE0XWhPYFq+stmfAb7oeydzVACwVGLc="
},
"N-V-__8AABzkUgISeKGgXAzgtutgJsZc0-kkeqBBscJgMkvy": {
"name": "glslang",
"url": "https://deps.files.ghostty.org/glslang-12201278a1a05c0ce0b6eb6026c65cd3e9247aa041b1c260324bf29cee559dd23ba1.tar.gz",
"hash": "sha256-FKLtu1Ccs+UamlPj9eQ12/WXFgS0uDPmPmB26MCpl7U="
},
"gobject-0.3.0-Skun7ANLnwDvEfIpVmohcppXgOvg_I6YOJFmPIsKfXk-": {
"name": "gobject",
"url": "https://deps.files.ghostty.org/gobject-2025-11-08-23-1.tar.zst",
"hash": "sha256-2b1DBvAIHY5LhItq3+q9L6tJgi7itnnrSAHc7fXWDEg="
},
"N-V-__8AALiNBAA-_0gprYr92CjrMj1I5bqNu0TSJOnjFNSr": {
"name": "gtk4_layer_shell",
"url": "https://deps.files.ghostty.org/gtk4-layer-shell-1.1.0.tar.gz",
"hash": "sha256-mChCgSYKXu9bT2OlXxbEv2p4ihAgptsDfssPcfozaYg="
},
"N-V-__8AAG02ugUcWec-Ndp-i7JTsJ0dgF8nnJRUInkGLG7G": {
"name": "harfbuzz",
"url": "https://deps.files.ghostty.org/harfbuzz-11.0.0.tar.xz",
"hash": "sha256-8WNRuv4hRyX+LB1bWfDZPkmQWkskeJn7kNcM/5U6K5s="
},
"N-V-__8AAGmZhABbsPJLfbqrh6JTHsXhY6qCaLAQyx25e0XE": {
"name": "highway",
"url": "https://deps.files.ghostty.org/highway-66486a10623fa0d72fe91260f96c892e41aceb06.tar.gz",
"hash": "sha256-h9T4iT704I8iSXNgj/6/lCaKgTgLp5wS6IQZaMgKohI="
},
"N-V-__8AAH0GaQC8a52s6vfIxg88OZgFgEW6DFxfSK4lX_l3": {
"name": "imgui",
"url": "https://deps.files.ghostty.org/imgui-1220bc6b9daceaf7c8c60f3c3998058045ba0c5c5f48ae255ff97776d9cd8bfc6402.tar.gz",
"hash": "sha256-oF/QHgTPEat4Hig4fGIdLkIPHmBEyOJ6JeYD6pnveGA="
},
"N-V-__8AANFEAwCzzNzNs3Gaq8pzGNl2BbeyFBwTyO5iZJL-": {
"name": "iterm2_themes",
"url": "https://github.com/mbadolato/iTerm2-Color-Schemes/releases/download/release-20251201-150531-bfb3ee1/ghostty-themes.tgz",
"hash": "sha256-5QePBQlSsz9W2r4zTS3QD+cDAeyObhR51E2AkJ3ZIUk="
},
"N-V-__8AAIC5lwAVPJJzxnCAahSvZTIlG-HhtOvnM1uh-66x": {
"name": "jetbrains_mono",
"url": "https://deps.files.ghostty.org/JetBrainsMono-2.304.tar.gz",
"hash": "sha256-xXppHouCrQmLWWPzlZAy5AOPORCHr3cViFulkEYQXMQ="
},
"N-V-__8AAJrvXQCqAT8Mg9o_tk6m0yf5Fz-gCNEOKLyTSerD": {
"name": "libpng",
"url": "https://deps.files.ghostty.org/libpng-1220aa013f0c83da3fb64ea6d327f9173fa008d10e28bc9349eac3463457723b1c66.tar.gz",
"hash": "sha256-/syVtGzwXo4/yKQUdQ4LparQDYnp/fF16U/wQcrxoDo="
},
"libxev-0.0.0-86vtc4IcEwCqEYxEYoN_3KXmc6A9VLcm22aVImfvecYs": {
"name": "libxev",
"url": "https://deps.files.ghostty.org/libxev-34fa50878aec6e5fa8f532867001ab3c36fae23e.tar.gz",
"hash": "sha256-YAPqa5bkpRihKPkyMn15oRvTCZaxO3O66ymRY3lIfdc="
},
"N-V-__8AAG3RoQEyRC2Vw7Qoro5SYBf62IHn3HjqtNVY6aWK": {
"name": "libxml2",
"url": "https://deps.files.ghostty.org/libxml2-2.11.5.tar.gz",
"hash": "sha256-bCgFni4+60K1tLFkieORamNGwQladP7jvGXNxdiaYhU="
},
"N-V-__8AAMVLTABmYkLqhZPLXnMl-KyN38R8UVYqGrxqO26s": {
"name": "nerd_fonts_symbols_only",
"url": "https://deps.files.ghostty.org/NerdFontsSymbolsOnly-3.4.0.tar.gz",
"hash": "sha256-EWTRuVbUveJI17LwmYxDzJT1ICQxoVZKeTiVsec7DQQ="
},
"N-V-__8AAHjwMQDBXnLq3Q2QhaivE0kE2aD138vtX2Bq1g7c": {
"name": "oniguruma",
"url": "https://deps.files.ghostty.org/oniguruma-1220c15e72eadd0d9085a8af134904d9a0f5dfcbed5f606ad60edc60ebeccd9706bb.tar.gz",
"hash": "sha256-ABqhIC54RI9MC/GkjHblVodrNvFtks4yB+zP1h2Z8qA="
},
"N-V-__8AADYiAAB_80AWnH1AxXC0tql9thT-R-DYO1gBqTLc": {
"name": "pixels",
"url": "https://deps.files.ghostty.org/pixels-12207ff340169c7d40c570b4b6a97db614fe47e0d83b5801a932dcd44917424c8806.tar.gz",
"hash": "sha256-Veg7FtCRCCUCvxSb9FfzH0IJLFmCZQ4/+657SIcb8Ro="
},
"N-V-__8AAKYZBAB-CFHBKs3u4JkeiT4BMvyHu3Y5aaWF3Bbs": {
"name": "plasma_wayland_protocols",
"url": "https://deps.files.ghostty.org/plasma_wayland_protocols-12207e0851c12acdeee0991e893e0132fc87bb763969a585dc16ecca33e88334c566.tar.gz",
"hash": "sha256-XFi6IUrNjmvKNCbcCLAixGqN2Zeymhs+KLrfccIN9EE="
},
"N-V-__8AAPlZGwBEa-gxrcypGBZ2R8Bse4JYSfo_ul8i2jlG": {
"name": "sentry",
"url": "https://deps.files.ghostty.org/sentry-1220446be831adcca918167647c06c7b825849fa3fba5f22da394667974537a9c77e.tar.gz",
"hash": "sha256-KsZJfMjWGo0xCT5HrduMmyxFsWsHBbszSoNbZCPDGN8="
},
"N-V-__8AANb6pwD7O1WG6L5nvD_rNMvnSc9Cpg1ijSlTYywv": {
"name": "spirv_cross",
"url": "https://deps.files.ghostty.org/spirv_cross-1220fb3b5586e8be67bc3feb34cbe749cf42a60d628d2953632c2f8141302748c8da.tar.gz",
"hash": "sha256-tStvz8Ref6abHwahNiwVVHNETizAmZVVaxVsU7pmV+M="
},
"N-V-__8AAHffAgDU0YQmynL8K35WzkcnMUmBVQHQ0jlcKpjH": {
"name": "utfcpp",
"url": "https://deps.files.ghostty.org/utfcpp-1220d4d18426ca72fc2b7e56ce47273149815501d0d2395c2a98c726b31ba931e641.tar.gz",
"hash": "sha256-/8ZooxDndgfTk/PBizJxXyI9oerExNbgV5oR345rWc8="
},
"uucode-0.1.0-ZZjBPj96QADXyt5sqwBJUnhaDYs_qBeeKijZvlRa0eqM": {
"name": "uucode",
"url": "git+https://github.com/jacobsandlund/uucode#5f05f8f83a75caea201f12cc8ea32a2d82ea9732",
"hash": "sha256-sHPh+TQSdUGus/QTbj7KSJJkTuNTrK4VNmQDjS30Lf8="
},
"uucode-0.1.0-ZZjBPicPTQDlG6OClzn2bPu7ICkkkyWrTB6aRsBr-A1E": {
"name": "uucode",
"url": "https://deps.files.ghostty.org/uucode-31655fba3c638229989cc524363ef5e3c7b580c1.tar.gz",
"hash": "sha256-SzpYGhgG4B6Luf8eT35sKLobCxjmwEuo1Twk0jeu9g4="
},
"vaxis-0.5.1-BWNV_LosCQAGmCCNOLljCIw6j6-yt53tji6n6rwJ2BhS": {
"name": "vaxis",
"url": "https://deps.files.ghostty.org/vaxis-7dbb9fd3122e4ffad262dd7c151d80d863b68558.tar.gz",
"hash": "sha256-LnIzK8icW1Qexua9SHaeHz+3V8QAbz0a+UC1T5sIjvY="
},
"N-V-__8AAKrHGAAs2shYq8UkE6bGcR1QJtLTyOE_lcosMn6t": {
"name": "wayland",
"url": "https://deps.files.ghostty.org/wayland-9cb3d7aa9dc995ffafdbdef7ab86a949d0fb0e7d.tar.gz",
"hash": "sha256-6kGR1o5DdnflHzqs3ieCmBAUTpMdOXoyfcYDXiw5xQ0="
},
"N-V-__8AAKw-DAAaV8bOAAGqA0-oD7o-HNIlPFYKRXSPT03S": {
"name": "wayland_protocols",
"url": "https://deps.files.ghostty.org/wayland-protocols-258d8f88f2c8c25a830c6316f87d23ce1a0f12d9.tar.gz",
"hash": "sha256-XO3K3egbdeYPI+XoO13SuOtO+5+Peb16NH0UiusFMPg="
},
"N-V-__8AAAzZywE3s51XfsLbP9eyEw57ae9swYB9aGB6fCMs": {
"name": "wuffs",
"url": "https://deps.files.ghostty.org/wuffs-122037b39d577ec2db3fd7b2130e7b69ef6cc1807d68607a7c232c958315d381b5cd.tar.gz",
"hash": "sha256-nkzSCr6W5sTG7enDBXEIhgEm574uLD41UVR2wlC+HBM="
},
"z2d-0.9.0-j5P_Hu-WFgA_JEfRpiFss6gdvcvS47cgOc0Via2eKD_T": {
"name": "z2d",
"url": "https://deps.files.ghostty.org/z2d-0.9.0-j5P_Hu-WFgA_JEfRpiFss6gdvcvS47cgOc0Via2eKD_T.tar.gz",
"hash": "sha256-+QqCRoXwrFA1/l+oWvYVyAVebGQitAFQNhi9U3EVrxA="
},
"zf-0.10.3-OIRy8RuJAACKA3Lohoumrt85nRbHwbpMcUaLES8vxDnh": {
"name": "zf",
"url": "https://deps.files.ghostty.org/zf-3c52637b7e937c5ae61fd679717da3e276765b23.tar.gz",
"hash": "sha256-OwFdkorwTp4mJyvBXrTbtNmp1GnrbSkKDdrmc7d8RWg="
},
"zig_js-0.0.0-rjCAV-6GAADxFug7rDmPH-uM_XcnJ5NmuAMJCAscMjhi": {
"name": "zig_js",
"url": "https://deps.files.ghostty.org/zig_js-04db83c617da1956ac5adc1cb9ba1e434c1cb6fd.tar.gz",
"hash": "sha256-TCAY5WAV05UEuAkDhq2c6Tk/ODgAhdnDI3O/flb8c6M="
},
"zig_objc-0.0.0-Ir_Sp5gTAQCvxxR7oVIrPXxXwsfKgVP7_wqoOQrZjFeK": {
"name": "zig_objc",
"url": "https://deps.files.ghostty.org/zig_objc-f356ed02833f0f1b8e84d50bed9e807bf7cdc0ae.tar.gz",
"hash": "sha256-3YSvc3YlNW/NciyzCQnzsujXAmZ89XlxSqfqvArAjsw="
},
"wayland-0.5.0-dev-lQa1khrMAQDJDwYFKpdH3HizherB7sHo5dKMECfvxQHe": {
"name": "zig_wayland",
"url": "https://deps.files.ghostty.org/zig_wayland-1b5c038ec10da20ed3a15b0b2a6db1c21383e8ea.tar.gz",
"hash": "sha256-TxRrc17Q1Sf1IOO/cdPpP3LD0PpYOujt06SFH3B5Ek4="
},
"zigimg-0.1.0-8_eo2vHnEwCIVW34Q14Ec-xUlzIoVg86-7FU2ypPtxms": {
"name": "zigimg",
"url": "https://github.com/ivanstepanovftw/zigimg/archive/d7b7ab0ba0899643831ef042bd73289510b39906.tar.gz",
"hash": "sha256-LB7Xa6KzVRRUSwwnyWM+y6fDG+kIDjfnoBDJO1obxVM="
},
"N-V-__8AAB0eQwD-0MdOEBmz7intriBReIsIDNlukNVoNu6o": {
"name": "zlib",
"url": "https://deps.files.ghostty.org/zlib-1220fed0c74e1019b3ee29edae2051788b080cd96e90d56836eea857b0b966742efb.tar.gz",
"hash": "sha256-F+iIY/NgBnKrSRgvIXKBtvxNPHYr3jYZNeQ2qVIU0Fw="
}
}

549
build.zig.zon.nix generated
View File

@ -1,22 +1,20 @@
# generated by zon2nix (https://github.com/Cloudef/zig2nix)
# generated by zon2nix (https://github.com/jcollie/zon2nix)
{
lib,
linkFarm,
fetchurl,
fetchgit,
runCommandLocal,
zig,
zig_0_15,
name ? "zig-packages",
}:
with builtins;
with lib; let
}: let
unpackZigArtifact = {
name,
artifact,
}:
runCommandLocal name
{
nativeBuildInputs = [zig];
nativeBuildInputs = [zig_0_15];
}
''
hash="$(zig fetch --global-cache-dir "$TMPDIR" ${artifact})"
@ -38,12 +36,12 @@ with lib; let
url,
hash,
}: let
parts = splitString "#" url;
url_base = elemAt parts 0;
url_without_query = elemAt (splitString "?" url_base) 0;
rev_base = elemAt parts 1;
parts = lib.splitString "#" url;
url_base = builtins.elemAt parts 0;
url_without_query = builtins.elemAt (lib.splitString "?" url_base) 0;
rev_base = builtins.elemAt parts 1;
rev =
if match "^[a-fA-F0-9]{40}$" rev_base != null
if builtins.match "^[a-fA-F0-9]{40}$" rev_base != null
then rev_base
else "refs/heads/${rev_base}";
in
@ -51,6 +49,7 @@ with lib; let
inherit name rev hash;
url = url_without_query;
deepClone = false;
fetchSubmodules = false;
};
fetchZigArtifact = {
@ -58,9 +57,9 @@ with lib; let
url,
hash,
}: let
parts = splitString "://" url;
proto = elemAt parts 0;
path = elemAt parts 1;
parts = lib.splitString "://" url;
proto = builtins.elemAt parts 0;
path = builtins.elemAt parts 1;
fetcher = {
"git+http" = fetchGitZig {
inherit name hash;
@ -84,215 +83,15 @@ with lib; let
in
linkFarm name [
{
name = "1220ebf88622c4d502dc59e71347e4d28c47e033f11b59aff774ae5787565c40999c";
name = "N-V-__8AALw2uwF_03u4JRkZwRLc3Y9hakkYV7NKRR9-RIZJ";
path = fetchZigArtifact {
name = "libxev";
url = "https://github.com/mitchellh/libxev/archive/31eed4e337fed7b0149319e5cdbb62b848c24fbd.tar.gz";
hash = "sha256-VHP90NTytIZ8UZsYRKOOxN490/I6yv6ec40sP8y5MJ8=";
name = "breakpad";
url = "https://deps.files.ghostty.org/breakpad-b99f444ba5f6b98cac261cbb391d8766b34a5918.tar.gz";
hash = "sha256-bMqYlD0amQdmzvYQd8Ca/1k4Bj/heh7+EijlQSttatk=";
};
}
{
name = "12206ed982e709e565d536ce930701a8c07edfd2cfdce428683f3f2a601d37696a62";
path = fetchZigArtifact {
name = "mach_glfw";
url = "https://github.com/mitchellh/mach-glfw/archive/37c2995f31abcf7e8378fba68ddcf4a3faa02de0.tar.gz";
hash = "sha256-HhXIvWUS8/CHWY4VXPG2ZEo+we8XOn3o5rYJCQ1n8Nk=";
};
}
{
name = "1220736fa4ba211162c7a0e46cc8fe04d95921927688bff64ab5da7420d098a7272d";
path = fetchZigArtifact {
name = "glfw";
url = "https://github.com/mitchellh/glfw/archive/b552c6ec47326b94015feddb36058ea567b87159.tar.gz";
hash = "sha256-IeBVAOQmtyFqVxzuXPek1onuPwIamcOyYtxqKpPEQjU=";
};
}
{
name = "12202adbfecdad671d585c9a5bfcbd5cdf821726779430047742ce1bf94ad67d19cb";
path = fetchZigArtifact {
name = "xcode_frameworks";
url = "https://github.com/mitchellh/xcode-frameworks/archive/69801c154c39d7ae6129ea1ba8fe1afe00585fc8.tar.gz";
hash = "sha256-mP/I2coL57UJm/3+4Q8sPAgQwk8V4zM+S4VBBTrX2To=";
};
}
{
name = "122004bfd4c519dadfb8e6281a42fc34fd1aa15aea654ea8a492839046f9894fa2cf";
path = fetchZigArtifact {
name = "vulkan_headers";
url = "https://github.com/mitchellh/vulkan-headers/archive/04c8a0389d5a0236a96312988017cd4ce27d8041.tar.gz";
hash = "sha256-K+zrRudgHFukOM6En1StRYRMNYkeRk+qHTXvrXaG+FU=";
};
}
{
name = "1220b3164434d2ec9db146a40bf3a30f490590d68fa8529776a3138074f0da2c11ca";
path = fetchZigArtifact {
name = "wayland_headers";
url = "https://github.com/mitchellh/wayland-headers/archive/5f991515a29f994d87b908115a2ab0b899474bd1.tar.gz";
hash = "sha256-uFilLZinKkZt6RdVTV3lUmJpzpswDdFva22FvwU/XQI=";
};
}
{
name = "122089c326186c84aa2fd034b16abc38f3ebf4862d9ae106dc1847ac44f557b36465";
path = fetchZigArtifact {
name = "x11_headers";
url = "https://github.com/mitchellh/x11-headers/archive/2ffbd62d82ff73ec929dd8de802bc95effa0ef88.tar.gz";
hash = "sha256-EhV2bmTY/OMYN1wEul35gD0hQgS/Al262jO3pVr0O+c=";
};
}
{
name = "12200df4ebeaed45de26cb2c9f3b6f3746d8013b604e035dae658f86f586c8c91d2f";
path = fetchZigArtifact {
name = "vaxis";
url = "git+https://github.com/rockorager/libvaxis/?ref=main#6d729a2dc3b934818dffe06d2ba3ce02841ed74b";
hash = "sha256-fFf79fCy4QQFVNcN722tSMjB6FyVEzCB36oH1olk9JQ=";
};
}
{
name = "1220dd654ef941fc76fd96f9ec6adadf83f69b9887a0d3f4ee5ac0a1a3e11be35cf5";
path = fetchZigArtifact {
name = "zigimg";
url = "git+https://github.com/zigimg/zigimg#3a667bdb3d7f0955a5a51c8468eac83210c1439e";
hash = "sha256-oLf3YH3yeg4ikVO/GahMCDRMTU31AHkfSnF4rt7xTKo=";
};
}
{
name = "122055beff332830a391e9895c044d33b15ea21063779557024b46169fb1984c6e40";
path = fetchZigArtifact {
name = "zg";
url = "https://codeberg.org/atman/zg/archive/v0.13.2.tar.gz";
hash = "sha256-2x9hT7bYq9KJYWLVOf21a+QvTG/F7HWT+YK15IMRzNY=";
};
}
{
name = "12201f0d542e7541cf492a001d4d0d0155c92f58212fbcb0d224e95edeba06b5416a";
path = fetchZigArtifact {
name = "z2d";
url = "git+https://github.com/vancluever/z2d?ref=v0.4.0#4638bb02a9dc41cc2fb811f092811f6a951c752a";
hash = "sha256-YpWXn1J3JKQSCrWB25mAfzd1/T56QstEZnhPzBwxgoM=";
};
}
{
name = "1220e17e64ef0ef561b3e4b9f3a96a2494285f2ec31c097721bf8c8677ec4415c634";
path = fetchZigArtifact {
name = "zig_objc";
url = "https://github.com/mitchellh/zig-objc/archive/9b8ba849b0f58fe207ecd6ab7c147af55b17556e.tar.gz";
hash = "sha256-H+HIbh2T23uzrsg9/1/vl9Ir1HCAa2pzeTx6zktJH9Q=";
};
}
{
name = "12205a66d423259567764fa0fc60c82be35365c21aeb76c5a7dc99698401f4f6fefc";
path = fetchZigArtifact {
name = "zig_js";
url = "https://github.com/mitchellh/zig-js/archive/d0b8b0a57c52fbc89f9d9fecba75ca29da7dd7d1.tar.gz";
hash = "sha256-fyNeCVbC9UAaKJY6JhAZlT0A479M/AKYMPIWEZbDWD0=";
};
}
{
name = "12207831bce7d4abce57b5a98e8f3635811cfefd160bca022eb91fe905d36a02cf25";
path = fetchZigArtifact {
name = "ziglyph";
url = "https://deps.files.ghostty.org/ziglyph-b89d43d1e3fb01b6074bc1f7fc980324b04d26a5.tar.gz";
hash = "sha256-cse98+Ft8QUjX+P88yyYfaxJOJGQ9M7Ymw7jFxDz89k=";
};
}
{
name = "12209ca054cb1919fa276e328967f10b253f7537c4136eb48f3332b0f7cf661cad38";
path = fetchZigArtifact {
name = "zig_wayland";
url = "https://deps.files.ghostty.org/zig-wayland-fbfe3b4ac0b472a27b1f1a67405436c58cbee12d.tar.gz";
hash = "sha256-RtAystqK/GRYIquTK1KfD7rRSCrfuzAvCD1Z9DE1ldc=";
};
}
{
name = "1220edc3b8d8bedbb50555947987e5e8e2f93871ca3c8e8d4cc8f1377c15b5dd35e8";
path = fetchZigArtifact {
name = "zf";
url = "git+https://github.com/natecraddock/zf/?ref=main#ed99ca18b02dda052e20ba467e90b623c04690dd";
hash = "sha256-t6QNrEJZ4GZZsYixjYvpdrYoCmNbG8TTUmGs2MFa4sU=";
};
}
{
name = "1220c72c1697dd9008461ead702997a15d8a1c5810247f02e7983b9f74c6c6e4c087";
path = fetchZigArtifact {
name = "vaxis";
url = "git+https://github.com/rockorager/libvaxis/?ref=main#dc0a228a5544988d4a920cfb40be9cd28db41423";
hash = "sha256-QWN4jOrA91KlbqmeEHHJ4HTnCC9nmfxt8DHUXJpAzLI=";
};
}
{
name = "12208d70ee791d7ef7e16e1c3c9c1127b57f1ed066a24f87d57fc9f730c5dc394b9d";
path = fetchZigArtifact {
name = "gobject";
url = "https://github.com/ianprime0509/zig-gobject/releases/download/v0.2.2/bindings-gnome47.tar.zst";
hash = "sha256-UU97kNv/bZzQPKz1djhEDLapLguvfBpFfWVb6FthtcI=";
};
}
{
name = "12202cdac858abc52413a6c6711d5026d2d3c8e13f95ca2c327eade0736298bb021f";
path = fetchZigArtifact {
name = "wayland";
url = "https://deps.files.ghostty.org/wayland-9cb3d7aa9dc995ffafdbdef7ab86a949d0fb0e7d.tar.gz";
hash = "sha256-m9G72jdG30KH2yQhNBcBJ46OnekzuX0i2uIOyczkpLk=";
};
}
{
name = "12201a57c6ce0001aa034fa80fba3e1cd2253c560a45748f4f4dd21ff23b491cddef";
path = fetchZigArtifact {
name = "wayland_protocols";
url = "https://deps.files.ghostty.org/wayland-protocols-258d8f88f2c8c25a830c6316f87d23ce1a0f12d9.tar.gz";
hash = "sha256-XO3K3egbdeYPI+XoO13SuOtO+5+Peb16NH0UiusFMPg=";
};
}
{
name = "12207e0851c12acdeee0991e893e0132fc87bb763969a585dc16ecca33e88334c566";
path = fetchZigArtifact {
name = "plasma_wayland_protocols";
url = "git+https://github.com/KDE/plasma-wayland-protocols?ref=main#db525e8f9da548cffa2ac77618dd0fbe7f511b86";
hash = "sha256-iWRv3+OfmHxmeCJ8m0ChjgZX6mwXlcFmK8P/Vt8gDj4=";
};
}
{
name = "12203d2647e5daf36a9c85b969e03f422540786ce9ea624eb4c26d204fe1f46218f3";
path = fetchZigArtifact {
name = "iterm2_themes";
url = "https://github.com/mbadolato/iTerm2-Color-Schemes/archive/db227d159adc265818f2e898da0f70ef8d7b580e.tar.gz";
hash = "sha256-Iyf7U4rpvNkPX4AOEbYSYGte5+SjRwsWD2luOn1Hz8U=";
};
}
{
name = "1220bc6b9daceaf7c8c60f3c3998058045ba0c5c5f48ae255ff97776d9cd8bfc6402";
path = fetchZigArtifact {
name = "imgui";
url = "https://github.com/ocornut/imgui/archive/e391fe2e66eb1c96b1624ae8444dc64c23146ef4.tar.gz";
hash = "sha256-oF/QHgTPEat4Hig4fGIdLkIPHmBEyOJ6JeYD6pnveGA=";
};
}
{
name = "1220b81f6ecfb3fd222f76cf9106fecfa6554ab07ec7fdc4124b9bb063ae2adf969d";
path = fetchZigArtifact {
name = "freetype";
url = "https://github.com/freetype/freetype/archive/refs/tags/VER-2-13-2.tar.gz";
hash = "sha256-QnIB9dUVFnDQXB9bRb713aHy592XHvVPD+qqf/0quQw=";
};
}
{
name = "1220aa013f0c83da3fb64ea6d327f9173fa008d10e28bc9349eac3463457723b1c66";
path = fetchZigArtifact {
name = "libpng";
url = "https://github.com/glennrp/libpng/archive/refs/tags/v1.6.43.tar.gz";
hash = "sha256-/syVtGzwXo4/yKQUdQ4LparQDYnp/fF16U/wQcrxoDo=";
};
}
{
name = "1220fed0c74e1019b3ee29edae2051788b080cd96e90d56836eea857b0b966742efb";
path = fetchZigArtifact {
name = "zlib";
url = "https://github.com/madler/zlib/archive/refs/tags/v1.3.1.tar.gz";
hash = "sha256-F+iIY/NgBnKrSRgvIXKBtvxNPHYr3jYZNeQ2qVIU0Fw=";
};
}
{
name = "12201149afb3326c56c05bb0a577f54f76ac20deece63aa2f5cd6ff31a4fa4fcb3b7";
name = "N-V-__8AAIrfdwARSa-zMmxWwFuwpXf1T3asIN7s5jqi9c1v";
path = fetchZigArtifact {
name = "fontconfig";
url = "https://deps.files.ghostty.org/fontconfig-2.14.2.tar.gz";
@ -300,91 +99,267 @@ in
};
}
{
name = "122032442d95c3b428ae8e526017fad881e7dc78eab4d558e9a58a80bfbd65a64f7d";
name = "N-V-__8AAKLKpwC4H27Ps_0iL3bPkQb-z6ZVSrB-x_3EEkub";
path = fetchZigArtifact {
name = "libxml2";
url = "https://github.com/GNOME/libxml2/archive/refs/tags/v2.11.5.tar.gz";
hash = "sha256-bCgFni4+60K1tLFkieORamNGwQladP7jvGXNxdiaYhU=";
name = "freetype";
url = "https://deps.files.ghostty.org/freetype-1220b81f6ecfb3fd222f76cf9106fecfa6554ab07ec7fdc4124b9bb063ae2adf969d.tar.gz";
hash = "sha256-QnIB9dUVFnDQXB9bRb713aHy592XHvVPD+qqf/0quQw=";
};
}
{
name = "1220b8588f106c996af10249bfa092c6fb2f35fbacb1505ef477a0b04a7dd1063122";
name = "N-V-__8AADcZkgn4cMhTUpIz6mShCKyqqB-NBtf_S2bHaTC-";
path = fetchZigArtifact {
name = "harfbuzz";
url = "https://github.com/harfbuzz/harfbuzz/archive/refs/tags/8.4.0.tar.gz";
hash = "sha256-nxygiYE7BZRK0c6MfgGCEwJtNdybq0gKIeuHaDg5ZVY=";
name = "gettext";
url = "https://deps.files.ghostty.org/gettext-0.24.tar.gz";
hash = "sha256-yRhQPVk9cNr0hE0XWhPYFq+stmfAb7oeydzVACwVGLc=";
};
}
{
name = "12205c83b8311a24b1d5ae6d21640df04f4b0726e314337c043cde1432758cbe165b";
path = fetchZigArtifact {
name = "highway";
url = "https://github.com/google/highway/archive/refs/tags/1.1.0.tar.gz";
hash = "sha256-NUqLRTm1iOcLmOxwhEJz4/J0EwLEw3e8xOgbPRhm98k=";
};
}
{
name = "1220c15e72eadd0d9085a8af134904d9a0f5dfcbed5f606ad60edc60ebeccd9706bb";
path = fetchZigArtifact {
name = "oniguruma";
url = "https://github.com/kkos/oniguruma/archive/refs/tags/v6.9.9.tar.gz";
hash = "sha256-ABqhIC54RI9MC/GkjHblVodrNvFtks4yB+zP1h2Z8qA=";
};
}
{
name = "1220446be831adcca918167647c06c7b825849fa3fba5f22da394667974537a9c77e";
path = fetchZigArtifact {
name = "sentry";
url = "https://github.com/getsentry/sentry-native/archive/refs/tags/0.7.8.tar.gz";
hash = "sha256-KsZJfMjWGo0xCT5HrduMmyxFsWsHBbszSoNbZCPDGN8=";
};
}
{
name = "12207fd37bb8251919c112dcdd8f616a491857b34a451f7e4486490077206dc2a1ea";
path = fetchZigArtifact {
name = "breakpad";
url = "https://github.com/getsentry/breakpad/archive/b99f444ba5f6b98cac261cbb391d8766b34a5918.tar.gz";
hash = "sha256-bMqYlD0amQdmzvYQd8Ca/1k4Bj/heh7+EijlQSttatk=";
};
}
{
name = "1220d4d18426ca72fc2b7e56ce47273149815501d0d2395c2a98c726b31ba931e641";
path = fetchZigArtifact {
name = "utfcpp";
url = "https://github.com/nemtrif/utfcpp/archive/refs/tags/v4.0.5.tar.gz";
hash = "sha256-/8ZooxDndgfTk/PBizJxXyI9oerExNbgV5oR345rWc8=";
};
}
{
name = "122037b39d577ec2db3fd7b2130e7b69ef6cc1807d68607a7c232c958315d381b5cd";
path = fetchZigArtifact {
name = "wuffs";
url = "https://github.com/google/wuffs/archive/refs/tags/v0.4.0-alpha.9.tar.gz";
hash = "sha256-nkzSCr6W5sTG7enDBXEIhgEm574uLD41UVR2wlC+HBM=";
};
}
{
name = "12207ff340169c7d40c570b4b6a97db614fe47e0d83b5801a932dcd44917424c8806";
path = fetchZigArtifact {
name = "pixels";
url = "git+https://github.com/make-github-pseudonymous-again/pixels?ref=main#d843c2714d32e15b48b8d7eeb480295af537f877";
hash = "sha256-kXYGO0qn2PfyOYCrRA49BHIgTzdmKhI8SNO1ZKfUYEE=";
};
}
{
name = "12201278a1a05c0ce0b6eb6026c65cd3e9247aa041b1c260324bf29cee559dd23ba1";
name = "N-V-__8AABzkUgISeKGgXAzgtutgJsZc0-kkeqBBscJgMkvy";
path = fetchZigArtifact {
name = "glslang";
url = "https://github.com/KhronosGroup/glslang/archive/refs/tags/14.2.0.tar.gz";
url = "https://deps.files.ghostty.org/glslang-12201278a1a05c0ce0b6eb6026c65cd3e9247aa041b1c260324bf29cee559dd23ba1.tar.gz";
hash = "sha256-FKLtu1Ccs+UamlPj9eQ12/WXFgS0uDPmPmB26MCpl7U=";
};
}
{
name = "1220fb3b5586e8be67bc3feb34cbe749cf42a60d628d2953632c2f8141302748c8da";
name = "gobject-0.3.0-Skun7ANLnwDvEfIpVmohcppXgOvg_I6YOJFmPIsKfXk-";
path = fetchZigArtifact {
name = "gobject";
url = "https://deps.files.ghostty.org/gobject-2025-11-08-23-1.tar.zst";
hash = "sha256-2b1DBvAIHY5LhItq3+q9L6tJgi7itnnrSAHc7fXWDEg=";
};
}
{
name = "N-V-__8AALiNBAA-_0gprYr92CjrMj1I5bqNu0TSJOnjFNSr";
path = fetchZigArtifact {
name = "gtk4_layer_shell";
url = "https://deps.files.ghostty.org/gtk4-layer-shell-1.1.0.tar.gz";
hash = "sha256-mChCgSYKXu9bT2OlXxbEv2p4ihAgptsDfssPcfozaYg=";
};
}
{
name = "N-V-__8AAG02ugUcWec-Ndp-i7JTsJ0dgF8nnJRUInkGLG7G";
path = fetchZigArtifact {
name = "harfbuzz";
url = "https://deps.files.ghostty.org/harfbuzz-11.0.0.tar.xz";
hash = "sha256-8WNRuv4hRyX+LB1bWfDZPkmQWkskeJn7kNcM/5U6K5s=";
};
}
{
name = "N-V-__8AAGmZhABbsPJLfbqrh6JTHsXhY6qCaLAQyx25e0XE";
path = fetchZigArtifact {
name = "highway";
url = "https://deps.files.ghostty.org/highway-66486a10623fa0d72fe91260f96c892e41aceb06.tar.gz";
hash = "sha256-h9T4iT704I8iSXNgj/6/lCaKgTgLp5wS6IQZaMgKohI=";
};
}
{
name = "N-V-__8AAH0GaQC8a52s6vfIxg88OZgFgEW6DFxfSK4lX_l3";
path = fetchZigArtifact {
name = "imgui";
url = "https://deps.files.ghostty.org/imgui-1220bc6b9daceaf7c8c60f3c3998058045ba0c5c5f48ae255ff97776d9cd8bfc6402.tar.gz";
hash = "sha256-oF/QHgTPEat4Hig4fGIdLkIPHmBEyOJ6JeYD6pnveGA=";
};
}
{
name = "N-V-__8AANFEAwCzzNzNs3Gaq8pzGNl2BbeyFBwTyO5iZJL-";
path = fetchZigArtifact {
name = "iterm2_themes";
url = "https://github.com/mbadolato/iTerm2-Color-Schemes/releases/download/release-20251201-150531-bfb3ee1/ghostty-themes.tgz";
hash = "sha256-5QePBQlSsz9W2r4zTS3QD+cDAeyObhR51E2AkJ3ZIUk=";
};
}
{
name = "N-V-__8AAIC5lwAVPJJzxnCAahSvZTIlG-HhtOvnM1uh-66x";
path = fetchZigArtifact {
name = "jetbrains_mono";
url = "https://deps.files.ghostty.org/JetBrainsMono-2.304.tar.gz";
hash = "sha256-xXppHouCrQmLWWPzlZAy5AOPORCHr3cViFulkEYQXMQ=";
};
}
{
name = "N-V-__8AAJrvXQCqAT8Mg9o_tk6m0yf5Fz-gCNEOKLyTSerD";
path = fetchZigArtifact {
name = "libpng";
url = "https://deps.files.ghostty.org/libpng-1220aa013f0c83da3fb64ea6d327f9173fa008d10e28bc9349eac3463457723b1c66.tar.gz";
hash = "sha256-/syVtGzwXo4/yKQUdQ4LparQDYnp/fF16U/wQcrxoDo=";
};
}
{
name = "libxev-0.0.0-86vtc4IcEwCqEYxEYoN_3KXmc6A9VLcm22aVImfvecYs";
path = fetchZigArtifact {
name = "libxev";
url = "https://deps.files.ghostty.org/libxev-34fa50878aec6e5fa8f532867001ab3c36fae23e.tar.gz";
hash = "sha256-YAPqa5bkpRihKPkyMn15oRvTCZaxO3O66ymRY3lIfdc=";
};
}
{
name = "N-V-__8AAG3RoQEyRC2Vw7Qoro5SYBf62IHn3HjqtNVY6aWK";
path = fetchZigArtifact {
name = "libxml2";
url = "https://deps.files.ghostty.org/libxml2-2.11.5.tar.gz";
hash = "sha256-bCgFni4+60K1tLFkieORamNGwQladP7jvGXNxdiaYhU=";
};
}
{
name = "N-V-__8AAMVLTABmYkLqhZPLXnMl-KyN38R8UVYqGrxqO26s";
path = fetchZigArtifact {
name = "nerd_fonts_symbols_only";
url = "https://deps.files.ghostty.org/NerdFontsSymbolsOnly-3.4.0.tar.gz";
hash = "sha256-EWTRuVbUveJI17LwmYxDzJT1ICQxoVZKeTiVsec7DQQ=";
};
}
{
name = "N-V-__8AAHjwMQDBXnLq3Q2QhaivE0kE2aD138vtX2Bq1g7c";
path = fetchZigArtifact {
name = "oniguruma";
url = "https://deps.files.ghostty.org/oniguruma-1220c15e72eadd0d9085a8af134904d9a0f5dfcbed5f606ad60edc60ebeccd9706bb.tar.gz";
hash = "sha256-ABqhIC54RI9MC/GkjHblVodrNvFtks4yB+zP1h2Z8qA=";
};
}
{
name = "N-V-__8AADYiAAB_80AWnH1AxXC0tql9thT-R-DYO1gBqTLc";
path = fetchZigArtifact {
name = "pixels";
url = "https://deps.files.ghostty.org/pixels-12207ff340169c7d40c570b4b6a97db614fe47e0d83b5801a932dcd44917424c8806.tar.gz";
hash = "sha256-Veg7FtCRCCUCvxSb9FfzH0IJLFmCZQ4/+657SIcb8Ro=";
};
}
{
name = "N-V-__8AAKYZBAB-CFHBKs3u4JkeiT4BMvyHu3Y5aaWF3Bbs";
path = fetchZigArtifact {
name = "plasma_wayland_protocols";
url = "https://deps.files.ghostty.org/plasma_wayland_protocols-12207e0851c12acdeee0991e893e0132fc87bb763969a585dc16ecca33e88334c566.tar.gz";
hash = "sha256-XFi6IUrNjmvKNCbcCLAixGqN2Zeymhs+KLrfccIN9EE=";
};
}
{
name = "N-V-__8AAPlZGwBEa-gxrcypGBZ2R8Bse4JYSfo_ul8i2jlG";
path = fetchZigArtifact {
name = "sentry";
url = "https://deps.files.ghostty.org/sentry-1220446be831adcca918167647c06c7b825849fa3fba5f22da394667974537a9c77e.tar.gz";
hash = "sha256-KsZJfMjWGo0xCT5HrduMmyxFsWsHBbszSoNbZCPDGN8=";
};
}
{
name = "N-V-__8AANb6pwD7O1WG6L5nvD_rNMvnSc9Cpg1ijSlTYywv";
path = fetchZigArtifact {
name = "spirv_cross";
url = "https://github.com/KhronosGroup/SPIRV-Cross/archive/476f384eb7d9e48613c45179e502a15ab95b6b49.tar.gz";
url = "https://deps.files.ghostty.org/spirv_cross-1220fb3b5586e8be67bc3feb34cbe749cf42a60d628d2953632c2f8141302748c8da.tar.gz";
hash = "sha256-tStvz8Ref6abHwahNiwVVHNETizAmZVVaxVsU7pmV+M=";
};
}
{
name = "N-V-__8AAHffAgDU0YQmynL8K35WzkcnMUmBVQHQ0jlcKpjH";
path = fetchZigArtifact {
name = "utfcpp";
url = "https://deps.files.ghostty.org/utfcpp-1220d4d18426ca72fc2b7e56ce47273149815501d0d2395c2a98c726b31ba931e641.tar.gz";
hash = "sha256-/8ZooxDndgfTk/PBizJxXyI9oerExNbgV5oR345rWc8=";
};
}
{
name = "uucode-0.1.0-ZZjBPj96QADXyt5sqwBJUnhaDYs_qBeeKijZvlRa0eqM";
path = fetchZigArtifact {
name = "uucode";
url = "git+https://github.com/jacobsandlund/uucode#5f05f8f83a75caea201f12cc8ea32a2d82ea9732";
hash = "sha256-sHPh+TQSdUGus/QTbj7KSJJkTuNTrK4VNmQDjS30Lf8=";
};
}
{
name = "uucode-0.1.0-ZZjBPicPTQDlG6OClzn2bPu7ICkkkyWrTB6aRsBr-A1E";
path = fetchZigArtifact {
name = "uucode";
url = "https://deps.files.ghostty.org/uucode-31655fba3c638229989cc524363ef5e3c7b580c1.tar.gz";
hash = "sha256-SzpYGhgG4B6Luf8eT35sKLobCxjmwEuo1Twk0jeu9g4=";
};
}
{
name = "vaxis-0.5.1-BWNV_LosCQAGmCCNOLljCIw6j6-yt53tji6n6rwJ2BhS";
path = fetchZigArtifact {
name = "vaxis";
url = "https://deps.files.ghostty.org/vaxis-7dbb9fd3122e4ffad262dd7c151d80d863b68558.tar.gz";
hash = "sha256-LnIzK8icW1Qexua9SHaeHz+3V8QAbz0a+UC1T5sIjvY=";
};
}
{
name = "N-V-__8AAKrHGAAs2shYq8UkE6bGcR1QJtLTyOE_lcosMn6t";
path = fetchZigArtifact {
name = "wayland";
url = "https://deps.files.ghostty.org/wayland-9cb3d7aa9dc995ffafdbdef7ab86a949d0fb0e7d.tar.gz";
hash = "sha256-6kGR1o5DdnflHzqs3ieCmBAUTpMdOXoyfcYDXiw5xQ0=";
};
}
{
name = "N-V-__8AAKw-DAAaV8bOAAGqA0-oD7o-HNIlPFYKRXSPT03S";
path = fetchZigArtifact {
name = "wayland_protocols";
url = "https://deps.files.ghostty.org/wayland-protocols-258d8f88f2c8c25a830c6316f87d23ce1a0f12d9.tar.gz";
hash = "sha256-XO3K3egbdeYPI+XoO13SuOtO+5+Peb16NH0UiusFMPg=";
};
}
{
name = "N-V-__8AAAzZywE3s51XfsLbP9eyEw57ae9swYB9aGB6fCMs";
path = fetchZigArtifact {
name = "wuffs";
url = "https://deps.files.ghostty.org/wuffs-122037b39d577ec2db3fd7b2130e7b69ef6cc1807d68607a7c232c958315d381b5cd.tar.gz";
hash = "sha256-nkzSCr6W5sTG7enDBXEIhgEm574uLD41UVR2wlC+HBM=";
};
}
{
name = "z2d-0.9.0-j5P_Hu-WFgA_JEfRpiFss6gdvcvS47cgOc0Via2eKD_T";
path = fetchZigArtifact {
name = "z2d";
url = "https://deps.files.ghostty.org/z2d-0.9.0-j5P_Hu-WFgA_JEfRpiFss6gdvcvS47cgOc0Via2eKD_T.tar.gz";
hash = "sha256-+QqCRoXwrFA1/l+oWvYVyAVebGQitAFQNhi9U3EVrxA=";
};
}
{
name = "zf-0.10.3-OIRy8RuJAACKA3Lohoumrt85nRbHwbpMcUaLES8vxDnh";
path = fetchZigArtifact {
name = "zf";
url = "https://deps.files.ghostty.org/zf-3c52637b7e937c5ae61fd679717da3e276765b23.tar.gz";
hash = "sha256-OwFdkorwTp4mJyvBXrTbtNmp1GnrbSkKDdrmc7d8RWg=";
};
}
{
name = "zig_js-0.0.0-rjCAV-6GAADxFug7rDmPH-uM_XcnJ5NmuAMJCAscMjhi";
path = fetchZigArtifact {
name = "zig_js";
url = "https://deps.files.ghostty.org/zig_js-04db83c617da1956ac5adc1cb9ba1e434c1cb6fd.tar.gz";
hash = "sha256-TCAY5WAV05UEuAkDhq2c6Tk/ODgAhdnDI3O/flb8c6M=";
};
}
{
name = "zig_objc-0.0.0-Ir_Sp5gTAQCvxxR7oVIrPXxXwsfKgVP7_wqoOQrZjFeK";
path = fetchZigArtifact {
name = "zig_objc";
url = "https://deps.files.ghostty.org/zig_objc-f356ed02833f0f1b8e84d50bed9e807bf7cdc0ae.tar.gz";
hash = "sha256-3YSvc3YlNW/NciyzCQnzsujXAmZ89XlxSqfqvArAjsw=";
};
}
{
name = "wayland-0.5.0-dev-lQa1khrMAQDJDwYFKpdH3HizherB7sHo5dKMECfvxQHe";
path = fetchZigArtifact {
name = "zig_wayland";
url = "https://deps.files.ghostty.org/zig_wayland-1b5c038ec10da20ed3a15b0b2a6db1c21383e8ea.tar.gz";
hash = "sha256-TxRrc17Q1Sf1IOO/cdPpP3LD0PpYOujt06SFH3B5Ek4=";
};
}
{
name = "zigimg-0.1.0-8_eo2vHnEwCIVW34Q14Ec-xUlzIoVg86-7FU2ypPtxms";
path = fetchZigArtifact {
name = "zigimg";
url = "https://github.com/ivanstepanovftw/zigimg/archive/d7b7ab0ba0899643831ef042bd73289510b39906.tar.gz";
hash = "sha256-LB7Xa6KzVRRUSwwnyWM+y6fDG+kIDjfnoBDJO1obxVM=";
};
}
{
name = "N-V-__8AAB0eQwD-0MdOEBmz7intriBReIsIDNlukNVoNu6o";
path = fetchZigArtifact {
name = "zlib";
url = "https://deps.files.ghostty.org/zlib-1220fed0c74e1019b3ee29edae2051788b080cd96e90d56836eea857b0b966742efb.tar.gz";
hash = "sha256-F+iIY/NgBnKrSRgvIXKBtvxNPHYr3jYZNeQ2qVIU0Fw=";
};
}
]

35
build.zig.zon.txt generated Normal file
View File

@ -0,0 +1,35 @@
git+https://github.com/jacobsandlund/uucode#5f05f8f83a75caea201f12cc8ea32a2d82ea9732
https://deps.files.ghostty.org/JetBrainsMono-2.304.tar.gz
https://deps.files.ghostty.org/NerdFontsSymbolsOnly-3.4.0.tar.gz
https://deps.files.ghostty.org/breakpad-b99f444ba5f6b98cac261cbb391d8766b34a5918.tar.gz
https://deps.files.ghostty.org/fontconfig-2.14.2.tar.gz
https://deps.files.ghostty.org/freetype-1220b81f6ecfb3fd222f76cf9106fecfa6554ab07ec7fdc4124b9bb063ae2adf969d.tar.gz
https://deps.files.ghostty.org/gettext-0.24.tar.gz
https://deps.files.ghostty.org/glslang-12201278a1a05c0ce0b6eb6026c65cd3e9247aa041b1c260324bf29cee559dd23ba1.tar.gz
https://deps.files.ghostty.org/gobject-2025-11-08-23-1.tar.zst
https://deps.files.ghostty.org/gtk4-layer-shell-1.1.0.tar.gz
https://deps.files.ghostty.org/harfbuzz-11.0.0.tar.xz
https://deps.files.ghostty.org/highway-66486a10623fa0d72fe91260f96c892e41aceb06.tar.gz
https://deps.files.ghostty.org/imgui-1220bc6b9daceaf7c8c60f3c3998058045ba0c5c5f48ae255ff97776d9cd8bfc6402.tar.gz
https://deps.files.ghostty.org/libpng-1220aa013f0c83da3fb64ea6d327f9173fa008d10e28bc9349eac3463457723b1c66.tar.gz
https://deps.files.ghostty.org/libxev-34fa50878aec6e5fa8f532867001ab3c36fae23e.tar.gz
https://deps.files.ghostty.org/libxml2-2.11.5.tar.gz
https://deps.files.ghostty.org/oniguruma-1220c15e72eadd0d9085a8af134904d9a0f5dfcbed5f606ad60edc60ebeccd9706bb.tar.gz
https://deps.files.ghostty.org/pixels-12207ff340169c7d40c570b4b6a97db614fe47e0d83b5801a932dcd44917424c8806.tar.gz
https://deps.files.ghostty.org/plasma_wayland_protocols-12207e0851c12acdeee0991e893e0132fc87bb763969a585dc16ecca33e88334c566.tar.gz
https://deps.files.ghostty.org/sentry-1220446be831adcca918167647c06c7b825849fa3fba5f22da394667974537a9c77e.tar.gz
https://deps.files.ghostty.org/spirv_cross-1220fb3b5586e8be67bc3feb34cbe749cf42a60d628d2953632c2f8141302748c8da.tar.gz
https://deps.files.ghostty.org/utfcpp-1220d4d18426ca72fc2b7e56ce47273149815501d0d2395c2a98c726b31ba931e641.tar.gz
https://deps.files.ghostty.org/uucode-31655fba3c638229989cc524363ef5e3c7b580c1.tar.gz
https://deps.files.ghostty.org/vaxis-7dbb9fd3122e4ffad262dd7c151d80d863b68558.tar.gz
https://deps.files.ghostty.org/wayland-9cb3d7aa9dc995ffafdbdef7ab86a949d0fb0e7d.tar.gz
https://deps.files.ghostty.org/wayland-protocols-258d8f88f2c8c25a830c6316f87d23ce1a0f12d9.tar.gz
https://deps.files.ghostty.org/wuffs-122037b39d577ec2db3fd7b2130e7b69ef6cc1807d68607a7c232c958315d381b5cd.tar.gz
https://deps.files.ghostty.org/z2d-0.9.0-j5P_Hu-WFgA_JEfRpiFss6gdvcvS47cgOc0Via2eKD_T.tar.gz
https://deps.files.ghostty.org/zf-3c52637b7e937c5ae61fd679717da3e276765b23.tar.gz
https://deps.files.ghostty.org/zig_js-04db83c617da1956ac5adc1cb9ba1e434c1cb6fd.tar.gz
https://deps.files.ghostty.org/zig_objc-f356ed02833f0f1b8e84d50bed9e807bf7cdc0ae.tar.gz
https://deps.files.ghostty.org/zig_wayland-1b5c038ec10da20ed3a15b0b2a6db1c21383e8ea.tar.gz
https://deps.files.ghostty.org/zlib-1220fed0c74e1019b3ee29edae2051788b080cd96e90d56836eea857b0b966742efb.tar.gz
https://github.com/ivanstepanovftw/zigimg/archive/d7b7ab0ba0899643831ef042bd73289510b39906.tar.gz
https://github.com/mbadolato/iTerm2-Color-Schemes/releases/download/release-20251201-150531-bfb3ee1/ghostty-themes.tgz

View File

@ -1,59 +0,0 @@
# Note: the flatpak build is likely broken right now and is not actively
# maintained. We may completely remove this file in the future. For now,
# we want to keep _trying_ but its something with known issues.
app-id: com.mitchellh.ghostty
runtime: org.gnome.Platform
runtime-version: "43"
sdk: org.gnome.Sdk
default-branch: tip
command: ghostty
build-options:
append-path: /app/tmp/zig
strip: false
no-debuginfo: true
# Note: we have to use cleanup-commands because flatpak-builder doesn't
# run "cleanup" on its own: https://github.com/flatpak/flatpak-builder/issues/14
cleanup-commands:
- "rm -rf /app/tmp"
finish-args:
# 3D rendering
- --device=dri
# Windowing
- --share=ipc
- --socket=x11
- --socket=wayland
# Files (we are a terminal so we need all of them)
- --filesystem=host
# So we can escape the sandbox
- --talk-name=org.freedesktop.Flatpak
modules:
# Note: this should be kept in sync with our flake.nix. Over time this
# should stabilize to being a release version and not a nightly.
- name: zig
buildsystem: simple
build-commands:
- mkdir -p /app/tmp/zig
- cp -r ./* /app/tmp/zig
sources:
- type: archive
url: https://ziglang.org/builds/zig-linux-x86_64-0.12.0-dev.141+ddf5859c2.tar.xz
sha256: eaf519b1ec3cb0f3c9bcbc47ead5f50610f9c106279a35b9feb09bed8afc628b
only-arches:
- x86_64
- type: archive
url: https://ziglang.org/builds/zig-linux-aarch64-0.12.0-dev.141+ddf5859c2.tar.xz
sha256: 4f918ae185a5dc281b5d30be92cd4c36ebd77b8665729c5e2c47a8eeccd243e8
only-arches:
- aarch64
- name: ghostty
buildsystem: simple
build-commands:
- MACH_SDK_PATH="$(pwd)/vendor/mach-sdk" zig build -Doptimize=ReleaseSafe -Dcpu=baseline -Dflatpak=true -Dapp-runtime=gtk --prefix /app
sources:
- type: dir
path: .
skip:
- .flatpak-builder
- zig-cache
- zig-out

BIN
dist/doxygen/favicon.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

18
dist/doxygen/footer.html vendored Normal file
View File

@ -0,0 +1,18 @@
<!-- HTML footer for doxygen 1.14.0-->
<!-- start footer part -->
<!--BEGIN GENERATE_TREEVIEW-->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
<ul>
$navpath
<li class="footer">$generatedby <a href="https://www.doxygen.org/index.html"><img class="footer" src="$relpath^doxygen.svg" width="104" height="31" alt="doxygen"/></a> $doxygenversion </li>
</ul>
</div>
<!--END GENERATE_TREEVIEW-->
<!--BEGIN !GENERATE_TREEVIEW-->
<hr class="footer"/><address class="footer"><small>
$generatedby&#160;<a href="https://www.doxygen.org/index.html"><img class="footer" src="$relpath^doxygen.svg" width="104" height="31" alt="doxygen"/></a> $doxygenversion
</small></address>
</div><!-- doc-content -->
<!--END !GENERATE_TREEVIEW-->
</body>
</html>

390
dist/doxygen/ghostty.css vendored Normal file
View File

@ -0,0 +1,390 @@
/**
* Ghostty Doxygen Custom Stylesheet
* Minimal branding customizations for Ghostty colors
*/
/* Ghostty brand color for links and accents - high contrast for dark bg */
a,
a:link {
color: #99b3ff;
}
a:visited {
color: #99b3ff;
}
a:hover {
color: #c2d4ff;
}
/* High contrast text colors */
body,
div.contents,
div.header,
.title,
.summary,
td,
th,
p,
li {
color: #e8e8e8 !important;
}
h1,
h2,
h3,
h4,
h5,
h6,
.groupheader {
color: #ffffff !important;
}
.memtitle,
.memname {
color: #ffffff !important;
}
.memdoc {
color: #e8e8e8 !important;
}
/* Selection color */
::selection {
background: rgba(53, 81, 243, 0.6);
}
/* Modern scrollbar styling for WebKit browsers (Safari, Chrome) */
::-webkit-scrollbar {
width: 14px;
height: 14px;
-webkit-appearance: none;
}
::-webkit-scrollbar-track {
background: #1a1f2e;
border-radius: 8px;
}
::-webkit-scrollbar-thumb {
background: #4a5260;
border-radius: 8px;
border: 3px solid #1a1f2e;
min-height: 40px;
}
::-webkit-scrollbar-thumb:hover {
background: #5a6270;
}
::-webkit-scrollbar-thumb:active {
background: #6a7280;
}
::-webkit-scrollbar-corner {
background: #1a1f2e;
}
/* Firefox scrollbar styling */
* {
scrollbar-width: thin;
scrollbar-color: #404754 #1a1f2e;
}
/* Tree view selected item */
#nav-tree .selected {
background-color: #3551f3 !important;
}
/* Custom syntax highlighting optimized for dark backgrounds with high contrast */
.fragment,
div.line {
color: #f0f0f0 !important;
}
/* Keywords (int, void, const, static, etc.) */
.keyword,
.keywordtype {
color: #ff8be6 !important;
font-weight: 500;
}
/* Control flow (if, else, return, for, while, etc.) */
.keywordflow {
color: #ff8be6 !important;
font-weight: 500;
}
/* Comments */
.comment {
color: #8bc34a !important;
font-style: italic;
}
/* Preprocessor directives (#include, #define, etc.) */
.preprocessor {
color: #ffcc66 !important;
}
/* String and character literals */
.stringliteral,
.charliteral {
color: #b8e986 !important;
}
/* Numbers */
span.charliteral {
color: #d4a5ff !important;
}
/* Function names */
.functionname {
color: #6fe87c !important;
font-weight: 500;
}
/* Line numbers */
span.lineno {
color: #8a8a8a !important;
background-color: transparent !important;
}
span.lineno a {
color: #8a8a8a !important;
background-color: transparent !important;
}
/* Desktop: ensure page-nav maintains default width */
@media screen and (min-width: 768px) {
#page-nav-toggle {
display: none !important;
}
#page-nav {
position: relative !important;
width: 250px !important;
height: auto !important;
right: auto !important;
top: auto !important;
box-shadow: none !important;
}
}
/* Mobile-friendly responsive styles */
@media screen and (max-width: 767px) {
body {
font-size: 14px !important;
}
/* Make navigation tree collapsible on mobile */
#side-nav {
display: none;
}
#doc-content {
margin-left: 0 !important;
margin-right: 0 !important;
}
/* Make right sidebar (page-nav) overlay on mobile */
#page-nav {
position: fixed !important;
top: 0 !important;
right: -280px !important;
width: 280px !important;
height: 100vh !important;
z-index: 10000 !important;
background: #101826 !important;
box-shadow: -2px 0 10px rgba(0, 0, 0, 0.5) !important;
transition: right 0.3s ease !important;
overflow-y: auto !important;
-webkit-overflow-scrolling: touch !important;
}
#page-nav.mobile-open {
right: 0 !important;
}
/* Hamburger menu button for page nav */
#page-nav-toggle {
display: block !important;
position: fixed !important;
top: 10px !important;
right: 15px !important;
z-index: 10001 !important;
width: 40px !important;
height: 40px !important;
background: rgba(53, 81, 243, 0.9) !important;
border: none !important;
border-radius: 5px !important;
cursor: pointer !important;
padding: 8px !important;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.3) !important;
}
#page-nav-toggle span {
display: block !important;
width: 24px !important;
height: 3px !important;
background: #fff !important;
margin: 4px 0 !important;
border-radius: 2px !important;
transition: 0.3s !important;
}
/* Mobile overlay backdrop */
#page-nav-backdrop {
display: none !important;
position: fixed !important;
top: 0 !important;
left: 0 !important;
width: 100% !important;
height: 100% !important;
background: rgba(0, 0, 0, 0.5) !important;
z-index: 9999 !important;
}
#page-nav-backdrop.active {
display: block !important;
}
/* Improve header and navigation */
#top {
height: auto !important;
}
#titlearea {
padding: 10px !important;
}
#projectname {
font-size: 18px !important;
}
#projectbrief,
#projectnumber {
font-size: 12px !important;
}
/* Make tabs stack better on mobile */
#navrow1,
#navrow2,
#navrow3,
#navrow4 {
overflow-x: auto !important;
white-space: nowrap !important;
-webkit-overflow-scrolling: touch !important;
}
.tablist li {
display: inline-block !important;
}
/* Content adjustments */
.contents {
padding: 10px !important;
width: 100% !important;
box-sizing: border-box !important;
}
.header {
padding: 5px !important;
}
/* Code blocks */
.fragment {
font-size: 12px !important;
overflow-x: auto !important;
-webkit-overflow-scrolling: touch !important;
}
div.line {
font-size: 12px !important;
}
/* Tables */
table {
display: block !important;
overflow-x: auto !important;
-webkit-overflow-scrolling: touch !important;
width: 100% !important;
}
.memberdecls table,
.fieldtable {
font-size: 12px !important;
}
.memtitle {
font-size: 14px !important;
padding: 8px !important;
}
.memname {
font-size: 13px !important;
word-break: break-word !important;
}
.memitem {
margin: 5px 0 !important;
}
/* Search box */
#MSearchBox {
width: 100% !important;
right: 0 !important;
}
/* Reduce padding and margins */
h1,
h2,
h3,
h4,
h5,
h6 {
margin-top: 10px !important;
margin-bottom: 8px !important;
}
h1 {
font-size: 22px !important;
}
h2 {
font-size: 18px !important;
}
h3 {
font-size: 16px !important;
}
h4 {
font-size: 14px !important;
}
/* Directory/file listings */
.directory .levels span {
display: none !important;
}
.directory .arrow {
margin-right: 5px !important;
}
/* Treeview adjustments */
#nav-tree {
width: 100% !important;
}
}
/* Tablet adjustments */
@media screen and (min-width: 768px) and (max-width: 1024px) {
.contents {
padding: 15px !important;
}
#side-nav {
width: 200px !important;
}
#doc-content {
margin-left: 200px !important;
}
}

77
dist/doxygen/header.html vendored Normal file
View File

@ -0,0 +1,77 @@
<!-- HTML header for doxygen 1.14.0-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="$langISO">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen $doxygenversion"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<!--BEGIN PROJECT_NAME--><title>$projectname: $title</title><!--END PROJECT_NAME-->
<!--BEGIN !PROJECT_NAME--><title>$title</title><!--END !PROJECT_NAME-->
<!--BEGIN PROJECT_ICON-->
<link rel="icon" href="$relpath^$projecticon" type="image/x-icon" />
<!--END PROJECT_ICON-->
<link href="$relpath^tabs.css" rel="stylesheet" type="text/css"/>
<!--BEGIN FULL_SIDEBAR-->
<script type="text/javascript">var page_layout=1;</script>
<!--END FULL_SIDEBAR-->
<script type="text/javascript" src="$relpath^jquery.js"></script>
<script type="text/javascript" src="$relpath^dynsections.js"></script>
<!--BEGIN COPY_CLIPBOARD-->
<script type="text/javascript" src="$relpath^clipboard.js"></script>
<!--END COPY_CLIPBOARD-->
$treeview
$search
$mathjax
$darkmode
<link href="$relpath^$stylesheet" rel="stylesheet" type="text/css" />
$extrastylesheet
<script type="text/javascript" src="$relpath^mobile-nav.js"></script>
</head>
<body>
<!--BEGIN FULL_SIDEBAR-->
<div id="side-nav" class="ui-resizable side-nav-resizable"><!-- do not remove this div, it is closed by doxygen! -->
<!--END FULL_SIDEBAR-->
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<!--BEGIN TITLEAREA-->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr id="projectrow">
<!--BEGIN PROJECT_LOGO-->
<td id="projectlogo"><img alt="Logo" src="$relpath^$projectlogo"$logosize/></td>
<!--END PROJECT_LOGO-->
<!--BEGIN PROJECT_NAME-->
<td id="projectalign">
<div id="projectname">$projectname<!--BEGIN PROJECT_NUMBER--><span id="projectnumber">&#160;$projectnumber</span><!--END PROJECT_NUMBER-->
</div>
<!--BEGIN PROJECT_BRIEF--><div id="projectbrief">$projectbrief</div><!--END PROJECT_BRIEF-->
</td>
<!--END PROJECT_NAME-->
<!--BEGIN !PROJECT_NAME-->
<!--BEGIN PROJECT_BRIEF-->
<td>
<div id="projectbrief">$projectbrief</div>
</td>
<!--END PROJECT_BRIEF-->
<!--END !PROJECT_NAME-->
<!--BEGIN DISABLE_INDEX-->
<!--BEGIN SEARCHENGINE-->
<!--BEGIN !FULL_SIDEBAR-->
<td>$searchbox</td>
<!--END !FULL_SIDEBAR-->
<!--END SEARCHENGINE-->
<!--END DISABLE_INDEX-->
</tr>
<!--BEGIN SEARCHENGINE-->
<!--BEGIN FULL_SIDEBAR-->
<tr><td colspan="2">$searchbox</td></tr>
<!--END FULL_SIDEBAR-->
<!--END SEARCHENGINE-->
</tbody>
</table>
</div>
<!--END TITLEAREA-->
<!-- end header part -->

65
dist/doxygen/mobile-nav.js vendored Normal file
View File

@ -0,0 +1,65 @@
/**
* Mobile navigation toggle for Doxygen documentation
*/
(function () {
// Only run on mobile devices
function isMobile() {
return window.innerWidth <= 767;
}
function initMobileNav() {
if (!isMobile()) return;
const pageNav = document.getElementById("page-nav");
if (!pageNav) return;
// Create toggle button
const toggleBtn = document.createElement("button");
toggleBtn.id = "page-nav-toggle";
toggleBtn.setAttribute("aria-label", "Toggle page navigation");
toggleBtn.innerHTML = "<span></span><span></span><span></span>";
document.body.appendChild(toggleBtn);
// Create backdrop
const backdrop = document.createElement("div");
backdrop.id = "page-nav-backdrop";
document.body.appendChild(backdrop);
// Toggle function
function toggleNav() {
const isOpen = pageNav.classList.toggle("mobile-open");
backdrop.classList.toggle("active", isOpen);
document.body.style.overflow = isOpen ? "hidden" : "";
}
// Event listeners
toggleBtn.addEventListener("click", toggleNav);
backdrop.addEventListener("click", toggleNav);
// Close on escape key
document.addEventListener("keydown", function (e) {
if (e.key === "Escape" && pageNav.classList.contains("mobile-open")) {
toggleNav();
}
});
}
// Initialize on load and resize
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", initMobileNav);
} else {
initMobileNav();
}
window.addEventListener("resize", function () {
const pageNav = document.getElementById("page-nav");
const backdrop = document.getElementById("page-nav-backdrop");
if (!isMobile() && pageNav) {
pageNav.classList.remove("mobile-open");
if (backdrop) backdrop.classList.remove("active");
document.body.style.overflow = "";
}
});
})();

2659
dist/doxygen/stylesheet.css vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,13 +1,15 @@
[Desktop Entry]
Name=Ghostty
Version=1.0
Name=@NAME@
Type=Application
Comment=A terminal emulator
Exec=ghostty
TryExec=@GHOSTTY@
Exec=@GHOSTTY@ --gtk-single-instance=true
Icon=com.mitchellh.ghostty
Categories=System;TerminalEmulator;
Keywords=terminal;tty;pty;
StartupNotify=true
StartupWMClass=com.mitchellh.ghostty
StartupWMClass=@APPID@
Terminal=false
Actions=new-window;
X-GNOME-UsesNotifications=true
@ -16,7 +18,9 @@ X-TerminalArgTitle=--title=
X-TerminalArgAppId=--class=
X-TerminalArgDir=--working-directory=
X-TerminalArgHold=--wait-after-command
DBusActivatable=true
X-KDE-Shortcuts=Ctrl+Alt+T
[Desktop Action new-window]
Name=New Window
Exec=ghostty
Exec=@GHOSTTY@ --gtk-single-instance=true

View File

@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?>
<component type="desktop-application">
<id>@APPID@</id>
<launchable type="desktop-id">@APPID@.desktop</launchable>
<name>@NAME@</name>
<url type="homepage">https://ghostty.org</url>
<url type="help">https://ghostty.org/docs</url>
<url type="bugtracker">https://github.com/ghostty-org/ghostty/discussions</url>
<url type="contact">https://ghostty.org/docs/help</url>
<url type="contribute">https://github.com/ghostty-org/ghostty/blob/main/CONTRIBUTING.md</url>
<url type="translate">https://github.com/ghostty-org/ghostty/blob/main/po/README_TRANSLATORS.md</url>
<url type="vcs-browser">https://github.com/ghostty-org/ghostty</url>
<summary>Ghostty is a fast, feature-rich, and cross-platform terminal emulator</summary>
<metadata_license>MIT</metadata_license>
<project_license>MIT</project_license>
<content_rating type="oars-1.1" />
<developer id="com.mitchellh">
<name>Mitchell Hashimoto</name>
</developer>
<update_contact>m@mitchellh.com</update_contact>
<description>
<p>
Ghostty is a terminal emulator that differentiates itself by being fast,
feature-rich, and native. While there are many excellent terminal
emulators available, they all force you to choose between speed,
features, or native UIs. Ghostty provides all three.
</p>
</description>
<recommends>
<control>keyboard</control>
<control>pointing</control>
</recommends>
<requires>
<!--
Mobile/tablet AND desktop supported
Ref: https://docs.flathub.org/docs/for-app-authors/metainfo-guidelines#display-size
-->
<display_length compare="ge">360</display_length>
</requires>
<translation type="gettext">com.mitchellh.ghostty</translation>
<!--
TODO: Generate manifest location data.
Ref: https://docs.flathub.org/docs/for-app-authors/metainfo-guidelines#manifest-location
<custom>
<value key="flathub::manifest">https://github.com/ghostty-org/ghostty/blob/<hash>/flatpak/com.mitchellh.ghostty.yml</value>
</custom>
-->
<releases>
<!-- TODO: Generate this automatically -->
<release version="1.0.1" date="2024-12-31">
<url type="details">https://ghostty.org/docs/install/release-notes/1-0-1</url>
</release>
</releases>
</component>

3
dist/linux/dbus.service.flatpak.in vendored Normal file
View File

@ -0,0 +1,3 @@
[D-BUS Service]
Name=@APPID@
Exec=@GHOSTTY@ --gtk-single-instance=true --initial-window=false

4
dist/linux/dbus.service.in vendored Normal file
View File

@ -0,0 +1,4 @@
[D-BUS Service]
Name=@APPID@
SystemdService=app-@APPID@.service
Exec=@GHOSTTY@ --gtk-single-instance=true --initial-window=false

14
dist/linux/systemd.service.in vendored Normal file
View File

@ -0,0 +1,14 @@
[Unit]
Description=@NAME@
After=graphical-session.target
After=dbus.socket
Requires=dbus.socket
[Service]
Type=notify-reload
ReloadSignal=SIGUSR2
BusName=@APPID@
ExecStart=@GHOSTTY@ --gtk-single-instance=true --initial-window=false
[Install]
WantedBy=graphical-session.target

Binary file not shown.

17
dist/macos/Info.plist vendored
View File

@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleExecutable</key>
<string>ghostty</string>
<key>CFBundleIdentifier</key>
<string>com.mitchellh.ghostty</string>
<key>CFBundleName</key>
<string>Ghostty</string>
<key>CFBundleDisplayName</key>
<string>Ghostty</string>
<key>CFBundleIconFile</key>
<string>Ghostty.icns</string>
</dict>
</plist>

View File

@ -1,189 +0,0 @@
import { ZigJS } from "zig-js";
const zjs = new ZigJS();
const importObject = {
module: {},
env: {
memory: new WebAssembly.Memory({
initial: 25,
maximum: 65536,
shared: true,
}),
log: (ptr: number, len: number) => {
const arr = new Uint8ClampedArray(zjs.memory.buffer, ptr, len);
const data = arr.slice();
const str = new TextDecoder("utf-8").decode(data);
console.log(str);
},
},
...zjs.importObject(),
};
const url = new URL("ghostty-wasm.wasm", import.meta.url);
fetch(url.href)
.then((response) => response.arrayBuffer())
.then((bytes) => WebAssembly.instantiate(bytes, importObject))
.then((results) => {
const memory = importObject.env.memory;
const {
malloc,
free,
config_new,
config_free,
config_load_string,
config_finalize,
face_new,
face_free,
face_render_glyph,
face_debug_canvas,
deferred_face_new,
deferred_face_free,
deferred_face_load,
deferred_face_face,
group_new,
group_free,
group_add_face,
group_init_sprite_face,
group_index_for_codepoint,
group_render_glyph,
group_cache_new,
group_cache_free,
group_cache_index_for_codepoint,
group_cache_render_glyph,
group_cache_atlas_grayscale,
group_cache_atlas_color,
atlas_new,
atlas_free,
atlas_debug_canvas,
shaper_new,
shaper_free,
shaper_test,
} = results.instance.exports;
// Give us access to the zjs value for debugging.
globalThis.zjs = zjs;
console.log(zjs);
// Initialize our zig-js memory
zjs.memory = memory;
// Helpers
const makeStr = (str) => {
const utf8 = new TextEncoder().encode(str);
const ptr = malloc(utf8.byteLength);
new Uint8Array(memory.buffer, ptr).set(utf8);
return { ptr: ptr, len: utf8.byteLength };
};
// Create our config
const config = config_new();
const config_str = makeStr("font-family = monospace");
config_load_string(config, config_str.ptr, config_str.len);
config_finalize(config);
free(config_str.ptr);
// Create our atlas
// const atlas = atlas_new(512, 0 /* grayscale */);
// Create some memory for our string
const font_name = makeStr("monospace");
// Initialize our deferred face
// const df = deferred_face_new(font_ptr, font.byteLength, 0 /* text */);
//deferred_face_load(df, 72 /* size */);
//const face = deferred_face_face(df);
// Initialize our font face
//const face = face_new(font_ptr, font.byteLength, 72 /* size in px */);
//free(font_ptr);
// Create our group
const group = group_new(32 /* size */);
group_add_face(
group,
0 /* regular */,
deferred_face_new(font_name.ptr, font_name.len, 0 /* text */),
);
group_add_face(
group,
0 /* regular */,
deferred_face_new(font_name.ptr, font_name.len, 1 /* emoji */),
);
// Initialize our sprite font, without this we just use the browser.
group_init_sprite_face(group);
// Create our group cache
const group_cache = group_cache_new(group);
// Render a glyph
// for (let i = 33; i <= 126; i++) {
// const font_idx = group_cache_index_for_codepoint(group_cache, i, 0, -1);
// group_cache_render_glyph(group_cache, font_idx, i, 0);
// //face_render_glyph(face, atlas, i);
// }
//
// const emoji = ["🐏","🌞","🌚","🍱","💿","🐈","📃","📀","🕡","🙃"];
// for (let i = 0; i < emoji.length; i++) {
// const cp = emoji[i].codePointAt(0);
// const font_idx = group_cache_index_for_codepoint(group_cache, cp, 0, -1 /* best choice */);
// group_cache_render_glyph(group_cache, font_idx, cp, 0);
// }
for (let i = 0x2500; i <= 0x257f; i++) {
const font_idx = group_cache_index_for_codepoint(group_cache, i, 0, -1);
group_cache_render_glyph(group_cache, font_idx, i, 0);
}
for (let i = 0x2580; i <= 0x259f; i++) {
const font_idx = group_cache_index_for_codepoint(group_cache, i, 0, -1);
group_cache_render_glyph(group_cache, font_idx, i, 0);
}
for (let i = 0x2800; i <= 0x28ff; i++) {
const font_idx = group_cache_index_for_codepoint(group_cache, i, 0, -1);
group_cache_render_glyph(group_cache, font_idx, i, 0);
}
for (let i = 0x1fb00; i <= 0x1fb3b; i++) {
const font_idx = group_cache_index_for_codepoint(group_cache, i, 0, -1);
group_cache_render_glyph(group_cache, font_idx, i, 0);
}
for (let i = 0x1fb3c; i <= 0x1fb6b; i++) {
const font_idx = group_cache_index_for_codepoint(group_cache, i, 0, -1);
group_cache_render_glyph(group_cache, font_idx, i, 0);
}
//face_render_glyph(face, atlas, "橋".codePointAt(0));
//face_render_glyph(face, atlas, "p".codePointAt(0));
// Debug our canvas
//face_debug_canvas(face);
// Let's try shaping
const shaper = shaper_new(120);
//const input = makeStr("hello🐏");
const input = makeStr("hello🐏👍🏽");
shaper_test(shaper, group_cache, input.ptr, input.len);
const cp = 1114112;
const font_idx = group_cache_index_for_codepoint(
group_cache,
cp,
0,
-1 /* best choice */,
);
group_cache_render_glyph(group_cache, font_idx, cp, -1);
// Debug our atlas canvas
{
const atlas = group_cache_atlas_grayscale(group_cache);
const id = atlas_debug_canvas(atlas);
document.getElementById("atlas-canvas").append(zjs.deleteValue(id));
}
{
const atlas = group_cache_atlas_color(group_cache);
const id = atlas_debug_canvas(atlas);
document.getElementById("atlas-color-canvas").append(zjs.deleteValue(id));
}
//face_free(face);
});

View File

@ -0,0 +1,22 @@
# Example: `ghostty-vt` C Key Encoding
This example demonstrates how to use the `ghostty-vt` C library to encode key
events into terminal escape sequences.
This example specifically shows how to:
1. Create a key encoder with the C API
2. Configure Kitty keyboard protocol flags (this example uses KKP)
3. Create and configure a key event
4. Encode the key event into a terminal escape sequence
The example encodes a Ctrl key release event with the Ctrl modifier set,
producing the escape sequence `\x1b[57442;5:3u`.
## Usage
Run the program:
```shell-session
zig build run
```

View File

@ -0,0 +1,42 @@
const std = @import("std");
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const run_step = b.step("run", "Run the app");
const exe_mod = b.createModule(.{
.target = target,
.optimize = optimize,
});
exe_mod.addCSourceFiles(.{
.root = b.path("src"),
.files = &.{"main.c"},
});
// You'll want to use a lazy dependency here so that ghostty is only
// downloaded if you actually need it.
if (b.lazyDependency("ghostty", .{
// Setting simd to false will force a pure static build that
// doesn't even require libc, but it has a significant performance
// penalty. If your embedding app requires libc anyway, you should
// always keep simd enabled.
// .simd = false,
})) |dep| {
exe_mod.linkLibrary(dep.artifact("ghostty-vt"));
}
// Exe
const exe = b.addExecutable(.{
.name = "c_vt_key_encode",
.root_module = exe_mod,
});
b.installArtifact(exe);
// Run
const run_cmd = b.addRunArtifact(exe);
run_cmd.step.dependOn(b.getInstallStep());
if (b.args) |args| run_cmd.addArgs(args);
run_step.dependOn(&run_cmd.step);
}

View File

@ -0,0 +1,24 @@
.{
.name = .c_vt,
.version = "0.0.0",
.fingerprint = 0x413a8529b1255f9a,
.minimum_zig_version = "0.15.1",
.dependencies = .{
// Ghostty dependency. In reality, you'd probably use a URL-based
// dependency like the one showed (and commented out) below this one.
// We use a path dependency here for simplicity and to ensure our
// examples always test against the source they're bundled with.
.ghostty = .{ .path = "../../" },
// Example of what a URL-based dependency looks like:
// .ghostty = .{
// .url = "https://github.com/ghostty-org/ghostty/archive/COMMIT.tar.gz",
// .hash = "N-V-__8AAMVLTABmYkLqhZPLXnMl-KyN38R8UVYqGrxqO36s",
// },
},
.paths = .{
"build.zig",
"build.zig.zon",
"src",
},
}

View File

@ -0,0 +1,59 @@
#include <assert.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <ghostty/vt.h>
int main() {
GhosttyKeyEncoder encoder;
GhosttyResult result = ghostty_key_encoder_new(NULL, &encoder);
assert(result == GHOSTTY_SUCCESS);
// Set kitty flags with all features enabled
ghostty_key_encoder_setopt(encoder, GHOSTTY_KEY_ENCODER_OPT_KITTY_FLAGS, &(uint8_t){GHOSTTY_KITTY_KEY_ALL});
// Create key event
GhosttyKeyEvent event;
result = ghostty_key_event_new(NULL, &event);
assert(result == GHOSTTY_SUCCESS);
ghostty_key_event_set_action(event, GHOSTTY_KEY_ACTION_RELEASE);
ghostty_key_event_set_key(event, GHOSTTY_KEY_CONTROL_LEFT);
ghostty_key_event_set_mods(event, GHOSTTY_MODS_CTRL);
printf("Encoding event: left ctrl release with all Kitty flags enabled\n");
// Optionally, encode with null buffer to get required size. You can
// skip this step and provide a sufficiently large buffer directly.
// If there isn't enoug hspace, the function will return an out of memory
// error.
size_t required = 0;
result = ghostty_key_encoder_encode(encoder, event, NULL, 0, &required);
assert(result == GHOSTTY_OUT_OF_MEMORY);
printf("Required buffer size: %zu bytes\n", required);
// Encode the key event. We don't use our required size above because
// that was just an example; we know 128 bytes is enough.
char buf[128];
size_t written = 0;
result = ghostty_key_encoder_encode(encoder, event, buf, sizeof(buf), &written);
assert(result == GHOSTTY_SUCCESS);
printf("Encoded %zu bytes\n", written);
// Print the encoded sequence (hex and string)
printf("Hex: ");
for (size_t i = 0; i < written; i++) printf("%02x ", (unsigned char)buf[i]);
printf("\n");
printf("String: ");
for (size_t i = 0; i < written; i++) {
if (buf[i] == 0x1b) {
printf("\\x1b");
} else {
printf("%c", buf[i]);
}
}
printf("\n");
ghostty_key_event_free(event);
ghostty_key_encoder_free(encoder);
return 0;
}

View File

@ -0,0 +1,17 @@
# Example: `ghostty-vt` Paste Safety Check
This contains a simple example of how to use the `ghostty-vt` paste
utilities to check if paste data is safe.
This uses a `build.zig` and `Zig` to build the C program so that we
can reuse a lot of our build logic and depend directly on our source
tree, but Ghostty emits a standard C library that can be used with any
C tooling.
## Usage
Run the program:
```shell-session
zig build run
```

View File

@ -0,0 +1,42 @@
const std = @import("std");
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const run_step = b.step("run", "Run the app");
const exe_mod = b.createModule(.{
.target = target,
.optimize = optimize,
});
exe_mod.addCSourceFiles(.{
.root = b.path("src"),
.files = &.{"main.c"},
});
// You'll want to use a lazy dependency here so that ghostty is only
// downloaded if you actually need it.
if (b.lazyDependency("ghostty", .{
// Setting simd to false will force a pure static build that
// doesn't even require libc, but it has a significant performance
// penalty. If your embedding app requires libc anyway, you should
// always keep simd enabled.
// .simd = false,
})) |dep| {
exe_mod.linkLibrary(dep.artifact("ghostty-vt"));
}
// Exe
const exe = b.addExecutable(.{
.name = "c_vt_paste",
.root_module = exe_mod,
});
b.installArtifact(exe);
// Run
const run_cmd = b.addRunArtifact(exe);
run_cmd.step.dependOn(b.getInstallStep());
if (b.args) |args| run_cmd.addArgs(args);
run_step.dependOn(&run_cmd.step);
}

View File

@ -0,0 +1,24 @@
.{
.name = .c_vt_paste,
.version = "0.0.0",
.fingerprint = 0xa105002abbc8cf74,
.minimum_zig_version = "0.15.1",
.dependencies = .{
// Ghostty dependency. In reality, you'd probably use a URL-based
// dependency like the one showed (and commented out) below this one.
// We use a path dependency here for simplicity and to ensure our
// examples always test against the source they're bundled with.
.ghostty = .{ .path = "../../" },
// Example of what a URL-based dependency looks like:
// .ghostty = .{
// .url = "https://github.com/ghostty-org/ghostty/archive/COMMIT.tar.gz",
// .hash = "N-V-__8AAMVLTABmYkLqhZPLXnMl-KyN38R8UVYqGrxqO36s",
// },
},
.paths = .{
"build.zig",
"build.zig.zon",
"src",
},
}

View File

@ -0,0 +1,31 @@
#include <stdio.h>
#include <string.h>
#include <ghostty/vt.h>
int main() {
// Test safe paste data
const char *safe_data = "hello world";
if (ghostty_paste_is_safe(safe_data, strlen(safe_data))) {
printf("'%s' is safe to paste\n", safe_data);
}
// Test unsafe paste data with newline
const char *unsafe_newline = "rm -rf /\n";
if (!ghostty_paste_is_safe(unsafe_newline, strlen(unsafe_newline))) {
printf("'%s' is UNSAFE - contains newline\n", unsafe_newline);
}
// Test unsafe paste data with bracketed paste end sequence
const char *unsafe_escape = "evil\x1b[201~code";
if (!ghostty_paste_is_safe(unsafe_escape, strlen(unsafe_escape))) {
printf("Data with escape sequence is UNSAFE\n");
}
// Test empty data
const char *empty_data = "";
if (ghostty_paste_is_safe(empty_data, 0)) {
printf("Empty data is safe\n");
}
return 0;
}

View File

@ -0,0 +1,21 @@
# Example: `ghostty-vt` SGR Parser
This contains a simple example of how to use the `ghostty-vt` SGR parser
to parse terminal styling sequences and extract text attributes.
This example demonstrates parsing a complex SGR sequence from Kakoune that
includes curly underline, RGB foreground/background colors, and RGB underline
color with mixed semicolon and colon separators.
This uses a `build.zig` and `Zig` to build the C program so that we
can reuse a lot of our build logic and depend directly on our source
tree, but Ghostty emits a standard C library that can be used with any
C tooling.
## Usage
Run the program:
```shell-session
zig build run
```

View File

@ -0,0 +1,42 @@
const std = @import("std");
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const run_step = b.step("run", "Run the app");
const exe_mod = b.createModule(.{
.target = target,
.optimize = optimize,
});
exe_mod.addCSourceFiles(.{
.root = b.path("src"),
.files = &.{"main.c"},
});
// You'll want to use a lazy dependency here so that ghostty is only
// downloaded if you actually need it.
if (b.lazyDependency("ghostty", .{
// Setting simd to false will force a pure static build that
// doesn't even require libc, but it has a significant performance
// penalty. If your embedding app requires libc anyway, you should
// always keep simd enabled.
// .simd = false,
})) |dep| {
exe_mod.linkLibrary(dep.artifact("ghostty-vt"));
}
// Exe
const exe = b.addExecutable(.{
.name = "c_vt_sgr",
.root_module = exe_mod,
});
b.installArtifact(exe);
// Run
const run_cmd = b.addRunArtifact(exe);
run_cmd.step.dependOn(b.getInstallStep());
if (b.args) |args| run_cmd.addArgs(args);
run_step.dependOn(&run_cmd.step);
}

View File

@ -0,0 +1,24 @@
.{
.name = .c_vt_sgr,
.version = "0.0.0",
.fingerprint = 0x6e9c6d318e59c268,
.minimum_zig_version = "0.15.1",
.dependencies = .{
// Ghostty dependency. In reality, you'd probably use a URL-based
// dependency like the one showed (and commented out) below this one.
// We use a path dependency here for simplicity and to ensure our
// examples always test against the source they're bundled with.
.ghostty = .{ .path = "../../" },
// Example of what a URL-based dependency looks like:
// .ghostty = .{
// .url = "https://github.com/ghostty-org/ghostty/archive/COMMIT.tar.gz",
// .hash = "N-V-__8AAMVLTABmYkLqhZPLXnMl-KyN38R8UVYqGrxqO36s",
// },
},
.paths = .{
"build.zig",
"build.zig.zon",
"src",
},
}

131
example/c-vt-sgr/src/main.c Normal file
View File

@ -0,0 +1,131 @@
#include <assert.h>
#include <stdio.h>
#include <ghostty/vt.h>
int main() {
// Create parser
GhosttySgrParser parser;
GhosttyResult result = ghostty_sgr_new(NULL, &parser);
assert(result == GHOSTTY_SUCCESS);
// Parse a complex SGR sequence from Kakoune
// This corresponds to the escape sequence:
// ESC[4:3;38;2;51;51;51;48;2;170;170;170;58;2;255;97;136m
//
// Breaking down the sequence:
// - 4:3 = curly underline (colon-separated sub-parameters)
// - 38;2;51;51;51 = foreground RGB color (51, 51, 51) - dark gray
// - 48;2;170;170;170 = background RGB color (170, 170, 170) - light gray
// - 58;2;255;97;136 = underline RGB color (255, 97, 136) - pink
uint16_t params[] = {4, 3, 38, 2, 51, 51, 51, 48, 2, 170, 170, 170, 58, 2, 255, 97, 136};
// Separator array: ':' at position 0 (between 4 and 3), ';' elsewhere
char separators[] = ";;;;;;;;;;;;;;;;";
separators[0] = ':';
result = ghostty_sgr_set_params(parser, params, separators, sizeof(params) / sizeof(params[0]));
assert(result == GHOSTTY_SUCCESS);
printf("Parsing Kakoune SGR sequence:\n");
printf("ESC[4:3;38;2;51;51;51;48;2;170;170;170;58;2;255;97;136m\n\n");
// Iterate through attributes
GhosttySgrAttribute attr;
int count = 0;
while (ghostty_sgr_next(parser, &attr)) {
count++;
printf("Attribute %d: ", count);
switch (attr.tag) {
case GHOSTTY_SGR_ATTR_UNDERLINE:
printf("Underline style = ");
switch (attr.value.underline) {
case GHOSTTY_SGR_UNDERLINE_NONE:
printf("none\n");
break;
case GHOSTTY_SGR_UNDERLINE_SINGLE:
printf("single\n");
break;
case GHOSTTY_SGR_UNDERLINE_DOUBLE:
printf("double\n");
break;
case GHOSTTY_SGR_UNDERLINE_CURLY:
printf("curly\n");
break;
case GHOSTTY_SGR_UNDERLINE_DOTTED:
printf("dotted\n");
break;
case GHOSTTY_SGR_UNDERLINE_DASHED:
printf("dashed\n");
break;
default:
printf("unknown (%d)\n", attr.value.underline);
break;
}
break;
case GHOSTTY_SGR_ATTR_DIRECT_COLOR_FG:
printf("Foreground RGB = (%d, %d, %d)\n",
attr.value.direct_color_fg.r,
attr.value.direct_color_fg.g,
attr.value.direct_color_fg.b);
break;
case GHOSTTY_SGR_ATTR_DIRECT_COLOR_BG:
printf("Background RGB = (%d, %d, %d)\n",
attr.value.direct_color_bg.r,
attr.value.direct_color_bg.g,
attr.value.direct_color_bg.b);
break;
case GHOSTTY_SGR_ATTR_UNDERLINE_COLOR:
printf("Underline color RGB = (%d, %d, %d)\n",
attr.value.underline_color.r,
attr.value.underline_color.g,
attr.value.underline_color.b);
break;
case GHOSTTY_SGR_ATTR_FG_8:
printf("Foreground 8-color = %d\n", attr.value.fg_8);
break;
case GHOSTTY_SGR_ATTR_BG_8:
printf("Background 8-color = %d\n", attr.value.bg_8);
break;
case GHOSTTY_SGR_ATTR_FG_256:
printf("Foreground 256-color = %d\n", attr.value.fg_256);
break;
case GHOSTTY_SGR_ATTR_BG_256:
printf("Background 256-color = %d\n", attr.value.bg_256);
break;
case GHOSTTY_SGR_ATTR_BOLD:
printf("Bold\n");
break;
case GHOSTTY_SGR_ATTR_ITALIC:
printf("Italic\n");
break;
case GHOSTTY_SGR_ATTR_UNSET:
printf("Reset all attributes\n");
break;
case GHOSTTY_SGR_ATTR_UNKNOWN:
printf("Unknown attribute\n");
break;
default:
printf("Other attribute (tag=%d)\n", attr.tag);
break;
}
}
printf("\nTotal attributes parsed: %d\n", count);
// Cleanup
ghostty_sgr_free(parser);
return 0;
}

17
example/c-vt/README.md Normal file
View File

@ -0,0 +1,17 @@
# Example: `ghostty-vt` C Program
This contains a simple example of how to use the `ghostty-vt` C library
with a C program.
This uses a `build.zig` and `Zig` to build the C program so that we
can reuse a lot of our build logic and depend directly on our source
tree, but Ghostty emits a standard C library that can be used with any
C tooling.
## Usage
Run the program:
```shell-session
zig build run
```

42
example/c-vt/build.zig Normal file
View File

@ -0,0 +1,42 @@
const std = @import("std");
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const run_step = b.step("run", "Run the app");
const exe_mod = b.createModule(.{
.target = target,
.optimize = optimize,
});
exe_mod.addCSourceFiles(.{
.root = b.path("src"),
.files = &.{"main.c"},
});
// You'll want to use a lazy dependency here so that ghostty is only
// downloaded if you actually need it.
if (b.lazyDependency("ghostty", .{
// Setting simd to false will force a pure static build that
// doesn't even require libc, but it has a significant performance
// penalty. If your embedding app requires libc anyway, you should
// always keep simd enabled.
// .simd = false,
})) |dep| {
exe_mod.linkLibrary(dep.artifact("ghostty-vt"));
}
// Exe
const exe = b.addExecutable(.{
.name = "c_vt",
.root_module = exe_mod,
});
b.installArtifact(exe);
// Run
const run_cmd = b.addRunArtifact(exe);
run_cmd.step.dependOn(b.getInstallStep());
if (b.args) |args| run_cmd.addArgs(args);
run_step.dependOn(&run_cmd.step);
}

View File

@ -0,0 +1,24 @@
.{
.name = .c_vt,
.version = "0.0.0",
.fingerprint = 0x413a8529b1255f9a,
.minimum_zig_version = "0.15.1",
.dependencies = .{
// Ghostty dependency. In reality, you'd probably use a URL-based
// dependency like the one showed (and commented out) below this one.
// We use a path dependency here for simplicity and to ensure our
// examples always test against the source they're bundled with.
.ghostty = .{ .path = "../../" },
// Example of what a URL-based dependency looks like:
// .ghostty = .{
// .url = "https://github.com/ghostty-org/ghostty/archive/COMMIT.tar.gz",
// .hash = "N-V-__8AAMVLTABmYkLqhZPLXnMl-KyN38R8UVYqGrxqO36s",
// },
},
.paths = .{
"build.zig",
"build.zig.zon",
"src",
},
}

36
example/c-vt/src/main.c Normal file
View File

@ -0,0 +1,36 @@
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <ghostty/vt.h>
int main() {
GhosttyOscParser parser;
if (ghostty_osc_new(NULL, &parser) != GHOSTTY_SUCCESS) {
return 1;
}
// Setup change window title command to change the title to "hello"
ghostty_osc_next(parser, '0');
ghostty_osc_next(parser, ';');
const char *title = "hello";
for (size_t i = 0; i < strlen(title); i++) {
ghostty_osc_next(parser, title[i]);
}
// End parsing and get command
GhosttyOscCommand command = ghostty_osc_end(parser, 0);
// Get and print command type
GhosttyOscCommandType type = ghostty_osc_command_type(command);
printf("Command type: %d\n", type);
// Extract and print the title
if (ghostty_osc_command_data(command, GHOSTTY_OSC_DATA_CHANGE_WINDOW_TITLE_STR, &title)) {
printf("Extracted title: %s\n", title);
} else {
printf("Failed to extract title\n");
}
ghostty_osc_free(parser);
return 0;
}

View File

@ -1,15 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<title>Ghostty Example</title>
<script type="module" src="app.ts"></script>
</head>
<body>
<p>Open your console, we are just debugging here.</p>
<p>The current <b>grayscale</b> font atlas is rendered below.</p>
<div><div id="atlas-canvas" style="display: inline-block; border: 1px solid green;"></div></div>
<p>The current <b>color</b> font atlas is rendered below.</p>
<div><div id="atlas-color-canvas" style="display: inline-block; border: 1px solid blue;"></div></div>
</body>
</html>

4436
example/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,22 +0,0 @@
{
"name": "ghostty example",
"version": "0.1.0",
"description": "Example showing ghostty and wasm.",
"source": "index.html",
"browserslist": "> 0.5%, last 2 versions, not dead",
"scripts": {
"start": "parcel",
"build": "parcel build",
"check": "tsc --noEmit"
},
"author": "Mitchell Hashimoto",
"license": "MIT",
"devDependencies": {
"@parcel/transformer-inline-string": "^2.8.0",
"parcel": "^2.8.0",
"typescript": "^4.9.3"
},
"dependencies": {
"zig-js": "file:../vendor/zig-js/js"
}
}

View File

@ -0,0 +1,40 @@
# WebAssembly Key Encoder Example
This example demonstrates how to use the Ghostty VT library from WebAssembly
to encode key events into terminal escape sequences.
## Building
First, build the WebAssembly module:
```bash
zig build lib-vt -Dtarget=wasm32-freestanding -Doptimize=ReleaseSmall
```
This will create `zig-out/bin/ghostty-vt.wasm`.
## Running
**Important:** You must serve this via HTTP, not open it as a file directly.
Browsers block loading WASM files from `file://` URLs.
From the **root of the ghostty repository**, serve with a local HTTP server:
```bash
# Using Python (recommended)
python3 -m http.server 8000
# Or using Node.js
npx serve .
# Or using PHP
php -S localhost:8000
```
Then open your browser to:
```
http://localhost:8000/example/wasm-key-encode/
```
Focus the text input field and press any key combination to see the encoded output.

View File

@ -0,0 +1,687 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Ghostty VT Key Encoder - WebAssembly Example</title>
<style>
body {
font-family: system-ui, -apple-system, sans-serif;
max-width: 800px;
margin: 40px auto;
padding: 0 20px;
line-height: 1.6;
}
h1 {
color: #333;
}
.output {
background: #f5f5f5;
border: 1px solid #ddd;
border-radius: 4px;
padding: 15px;
margin: 20px 0;
font-family: 'Courier New', monospace;
white-space: pre-wrap;
word-break: break-all;
}
.error {
background: #fee;
border-color: #faa;
color: #c00;
}
button {
background: #0066cc;
color: white;
border: none;
padding: 10px 20px;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
}
button:hover {
background: #0052a3;
}
button:disabled {
background: #ccc;
cursor: not-allowed;
}
.key-input {
width: 100%;
padding: 15px;
font-size: 16px;
border: 2px solid #0066cc;
border-radius: 4px;
margin: 20px 0;
box-sizing: border-box;
}
.key-input:focus {
outline: none;
border-color: #0052a3;
box-shadow: 0 0 0 3px rgba(0, 102, 204, 0.1);
}
.status {
color: #666;
font-size: 14px;
margin: 10px 0;
}
.controls {
background: #f9f9f9;
border: 1px solid #ddd;
border-radius: 4px;
padding: 15px;
margin: 20px 0;
}
.controls h3 {
margin-top: 0;
margin-bottom: 10px;
font-size: 16px;
}
.checkbox-group {
display: flex;
flex-wrap: wrap;
gap: 15px;
}
.checkbox-group label {
display: flex;
align-items: center;
gap: 5px;
cursor: pointer;
}
.checkbox-group input[type="checkbox"] {
cursor: pointer;
}
.radio-group {
display: flex;
gap: 15px;
}
.radio-group label {
display: flex;
align-items: center;
gap: 5px;
cursor: pointer;
}
.radio-group input[type="radio"] {
cursor: pointer;
}
.warning {
background: #fff3cd;
border: 1px solid #ffc107;
border-radius: 4px;
padding: 15px;
margin: 20px 0;
color: #856404;
}
.warning strong {
display: block;
margin-bottom: 5px;
}
</style>
</head>
<body>
<h1>Ghostty VT Key Encoder - WebAssembly Example</h1>
<p>This example demonstrates encoding key events into terminal escape sequences using the Ghostty VT WebAssembly module.</p>
<div class="warning">
<strong>⚠️ Warning:</strong>
This is an example of the libghostty-vt WebAssembly API. The JavaScript
keyboard event mapping to the libghostty-vt API may not be perfect
and may result in encoding inaccuracies for certain keys or layouts.
Do not use this as a key encoding reference.
</div>
<div class="status" id="status">Loading WebAssembly module...</div>
<div class="controls">
<h3>Key Action</h3>
<div class="radio-group">
<label><input type="radio" name="action" value="1" checked> Press</label>
<label><input type="radio" name="action" value="0"> Release</label>
<label><input type="radio" name="action" value="2"> Repeat</label>
</div>
</div>
<div class="controls">
<h3>Kitty Keyboard Protocol Flags</h3>
<div class="checkbox-group">
<label><input type="checkbox" id="flag_disambiguate" checked> Disambiguate</label>
<label><input type="checkbox" id="flag_report_events" checked> Report Events</label>
<label><input type="checkbox" id="flag_report_alternates" checked> Report Alternates</label>
<label><input type="checkbox" id="flag_report_all_as_escapes" checked> Report All As Escapes</label>
<label><input type="checkbox" id="flag_report_text" checked> Report Text</label>
</div>
</div>
<input type="text" class="key-input" id="keyInput" placeholder="Focus here and press any key combination (e.g., Ctrl+A, Shift+Enter)..." disabled>
<div id="output" class="output">Waiting for key events...</div>
<p><strong>Note:</strong> This example must be served via HTTP (not opened directly as a file). See the README for instructions.</p>
<script>
let wasmInstance = null;
let wasmMemory = null;
let encoderPtr = null;
let lastKeyEvent = null;
async function loadWasm() {
try {
// Load the wasm module - adjust path as needed
const response = await fetch('../../zig-out/bin/ghostty-vt.wasm');
const wasmBytes = await response.arrayBuffer();
// Instantiate the wasm module
const wasmModule = await WebAssembly.instantiate(wasmBytes, {
env: {
// Logging function for wasm module
log: (ptr, len) => {
const bytes = new Uint8Array(wasmModule.instance.exports.memory.buffer, ptr, len);
const text = new TextDecoder().decode(bytes);
console.log('[wasm]', text);
}
}
});
wasmInstance = wasmModule.instance;
wasmMemory = wasmInstance.exports.memory;
return true;
} catch (e) {
console.error('Failed to load WASM:', e);
if (window.location.protocol === 'file:') {
throw new Error('Cannot load WASM from file:// protocol. Please serve via HTTP (see README)');
}
return false;
}
}
function getBuffer() {
return wasmMemory.buffer;
}
function formatHex(bytes) {
return Array.from(bytes)
.map(b => b.toString(16).padStart(2, '0'))
.join(' ');
}
function formatString(bytes) {
let result = '';
for (let i = 0; i < bytes.length; i++) {
if (bytes[i] === 0x1b) {
result += '\\x1b';
} else {
result += String.fromCharCode(bytes[i]);
}
}
return result;
}
// Map W3C KeyboardEvent.code values to Ghostty key codes
// Based on include/ghostty/vt/key/event.h
const keyCodeMap = {
// Writing System Keys
'Backquote': 1, // GHOSTTY_KEY_BACKQUOTE
'Backslash': 2, // GHOSTTY_KEY_BACKSLASH
'BracketLeft': 3, // GHOSTTY_KEY_BRACKET_LEFT
'BracketRight': 4, // GHOSTTY_KEY_BRACKET_RIGHT
'Comma': 5, // GHOSTTY_KEY_COMMA
'Digit0': 6, // GHOSTTY_KEY_DIGIT_0
'Digit1': 7, // GHOSTTY_KEY_DIGIT_1
'Digit2': 8, // GHOSTTY_KEY_DIGIT_2
'Digit3': 9, // GHOSTTY_KEY_DIGIT_3
'Digit4': 10, // GHOSTTY_KEY_DIGIT_4
'Digit5': 11, // GHOSTTY_KEY_DIGIT_5
'Digit6': 12, // GHOSTTY_KEY_DIGIT_6
'Digit7': 13, // GHOSTTY_KEY_DIGIT_7
'Digit8': 14, // GHOSTTY_KEY_DIGIT_8
'Digit9': 15, // GHOSTTY_KEY_DIGIT_9
'Equal': 16, // GHOSTTY_KEY_EQUAL
'IntlBackslash': 17, // GHOSTTY_KEY_INTL_BACKSLASH
'IntlRo': 18, // GHOSTTY_KEY_INTL_RO
'IntlYen': 19, // GHOSTTY_KEY_INTL_YEN
'KeyA': 20, // GHOSTTY_KEY_A
'KeyB': 21, // GHOSTTY_KEY_B
'KeyC': 22, // GHOSTTY_KEY_C
'KeyD': 23, // GHOSTTY_KEY_D
'KeyE': 24, // GHOSTTY_KEY_E
'KeyF': 25, // GHOSTTY_KEY_F
'KeyG': 26, // GHOSTTY_KEY_G
'KeyH': 27, // GHOSTTY_KEY_H
'KeyI': 28, // GHOSTTY_KEY_I
'KeyJ': 29, // GHOSTTY_KEY_J
'KeyK': 30, // GHOSTTY_KEY_K
'KeyL': 31, // GHOSTTY_KEY_L
'KeyM': 32, // GHOSTTY_KEY_M
'KeyN': 33, // GHOSTTY_KEY_N
'KeyO': 34, // GHOSTTY_KEY_O
'KeyP': 35, // GHOSTTY_KEY_P
'KeyQ': 36, // GHOSTTY_KEY_Q
'KeyR': 37, // GHOSTTY_KEY_R
'KeyS': 38, // GHOSTTY_KEY_S
'KeyT': 39, // GHOSTTY_KEY_T
'KeyU': 40, // GHOSTTY_KEY_U
'KeyV': 41, // GHOSTTY_KEY_V
'KeyW': 42, // GHOSTTY_KEY_W
'KeyX': 43, // GHOSTTY_KEY_X
'KeyY': 44, // GHOSTTY_KEY_Y
'KeyZ': 45, // GHOSTTY_KEY_Z
'Minus': 46, // GHOSTTY_KEY_MINUS
'Period': 47, // GHOSTTY_KEY_PERIOD
'Quote': 48, // GHOSTTY_KEY_QUOTE
'Semicolon': 49, // GHOSTTY_KEY_SEMICOLON
'Slash': 50, // GHOSTTY_KEY_SLASH
// Functional Keys
'AltLeft': 51, // GHOSTTY_KEY_ALT_LEFT
'AltRight': 52, // GHOSTTY_KEY_ALT_RIGHT
'Backspace': 53, // GHOSTTY_KEY_BACKSPACE
'CapsLock': 54, // GHOSTTY_KEY_CAPS_LOCK
'ContextMenu': 55, // GHOSTTY_KEY_CONTEXT_MENU
'ControlLeft': 56, // GHOSTTY_KEY_CONTROL_LEFT
'ControlRight': 57, // GHOSTTY_KEY_CONTROL_RIGHT
'Enter': 58, // GHOSTTY_KEY_ENTER
'MetaLeft': 59, // GHOSTTY_KEY_META_LEFT
'MetaRight': 60, // GHOSTTY_KEY_META_RIGHT
'ShiftLeft': 61, // GHOSTTY_KEY_SHIFT_LEFT
'ShiftRight': 62, // GHOSTTY_KEY_SHIFT_RIGHT
'Space': 63, // GHOSTTY_KEY_SPACE
'Tab': 64, // GHOSTTY_KEY_TAB
'Convert': 65, // GHOSTTY_KEY_CONVERT
'KanaMode': 66, // GHOSTTY_KEY_KANA_MODE
'NonConvert': 67, // GHOSTTY_KEY_NON_CONVERT
// Control Pad Section
'Delete': 68, // GHOSTTY_KEY_DELETE
'End': 69, // GHOSTTY_KEY_END
'Help': 70, // GHOSTTY_KEY_HELP
'Home': 71, // GHOSTTY_KEY_HOME
'Insert': 72, // GHOSTTY_KEY_INSERT
'PageDown': 73, // GHOSTTY_KEY_PAGE_DOWN
'PageUp': 74, // GHOSTTY_KEY_PAGE_UP
// Arrow Pad Section
'ArrowDown': 75, // GHOSTTY_KEY_ARROW_DOWN
'ArrowLeft': 76, // GHOSTTY_KEY_ARROW_LEFT
'ArrowRight': 77, // GHOSTTY_KEY_ARROW_RIGHT
'ArrowUp': 78, // GHOSTTY_KEY_ARROW_UP
// Numpad Section
'NumLock': 79, // GHOSTTY_KEY_NUM_LOCK
'Numpad0': 80, // GHOSTTY_KEY_NUMPAD_0
'Numpad1': 81, // GHOSTTY_KEY_NUMPAD_1
'Numpad2': 82, // GHOSTTY_KEY_NUMPAD_2
'Numpad3': 83, // GHOSTTY_KEY_NUMPAD_3
'Numpad4': 84, // GHOSTTY_KEY_NUMPAD_4
'Numpad5': 85, // GHOSTTY_KEY_NUMPAD_5
'Numpad6': 86, // GHOSTTY_KEY_NUMPAD_6
'Numpad7': 87, // GHOSTTY_KEY_NUMPAD_7
'Numpad8': 88, // GHOSTTY_KEY_NUMPAD_8
'Numpad9': 89, // GHOSTTY_KEY_NUMPAD_9
'NumpadAdd': 90, // GHOSTTY_KEY_NUMPAD_ADD
'NumpadBackspace': 91, // GHOSTTY_KEY_NUMPAD_BACKSPACE
'NumpadClear': 92, // GHOSTTY_KEY_NUMPAD_CLEAR
'NumpadClearEntry': 93, // GHOSTTY_KEY_NUMPAD_CLEAR_ENTRY
'NumpadComma': 94, // GHOSTTY_KEY_NUMPAD_COMMA
'NumpadDecimal': 95, // GHOSTTY_KEY_NUMPAD_DECIMAL
'NumpadDivide': 96, // GHOSTTY_KEY_NUMPAD_DIVIDE
'NumpadEnter': 97, // GHOSTTY_KEY_NUMPAD_ENTER
'NumpadEqual': 98, // GHOSTTY_KEY_NUMPAD_EQUAL
'NumpadMemoryAdd': 99, // GHOSTTY_KEY_NUMPAD_MEMORY_ADD
'NumpadMemoryClear': 100,// GHOSTTY_KEY_NUMPAD_MEMORY_CLEAR
'NumpadMemoryRecall': 101,// GHOSTTY_KEY_NUMPAD_MEMORY_RECALL
'NumpadMemoryStore': 102,// GHOSTTY_KEY_NUMPAD_MEMORY_STORE
'NumpadMemorySubtract': 103,// GHOSTTY_KEY_NUMPAD_MEMORY_SUBTRACT
'NumpadMultiply': 104, // GHOSTTY_KEY_NUMPAD_MULTIPLY
'NumpadParenLeft': 105, // GHOSTTY_KEY_NUMPAD_PAREN_LEFT
'NumpadParenRight': 106, // GHOSTTY_KEY_NUMPAD_PAREN_RIGHT
'NumpadSubtract': 107, // GHOSTTY_KEY_NUMPAD_SUBTRACT
'NumpadSeparator': 108, // GHOSTTY_KEY_NUMPAD_SEPARATOR
'NumpadUp': 109, // GHOSTTY_KEY_NUMPAD_UP
'NumpadDown': 110, // GHOSTTY_KEY_NUMPAD_DOWN
'NumpadRight': 111, // GHOSTTY_KEY_NUMPAD_RIGHT
'NumpadLeft': 112, // GHOSTTY_KEY_NUMPAD_LEFT
'NumpadBegin': 113, // GHOSTTY_KEY_NUMPAD_BEGIN
'NumpadHome': 114, // GHOSTTY_KEY_NUMPAD_HOME
'NumpadEnd': 115, // GHOSTTY_KEY_NUMPAD_END
'NumpadInsert': 116, // GHOSTTY_KEY_NUMPAD_INSERT
'NumpadDelete': 117, // GHOSTTY_KEY_NUMPAD_DELETE
'NumpadPageUp': 118, // GHOSTTY_KEY_NUMPAD_PAGE_UP
'NumpadPageDown': 119, // GHOSTTY_KEY_NUMPAD_PAGE_DOWN
// Function Section
'Escape': 120, // GHOSTTY_KEY_ESCAPE
'F1': 121, // GHOSTTY_KEY_F1
'F2': 122, // GHOSTTY_KEY_F2
'F3': 123, // GHOSTTY_KEY_F3
'F4': 124, // GHOSTTY_KEY_F4
'F5': 125, // GHOSTTY_KEY_F5
'F6': 126, // GHOSTTY_KEY_F6
'F7': 127, // GHOSTTY_KEY_F7
'F8': 128, // GHOSTTY_KEY_F8
'F9': 129, // GHOSTTY_KEY_F9
'F10': 130, // GHOSTTY_KEY_F10
'F11': 131, // GHOSTTY_KEY_F11
'F12': 132, // GHOSTTY_KEY_F12
'F13': 133, // GHOSTTY_KEY_F13
'F14': 134, // GHOSTTY_KEY_F14
'F15': 135, // GHOSTTY_KEY_F15
'F16': 136, // GHOSTTY_KEY_F16
'F17': 137, // GHOSTTY_KEY_F17
'F18': 138, // GHOSTTY_KEY_F18
'F19': 139, // GHOSTTY_KEY_F19
'F20': 140, // GHOSTTY_KEY_F20
'F21': 141, // GHOSTTY_KEY_F21
'F22': 142, // GHOSTTY_KEY_F22
'F23': 143, // GHOSTTY_KEY_F23
'F24': 144, // GHOSTTY_KEY_F24
'F25': 145, // GHOSTTY_KEY_F25
'Fn': 146, // GHOSTTY_KEY_FN
'FnLock': 147, // GHOSTTY_KEY_FN_LOCK
'PrintScreen': 148, // GHOSTTY_KEY_PRINT_SCREEN
'ScrollLock': 149, // GHOSTTY_KEY_SCROLL_LOCK
'Pause': 150, // GHOSTTY_KEY_PAUSE
// Media Keys
'BrowserBack': 151, // GHOSTTY_KEY_BROWSER_BACK
'BrowserFavorites': 152, // GHOSTTY_KEY_BROWSER_FAVORITES
'BrowserForward': 153, // GHOSTTY_KEY_BROWSER_FORWARD
'BrowserHome': 154, // GHOSTTY_KEY_BROWSER_HOME
'BrowserRefresh': 155, // GHOSTTY_KEY_BROWSER_REFRESH
'BrowserSearch': 156, // GHOSTTY_KEY_BROWSER_SEARCH
'BrowserStop': 157, // GHOSTTY_KEY_BROWSER_STOP
'Eject': 158, // GHOSTTY_KEY_EJECT
'LaunchApp1': 159, // GHOSTTY_KEY_LAUNCH_APP_1
'LaunchApp2': 160, // GHOSTTY_KEY_LAUNCH_APP_2
'LaunchMail': 161, // GHOSTTY_KEY_LAUNCH_MAIL
'MediaPlayPause': 162, // GHOSTTY_KEY_MEDIA_PLAY_PAUSE
'MediaSelect': 163, // GHOSTTY_KEY_MEDIA_SELECT
'MediaStop': 164, // GHOSTTY_KEY_MEDIA_STOP
'MediaTrackNext': 165, // GHOSTTY_KEY_MEDIA_TRACK_NEXT
'MediaTrackPrevious': 166,// GHOSTTY_KEY_MEDIA_TRACK_PREVIOUS
'Power': 167, // GHOSTTY_KEY_POWER
'Sleep': 168, // GHOSTTY_KEY_SLEEP
'AudioVolumeDown': 169, // GHOSTTY_KEY_AUDIO_VOLUME_DOWN
'AudioVolumeMute': 170, // GHOSTTY_KEY_AUDIO_VOLUME_MUTE
'AudioVolumeUp': 171, // GHOSTTY_KEY_AUDIO_VOLUME_UP
'WakeUp': 172, // GHOSTTY_KEY_WAKE_UP
// Legacy, Non-standard, and Special Keys
'Copy': 173, // GHOSTTY_KEY_COPY
'Cut': 174, // GHOSTTY_KEY_CUT
'Paste': 175, // GHOSTTY_KEY_PASTE
};
function encodeKeyEvent(event) {
if (!encoderPtr) return null;
try {
// Create key event
const eventPtrPtr = wasmInstance.exports.ghostty_wasm_alloc_opaque();
const result = wasmInstance.exports.ghostty_key_event_new(0, eventPtrPtr);
if (result !== 0) {
throw new Error(`ghostty_key_event_new failed with result ${result}`);
}
const eventPtr = new DataView(getBuffer()).getUint32(eventPtrPtr, true);
// Get action from radio buttons
const actionRadio = document.querySelector('input[name="action"]:checked');
const action = parseInt(actionRadio.value);
wasmInstance.exports.ghostty_key_event_set_action(eventPtr, action);
// Map key code from event.code (preferred, layout-independent)
let keyCode = keyCodeMap[event.code] || 0; // GHOSTTY_KEY_UNIDENTIFIED = 0
wasmInstance.exports.ghostty_key_event_set_key(eventPtr, keyCode);
// Map modifiers with left/right side information
let mods = 0;
if (event.shiftKey) {
mods |= 0x01; // GHOSTTY_MODS_SHIFT
if (event.code === 'ShiftRight') mods |= 0x40; // GHOSTTY_MODS_SHIFT_SIDE
}
if (event.ctrlKey) {
mods |= 0x02; // GHOSTTY_MODS_CTRL
if (event.code === 'ControlRight') mods |= 0x80; // GHOSTTY_MODS_CTRL_SIDE
}
if (event.altKey) {
mods |= 0x04; // GHOSTTY_MODS_ALT
if (event.code === 'AltRight') mods |= 0x100; // GHOSTTY_MODS_ALT_SIDE
}
if (event.metaKey) {
mods |= 0x08; // GHOSTTY_MODS_SUPER
if (event.code === 'MetaRight') mods |= 0x200; // GHOSTTY_MODS_SUPER_SIDE
}
wasmInstance.exports.ghostty_key_event_set_mods(eventPtr, mods);
// Set UTF-8 text from the key event (the actual character produced)
if (event.key.length === 1) {
const utf8Bytes = new TextEncoder().encode(event.key);
const utf8Ptr = wasmInstance.exports.ghostty_wasm_alloc_u8_array(utf8Bytes.length);
new Uint8Array(getBuffer()).set(utf8Bytes, utf8Ptr);
wasmInstance.exports.ghostty_key_event_set_utf8(eventPtr, utf8Ptr, utf8Bytes.length);
}
// Set unshifted codepoint
const unshiftedCodepoint = getUnshiftedCodepoint(event);
if (unshiftedCodepoint !== 0) {
wasmInstance.exports.ghostty_key_event_set_unshifted_codepoint(eventPtr, unshiftedCodepoint);
}
// Encode the key event
const requiredPtr = wasmInstance.exports.ghostty_wasm_alloc_usize();
wasmInstance.exports.ghostty_key_encoder_encode(
encoderPtr, eventPtr, 0, 0, requiredPtr
);
const required = new DataView(getBuffer()).getUint32(requiredPtr, true);
const bufPtr = wasmInstance.exports.ghostty_wasm_alloc_u8_array(required);
const writtenPtr = wasmInstance.exports.ghostty_wasm_alloc_usize();
const encodeResult = wasmInstance.exports.ghostty_key_encoder_encode(
encoderPtr, eventPtr, bufPtr, required, writtenPtr
);
if (encodeResult !== 0) {
return null; // No encoding for this key
}
const written = new DataView(getBuffer()).getUint32(writtenPtr, true);
const encoded = new Uint8Array(getBuffer()).slice(bufPtr, bufPtr + written);
return {
bytes: Array.from(encoded),
hex: formatHex(encoded),
string: formatString(encoded)
};
} catch (e) {
console.error('Encoding error:', e);
return null;
}
}
function getUnshiftedCodepoint(event) {
// Derive unshifted codepoint from the physical key code
const code = event.code;
// Letter keys (KeyA-KeyZ) -> lowercase letters
if (code.startsWith('Key')) {
const letter = code.substring(3).toLowerCase();
return letter.codePointAt(0);
}
// Digit keys (Digit0-Digit9) -> the digit itself
if (code.startsWith('Digit')) {
const digit = code.substring(5);
return digit.codePointAt(0);
}
// Space
if (code === 'Space') {
return ' '.codePointAt(0);
}
// Symbol keys -> unshifted character
const unshiftedSymbols = {
'Minus': '-', 'Equal': '=', 'BracketLeft': '[', 'BracketRight': ']',
'Backslash': '\\', 'Semicolon': ';', 'Quote': "'",
'Backquote': '`', 'Comma': ',', 'Period': '.', 'Slash': '/'
};
if (unshiftedSymbols[code]) {
return unshiftedSymbols[code].codePointAt(0);
}
// Fallback: use the produced character's codepoint
if (event.key.length > 0) {
return event.key.codePointAt(0) || 0;
}
return 0;
}
function getKittyFlags() {
let flags = 0;
if (document.getElementById('flag_disambiguate').checked) flags |= 0x01;
if (document.getElementById('flag_report_events').checked) flags |= 0x02;
if (document.getElementById('flag_report_alternates').checked) flags |= 0x04;
if (document.getElementById('flag_report_all_as_escapes').checked) flags |= 0x08;
if (document.getElementById('flag_report_text').checked) flags |= 0x10;
return flags;
}
function updateEncoderFlags() {
if (!encoderPtr) return;
const flags = getKittyFlags();
const flagsPtr = wasmInstance.exports.ghostty_wasm_alloc_u8();
new DataView(getBuffer()).setUint8(flagsPtr, flags);
wasmInstance.exports.ghostty_key_encoder_setopt(
encoderPtr,
5, // GHOSTTY_KEY_ENCODER_OPT_KITTY_FLAGS
flagsPtr
);
// Re-encode last key with new flags
reencodeLastKey();
}
function displayEncoding(event) {
const outputDiv = document.getElementById('output');
const encoded = encodeKeyEvent(event);
const actionRadio = document.querySelector('input[name="action"]:checked');
const actionName = actionRadio.parentElement.textContent.trim();
let output = `Action: ${actionName}\n`;
output += `Key: ${event.key} (code: ${event.code})\n`;
output += `Modifiers: `;
const mods = [];
if (event.shiftKey) mods.push('Shift');
if (event.ctrlKey) mods.push('Ctrl');
if (event.altKey) mods.push('Alt');
if (event.metaKey) mods.push('Meta');
output += mods.length ? mods.join('+') : 'none';
output += '\n';
// Show Kitty flags state
const flags = [];
if (document.getElementById('flag_disambiguate').checked) flags.push('Disambiguate');
if (document.getElementById('flag_report_events').checked) flags.push('Report Events');
if (document.getElementById('flag_report_alternates').checked) flags.push('Report Alternates');
if (document.getElementById('flag_report_all_as_escapes').checked) flags.push('Report All As Escapes');
if (document.getElementById('flag_report_text').checked) flags.push('Report Text');
output += 'Kitty Flags:\n';
if (flags.length) {
flags.forEach(flag => output += ` - ${flag}\n`);
} else {
output += ' - none\n';
}
output += '\n';
if (encoded) {
output += `Encoded ${encoded.bytes.length} bytes\n`;
output += `Hex: ${encoded.hex}\n`;
output += `String: ${encoded.string}`;
} else {
output += 'No encoding for this key event';
}
outputDiv.textContent = output;
}
function handleKeyEvent(event) {
// Allow modifier keys to be pressed without clearing input
// Only prevent default for keys we want to capture
if (event.key !== 'Tab' && event.key !== 'F5') {
event.preventDefault();
}
lastKeyEvent = event;
displayEncoding(event);
}
function reencodeLastKey() {
if (lastKeyEvent) {
displayEncoding(lastKeyEvent);
}
}
async function init() {
const statusDiv = document.getElementById('status');
const keyInput = document.getElementById('keyInput');
const outputDiv = document.getElementById('output');
try {
statusDiv.textContent = 'Loading WebAssembly module...';
const loaded = await loadWasm();
if (!loaded) {
throw new Error('Failed to load WebAssembly module');
}
// Create key encoder
const encoderPtrPtr = wasmInstance.exports.ghostty_wasm_alloc_opaque();
const result = wasmInstance.exports.ghostty_key_encoder_new(0, encoderPtrPtr);
if (result !== 0) {
throw new Error(`ghostty_key_encoder_new failed with result ${result}`);
}
encoderPtr = new DataView(getBuffer()).getUint32(encoderPtrPtr, true);
// Set kitty flags based on checkboxes
updateEncoderFlags();
statusDiv.textContent = '';
keyInput.disabled = false;
keyInput.focus();
// Listen for key events (only keydown since action is selected manually)
keyInput.addEventListener('keydown', handleKeyEvent);
// Listen for flag changes
const flagCheckboxes = document.querySelectorAll('.checkbox-group input[type="checkbox"]');
flagCheckboxes.forEach(checkbox => {
checkbox.addEventListener('change', updateEncoderFlags);
});
// Listen for action changes
const actionRadios = document.querySelectorAll('input[name="action"]');
actionRadios.forEach(radio => {
radio.addEventListener('change', reencodeLastKey);
});
} catch (e) {
statusDiv.textContent = `Error: ${e.message}`;
statusDiv.style.color = '#c00';
outputDiv.className = 'output error';
outputDiv.textContent = `Error: ${e.message}\n\nStack trace:\n${e.stack}`;
}
}
// Initialize on page load
window.addEventListener('DOMContentLoaded', init);
</script>
</body>
</html>

View File

@ -0,0 +1,39 @@
# WebAssembly SGR Parser Example
This example demonstrates how to use the Ghostty VT library from WebAssembly
to parse terminal SGR (Select Graphic Rendition) sequences and extract text
styling attributes.
## Building
First, build the WebAssembly module:
```bash
zig build lib-vt -Dtarget=wasm32-freestanding -Doptimize=ReleaseSmall
```
This will create `zig-out/bin/ghostty-vt.wasm`.
## Running
**Important:** You must serve this via HTTP, not open it as a file directly.
Browsers block loading WASM files from `file://` URLs.
From the **root of the ghostty repository**, serve with a local HTTP server:
```bash
# Using Python (recommended)
python3 -m http.server 8000
# Or using Node.js
npx serve .
# Or using PHP
php -S localhost:8000
```
Then open your browser to:
```
http://localhost:8000/example/wasm-sgr/
```

457
example/wasm-sgr/index.html Normal file
View File

@ -0,0 +1,457 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Ghostty VT SGR Parser - WebAssembly Example</title>
<style>
body {
font-family: system-ui, -apple-system, sans-serif;
max-width: 900px;
margin: 40px auto;
padding: 0 20px;
line-height: 1.6;
}
h1 {
color: #333;
}
.input-section {
background: #f9f9f9;
border: 1px solid #ddd;
border-radius: 4px;
padding: 15px;
margin: 20px 0;
}
.input-section h3 {
margin-top: 0;
margin-bottom: 10px;
font-size: 16px;
}
textarea {
width: 100%;
padding: 10px;
font-family: 'Courier New', monospace;
font-size: 14px;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
resize: vertical;
}
button {
background: #0066cc;
color: white;
border: none;
padding: 10px 20px;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
margin-top: 10px;
}
button:hover {
background: #0052a3;
}
button:disabled {
background: #ccc;
cursor: not-allowed;
}
.output {
background: #f5f5f5;
border: 1px solid #ddd;
border-radius: 4px;
padding: 15px;
margin: 20px 0;
font-family: 'Courier New', monospace;
white-space: pre-wrap;
font-size: 14px;
}
.error {
background: #fee;
border-color: #faa;
color: #c00;
}
.status {
color: #666;
font-size: 14px;
margin: 10px 0;
}
.attribute {
padding: 8px;
margin: 5px 0;
background: white;
border-left: 3px solid #0066cc;
}
.attribute-name {
font-weight: bold;
color: #0066cc;
}
</style>
</head>
<body>
<h1>Ghostty VT SGR Parser - WebAssembly Example</h1>
<p>This example demonstrates parsing terminal SGR (Select Graphic Rendition) sequences using the Ghostty VT WebAssembly module.</p>
<div class="status" id="status">Loading WebAssembly module...</div>
<div class="input-section">
<h3>SGR Sequence</h3>
<label for="sequence">Enter SGR sequence (numbers separated by ':' or ';'):</label>
<textarea id="sequence" rows="2" disabled>4:3;38;2;51;51;51;48;2;170;170;170;58;2;255;97;136</textarea>
<p style="font-size: 13px; color: #666; margin-top: 5px;">The parser runs live as you type.</p>
</div>
<div id="output" class="output">Waiting for input...</div>
<p><strong>Note:</strong> This example must be served via HTTP (not opened directly as a file). See the README for instructions.</p>
<script>
let wasmInstance = null;
let wasmMemory = null;
async function loadWasm() {
try {
const response = await fetch('../../zig-out/bin/ghostty-vt.wasm');
const wasmBytes = await response.arrayBuffer();
const wasmModule = await WebAssembly.instantiate(wasmBytes, {
env: {
log: (ptr, len) => {
const bytes = new Uint8Array(wasmModule.instance.exports.memory.buffer, ptr, len);
const text = new TextDecoder().decode(bytes);
console.log('[wasm]', text);
}
}
});
wasmInstance = wasmModule.instance;
wasmMemory = wasmInstance.exports.memory;
return true;
} catch (e) {
console.error('Failed to load WASM:', e);
if (window.location.protocol === 'file:') {
throw new Error('Cannot load WASM from file:// protocol. Please serve via HTTP (see README)');
}
return false;
}
}
function getBuffer() {
return wasmMemory.buffer;
}
// SGR attribute tag values from include/ghostty/vt/sgr.h
const SGR_ATTR_TAGS = {
UNSET: 0,
UNKNOWN: 1,
BOLD: 2,
RESET_BOLD: 3,
ITALIC: 4,
RESET_ITALIC: 5,
FAINT: 6,
UNDERLINE: 7,
RESET_UNDERLINE: 8,
UNDERLINE_COLOR: 9,
UNDERLINE_COLOR_256: 10,
RESET_UNDERLINE_COLOR: 11,
OVERLINE: 12,
RESET_OVERLINE: 13,
BLINK: 14,
RESET_BLINK: 15,
INVERSE: 16,
RESET_INVERSE: 17,
INVISIBLE: 18,
RESET_INVISIBLE: 19,
STRIKETHROUGH: 20,
RESET_STRIKETHROUGH: 21,
DIRECT_COLOR_FG: 22,
DIRECT_COLOR_BG: 23,
BG_8: 24,
FG_8: 25,
RESET_FG: 26,
RESET_BG: 27,
BRIGHT_BG_8: 28,
BRIGHT_FG_8: 29,
BG_256: 30,
FG_256: 31
};
// Underline style values
const UNDERLINE_STYLES = {
0: 'none',
1: 'single',
2: 'double',
3: 'curly',
4: 'dotted',
5: 'dashed'
};
function getTagName(tag) {
for (const [name, value] of Object.entries(SGR_ATTR_TAGS)) {
if (value === tag) return name;
}
return `UNKNOWN(${tag})`;
}
function parseSGR() {
const outputDiv = document.getElementById('output');
try {
const sequenceText = document.getElementById('sequence').value.trim();
if (!sequenceText) {
outputDiv.className = 'output';
outputDiv.textContent = 'Enter an SGR sequence to parse...';
return;
}
// Parse the raw sequence into parameters and separators
const params = [];
const separators = [];
let currentNum = '';
for (let i = 0; i < sequenceText.length; i++) {
const char = sequenceText[i];
if (char === ':' || char === ';') {
if (currentNum) {
const num = parseInt(currentNum, 10);
if (isNaN(num) || num < 0 || num > 65535) {
throw new Error(`Invalid parameter: ${currentNum}`);
}
params.push(num);
separators.push(char);
currentNum = '';
}
} else if (char >= '0' && char <= '9') {
currentNum += char;
} else if (char !== ' ' && char !== '\t' && char !== '\n') {
throw new Error(`Invalid character in sequence: '${char}'`);
}
}
// Don't forget the last number
if (currentNum) {
const num = parseInt(currentNum, 10);
if (isNaN(num) || num < 0 || num > 65535) {
throw new Error(`Invalid parameter: ${currentNum}`);
}
params.push(num);
}
if (params.length === 0) {
outputDiv.className = 'output error';
outputDiv.textContent = 'Error: No parameters found in sequence';
return;
}
// Create SGR parser
const parserPtrPtr = wasmInstance.exports.ghostty_wasm_alloc_opaque();
const result = wasmInstance.exports.ghostty_sgr_new(0, parserPtrPtr);
if (result !== 0) {
throw new Error(`ghostty_sgr_new failed with result ${result}`);
}
const parserPtr = new DataView(getBuffer()).getUint32(parserPtrPtr, true);
// Allocate and set parameters
const paramsPtr = wasmInstance.exports.ghostty_wasm_alloc_u16_array(params.length);
const paramsView = new Uint16Array(getBuffer(), paramsPtr, params.length);
params.forEach((p, i) => paramsView[i] = p);
// Allocate and set separators (or use null if empty)
let sepsPtr = 0;
if (separators.length > 0) {
sepsPtr = wasmInstance.exports.ghostty_wasm_alloc_u8_array(separators.length);
const sepsView = new Uint8Array(getBuffer(), sepsPtr, separators.length);
separators.forEach((s, i) => sepsView[i] = s.charCodeAt(0));
}
// Set parameters in parser
const setResult = wasmInstance.exports.ghostty_sgr_set_params(
parserPtr,
paramsPtr,
sepsPtr,
params.length
);
if (setResult !== 0) {
throw new Error(`ghostty_sgr_set_params failed with result ${setResult}`);
}
// Build output
let output = 'Parsing SGR sequence:\n';
output += 'ESC[';
params.forEach((p, i) => {
if (i > 0) output += separators[i - 1];
output += p;
});
output += 'm\n\n';
// Iterate through attributes
const attrPtr = wasmInstance.exports.ghostty_wasm_alloc_sgr_attribute();
let count = 0;
while (wasmInstance.exports.ghostty_sgr_next(parserPtr, attrPtr)) {
count++;
// Use the new ghostty_sgr_attribute_tag getter function
const tag = wasmInstance.exports.ghostty_sgr_attribute_tag(attrPtr);
// Use ghostty_sgr_attribute_value to get a pointer to the value union
const valuePtr = wasmInstance.exports.ghostty_sgr_attribute_value(attrPtr);
output += `Attribute ${count}: `;
switch (tag) {
case SGR_ATTR_TAGS.UNDERLINE: {
const view = new DataView(getBuffer(), valuePtr, 4);
const style = view.getUint32(0, true);
output += `Underline style = ${UNDERLINE_STYLES[style] || `unknown(${style})`}\n`;
break;
}
case SGR_ATTR_TAGS.DIRECT_COLOR_FG: {
// Use ghostty_color_rgb_get to extract RGB components
const rPtr = wasmInstance.exports.ghostty_wasm_alloc_u8();
const gPtr = wasmInstance.exports.ghostty_wasm_alloc_u8();
const bPtr = wasmInstance.exports.ghostty_wasm_alloc_u8();
wasmInstance.exports.ghostty_color_rgb_get(valuePtr, rPtr, gPtr, bPtr);
const r = new Uint8Array(getBuffer(), rPtr, 1)[0];
const g = new Uint8Array(getBuffer(), gPtr, 1)[0];
const b = new Uint8Array(getBuffer(), bPtr, 1)[0];
output += `Foreground RGB = (${r}, ${g}, ${b})\n`;
wasmInstance.exports.ghostty_wasm_free_u8(rPtr);
wasmInstance.exports.ghostty_wasm_free_u8(gPtr);
wasmInstance.exports.ghostty_wasm_free_u8(bPtr);
break;
}
case SGR_ATTR_TAGS.DIRECT_COLOR_BG: {
// Use ghostty_color_rgb_get to extract RGB components
const rPtr = wasmInstance.exports.ghostty_wasm_alloc_u8();
const gPtr = wasmInstance.exports.ghostty_wasm_alloc_u8();
const bPtr = wasmInstance.exports.ghostty_wasm_alloc_u8();
wasmInstance.exports.ghostty_color_rgb_get(valuePtr, rPtr, gPtr, bPtr);
const r = new Uint8Array(getBuffer(), rPtr, 1)[0];
const g = new Uint8Array(getBuffer(), gPtr, 1)[0];
const b = new Uint8Array(getBuffer(), bPtr, 1)[0];
output += `Background RGB = (${r}, ${g}, ${b})\n`;
wasmInstance.exports.ghostty_wasm_free_u8(rPtr);
wasmInstance.exports.ghostty_wasm_free_u8(gPtr);
wasmInstance.exports.ghostty_wasm_free_u8(bPtr);
break;
}
case SGR_ATTR_TAGS.UNDERLINE_COLOR: {
// Use ghostty_color_rgb_get to extract RGB components
const rPtr = wasmInstance.exports.ghostty_wasm_alloc_u8();
const gPtr = wasmInstance.exports.ghostty_wasm_alloc_u8();
const bPtr = wasmInstance.exports.ghostty_wasm_alloc_u8();
wasmInstance.exports.ghostty_color_rgb_get(valuePtr, rPtr, gPtr, bPtr);
const r = new Uint8Array(getBuffer(), rPtr, 1)[0];
const g = new Uint8Array(getBuffer(), gPtr, 1)[0];
const b = new Uint8Array(getBuffer(), bPtr, 1)[0];
output += `Underline color RGB = (${r}, ${g}, ${b})\n`;
wasmInstance.exports.ghostty_wasm_free_u8(rPtr);
wasmInstance.exports.ghostty_wasm_free_u8(gPtr);
wasmInstance.exports.ghostty_wasm_free_u8(bPtr);
break;
}
case SGR_ATTR_TAGS.FG_8:
case SGR_ATTR_TAGS.BG_8:
case SGR_ATTR_TAGS.FG_256:
case SGR_ATTR_TAGS.BG_256:
case SGR_ATTR_TAGS.UNDERLINE_COLOR_256: {
const view = new DataView(getBuffer(), valuePtr, 1);
const color = view.getUint8(0);
const colorType = tag === SGR_ATTR_TAGS.FG_8 ? 'Foreground 8-color' :
tag === SGR_ATTR_TAGS.BG_8 ? 'Background 8-color' :
tag === SGR_ATTR_TAGS.FG_256 ? 'Foreground 256-color' :
tag === SGR_ATTR_TAGS.BG_256 ? 'Background 256-color' :
'Underline 256-color';
output += `${colorType} = ${color}\n`;
break;
}
case SGR_ATTR_TAGS.BOLD:
output += 'Bold\n';
break;
case SGR_ATTR_TAGS.ITALIC:
output += 'Italic\n';
break;
case SGR_ATTR_TAGS.UNSET:
output += 'Reset all attributes\n';
break;
case SGR_ATTR_TAGS.UNKNOWN:
output += 'Unknown attribute\n';
break;
default:
output += `Other attribute (tag=${getTagName(tag)})\n`;
break;
}
}
output += `\nTotal attributes parsed: ${count}`;
outputDiv.className = 'output';
outputDiv.textContent = output;
// Cleanup
wasmInstance.exports.ghostty_wasm_free_sgr_attribute(attrPtr);
wasmInstance.exports.ghostty_sgr_free(parserPtr);
} catch (e) {
console.error('Parse error:', e);
outputDiv.className = 'output error';
outputDiv.textContent = `Error: ${e.message}\n\nStack trace:\n${e.stack}`;
}
}
async function init() {
const statusDiv = document.getElementById('status');
const sequenceInput = document.getElementById('sequence');
try {
statusDiv.textContent = 'Loading WebAssembly module...';
const loaded = await loadWasm();
if (!loaded) {
throw new Error('Failed to load WebAssembly module');
}
statusDiv.textContent = '';
sequenceInput.disabled = false;
// Parse live as user types
sequenceInput.addEventListener('input', parseSGR);
// Parse the default example on load
parseSGR();
} catch (e) {
statusDiv.textContent = `Error: ${e.message}`;
statusDiv.style.color = '#c00';
}
}
window.addEventListener('DOMContentLoaded', init);
</script>
</body>
</html>

View File

@ -0,0 +1,24 @@
# Example: stdin to HTML using `vtStream` and `TerminalFormatter`
This example demonstrates how to read VT sequences from stdin, parse them
using `vtStream`, and output styled HTML using `TerminalFormatter`. The
purpose of this example is primarily to show how to use formatters with
terminals.
Requires the Zig version stated in the `build.zig.zon` file.
## Usage
Basic usage:
```shell-session
echo -e "Hello \033[1;32mGreen\033[0m World" | zig build run
```
This will output HTML with inline styles and CSS palette variables.
You can also pipe complex terminal output:
```shell-session
ls --color=always | zig build run > output.html
```

View File

@ -0,0 +1,39 @@
const std = @import("std");
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const run_step = b.step("run", "Run the app");
const test_step = b.step("test", "Run unit tests");
const exe_mod = b.createModule(.{
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
});
if (b.lazyDependency("ghostty", .{})) |dep| {
exe_mod.addImport(
"ghostty-vt",
dep.module("ghostty-vt"),
);
}
const exe = b.addExecutable(.{
.name = "zig_formatter",
.root_module = exe_mod,
});
b.installArtifact(exe);
const run_cmd = b.addRunArtifact(exe);
run_cmd.step.dependOn(b.getInstallStep());
if (b.args) |args| run_cmd.addArgs(args);
run_step.dependOn(&run_cmd.step);
const exe_unit_tests = b.addTest(.{
.root_module = exe_mod,
});
const run_exe_unit_tests = b.addRunArtifact(exe_unit_tests);
test_step.dependOn(&run_exe_unit_tests.step);
}

View File

@ -0,0 +1,13 @@
.{
.name = .zig_formatter,
.version = "0.0.0",
.fingerprint = 0x578de530797eafe6,
.dependencies = .{
.ghostty = .{ .path = "../../" },
},
.paths = .{
"build.zig",
"build.zig.zon",
"src",
},
}

View File

@ -0,0 +1,42 @@
const std = @import("std");
const ghostty_vt = @import("ghostty-vt");
pub fn main() !void {
var gpa: std.heap.DebugAllocator(.{}) = .init;
defer _ = gpa.deinit();
const alloc = gpa.allocator();
// Create a terminal
var t: ghostty_vt.Terminal = try .init(alloc, .{ .cols = 150, .rows = 80 });
defer t.deinit(alloc);
// Create a read-only VT stream for parsing terminal sequences
var stream = t.vtStream();
defer stream.deinit();
// Read from stdin
const stdin = std.fs.File.stdin();
var buf: [4096]u8 = undefined;
while (true) {
const n = try stdin.readAll(&buf);
if (n == 0) break;
// Replace \n with \r\n
for (buf[0..n]) |byte| {
if (byte == '\n') try stream.next('\r');
try stream.next(byte);
}
}
// Use TerminalFormatter to emit HTML
const formatter: ghostty_vt.formatter.TerminalFormatter = .init(&t, .{
.emit = .html,
.palette = &t.colors.palette.current,
});
// Write to stdout
var stdout_writer = std.fs.File.stdout().writer(&buf);
const stdout = &stdout_writer.interface;
try stdout.print("{f}", .{formatter});
try stdout.flush();
}

View File

@ -0,0 +1,33 @@
# Example: `vtStream` API for Parsing Terminal Streams
This example demonstrates how to use the `vtStream` API to parse and process
VT sequences. The `vtStream` API is ideal for read-only terminal applications
that need to parse terminal output without responding to queries, such as:
- Replay tooling
- CI log viewers
- PaaS builder output
- etc.
The stream processes VT escape sequences and updates terminal state, while
ignoring sequences that require responses (like device status queries).
Requires the Zig version stated in the `build.zig.zon` file.
## Usage
Run the program:
```shell-session
zig build run
```
The example will process various VT sequences including:
- Plain text output
- ANSI color codes
- Cursor positioning
- Line clearing
- Multiple line handling
And display the final terminal state after processing all sequences.

View File

@ -0,0 +1,39 @@
const std = @import("std");
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const run_step = b.step("run", "Run the app");
const test_step = b.step("test", "Run unit tests");
const exe_mod = b.createModule(.{
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
});
if (b.lazyDependency("ghostty", .{})) |dep| {
exe_mod.addImport(
"ghostty-vt",
dep.module("ghostty-vt"),
);
}
const exe = b.addExecutable(.{
.name = "zig_vt_stream",
.root_module = exe_mod,
});
b.installArtifact(exe);
const run_cmd = b.addRunArtifact(exe);
run_cmd.step.dependOn(b.getInstallStep());
if (b.args) |args| run_cmd.addArgs(args);
run_step.dependOn(&run_cmd.step);
const exe_unit_tests = b.addTest(.{
.root_module = exe_mod,
});
const run_exe_unit_tests = b.addRunArtifact(exe_unit_tests);
test_step.dependOn(&run_exe_unit_tests.step);
}

View File

@ -0,0 +1,14 @@
.{
.name = .zig_vt_stream,
.version = "0.0.0",
.fingerprint = 0x34c1f71303690b3f,
.minimum_zig_version = "0.15.1",
.dependencies = .{
.ghostty = .{ .path = "../../" },
},
.paths = .{
"build.zig",
"build.zig.zon",
"src",
},
}

View File

@ -0,0 +1,40 @@
const std = @import("std");
const ghostty_vt = @import("ghostty-vt");
pub fn main() !void {
var gpa: std.heap.DebugAllocator(.{}) = .init;
defer _ = gpa.deinit();
const alloc = gpa.allocator();
var t: ghostty_vt.Terminal = try .init(alloc, .{ .cols = 80, .rows = 24 });
defer t.deinit(alloc);
// Create a read-only VT stream for parsing terminal sequences
var stream = t.vtStream();
defer stream.deinit();
// Basic text with newline
try stream.nextSlice("Hello, World!\r\n");
// ANSI color codes: ESC[1;32m = bold green, ESC[0m = reset
try stream.nextSlice("\x1b[1;32mGreen Text\x1b[0m\r\n");
// Cursor positioning: ESC[1;1H = move to row 1, column 1
try stream.nextSlice("\x1b[1;1HTop-left corner\r\n");
// Cursor movement: ESC[5B = move down 5 lines
try stream.nextSlice("\x1b[5B");
try stream.nextSlice("Moved down!\r\n");
// Erase line: ESC[2K = clear entire line
try stream.nextSlice("\x1b[2K");
try stream.nextSlice("New content\r\n");
// Multiple lines
try stream.nextSlice("Line A\r\nLine B\r\nLine C\r\n");
// Get the final terminal state as a plain string
const str = try t.plainString(alloc);
defer alloc.free(str);
std.debug.print("{s}\n", .{str});
}

14
example/zig-vt/README.md Normal file
View File

@ -0,0 +1,14 @@
# Example: `ghostty-vt` Zig Module
This contains a simple example of how to use the `ghostty-vt` Zig module
exported by Ghostty to have access to a production grade terminal emulator.
Requires the Zig version stated in the `build.zig.zon` file.
## Usage
Run the program:
```shell-session
zig build run
```

50
example/zig-vt/build.zig Normal file
View File

@ -0,0 +1,50 @@
const std = @import("std");
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const run_step = b.step("run", "Run the app");
const test_step = b.step("test", "Run unit tests");
const exe_mod = b.createModule(.{
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
});
// You'll want to use a lazy dependency here so that ghostty is only
// downloaded if you actually need it.
if (b.lazyDependency("ghostty", .{
// Setting simd to false will force a pure static build that
// doesn't even require libc, but it has a significant performance
// penalty. If your embedding app requires libc anyway, you should
// always keep simd enabled.
// .simd = false,
})) |dep| {
exe_mod.addImport(
"ghostty-vt",
dep.module("ghostty-vt"),
);
}
// Exe
const exe = b.addExecutable(.{
.name = "zig_vt",
.root_module = exe_mod,
});
b.installArtifact(exe);
// Run
const run_cmd = b.addRunArtifact(exe);
run_cmd.step.dependOn(b.getInstallStep());
if (b.args) |args| run_cmd.addArgs(args);
run_step.dependOn(&run_cmd.step);
// Test
const exe_unit_tests = b.addTest(.{
.root_module = exe_mod,
});
const run_exe_unit_tests = b.addRunArtifact(exe_unit_tests);
test_step.dependOn(&run_exe_unit_tests.step);
}

View File

@ -0,0 +1,24 @@
.{
.name = .zig_vt,
.version = "0.0.0",
.fingerprint = 0x6045575a7a8387e6,
.minimum_zig_version = "0.15.1",
.dependencies = .{
// Ghostty dependency. In reality, you'd probably use a URL-based
// dependency like the one showed (and commented out) below this one.
// We use a path dependency here for simplicity and to ensure our
// examples always test against the source they're bundled with.
.ghostty = .{ .path = "../../" },
// Example of what a URL-based dependency looks like:
// .ghostty = .{
// .url = "https://github.com/ghostty-org/ghostty/archive/COMMIT.tar.gz",
// .hash = "N-V-__8AAMVLTABmYkLqhZPLXnMl-KyN38R8UVYqGrxqO36s",
// },
},
.paths = .{
"build.zig",
"build.zig.zon",
"src",
},
}

View File

@ -0,0 +1,26 @@
const std = @import("std");
const ghostty_vt = @import("ghostty-vt");
pub fn main() !void {
// Use a debug allocator so we get leak checking. You probably want
// to replace this for release builds.
var gpa: std.heap.DebugAllocator(.{}) = .init;
defer _ = gpa.deinit();
const alloc = gpa.allocator();
// Initialize a terminal.
var t: ghostty_vt.Terminal = try .init(alloc, .{
.cols = 6,
.rows = 40,
});
defer t.deinit(alloc);
// Write some text. It'll wrap because this is too long for our
// columns size above (6).
try t.printString("Hello, World!");
// Get the plain string view of the terminal screen.
const str = try t.plainString(alloc);
defer alloc.free(str);
std.debug.print("{s}\n", .{str});
}

View File

@ -3,11 +3,11 @@
"flake-compat": {
"flake": false,
"locked": {
"lastModified": 1733328505,
"narHash": "sha256-NeCCThCEP3eCl2l/+27kNNK7QrwZB1IJCrXfrbv5oqU=",
"lastModified": 1761588595,
"narHash": "sha256-XKUZz9zewJNUj46b4AJdiRZJAvSZ0Dqj2BNfXvFlJC4=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "ff81ac966bb2cae68946d5ed5fc4994f96d0ffec",
"rev": "f387cd2afec9419c8ee37694406ca490c3f34ee5",
"type": "github"
},
"original": {
@ -34,46 +34,48 @@
"type": "github"
}
},
"nixpkgs-stable": {
"home-manager": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1738255539,
"narHash": "sha256-hP2eOqhIO/OILW+3moNWO4GtdJFYCqAe9yJZgvlCoDQ=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "c3511a3b53b482aa7547c9d1626fd7310c1de1c5",
"lastModified": 1755776884,
"narHash": "sha256-CPM7zm6csUx7vSfKvzMDIjepEJv1u/usmaT7zydzbuI=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "4fb695d10890e9fc6a19deadf85ff79ffb78da86",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "release-24.11",
"repo": "nixpkgs",
"owner": "nix-community",
"ref": "release-25.05",
"repo": "home-manager",
"type": "github"
}
},
"nixpkgs-unstable": {
"nixpkgs": {
"locked": {
"lastModified": 1738136902,
"narHash": "sha256-pUvLijVGARw4u793APze3j6mU1Zwdtz7hGkGGkD87qw=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "9a5db3142ce450045840cc8d832b13b8a2018e0c",
"type": "github"
"lastModified": 1763191728,
"narHash": "sha256-gI9PpaoX4/f28HkjcTbFVpFhtOxSDtOEdFaHZrdETe0=",
"rev": "1d4c88323ac36805d09657d13a5273aea1b34f0c",
"type": "tarball",
"url": "https://releases.nixos.org/nixpkgs/nixpkgs-25.11pre896415.1d4c88323ac3/nixexprs.tar.xz"
},
"original": {
"owner": "nixos",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
"type": "tarball",
"url": "https://channels.nixos.org/nixpkgs-unstable/nixexprs.tar.xz"
}
},
"root": {
"inputs": {
"flake-compat": "flake-compat",
"flake-utils": "flake-utils",
"nixpkgs-stable": "nixpkgs-stable",
"nixpkgs-unstable": "nixpkgs-unstable",
"home-manager": "home-manager",
"nixpkgs": "nixpkgs",
"zig": "zig",
"zig2nix": "zig2nix"
"zon2nix": "zon2nix"
}
},
"systems": {
@ -93,20 +95,22 @@
},
"zig": {
"inputs": {
"flake-compat": [],
"flake-compat": [
"flake-compat"
],
"flake-utils": [
"flake-utils"
],
"nixpkgs": [
"nixpkgs-stable"
"nixpkgs"
]
},
"locked": {
"lastModified": 1738239110,
"narHash": "sha256-Y5i9mQ++dyIQr+zEPNy+KIbc5wjPmfllBrag3cHZgcE=",
"lastModified": 1763295135,
"narHash": "sha256-sGv/NHCmEnJivguGwB5w8LRmVqr1P72OjS+NzcJsssE=",
"owner": "mitchellh",
"repo": "zig-overlay",
"rev": "1a8fb6f3a04724519436355564b95fce5e272504",
"rev": "64f8b42cfc615b2cf99144adf2b7728c7847c72a",
"type": "github"
},
"original": {
@ -115,27 +119,24 @@
"type": "github"
}
},
"zig2nix": {
"zon2nix": {
"inputs": {
"flake-utils": [
"flake-utils"
],
"nixpkgs": [
"nixpkgs-stable"
"nixpkgs"
]
},
"locked": {
"lastModified": 1738263917,
"narHash": "sha256-j/3fwe2pEOquHabP/puljOKwAZFjIE9gXZqA91sC48M=",
"lastModified": 1758405547,
"narHash": "sha256-WgaDgvIZMPvlZcZrpPMjkaalTBnGF2lTG+62znXctWM=",
"owner": "jcollie",
"repo": "zig2nix",
"rev": "c311d8e77a6ee0d995f40a6e10a89a3a4ab04f9a",
"repo": "zon2nix",
"rev": "bf983aa90ff169372b9fa8c02e57ea75e0b42245",
"type": "github"
},
"original": {
"owner": "jcollie",
"ref": "c311d8e77a6ee0d995f40a6e10a89a3a4ab04f9a",
"repo": "zig2nix",
"repo": "zon2nix",
"rev": "bf983aa90ff169372b9fa8c02e57ea75e0b42245",
"type": "github"
}
}

View File

@ -2,12 +2,14 @@
description = "👻";
inputs = {
nixpkgs-unstable.url = "github:nixos/nixpkgs/nixpkgs-unstable";
# We want to stay as up to date as possible but need to be careful that the
# glibc versions used by our dependencies from Nix are compatible with the
# system glibc that the user is building for.
nixpkgs-stable.url = "github:nixos/nixpkgs/release-24.11";
#
# We are currently on nixpkgs-unstable to get Zig 0.15 for our package.nix and
# Gnome 49/Gtk 4.20.
#
nixpkgs.url = "https://channels.nixos.org/nixpkgs-unstable/nixexprs.tar.xz";
flake-utils.url = "github:numtide/flake-utils";
# Used for shell.nix
@ -19,39 +21,52 @@
zig = {
url = "github:mitchellh/zig-overlay";
inputs = {
nixpkgs.follows = "nixpkgs-stable";
nixpkgs.follows = "nixpkgs";
flake-utils.follows = "flake-utils";
flake-compat.follows = "";
flake-compat.follows = "flake-compat";
};
};
zig2nix = {
url = "github:jcollie/zig2nix?ref=c311d8e77a6ee0d995f40a6e10a89a3a4ab04f9a";
zon2nix = {
url = "github:jcollie/zon2nix?rev=bf983aa90ff169372b9fa8c02e57ea75e0b42245";
inputs = {
nixpkgs.follows = "nixpkgs-stable";
flake-utils.follows = "flake-utils";
nixpkgs.follows = "nixpkgs";
};
};
home-manager = {
url = "github:nix-community/home-manager?ref=release-25.05";
inputs = {
nixpkgs.follows = "nixpkgs";
};
};
};
outputs = {
self,
nixpkgs-unstable,
nixpkgs-stable,
nixpkgs,
zig,
zig2nix,
zon2nix,
home-manager,
...
}:
builtins.foldl' nixpkgs-stable.lib.recursiveUpdate {} (
builtins.foldl' nixpkgs.lib.recursiveUpdate {} (
builtins.map (
system: let
pkgs-stable = nixpkgs-stable.legacyPackages.${system};
pkgs-unstable = nixpkgs-unstable.legacyPackages.${system};
pkgs = nixpkgs.legacyPackages.${system};
in {
devShell.${system} = pkgs-stable.callPackage ./nix/devShell.nix {
zig = zig.packages.${system}."0.13.0";
wraptest = pkgs-stable.callPackage ./nix/wraptest.nix {};
zig2nix = zig2nix;
devShells.${system}.default = pkgs.callPackage ./nix/devShell.nix {
zig = zig.packages.${system}."0.15.2";
wraptest = pkgs.callPackage ./nix/pkgs/wraptest.nix {};
zon2nix = zon2nix;
python3 = pkgs.python3.override {
self = pkgs.python3;
packageOverrides = pyfinal: pyprev: {
blessed = pyfinal.callPackage ./nix/pkgs/blessed.nix {};
ucs-detect = pyfinal.callPackage ./nix/pkgs/ucs-detect.nix {};
};
};
};
packages.${system} = let
@ -61,34 +76,40 @@
revision = self.shortRev or self.dirtyShortRev or "dirty";
};
in rec {
deps = pkgs-stable.callPackage ./build.zig.zon.nix {};
ghostty-debug = pkgs-stable.callPackage ./nix/package.nix (mkArgs "Debug");
ghostty-releasesafe = pkgs-stable.callPackage ./nix/package.nix (mkArgs "ReleaseSafe");
ghostty-releasefast = pkgs-stable.callPackage ./nix/package.nix (mkArgs "ReleaseFast");
deps = pkgs.callPackage ./build.zig.zon.nix {};
ghostty-debug = pkgs.callPackage ./nix/package.nix (mkArgs "Debug");
ghostty-releasesafe = pkgs.callPackage ./nix/package.nix (mkArgs "ReleaseSafe");
ghostty-releasefast = pkgs.callPackage ./nix/package.nix (mkArgs "ReleaseFast");
ghostty = ghostty-releasefast;
default = ghostty;
};
formatter.${system} = pkgs-stable.alejandra;
formatter.${system} = pkgs.alejandra;
checks.${system} = import ./nix/tests.nix {
inherit home-manager nixpkgs self system;
};
apps.${system} = let
runVM = (
module: let
vm = import ./nix/vm/create.nix {
inherit system module;
nixpkgs = nixpkgs-stable;
inherit system module nixpkgs;
overlay = self.overlays.debug;
};
program = pkgs-stable.writeShellScript "run-ghostty-vm" ''
program = pkgs.writeShellScript "run-ghostty-vm" ''
SHARED_DIR=$(pwd)
export SHARED_DIR
${pkgs-stable.lib.getExe vm.config.system.build.vm} "$@"
${pkgs.lib.getExe vm.config.system.build.vm} "$@"
'';
in {
type = "app";
program = "${program}";
meta = {
description = "start a vm from ${toString module}";
};
}
);
in {
@ -108,17 +129,12 @@
overlays = {
default = self.overlays.releasefast;
releasefast = final: prev: {
ghostty = self.packages.${prev.system}.ghostty-releasefast;
ghostty = self.packages.${prev.stdenv.hostPlatform.system}.ghostty-releasefast;
};
debug = final: prev: {
ghostty = self.packages.${prev.system}.ghostty-debug;
ghostty = self.packages.${prev.stdenv.hostPlatform.system}.ghostty-debug;
};
};
create-vm = import ./nix/vm/create.nix;
create-cinnamon-vm = import ./nix/vm/create-cinnamon.nix;
create-gnome-vm = import ./nix/vm/create-gnome.nix;
create-plasma6-vm = import ./nix/vm/create-plasma6.nix;
create-xfce-vm = import ./nix/vm/create-xfce.nix;
};
nixConfig = {

View File

@ -0,0 +1,59 @@
app-id: com.mitchellh.ghostty-debug
runtime: org.gnome.Platform
runtime-version: "49"
sdk: org.gnome.Sdk
default-branch: tip
command: ghostty
rename-icon: com.mitchellh.ghostty
finish-args:
# 3D rendering
- --device=dri
# use host PTS namespace
- --device=all
# Windowing
- --share=ipc
- --socket=fallback-x11
- --socket=wayland
# Allow user to specify additional config files in home by default
- --filesystem=home:ro
# So we can escape the sandbox
- --talk-name=org.freedesktop.Flatpak
cleanup:
- /include
- /lib/girepository-1.0
- /lib/pkgconfig
- /share/gir-1.0
- /share/pkgconfig
- /share/vala
- "*.la"
- "*.a"
- "*.so"
modules:
- dependencies.yml
- name: ghostty
buildsystem: simple
build-options:
append-path: /app/zig
build-commands:
- zig build
-Doptimize=Debug
-Dcpu=baseline
-Dflatpak=true
-Dstrip=false
-fno-sys=oniguruma
--prefix /app
--search-prefix /app
--system $PWD/vendor/p
sources:
- type: dir
path: ..
skip:
- flatpak/.flatpak-builder
- flatpak/builddir
- flatpak/repo
- zig-cache
- zig-out
- zig-packages.json

View File

@ -0,0 +1,58 @@
app-id: com.mitchellh.ghostty
runtime: org.gnome.Platform
runtime-version: "49"
sdk: org.gnome.Sdk
default-branch: tip
command: ghostty
finish-args:
# 3D rendering
- --device=dri
# use host PTS namespace
- --device=all
# Windowing
- --share=ipc
- --socket=fallback-x11
- --socket=wayland
# Allow user to specify additional config files in home by default
- --filesystem=home:ro
# So we can escape the sandbox
- --talk-name=org.freedesktop.Flatpak
cleanup:
- /include
- /lib/girepository-1.0
- /lib/pkgconfig
- /share/gir-1.0
- /share/pkgconfig
- /share/vala
- "*.la"
- "*.a"
- "*.so"
modules:
- dependencies.yml
- name: ghostty
buildsystem: simple
build-options:
append-path: /app/zig
build-commands:
- zig build
-Doptimize=ReleaseFast
-Dcpu=baseline
-Dflatpak=true
-Dstrip=false
-fno-sys=oniguruma
--prefix /app
--search-prefix /app
--system $PWD/vendor/p
sources:
- type: dir
path: ..
skip:
- flatpak/.flatpak-builder
- flatpak/builddir
- flatpak/repo
- zig-cache
- zig-out
- zig-packages.json

71
flatpak/dependencies.yml Normal file
View File

@ -0,0 +1,71 @@
name: dependencies-meta
buildsystem: simple
build-commands:
- true
modules:
- name: zig
buildsystem: simple
cleanup:
- "*"
build-commands:
- mkdir -p /app/zig
- cp -r ./* /app/zig
- chmod a+x /app/zig/zig
sources:
- type: archive
sha256: 02aa270f183da276e5b5920b1dac44a63f1a49e55050ebde3aecc9eb82f93239
url: https://ziglang.org/download/0.15.2/zig-x86_64-linux-0.15.2.tar.xz
only-arches: [x86_64]
- type: archive
sha256: 958ed7d1e00d0ea76590d27666efbf7a932281b3d7ba0c6b01b0ff26498f667f
url: https://ziglang.org/download/0.15.2/zig-aarch64-linux-0.15.2.tar.xz
only-arches: [aarch64]
- name: bzip2-redirect
buildsystem: simple
build-commands:
- install -Dm644 libbzip2.so /app/lib/libbzip2.so
sources:
- type: inline
contents: INPUT(libbz2.so)
dest-filename: libbzip2.so
- name: gtk4-layer-shell
buildsystem: meson
sources:
# no x-checker-data since this should be synchronized with Nix
#
# TODO: Automate this with check-zig-cache.sh
- type: archive
url: https://github.com/wmww/gtk4-layer-shell/archive/refs/tags/v1.1.0.tar.gz
sha256: 98284281260a5eef5b4f63a55f16c4bf6a788a1020a6db037ecb0f71fa336988
- name: pandoc
buildsystem: simple
cleanup:
- "*"
build-commands:
- install -Dm755 bin/pandoc /app/bin/pandoc
sources:
- type: archive
sha256: d04c95c138202f87d6b00ac19aa3dd874c681f60a9feb3b55c74f764d6d1a17d
url: https://github.com/jgm/pandoc/releases/download/3.6.3/pandoc-3.6.3-linux-amd64.tar.gz
only-arches: [x86_64]
x-checker-data:
type: json
url: https://api.github.com/repos/jgm/pandoc/releases/latest
url-query:
.assets[] | select(.name=="pandoc-" + $version + "-linux-amd64.tar.gz")
| .browser_download_url
version-query: .tag_name
- type: archive
sha256: 4e774cb1bdb6e56bc55b8eb79200bd9aa6a39905a04ecda7267f5149116f0881
url: https://github.com/jgm/pandoc/releases/download/3.6.3/pandoc-3.6.3-linux-arm64.tar.gz
only-arches: [aarch64]
x-checker-data:
type: json
url: https://api.github.com/repos/jgm/pandoc/releases/latest
url-query:
.assets[] | select(.name=="pandoc-" + $version + "-linux-arm64.tar.gz")
| .browser_download_url
version-query: .tag_name

3
flatpak/exceptions.json Normal file
View File

@ -0,0 +1,3 @@
{
"com.mitchellh.ghostty": ["finish-args-flatpak-spawn-access"]
}

212
flatpak/zig-packages.json Normal file
View File

@ -0,0 +1,212 @@
[
{
"type": "archive",
"url": "https://deps.files.ghostty.org/breakpad-b99f444ba5f6b98cac261cbb391d8766b34a5918.tar.gz",
"dest": "vendor/p/N-V-__8AALw2uwF_03u4JRkZwRLc3Y9hakkYV7NKRR9-RIZJ",
"sha256": "6cca98943d1a990766cef61077c09aff5938063fe17a1efe1228e5412b6d6ad9"
},
{
"type": "archive",
"url": "https://deps.files.ghostty.org/fontconfig-2.14.2.tar.gz",
"dest": "vendor/p/N-V-__8AAIrfdwARSa-zMmxWwFuwpXf1T3asIN7s5jqi9c1v",
"sha256": "3ba2dd92158718acec5caaf1a716043b5aa055c27b081d914af3ccb40dce8a55"
},
{
"type": "archive",
"url": "https://deps.files.ghostty.org/freetype-1220b81f6ecfb3fd222f76cf9106fecfa6554ab07ec7fdc4124b9bb063ae2adf969d.tar.gz",
"dest": "vendor/p/N-V-__8AAKLKpwC4H27Ps_0iL3bPkQb-z6ZVSrB-x_3EEkub",
"sha256": "427201f5d5151670d05c1f5b45bef5dda1f2e7dd971ef54f0feaaa7ffd2ab90c"
},
{
"type": "archive",
"url": "https://deps.files.ghostty.org/gettext-0.24.tar.gz",
"dest": "vendor/p/N-V-__8AADcZkgn4cMhTUpIz6mShCKyqqB-NBtf_S2bHaTC-",
"sha256": "c918503d593d70daf4844d175a13d816afacb667c06fba1ec9dcd5002c1518b7"
},
{
"type": "archive",
"url": "https://deps.files.ghostty.org/glslang-12201278a1a05c0ce0b6eb6026c65cd3e9247aa041b1c260324bf29cee559dd23ba1.tar.gz",
"dest": "vendor/p/N-V-__8AABzkUgISeKGgXAzgtutgJsZc0-kkeqBBscJgMkvy",
"sha256": "14a2edbb509cb3e51a9a53e3f5e435dbf5971604b4b833e63e6076e8c0a997b5"
},
{
"type": "archive",
"url": "https://deps.files.ghostty.org/gobject-2025-11-08-23-1.tar.zst",
"dest": "vendor/p/gobject-0.3.0-Skun7ANLnwDvEfIpVmohcppXgOvg_I6YOJFmPIsKfXk-",
"sha256": "d9bd4306f0081d8e4b848b6adfeabd2fab49822ee2b679eb4801dcedf5d60c48"
},
{
"type": "archive",
"url": "https://deps.files.ghostty.org/gtk4-layer-shell-1.1.0.tar.gz",
"dest": "vendor/p/N-V-__8AALiNBAA-_0gprYr92CjrMj1I5bqNu0TSJOnjFNSr",
"sha256": "98284281260a5eef5b4f63a55f16c4bf6a788a1020a6db037ecb0f71fa336988"
},
{
"type": "archive",
"url": "https://deps.files.ghostty.org/harfbuzz-11.0.0.tar.xz",
"dest": "vendor/p/N-V-__8AAG02ugUcWec-Ndp-i7JTsJ0dgF8nnJRUInkGLG7G",
"sha256": "f16351bafe214725fe2c1d5b59f0d93e49905a4b247899fb90d70cff953a2b9b"
},
{
"type": "archive",
"url": "https://deps.files.ghostty.org/highway-66486a10623fa0d72fe91260f96c892e41aceb06.tar.gz",
"dest": "vendor/p/N-V-__8AAGmZhABbsPJLfbqrh6JTHsXhY6qCaLAQyx25e0XE",
"sha256": "87d4f8893ef4e08f224973608ffebf94268a81380ba79c12e8841968c80aa212"
},
{
"type": "archive",
"url": "https://deps.files.ghostty.org/imgui-1220bc6b9daceaf7c8c60f3c3998058045ba0c5c5f48ae255ff97776d9cd8bfc6402.tar.gz",
"dest": "vendor/p/N-V-__8AAH0GaQC8a52s6vfIxg88OZgFgEW6DFxfSK4lX_l3",
"sha256": "a05fd01e04cf11ab781e28387c621d2e420f1e6044c8e27a25e603ea99ef7860"
},
{
"type": "archive",
"url": "https://github.com/mbadolato/iTerm2-Color-Schemes/releases/download/release-20251201-150531-bfb3ee1/ghostty-themes.tgz",
"dest": "vendor/p/N-V-__8AANFEAwCzzNzNs3Gaq8pzGNl2BbeyFBwTyO5iZJL-",
"sha256": "e5078f050952b33f56dabe334d2dd00fe70301ec8e6e1479d44d80909dd92149"
},
{
"type": "archive",
"url": "https://deps.files.ghostty.org/JetBrainsMono-2.304.tar.gz",
"dest": "vendor/p/N-V-__8AAIC5lwAVPJJzxnCAahSvZTIlG-HhtOvnM1uh-66x",
"sha256": "c57a691e8b82ad098b5963f3959032e4038f391087af7715885ba59046105cc4"
},
{
"type": "archive",
"url": "https://deps.files.ghostty.org/libpng-1220aa013f0c83da3fb64ea6d327f9173fa008d10e28bc9349eac3463457723b1c66.tar.gz",
"dest": "vendor/p/N-V-__8AAJrvXQCqAT8Mg9o_tk6m0yf5Fz-gCNEOKLyTSerD",
"sha256": "fecc95b46cf05e8e3fc8a414750e0ba5aad00d89e9fdf175e94ff041caf1a03a"
},
{
"type": "archive",
"url": "https://deps.files.ghostty.org/libxev-34fa50878aec6e5fa8f532867001ab3c36fae23e.tar.gz",
"dest": "vendor/p/libxev-0.0.0-86vtc4IcEwCqEYxEYoN_3KXmc6A9VLcm22aVImfvecYs",
"sha256": "6003ea6b96e4a518a128f932327d79a11bd30996b13b73baeb29916379487dd7"
},
{
"type": "archive",
"url": "https://deps.files.ghostty.org/libxml2-2.11.5.tar.gz",
"dest": "vendor/p/N-V-__8AAG3RoQEyRC2Vw7Qoro5SYBf62IHn3HjqtNVY6aWK",
"sha256": "6c28059e2e3eeb42b5b4b16489e3916a6346c1095a74fee3bc65cdc5d89a6215"
},
{
"type": "archive",
"url": "https://deps.files.ghostty.org/NerdFontsSymbolsOnly-3.4.0.tar.gz",
"dest": "vendor/p/N-V-__8AAMVLTABmYkLqhZPLXnMl-KyN38R8UVYqGrxqO26s",
"sha256": "1164d1b956d4bde248d7b2f0998c43cc94f5202431a1564a793895b1e73b0d04"
},
{
"type": "archive",
"url": "https://deps.files.ghostty.org/oniguruma-1220c15e72eadd0d9085a8af134904d9a0f5dfcbed5f606ad60edc60ebeccd9706bb.tar.gz",
"dest": "vendor/p/N-V-__8AAHjwMQDBXnLq3Q2QhaivE0kE2aD138vtX2Bq1g7c",
"sha256": "001aa1202e78448f4c0bf1a48c76e556876b36f16d92ce3207eccfd61d99f2a0"
},
{
"type": "archive",
"url": "https://deps.files.ghostty.org/pixels-12207ff340169c7d40c570b4b6a97db614fe47e0d83b5801a932dcd44917424c8806.tar.gz",
"dest": "vendor/p/N-V-__8AADYiAAB_80AWnH1AxXC0tql9thT-R-DYO1gBqTLc",
"sha256": "55e83b16d091082502bf149bf457f31f42092c5982650e3ffbae7b48871bf11a"
},
{
"type": "archive",
"url": "https://deps.files.ghostty.org/plasma_wayland_protocols-12207e0851c12acdeee0991e893e0132fc87bb763969a585dc16ecca33e88334c566.tar.gz",
"dest": "vendor/p/N-V-__8AAKYZBAB-CFHBKs3u4JkeiT4BMvyHu3Y5aaWF3Bbs",
"sha256": "5c58ba214acd8e6bca3426dc08b022c46a8dd997b29a1b3e28badf71c20df441"
},
{
"type": "archive",
"url": "https://deps.files.ghostty.org/sentry-1220446be831adcca918167647c06c7b825849fa3fba5f22da394667974537a9c77e.tar.gz",
"dest": "vendor/p/N-V-__8AAPlZGwBEa-gxrcypGBZ2R8Bse4JYSfo_ul8i2jlG",
"sha256": "2ac6497cc8d61a8d31093e47addb8c9b2c45b16b0705bb334a835b6423c318df"
},
{
"type": "archive",
"url": "https://deps.files.ghostty.org/spirv_cross-1220fb3b5586e8be67bc3feb34cbe749cf42a60d628d2953632c2f8141302748c8da.tar.gz",
"dest": "vendor/p/N-V-__8AANb6pwD7O1WG6L5nvD_rNMvnSc9Cpg1ijSlTYywv",
"sha256": "b52b6fcfc45e7fa69b1f06a1362c155473444e2cc09995556b156c53ba6657e3"
},
{
"type": "archive",
"url": "https://deps.files.ghostty.org/utfcpp-1220d4d18426ca72fc2b7e56ce47273149815501d0d2395c2a98c726b31ba931e641.tar.gz",
"dest": "vendor/p/N-V-__8AAHffAgDU0YQmynL8K35WzkcnMUmBVQHQ0jlcKpjH",
"sha256": "ffc668a310e77607d393f3c18b32715f223da1eac4c4d6e0579a11df8e6b59cf"
},
{
"type": "git",
"url": "https://github.com/jacobsandlund/uucode",
"commit": "5f05f8f83a75caea201f12cc8ea32a2d82ea9732",
"dest": "vendor/p/uucode-0.1.0-ZZjBPj96QADXyt5sqwBJUnhaDYs_qBeeKijZvlRa0eqM"
},
{
"type": "archive",
"url": "https://deps.files.ghostty.org/uucode-31655fba3c638229989cc524363ef5e3c7b580c1.tar.gz",
"dest": "vendor/p/uucode-0.1.0-ZZjBPicPTQDlG6OClzn2bPu7ICkkkyWrTB6aRsBr-A1E",
"sha256": "4b3a581a1806e01e8bb9ff1e4f7e6c28ba1b0b18e6c04ba8d53c24d237aef60e"
},
{
"type": "archive",
"url": "https://deps.files.ghostty.org/vaxis-7dbb9fd3122e4ffad262dd7c151d80d863b68558.tar.gz",
"dest": "vendor/p/vaxis-0.5.1-BWNV_LosCQAGmCCNOLljCIw6j6-yt53tji6n6rwJ2BhS",
"sha256": "2e72332bc89c5b541ec6e6bd48769e1f3fb757c4006f3d1af940b54f9b088ef6"
},
{
"type": "archive",
"url": "https://deps.files.ghostty.org/wayland-9cb3d7aa9dc995ffafdbdef7ab86a949d0fb0e7d.tar.gz",
"dest": "vendor/p/N-V-__8AAKrHGAAs2shYq8UkE6bGcR1QJtLTyOE_lcosMn6t",
"sha256": "ea4191d68e437677e51f3aacde27829810144e931d397a327dc6035e2c39c50d"
},
{
"type": "archive",
"url": "https://deps.files.ghostty.org/wayland-protocols-258d8f88f2c8c25a830c6316f87d23ce1a0f12d9.tar.gz",
"dest": "vendor/p/N-V-__8AAKw-DAAaV8bOAAGqA0-oD7o-HNIlPFYKRXSPT03S",
"sha256": "5cedcadde81b75e60f23e5e83b5dd2b8eb4efb9f8f79bd7a347d148aeb0530f8"
},
{
"type": "archive",
"url": "https://deps.files.ghostty.org/wuffs-122037b39d577ec2db3fd7b2130e7b69ef6cc1807d68607a7c232c958315d381b5cd.tar.gz",
"dest": "vendor/p/N-V-__8AAAzZywE3s51XfsLbP9eyEw57ae9swYB9aGB6fCMs",
"sha256": "9e4cd20abe96e6c4c6ede9c3057108860126e7be2e2c3e35515476c250be1c13"
},
{
"type": "archive",
"url": "https://deps.files.ghostty.org/z2d-0.9.0-j5P_Hu-WFgA_JEfRpiFss6gdvcvS47cgOc0Via2eKD_T.tar.gz",
"dest": "vendor/p/z2d-0.9.0-j5P_Hu-WFgA_JEfRpiFss6gdvcvS47cgOc0Via2eKD_T",
"sha256": "f90a824685f0ac5035fe5fa85af615c8055e6c6422b401503618bd537115af10"
},
{
"type": "archive",
"url": "https://deps.files.ghostty.org/zf-3c52637b7e937c5ae61fd679717da3e276765b23.tar.gz",
"dest": "vendor/p/zf-0.10.3-OIRy8RuJAACKA3Lohoumrt85nRbHwbpMcUaLES8vxDnh",
"sha256": "3b015d928af04e9e26272bc15eb4dbb4d9a9d469eb6d290a0ddae673b77c4568"
},
{
"type": "archive",
"url": "https://deps.files.ghostty.org/zig_js-04db83c617da1956ac5adc1cb9ba1e434c1cb6fd.tar.gz",
"dest": "vendor/p/zig_js-0.0.0-rjCAV-6GAADxFug7rDmPH-uM_XcnJ5NmuAMJCAscMjhi",
"sha256": "4c2018e56015d39504b8090386ad9ce9393f38380085d9c32373bf7e56fc73a3"
},
{
"type": "archive",
"url": "https://deps.files.ghostty.org/zig_objc-f356ed02833f0f1b8e84d50bed9e807bf7cdc0ae.tar.gz",
"dest": "vendor/p/zig_objc-0.0.0-Ir_Sp5gTAQCvxxR7oVIrPXxXwsfKgVP7_wqoOQrZjFeK",
"sha256": "dd84af737625356fcd722cb30909f3b2e8d702667cf579714aa7eabc0ac08ecc"
},
{
"type": "archive",
"url": "https://deps.files.ghostty.org/zig_wayland-1b5c038ec10da20ed3a15b0b2a6db1c21383e8ea.tar.gz",
"dest": "vendor/p/wayland-0.5.0-dev-lQa1khrMAQDJDwYFKpdH3HizherB7sHo5dKMECfvxQHe",
"sha256": "4f146b735ed0d527f520e3bf71d3e93f72c3d0fa583ae8edd3a4851f7079124e"
},
{
"type": "archive",
"url": "https://github.com/ivanstepanovftw/zigimg/archive/d7b7ab0ba0899643831ef042bd73289510b39906.tar.gz",
"dest": "vendor/p/zigimg-0.1.0-8_eo2vHnEwCIVW34Q14Ec-xUlzIoVg86-7FU2ypPtxms",
"sha256": "2c1ed76ba2b35514544b0c27c9633ecba7c31be9080e37e7a010c93b5a1bc553"
},
{
"type": "archive",
"url": "https://deps.files.ghostty.org/zlib-1220fed0c74e1019b3ee29edae2051788b080cd96e90d56836eea857b0b966742efb.tar.gz",
"dest": "vendor/p/N-V-__8AAB0eQwD-0MdOEBmz7intriBReIsIDNlukNVoNu6o",
"sha256": "17e88863f3600672ab49182f217281b6fc4d3c762bde361935e436a95214d05c"
}
]

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 426 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

Some files were not shown because too many files have changed in this diff Show More