11302 Commits

Author SHA1 Message Date
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
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
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