Commit Graph

1881 Commits

Author SHA1 Message Date
Aurelien Brabant
7ee3ac9ec8 refactor: use arena allocator 2026-07-26 17:50:33 +02:00
Aurelien Brabant
0075c75b61 refactor: remove unneeded appendAssumeCapacity 2026-07-26 17:09:52 +02:00
Aurelien Brabant
3024c5d19e refactor: address nits 2026-07-26 16:37:46 +02:00
Aurelien Brabant
88bd4fdcea feat: implement vicinae-hotkey-v1 2026-07-26 05:47:40 +02:00
Mitchell Hashimoto
b988efcfe5 fix some 0.16 translation regressions 2026-07-22 08:07:06 -07:00
Chris Marchesi
e8525c0fd9 Update to Zig 0.16.0
This commit represents the majority of the work necessary to upgrade
Ghostty to use Zig 0.16.0.

Key parts:

* In addition to its previous responsibilities, the global state now
  houses state for global I/O implementations and the process
  environment. It is now also utilized in the main application along
  with the C library. Where necessary, global state is isolated from key
  parts of the implementation (e.g., in libghostty subsystems), and it's
  expected that this list will grow.

* We currently manage our own C translation layer where necessary. In
  these cases, cImport has been removed in favor of the new external
  translate-c package. Due to fixes that have needed be made to properly
  translate the dependencies that were swapped out, as mentioned, we
  have had to backport fixes from the current translate-c package (and
  the upstream Arocc dependency). We will host this ourselves until Zig
  0.17.0 is released with these fixes.

* Where necessary (only a small number of cases), some stdlib code from
  0.15.2 (and even from 0.17.0) has been taken, adopted, and vendored in
  lib/compat.

