Commit Graph

13854 Commits

Author SHA1 Message Date
Everton Correia
60da5eb3a6 Apply suggestion from @pluiedev
Co-authored-by: Leah Amelia Chen <github@acc.pluie.me>
2026-01-16 12:25:49 -03:00
evertonstz
c553296d7a Remove unused import of 'builtin' in gsettings.zig 2026-01-15 19:08:37 -03:00
evertonstz
04a7bcd138 Fix middle button paste condition to respect GNOME settings 2026-01-15 18:20:44 -03:00
evertonstz
db7df92a81 Refactor gsettings usage for gtk-xft-dpi and gtk-enable-primary-paste with improved logging 2026-01-15 18:15:31 -03:00
evertonstz
29adcf4b64 Enhance GTK settings handling with well-defined types and utility functions 2026-01-15 17:16:11 -03:00
Everton Correia
7a306e52c2 Update src/apprt/gtk/class/surface.zig
Co-authored-by: Leah Amelia Chen <github@acc.pluie.me>
2026-01-15 11:49:23 -03:00
evertonstz
78a503491e initial commit 2026-01-15 10:53:00 -03:00
Ken VanDine
2fd3efd6cd snap: fix handling of nonexistent last_revision file (#10241)
Assuming /bin/sh is symlinked to bash, the handling of special builtin
'source' is slightly different between bash and bash-in-POSIX-mode (as a
result of being invoked through /bin/sh). Specifically errors in builtin
'source' cannot be masked with `|| true`. Compare

```
$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Dec 11 11:00 /bin/sh -> bash
$ /bin/sh -c 'set -e ; source nofile || true; echo ok'
/bin/sh: line 1: source: nofile: file not found
$ /bin/bash -c 'set -e ; source nofile || true; echo ok'
/bin/bash: line 1: nofile: No such file or directory
ok
```

Thus ghostty from snap would not start at all when
$SNAP_USER_DATA/.last_revision does not exist causign the launcher
script to exit prematurely.
2026-01-14 09:47:40 -05:00
Jon Parise
5ff99ba9a0 macos: cycle through our icons in the About view (#10298)
Clicking on the icon immediately advances to the next one. Hovering on
the icon pauses the automatic cycling, and the "help" tooltip displays
the icon's configuration name (for `macos-icon`).

---


https://github.com/user-attachments/assets/5cfbd225-bbdf-4077-96c1-7da315ce02cc
2026-01-14 07:53:51 -05:00
Jon Parise
1537590a5f macos: cycle through our icons in the About view
Clicking on the icon immediately advances to the next one. Hovering on
the icon pauses the automatic cycling, and the "help" tooltip displays
the icon's configuration name (for `macos-icon`).
2026-01-12 15:20:14 -05:00
Mitchell Hashimoto
c90f47f11f Terminal: keep cross-boundary rows dirty in {insert,delete}Lines (#10290)
This fixes #10265 and thus also the remaining part of #9718 and likely
#10250.

The issue was that when using `insertLines` and `deleteLines` to
generate scrolling in a region that spans a page boundary, rows that are
replaced by a row from a different page lose their dirty flags in the
clone operation, since the flag is part of the data that gets cloned.
The solution is to set the dirty flag again after the clone, just like
the non-cloning branch does after the pointer swap.

**AI disclosure:** Amp is the MVP here. I prompted it with the
hypothesis I developed in #10265 (that this happens when the scrolling
region spans a page boundary), supplemented with insight I gained from
perusing asciicast files (that the offending scrolling operations are
always triggered by `CSI 1 L` or `CSI 1 M`, that is,
`Terminal.insertLines` or `Terminal.deleteLines`). Amp figured out the
rest and drafted the fix and tests. For free!

I cleaned up the tests and then pushed back a bit against the logic
behind the fix, which led to a better understanding and what I think is
a more appropriate fix. I can explain the details if there's interest,
or people can just skim the thread here:
https://ampcode.com/threads/T-019bb0d6-5334-744a-b78a-7c997ec1fade.
2026-01-12 10:21:36 -08:00
Mitchell Hashimoto
136df4a0f5 nix: update nixpkgs, remove zig.hook, and remove x11-gnome (#10286)
As of NixOS/nixpkgs#473413, `zig.hook` no longer supports
`zig_default_flags`, and now they can and must be provided in
`zigBuildFlags` instead.

Updating also requires removing gnome-xorg since it has been removed
from nixpkgs.

`nix flake check` succeeds on my system (x86_64-linux), with a couple
deprecation warnings that I believe aren't important.
2026-01-12 10:20:59 -08:00
MithicSpirit
8f4bfeece5 ci: fix ryand56/r2-upload-action version comment
Does not entail any actual changes in the version, merely in the comment
indicating the used version.

Detected by CI (GitHub Action Pins) after nixpkgs update.
2026-01-12 13:17:27 -05:00
MithicSpirit
2af6e255e4 chore: fix typo curor->cursor (2x)
Detected by CI (typos) after nixpkgs update.
2026-01-12 13:17:05 -05:00
Mitchell Hashimoto
eb462ad66f PageList can initialize with more than ~46,000 columns (#10297)
I've been poking around our internals around overflow cases while
diagnosing systemic ways to fix #10258.

One thing I found is that our terminal internals advertise that they can
accept up to u16 (~65K) rows and columns for the active area, but at
around 46K columns on x86_64 and 47K on aarch64, our terminal initialize
would error out. Worse, we'd actually trigger integer overflow and crash
in safe builds (and have silent corruption in release builds).

In fixing this, I realized we could comptime-verify a bunch of things
and avoid overflows completely. So this diff contains a bunch of places
that previously had error returns and now do not! 😄 This is a bit silly,
but with libghostty it's more relevant to have correctness around the
edges.

We now accept full u16 rows/cols. More than that isn't allowed by the
type system and our upstream callers must handle that appropriately.

cc @qwerasd205 since its relevant to layout fallibility but not on the
same path
2026-01-12 10:16:18 -08:00
Mitchell Hashimoto
5817e1dc5f terminal: PageList can initialize with memory requirements > std 2026-01-12 09:57:20 -08:00
MithicSpirit
d512de7e78 nix: update zon2nix
After the last commit, zon2nix required recompiling zig, which caused
slow build times and CI failures.
2026-01-12 12:53:21 -05:00
Daniel Wennberg
257aafb7b4 Consolidate dirty marking in insertLines/deleteLines 2026-01-12 09:49:08 -08:00
Mitchell Hashimoto
7ed19689b9 terminal: add Capacity.maxCols 2026-01-12 08:53:34 -08:00
Daniel Wennberg
095c82910b Terminal: keep cross-boundary rows dirty in {insert,delete}Lines 2026-01-11 23:26:46 -08:00
Daniel Wennberg
87b11e0892 Add failing tests for #10265 2026-01-11 23:25:44 -08:00
MithicSpirit
5c8c7c627c nix: update nixpkgs, remove zig.hook, and remove x11-gnome
As of NixOS/nixpkgs#473413[1], `zig.hook` no longer supports
`zig_default_flags`, and now they can and must be provided in
`zigBuildFlags` instead.

Updating also requires removing gnome-xorg since it has been removed
from nixpkgs.

[1] https://github.com/NixOS/nixpkgs/pull/473413
2026-01-11 20:17:12 -05:00
Jon Parise
bb1c3bce10 fix(completions.fish): add +help and +version to completions (#10287)
`+help` and `+version` is missing from completions, even though they are
working actions and are referenced in discussion template
[here](https://github.com/ghostty-org/ghostty/pull/7012). This PR adds
the completion for fish (as that is the shell that I use).
2026-01-11 19:45:25 -05:00
Jon Parise
e47272878d extra: enable +help and +version in bash and zsh 2026-01-11 19:26:27 -05:00
Peter Cardenas
2bdbda20fd fix(completions.fish): add +help and +version to completions 2026-01-11 15:29:32 -08:00
Mitchell Hashimoto
09168afb80 terminal: tracked pins need to be invalidated for the non-std page (#10285)
Fixes a regression from #10251

Thanks to @grishy again for finding this. Updated tests to catch it,
too.

No AI used, wrote this with my meat sticks.
2026-01-11 14:35:23 -08:00
Mitchell Hashimoto
b995595953 terminal: tracked pins need to be invalidated for the non-std page
Fixes a regression from #10251

Thanks to @grishy again for finding this. Updated tests to catch it,
too.
2026-01-11 14:25:45 -08:00
Mitchell Hashimoto
24880becb7 terminal: remove the ability to reuse a pool from PageList (#10271)
This was an unused codepath and it complicates some things I'd like to
do, such as resetting our pools during resize. It complicates those
paths because if a user provides a pool we can't reset it (because other
things might be in it). It's best to own the pools. And since we didn't
reuse pools anyway, let's remove that.

Note this was previously used by our old render state mechanism (before
`terminal.RenderState`) as a way for the renderer to speed up clones by
having a preheated pool that was likely the right size before every
frame. Since we changed methods, we don't need it.
2026-01-11 07:23:45 -08:00
Mitchell Hashimoto
4db3245a92 GTK: start search accepts selection contents (#10262)
Fixes: #10196

If user invokes `search_selection` the contents of that string are no
longer ignored.

I'm not very familar with how apprt actions are sent to macos to ensure
the defer free will work there, but it is required for GTK otherwise we
are leaking the memory

I'm also open to making the string optional instead of checking against
`""` thats just how the current `start_search` action was sending its
needle (which I assume is better for macos?)

The text is also highlighted currently due to `grabFocus` always
selecting the search contents, not sure how the macos part works but
that could easily be changed to change the contents after focus was
grabbed

https://github.com/ghostty-org/ghostty/blob/main/src/apprt/gtk/class/search_overlay.zig#L233-L241
2026-01-11 07:23:29 -08:00
Mitchell Hashimoto
6037e2194a terminal: remove the ability to reuse a pool from PageList
This complicates logic and is unused.
2026-01-11 07:18:35 -08:00
rhodes-b
50516ed581 add search selection for GTK 2026-01-10 19:45:05 -06:00
Mitchell Hashimoto
17da13840d Fix memory leak when pruning scrollback with non-standard pages (#10251)
This _finally_ resolves #9962 (and the myriad of dupes). 

The core issue was that when a non-standard size page is reused as part
of our scrollback pruning, it was resized to be standard size, which
caused our future frees to believe it was pooled and not call `munmap`
properly.

The solution I chose was to never reuse non-standard sized pages. If
during scrollback pruning we detect a non-standard page, we destroy it
and re-alloc. This frees the old memory and reuses pool memory for the
new page.

As part of this, I also introduced a custom page allocator that uses
macOS's mach kernel virtual memory tagging feature to specifically tag
our PageList memory. I was able to use this in conjunction with
Instruments and `footprint` to verify that our PageList memory was
previously not freed and is now successfully freed.

**No AI was used in my work here.** AI was used by others in their
analysis of this issue that I used the results of to help guide me and
give me other things to consider, but the ultimate understanding and fix
was all done via my own meat sticks.

## Detailed Explainer

Ghostty uses a memory pool of fixed-size `mmap`-ed pages to serve as the
backing memory for our terminal. If the terminal requires a non-standard
(larger) amount of memory due to an abundance of emoji, styles,
hyperlinks, etc. then we allocate non-pooled pages directly with `mmap`.
When freeing our pages, if it is `<= standard size` we just put it back
into the memory pool. If it is larger, we `munmap` it.

This explains and defines both a _standard_ and therefore _non-standard_
page.

Ghostty also has the concept of a "scrollback limit" (exposed to the
user via the `scrollback-limit` config). This caps the size of our
scrollback or history. When we reach this limit, we have a trick that we
do: to avoid allocation, we reuse the oldest page in the history.

Unfortunately, as part of this process, we were resizing the underlying
memory to be standard size again. This was causing our future frees to
believe this was pooled memory, and never unmap it. This was the main
source of the leak.

## Thanks

Big shout out to @grishy for being the person that finally got me a
reproduction so I could analyze the issue for myself. His own analysis
got to the same conclusion as me but thanks to the reproduction I was
able to verify both our understandings independently.
2026-01-10 07:54:32 -08:00
Mitchell Hashimoto
509f073366 terminal: fix up our total row and pin accounting during reuse 2026-01-10 07:11:52 -08:00
Mitchell Hashimoto
235eebfa92 terminal: during test, use the testing allocator for pages 2026-01-10 06:55:24 -08:00
Mitchell Hashimoto
9ee78d82c0 terminal: fix memory leak when grow attempts to reuse non-standard page 2026-01-10 06:49:54 -08:00
Mitchell Hashimoto
1d63045c2f terminal: use tagged memory for PageList ops 2026-01-10 06:39:32 -08:00
Mitchell Hashimoto
b426a68297 os: mach taggedPageAllocator 2026-01-09 20:37:58 -08:00
Mitchell Hashimoto
6f1544b4a3 os: add mach VM tags 2026-01-09 20:23:39 -08:00
Mitchell Hashimoto
ec2912dbaf docs: bell border feature is available on macOS (#10242)
As of commit fe55d90 and PR #8768 this feature is also available on
macOS.
2026-01-09 11:40:12 -08:00
Martin Müller
d94ba5cf10 docs: add bell border feature version availability
Commit 22fc90f (PR #8222) on GTK and commit fe55d90 (PR #8768) on macOS.
2026-01-09 18:46:00 +01:00
Mitchell Hashimoto
51aed4d8b3 Binding internals improvements (#10243)
A handful of improvements. See individual commits.

1. **Actually compare values for the binding set.** This sounds crazy,
but up until now (for _years_) we've only compared _the hash value_ of a
trigger or action for our binding set. It's actually astounding this
hasn't bit us or at least not that we know of. This could result in
different triggers overwriting each other. Anyways, we actually compare
them now.

2. **Use an `ArrayHashMap` for sets.** This has been on the back burner
for awhile. Using an array hash map is a good idea in general (see:
https://github.com/ziglang/zig/issues/17851) but it also is a nicer API
for our use case and cleaned things up.

All unit tests pass, many new unit tests added particularly for equality
comparison. Hopeful this doesn't regress any bindings but this is the
right path forward so we should fix those if they come up.

**AI disclosure:** AI helped write the deepEqual unit tests, otherwise
everything else is certified meat.
2026-01-09 09:14:48 -08:00
Mitchell Hashimoto
0e9ce7e450 input: change our binding set to use array hash map
This is recommended for ongoing performance: 
https://github.com/ziglang/zig/issues/17851

Likely not an issue for this particular use case which is why it never
bit us; we don't actively modify this map much once it is created. But,
its still good hygiene and ArrayHashMap made some of the API usage
nicer.
2026-01-09 09:06:03 -08:00
Mitchell Hashimoto
201198c74a input: do value comparison for Set hash maps
We previously only compared the hashes for triggers and actions for hash
map equality. I'm genuinely surprised this never bit us before because
it can result in false positives when two different values have the same
hash. Fix that up!
2026-01-09 08:59:05 -08:00
Mitchell Hashimoto
c179de62a7 extract deepEqual 2026-01-09 08:59:05 -08:00
Mitchell Hashimoto
a584e6259f macOS: Only trigger main menu items if not performable or all targeted (#10240)
Fixes #10239

The main menu uses first responder which will hit a surface. If a
binding would target `all:` we need to avoid it. To achieve this, our
`is_key_binding` API now returns information about the binding (if any).
I've cleaned up the Swift to implement this.

In doing this I realized we have to do the same for `performable` since
main menus will effectively always consume.
2026-01-09 07:21:54 -08:00
Martin Müller
115351db87 docs: bell border feature is available on macOS
As of commit fe55d90 and PR #8768 this feature is also available on
macOS.
2026-01-09 16:19:50 +01:00
Mitchell Hashimoto
f34c69147a macos: use the new binding flags information value to trigger menu 2026-01-09 07:13:14 -08:00
Maciek Borzecki
49768c6464 snap: fix handling of nonexistent last_revision file
Assuming /bin/sh is symlinked to bash, the handling of special builtin
'source' is slightly different between bash and bash-in-POSIX-mode (as a
result of being invoked through /bin/sh). Specifically errors in builtin
'source' cannot be masked with `|| true`. Compare

$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Dec 11 11:00 /bin/sh -> bash
$ /bin/sh -c 'set -e ; source nofile || true; echo ok'
/bin/sh: line 1: source: nofile: file not found
$ /bin/bash -c 'set -e ; source nofile || true; echo ok'
/bin/bash: line 1: nofile: No such file or directory
ok

Thus ghostty from snap would not start at all when
$SNAP_USER_DATA/.last_revision does not exist causign the launcher
script to exit prematurely.

Signed-off-by: Maciek Borzecki <maciek.borzecki@gmail.com>
2026-01-09 16:12:27 +01:00
Mitchell Hashimoto
856ef1fc1b input: change the key_is_binding to return some information 2026-01-09 06:51:48 -08:00
Mitchell Hashimoto
18535f04d1 osc: refactor parsing helper functions into separate files (#10233)
Following up on #9950, refactor the parsing helper functions into
separate files.
2026-01-09 06:13:35 -08:00