Co-authored-by: Leah Amelia Chen <hi@pluie.me>
2026-07-21 12:35:05 -07:00
yak
004c88e41e fix: set max window clamp to current monitor size 2026-07-05 10:41:06 -04:00
Jeffrey C. Ollie
e5b65a2ce3 config: add gtk-horizontal-tab-scroll option (#12659)
I've implemented a GTK toggle (gtk-horizontal-tab-scroll) for the
2-finger tab swiping introduced in #10575.

This resolves the issue presented in #11566. Simply put, this allows
users to decide whether or not they want to use horizontal tab scrolling
or just have the events passed through. Passing through the horizontal
scroll events allows programs like Neovim to use them for horizontal
scrolling.

This PR was largely generated by Claude Code and fully reviewed/refined
by me.
2026-06-27 01:58:13 -05:00
Daniel Kinzler
0a117e0797 gtk: fix missing dbus connection causing crash
Changes GlobalShortcuts.refresh to do nothing when there is no dbus connection and GlobalShortcuts.close to always clean up arena memory.
2026-06-24 13:26:42 +02:00
Mitchell Hashimoto
7092b39445 GTK: Improve Split Close Behavior (#11173)
## Summary
- Adds a "Close Split" option to the right-click context menu in the
split submenu
- Allows users to close the focused split pane directly from the context
menu

Reference discussion:
https://github.com/ghostty-org/ghostty/discussions/10982
2026-06-06 14:02:16 -07:00
Jon Parise
c4e1ab8883 core: send selection_changed notification
The core had no signal to the apprt when the active selection changed,
so a consumer (e.g. a screen reader) kept reading a stale selection
until some unrelated query refreshed it.

This change adds a payload-less selection_changed action that's fired on
a selection state transition. The apprt reads the current selection
through the normal read path.

This consolidates selection state changes so the notification fires
consistently: all sites route through setSelection rather than calling
screen.select directly, including the mouse paths that previously
bypassed it for clipboard timing.

The new setSelectionAndCopy extends setSelection with the additional
'copy_on_select' behavior.

On macOS, this posts .ghosttySelectionDidChange, which is debounced
before posting a NSAccessibility .selectedTextChanged notification.

GTK has no consumer yet and no-ops the action.
2026-06-02 19:37:49 -04:00
Jeffrey C. Ollie
2c62d182ce gtk: fix context menu hiding quick-terminal (#12843)
Fixes #12783 where opening the context menu (with right click) inside
the quick-terminal will hide the quick-terminal if autohide is enabled.

The cause of this issue is the quick-terminal window becoming inactive
and immediately active again when you open the context-menu. When the
window becomes inactive, the autohide feature hides the quick-terminal.
The temporary focus loss in GTK is triggered by GDK focus change events,
which probably originate from the windowing backend treating the context
menu as its own window. Whereas in GTK the context menu is not a
separate window but instead part of the widget tree of the window it was
opened from, so even when the context menu has focus that window is
still the active one in GTK.

As a fix `Window.propIsActive`, which implements the autohide logic,
will now do its work from a timeout callback, since there is probably no
reliable way to distinguish a temporary focus loss from a real one from
inside GTK and I'm not sure we can make any assumptions about the timing
of things happening in the windowing backend. A 100ms delay should be
long enough for the focus state to settle while still hiding the
quick-terminal quickly.

I reproduced the bug and verified the fix on Wayland with both Hyprland
and KDE. Temporary focus loss happens on X11+KDE as well, although it
doesn't matter there because there is no quick-terminal.

### AI Disclosure

No AI was used, code and comments were written by myself.
2026-05-29 22:44:30 -05:00
Daniel Kinzler
ff963f3119 Renamed timeout source and callback function. Added comment explaining timeout delay. 2026-05-29 17:40:25 +02:00
Daniel Kinzler
1753d57bfd remove timeout source when window is disposed 2026-05-28 15:08:12 +02:00
Daniel Kinzler
37997f8dbe Use a timeout callback to wait for changes in window active state to settle. Depending on the backend a window might temporarily become inactive.
Fixes an issue where quick-terminal would disappear when opening the surface context menu.
2026-05-26 18:26:17 +02:00
Nikolay Bryskin
0708f932a5 apprt/gtk: add regression test for audio-bell MediaFile reuse
Guards the contract that prevents the bell thread leak: bellMediaFile
must return the same cached MediaFile for an unchanged path and only
rebuild when the path changes. A revert to per-bell allocation (the
leak) would fail this. Runs in the existing test-gtk CI job; needs no
display or playback since the path bookkeeping is all that's asserted.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-25 23:43:04 +03:00
Nikolay Bryskin
0b6d91e531 apprt/gtk: reuse one audio-bell MediaFile per surface to fix thread leak
Each audio bell called gtk.MediaFile.newForFilename, which spins up a
full GStreamer pipeline. The GTK4 GStreamer backend's GL sink starts
gstglcontext/gldisplay-event threads that are never joined on teardown,
so allocating a MediaFile per ring leaked a pipeline and ~4 threads on
every bell. A long-running instance accumulated 705 threads over ~4h of
normal use.

Cache one MediaFile per surface (priv.bell_media), rebuilt only when
bell-audio-path changes and unref'd on dispose. Each bell now replays
the same pipeline via seek(0)+play() instead of creating a new one. The
notify::ended -> unref handler is removed: it was what discarded (and
leaked) a pipeline per ring. seek(0) is required so an ended stream
plays again (#8957).

Verified on a real instance: GStreamer's global element counter reached
only oggdemux4 over an hour of use (one pipeline per bell-ringing
surface, reused) and thread count stayed flat, versus per-bell growth
before.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-25 23:43:01 +03:00
Mike Bommarito
88d30bb30a gtk: wire occlusionCallback to GLArea map/unmap
Calls core_surface.occlusionCallback(visible) from the existing
glareaMap/glareaUnmap handlers (added in #12698) so the renderer
thread learns when a surface is off-screen.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 22:50:03 -04:00
Jeffrey C. Ollie
4b7bf0b20e IPC: add +toggle-quick-terminal command (#12661)
Add `+toggle-quick-terminal` as a first-class IPC action, following the
same pattern as `+new-window`. This provides a proper CLI command
(`ghostty +toggle-quick-terminal`) to toggle the quick terminal on a
running Ghostty instance.

Closes discussion #12618
2026-05-17 21:03:09 -05:00
Daniel Kinzler
9f72eb9d7c added back accidentally deleted empty line 2026-05-15 17:52:48 +02:00
Daniel Kinzler
93d1142ada small formatting changes 2026-05-15 17:20:57 +02:00
Daniel Kinzler
54a38e8134 Distinguish resize and manual update using a combination of
max-position and position properties. Listening to drag events directly
did not work that well.
2026-05-14 15:45:29 +02:00
Daniel Kinzler
e59e27f8bd Fix nested splits disappearing and focus being lost.
The cause of these bugs is that GTK can initially allocate
a split/surface a width/height of 0 which causes it to
get unmapped and lose focus. Additionally the split ratio is
only set once but not accurately for tiny splits, which can keep
a surface invisible even when the split gets resized later.

To fix these problems the split ratio is always checked and
possibly corrected when a split gets resized. Changes in a split
ratio caused by the user dragging the divider are detected
separately using an event controller. If a surface loses focus
we restore it once the surface becomes mapped again.
2026-05-12 14:13:35 +02:00
Hua Jiang
81af65766f feat: add +toggle-quick-terminal IPC command
Expose toggle-quick-terminal as a proper IPC action so it can be
triggered via 'ghostty +toggle-quick-terminal' from the command line,
instead of calling the raw D-Bus org.gtk.Actions.Activate interface.

This follows the same pattern as the existing +new-window IPC command:

  - Add toggle_quick_terminal to apprt.ipc.Action enum (Zig + C ABI)
  - Create apprt/gtk/ipc/toggle_quick_terminal.zig (GTK D-Bus handler)
  - Route .toggle_quick_terminal in apprt/gtk/App.zig performIpc
  - Register toggle-quick-terminal GAction in application.zig
  - Add +toggle-quick-terminal CLI handler in cli/
  - Register in cli/ghostty.zig Action enum, runMain, and options
  - Add stub in apprt/embedded.zig
  - Update include/ghostty.h C header enum

Usage:
  ghostty +toggle-quick-terminal

Closes: #12618
2026-05-12 09:03:14 +08:00
00jciv00
5ea45919d7 config: add gtk-horizontal-tab-scroll option
Add a boolean config option to enable/disable two-finger horizontal
touchpad scrolling for switching tabs. Defaults to true to preserve
existing behavior.

When tab scrolling is disabled or the scroll source is not a touchpad,
forward horizontal scroll events to the terminal so applications like
neovim can handle them.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-11 11:46:56 -04:00
Mitchell Hashimoto
0b56ae2cc7 gtk: fix quick terminal breaking when manually toggled off while auto-hide is enabled (#12471)
Fixes quick terminal breaking when auto-hide is enabled and quick
terminal is manually toggled off (#11679).

`quick-terminal-autohide` is implemented by the `Window.propIsActive`
function in `apprt/gtk/class/window.zig` which calls
`Window.toggleVisibility` when the quick terminal window becomes
inactive (loses focus). However `Window.propIsActive` is also triggered
when you manually hide the quick terminal because hiding it causes the
window to become inactive. Normally that should just toggle the quick
terminal off and immediately back on, but there is also a re-entrancy
issue. Manually toggling off the terminal causes the
`Application.toggleQuickTerminal` (in `apprt/gtk/class/application.zig`)
to run which sets off the call chain `Window.toggleVisibility ->
gtk_widget_set_visible -> ... GTK signal/event handling ... ->
Window.propIsActive -> Window.toggleVisibility ->
gtk_widget_set_visible`.
The nested calls to `gtk_widget_set_visible` cause the GTK window state
to become corrupted. The window is marked visible, but is not actually
visible or just shows a placeholder. What exactly happens depends on the
compositor and how it handles moving window focus.

Reproduced the bug on KDE and hyprland and verified the fix on both.

### Changes

`apprt/gtk/class/window.zig`: added check to `Window.propIsActive` to
only toggle quick-terminal if it is inactive **and** visible.

### AI Disclosure

Found the bug without AI using "printf debugging" then traced it through
GTK with valgrind. Used GPT5.4 in setting up valgrind and researching
how signals/events move through GTK internally.
2026-04-27 09:26:24 -07:00
Mitchell Hashimoto
8e2a13cb60 gtk/SurfaceScrolledWindow: wrap root child with another Adw.Bin (#12426)
Due to a known Gtk issue, the scrolled_window at the root of the
template is free-ed twice on dispose. This causes crashes when used with
GNOME 49 platform (Gtk 4.20, libadwaita 1.8.5).

Workaround this issue by wrapping the root child in another Adw.Bin,
similar to widgets like ResizeOverlay.

LLM was used to perform discovery against a manually recorded Valgrind
trace, and helped tracking down known fixes for this problem. The
comment in code was taken from another instance in the repository.

Fixes https://github.com/ghostty-org/ghostty/discussions/12306

Assisted-by: OpenAI GPT-5.4
2026-04-25 09:22:59 -07:00
Leorize
560b7ba8e8 gtk/SurfaceScrolledWindow: wrap root child with another Adw.Bin
Due to a known Gtk issue, the scrolled_window at the root of the
template is free-ed twice on dispose. This causes crashes when used with
GNOME 49 platform (Gtk 4.20, libadwaita 1.8.5).

Workaround this issue by wrapping the root child in another Adw.Bin,
similar to widgets like ResizeOverlay.

LLM was used to perform discovery against a manually recorded Valgrind
trace, and helped tracking down known fixes for this problem.

Fixes https://github.com/ghostty-org/ghostty/discussions/12306

Assisted-by: OpenAI GPT-5.4
2026-04-25 09:18:21 -07:00
Lukas
7c91cef28d config: use Config to check key binding instead of App
Previously `ghostty_app_key_is_binding` (unlike Surface) is just using `config.keybind` to check whether a KeyEvent is in the set or not.

After this, I can add unit tests for keybinding more easily, with dummy configs.
2026-04-24 18:26:56 +02:00
Christo Wilken
9a9002202b macos: add pid and tty properties to AppleScript terminal class
Expose the foreground process PID and TTY device path as read-only properties on the AppleScript terminal class and App Intents TerminalEntity. This enables reliable process-to-terminal mapping for automation tools when multiple terminals share the same CWD.

Closes #11592
Closes #10756

Session: 019d341c-a165-7843-a2f7-2f426114cf17
2026-04-20 15:16:03 +02:00
Daniel Kinzler
2648668da9 fix quick-terminal breaking when it is manually toggled while autohide is enabled 2026-04-13 19:01:56 +02:00
Lukas
c8702ece8f gtk(chore): fix typos
### AI Disclosure

Claude wrote the regex to ignore base64-encoded sequences
2026-04-01 13:08:55 +02:00
Jeffrey C. Ollie
c2dd7579e2 core/gtk: ensure that first surface gets marked as focused surface by app (#12029) 2026-03-31 15:29:18 -05:00
Jeffrey C. Ollie
4b5f2d60e7 core/gtk: ensure that first surface gets marked as focused surface by app 2026-03-31 14:57:41 -05:00
Jeffrey C. Ollie
dee8598dc0 gtk: use surface id for notifications instead of pointer 2026-03-31 14:53:19 -05:00
Mitchell Hashimoto
4803d58bb4 apprt/embedded: fix ghostty_surface_free_text parameter mismatch
Fixes #12020

The C header declared ghostty_surface_free_text with both a
ghostty_surface_t and ghostty_text_s* parameter, but the Zig
implementation only accepted a *Text parameter. This caused the
surface pointer to be interpreted as the text pointer, so the
actual text allocation was never freed.
2026-03-31 09:46:35 -07:00
Jeffrey C. Ollie
af36959942 gtk: only trigger resize callbacks and overlay when size actually changes
Fixes #11970

Also fixes problem that resize overlay would intercept mouse activity
while active.
2026-03-29 23:38:34 -05:00
Michael Stevens
c0a124f3ca gtk: disable kinetic scrolling for trackpads until 4.20.1
Until gtk 4.20.1 trackpads have kinetic scrolling behavior regardless
of `Gtk.ScrolledWindow.kinetic_scrolling`. As a workaround, set
EventControllerScroll.kinetic to false on all controllers.

`observeControllers()` has this warning:
> Calling this function will enable extra internal bookkeeping to track controllers and emit signals on the returned listmodel. It may slow down operations a lot.
> Applications should try hard to avoid calling this function because of the slowdowns.

but judging from the [source](5301a91f1c/gtk/gtkwidget.c (L12375-L12383))
this is a one time penalty since we free the result immediately afterwards.

Fixes https://github.com/ghostty-org/ghostty/discussions/11460
2026-03-28 17:36:17 -04:00
Caleb
bcf12937d0 Merge remote-tracking branch 'origin/main' into close-split-gtk
# Conflicts:
#	po/hu.po
#	po/id.po
2026-03-25 16:24:11 -07:00
Timon de Groot
8bc75907b5 gtk: Fix casing for openUri 2026-03-23 07:29:36 +01:00
Timon de Groot
919e586c51 gtk/portal: Improve OpenURI lifecycle 2026-03-22 21:10:46 +01:00
Timon de Groot
37d297c03c gtk/portal: General improvements
- Token is formatted without allocation
- Reusable function for formatToken
- Tests in portal.zig are actuall included now
2026-03-22 21:09:38 +01:00
Timon de Groot
855a6b01fc gtk: Open urls with openuri portal 2026-03-22 18:17:09 +01:00
Leah Amelia Chen
27fd1c7788 gtk/winproto: fix memleak & other tweaks 2026-03-18 03:37:03 +08:00
Leah Amelia Chen
80ab5d92ea gtk/x11: use BlurRegion 2026-03-18 03:07:58 +08:00
Leah Amelia Chen
5abf21c1e2 gtk/wayland: complete blur region calculation
It took me a while and with lots of trial and error to arrive here,
but the end result looks pretty good.
2026-03-18 03:07:58 +08:00
Leah Amelia Chen
9e2e99c55f gtk/wayland: replace KDE blur with ext-background-effect-v1
The venerable KDE blur protocol has been replaced with the compositor-
agnostic ext-background-effect-v1 protocol, to be implemented by Niri and
others. The new protocol is much easier to use overall, though we do need
to calculate the blur region manually like X11.
2026-03-18 03:07:46 +08:00
Jeffrey C. Ollie
79162279d9 gtk: move audio playback into separate file, enabling reuse 2026-03-16 19:53:24 -05:00
Jeffrey C. Ollie
8a40e37b86 gtk: refactor application id and resource path 2026-03-16 18:26:37 -05:00
Leah Amelia Chen
2318e18df3 gtk/wayland: refactor global handling (#11559) 2026-03-16 18:06:37 +00:00