Commit Graph

9191 Commits

Author SHA1 Message Date
Mitchell Hashimoto
9033f6f8ce libghostty: add kitty graphics placement iterator API
Add a C API for iterating over Kitty graphics placements via the
new GhosttyKittyGraphics opaque handle. The API follows the same
pattern as the render state row iterator: allocate an iterator with
ghostty_kitty_graphics_placement_iterator_new, populate it from a
graphics handle via ghostty_kitty_graphics_get with the
PLACEMENT_ITERATOR data kind, advance with
ghostty_kitty_graphics_placement_next, and query per-placement
fields with ghostty_kitty_graphics_placement_get.
2026-04-06 09:15:26 -07:00
Mitchell Hashimoto
e89b2c88f3 libghostty: introduce the kitty graphics opaque type 2026-04-06 08:56:23 -07:00
Mitchell Hashimoto
d7fa92088c libghostty: expose sys interface to C API
The terminal sys module provides runtime-swappable function pointers
for operations that depend on external implementations (e.g. PNG
decoding). This exposes that functionality through the C API via a
ghostty_sys_set() function, modeled after the ghostty_terminal_set()
enum-based option pattern.

Embedders can install a PNG decode callback to enable Kitty Graphics
Protocol PNG support. The callback receives a userdata pointer
(set via GHOSTTY_SYS_OPT_USERDATA) and a GhosttyAllocator that must
be used to allocate the returned pixel data, since the library takes
ownership of the buffer. Passing NULL clears the callback and
disables the feature.
2026-04-06 07:45:16 -07:00
Mitchell Hashimoto
3a52e0e3bd libghostty: expose kitty image options via terminal set/get
Add four new terminal options for configuring Kitty graphics at runtime
through the C API: storage limit, and the three loading medium flags
(file, temporary file, shared memory).

The storage limit setter propagates to all initialized screens and
uses setLimit which handles eviction when lowering the limit. The
medium setters similarly propagate to all screens. Getters read from
the active screen. All options compile to no-ops or return no_value
when kitty graphics are disabled at build time.
2026-04-06 07:21:05 -07:00
Mitchell Hashimoto
810ebae8e8 terminal: lower default kitty image storage limit for libghostty
The default kitty image storage limit was 320 MB for all build
artifacts. For libghostty, this is overly generous since it is an
embedded library where conservative memory usage is preferred.
Lower the default to 10 MB when building as the lib artifact while
keeping the 320 MB default for the full Ghostty application.
2026-04-06 06:56:20 -07:00
Mitchell Hashimoto
306acc4941 terminal/kitty: use direct medium for tests if we're not using files 2026-04-05 07:22:44 -07:00
Mitchell Hashimoto
935d37fbf1 terminal: add kitty image limits to Terminal.Options
Move kitty_image_storage_limit and kitty_image_loading_limits into
Terminal.Options so callers can set them at construction time
rather than calling setter functions after init. The values flow
through to Screen.Options during ScreenSet initialization. Termio
now passes both at construction, keeping the setter functions for
the updateConfig path.
2026-04-05 07:21:15 -07:00
Mitchell Hashimoto
64dcb91c1f terminal/kitty: add loading limits to kitty graphics protocol
Add a Limits type to LoadingImage that controls which transmission
mediums (file, temporary_file, shared_memory) are allowed when
loading images. This defaults to "direct" (most restrictive) on
ImageStorage and is set to "all" by Termio, allowing apprt
embedders like libghostty to restrict medium types for resource or
security reasons.

The limits are stored on ImageStorage, plumbed through
Screen.Options for screen initialization and inheritance, and
enforced in graphics_exec during both query and transmit. Two new
Terminal methods (setKittyGraphicsSizeLimit, setKittyGraphicsLoadingLimits)
centralize updating all screens, replacing the manual iteration
previously done in Termio.
2026-04-05 07:18:45 -07:00
Mitchell Hashimoto
6a99c248d0 terminal/kitty: add Limits to restrict capabilities of image transfer 2026-04-05 07:08:30 -07:00
Mitchell Hashimoto
29e3de737e terminal: make wuffs runtime-swappable, enable Kitty graphics for libvt
Introduce terminal/sys.zig which provides runtime-swappable function
pointers for operations that depend on external implementations. This
allows embedders of the terminal package to swap out implementations
at startup without hard dependencies on specific libraries.

The first function exposed is decode_png, which defaults to a wuffs
implementation. The kitty graphics image loader now calls through
sys.decode_png instead of importing wuffs directly.

This allows us to enable Kitty graphics support in libghostty-vt
for all targets except wasm32-freestanding.
2026-04-04 22:01:38 -07:00
Mitchell Hashimoto
a8e92c9c53 terminal: add APC handler to stream_terminal
Wire up the APC handler to `terminal.TerminalStream` to process
APC sequences, enabling support for kitty graphics commands in 
libghostty, in theory.

The "in theory" is because we still don't export a way to actually
enable Kitty graphics in libghostty because we have some other things in
the way: PNG decoding and OS filesystem access that need to be more 
conditionally compiled before we can enable the feature. However, this
is a step in the right direction, and we can at least verify that the
APC handler works via a test in Ghostty GUI.
2026-04-04 21:11:31 -07:00
Mitchell Hashimoto
10696b5ed1 libghostty: add GhosttySelection type and selection support to formatter (#12115)
Add a new GhosttySelection C API type (selection.h / c/selection.zig)
that pairs two GhosttyGridRef endpoints with a rectangle flag. This maps
directly to the internal Selection type using untracked pins.

The formatter terminal options gain an optional selection pointer. When
non-null the formatter restricts output to the specified range instead
of emitting the entire screen. When null the existing behavior of
formatting the full screen is preserved.
2026-04-04 20:48:39 -07:00
Mitchell Hashimoto
757eff5881 libghostty: add GhosttySelection type and selection support to formatter
Add a new GhosttySelection C API type (selection.h / c/selection.zig)
that pairs two GhosttyGridRef endpoints with a rectangle flag. This
maps directly to the internal Selection type using untracked pins.

The formatter terminal options gain an optional selection pointer.
When non-null the formatter restricts output to the specified range
instead of emitting the entire screen. When null the existing
behavior of formatting the full screen is preserved.
2026-04-04 20:38:05 -07:00
Mitchell Hashimoto
b9a241d1e2 libghostty: add hyperlink URI accessor to grid_ref API
Add ghostty_grid_ref_hyperlink_uri to extract the OSC 8 hyperlink
URI from a cell at a grid reference position. Follows the same
buffer pattern as ghostty_grid_ref_graphemes: callers pass a buffer
and get back the byte length, or GHOSTTY_OUT_OF_SPACE with the
required size if the buffer is too small. Cells without a hyperlink
return success with length 0.
2026-04-04 20:28:13 -07:00
Mitchell Hashimoto
e157dd69c5 build: add pkg-config static linking support and fat archives to libghostty
The libghostty-vt pkg-config file was missing Libs.private, so
pkg-config --libs --static returned the same flags as the shared
case, omitting the C++ standard library needed by the SIMD code.

Additionally, the static archive did not bundle the vendored SIMD
dependencies (simdutf, highway, utfcpp), leaving consumers with
unresolved symbols when linking. If we're choosing to vendor (no -fsys)
then we should produce a fat static archive that includes them. If `-fsys`
is used, then we should not bundle them and instead reference them via
Requires.private, letting pkg-config chain to their own .pc files.

Add Libs.private with the C++ runtime (-lc++ on Darwin, -lstdc++
on Linux) and Requires.private for any SIMD deps provided via
system integration. When SIMD deps are vendored (the default),
produce a fat static archive that bundles them using libtool on
Darwin and ar on Linux. When they come from the system (-fsys=),
reference them via Requires.private instead, letting pkg-config
chain to their own .pc files.
2026-04-04 06:54:42 -07:00
Lukas
18f2702225 macOS: fix Find Next/Previous button in the menu bar is not working as expected 2026-04-02 20:31:31 +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
Jeffrey C. Ollie
ff02ed1b34 core: add 64 bit unique ID to every core surface
- Expose that ID as the environment variable GHOSTTY_SURFACE_ID to
  processes running in Ghostty surfaces.
- Add a function to the core app to search for surfaces by ID.
- ID is randomly generated, it has no other meaning other than as a
  unique identifier for the surface. The ID also cannot be zero as that
  is used to indicate a null ID in some situations.
2026-03-31 13:13:05 -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
Elias Andualem
1d0a247c20 sort map alphabetically 2026-03-31 19:34:52 +08:00
Elias Andualem
30c9dec76b add all C struct layout metadata for WASM 2026-03-31 19:28:46 +08:00
Mitchell Hashimoto
50f3b1d60d libghostty: export function table and make it growable for wasm (#12003)
Replaces #11958

This exports the function table and makes it growable so that the
effects API can be used. It's still very not ergonomic to use the
effects API so I'm going to work on that next, but this at least makes
it _possible_. Zig 0.15.x is missing the ability to pass
`--growable-table` to the linker so we use binary patching to add it
(yay!) lol.
2026-03-30 15:29:29 -07:00
Barut
a83a82b3f8 build: normalize input archives before Darwin libtool merge
Apple's recent libtool can warn about misaligned 64-bit archive members
and silently drop them when merging static libraries. In Ghostty this
showed up in the Darwin libtool step that builds libghostty-fat.a.

Normalize each input archive by copying it and running ranlib on the
copy
before handing it to libtool. That rewrites the archive into a layout
Apple's linker tools accept without flattening members through the
filesystem or changing Ghostty's archive format.
2026-03-30 16:59:07 -04:00
Mitchell Hashimoto
01a8ea7212 build: binary patching with Zig 2026-03-30 12:06:41 -07:00
Mitchell Hashimoto
6c085e5442 build: binary patch to add growable tables 2026-03-30 11:41:24 -07:00
Mitchell Hashimoto
624b4884c3 Add build_table 2026-03-30 11:34:09 -07:00
Mitchell Hashimoto
bd7415f4b7 terminal: clean up some types tests 2026-03-30 10:21:08 -07:00
Mitchell Hashimoto
0c38e8be60 vt: simplify ghostty_type_json to return null-terminated string
The function previously took a size_t* out-parameter for the string
length. Since the JSON blob is now null-terminated, the len parameter
is unnecessary. Remove it from the Zig implementation, C header, and
the WASM example consumer which no longer needs to allocate and free
a usize just to read the length.
2026-03-30 10:16:19 -07:00
Mitchell Hashimoto
2e827cc39d vt: add ghostty_type_json for struct layout metadata
Add a new C API function that returns a comptime-generated JSON string
describing the size, alignment, and field layout of every C API extern
struct. This lets FFI consumers (particularly WASM) construct structs
by byte offset without hardcoding platform-specific layout.

The JSON is built at comptime using std.json.Stringify via a
StructInfo type that holds per-struct metadata and implements
jsonStringify. A StaticStringMap keyed by C struct name provides
lookup by name as well as iteration for the JSON serialization.

The function is declared in types.h alongside the other common types
and exported as ghostty_type_json.
2026-03-30 10:16:19 -07:00
Mitchell Hashimoto
f66cf179cd gtk: only trigger resize callbacks and overlay when size actually changes (#11972)
Fixes #11970

Also fixes problem that resize overlay would intercept mouse activity
while active.
2026-03-30 08:45:50 -07:00
Jon Parise
840ab46009 cli: also recognize $GHOSTTY_PAGER
When defined, GHOSTTY_PAGER takes precedence over PAGER. If either of
those variables is set to an empty value, paging is disabled.
2026-03-30 10:53:53 -04:00
Jon Parise
11d45cd43c cli: add pager support for +show-config 2026-03-30 10:48:07 -04:00
Jon Parise
62f8a1cbcf cli: use a caller-provided write buffer
This follows Zig's conventions more closely, where the caller owns the
write buffer.
2026-03-30 10:48:07 -04:00
Jon Parise
4a0cca1c5b cli: add pager support to +explain-config
Add a new Pager type that wraps output to an external pager program when
stdout is a TTY, following the same conventions as git. The pager
command is resolved from $PAGER, falling back to `less`. An empty $PAGER
disables paging. If the pager fails to spawn, we fall back to stdout.

Previously, +explain-config wrote directly to stdout with no paging,
which meant long help text would scroll by. Now output is automatically
piped through the user's preferred pager when running interactively. A
--no-pager flag is available to disable this.
2026-03-30 10:48:07 -04: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
Mitchell Hashimoto
d784600fd6 terminal: update page_serial_min in erasePage
Fixes #11957

erasePage now updates page_serial_min when the first page is erased,
and asserts that only front or back pages are erased since
page_serial_min cannot represent serial gaps from middle erasure.

To enforce this invariant at the API level, PageList.eraseRows is
now private. Two public wrappers replace it: eraseHistory always
starts from the beginning of history, and eraseActive takes a y
coordinate (with bounds assertion) and always starts from the top
of the active area. This makes middle-page erasure impossible by
construction.
2026-03-29 15:10:12 -07:00
Elias Andualem
420de124f0 fix: ensure memory is zeroed in runtime safety modes for wasm/freestanding 2026-03-29 17:28:18 +08:00
Mitchell Hashimoto
0f6e733f8c build: use VERSION file if present, expose via libghostty (#11932)
If a `VERSION` file is present from our build root, prefer that as our
version source of truth over `build.zig.zon`. This file is automatically
created in source tarballs and will allow us to cut pre-release tarballs
of libghostty in particular (but affects all) that has a more specific
version than what can be in build.zig.zon.

This also adds the APIs necessary to extract this via the C API.

I started prepping for a separate libghostty version but not sure if
I'll wire that up in this PR yet or not...
2026-03-28 18:29:34 -07:00
Jeffrey C. Ollie
4903e2821d gtk: disable kinetic scrolling for trackpads until 4.20.1 (#11793)
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.

### AI usage
Zed + Opus 4.5 generated the first pass, but it missed freeing the
result of `observeControllers()` and conveniently binding
`scrolled_window` to the blueprint. Figuring out what was going on also
took a lot of [human
debugging](https://github.com/ghostty-org/ghostty/discussions/11460#discussioncomment-16245664).
2026-03-28 19:08:15 -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
Mitchell Hashimoto
8fa50f84d7 cli: dupe argument strings to retain their memory (#11931)
The argument iterator's .next() method returns a transient slice of the
command line buffer so we need to make our own copies of these values to
avoid referencing stale memory.
2026-03-28 09:26:28 -07:00
Mitchell Hashimoto
8813261341 libghostty: expose version information via build options and C API
Add version (std.SemanticVersion) to the terminal build options so that
the terminal module has access to the application version at comptime.
The add() function breaks it out into version_string, version_major,
version_minor, version_patch, and version_build terminal options.

On the C API side, five new GhosttyBuildInfo variants expose these
through ghostty_build_info(). String values use GhosttyString; numeric
values use size_t. When no build metadata is present, version_build
returns a zero-length string.

The c-vt-build-info example is updated to query and print all version
fields.
2026-03-28 09:17:52 -07:00
Jon Parise
2b1ec5db6d cli: dupe argument strings to retain their memory
The argument iterator's .next() method returns a transient slice of the
command line buffer so we need to make our own copies of these values to
avoid referencing stale memory.
2026-03-28 12:14:28 -04:00
Mitchell Hashimoto
608bc7d24d cli: +edit-config works properly when editor command contains arguments (#11898)
If `$EDITOR` or `$VISUAL` contained arguments, not just the path to an
editor (e.g. `zed --new`) `+edit-config` would fail because we were
treating the whole command as a path. Instead, wrap the command with
`/bin/sh -c <command>` so that the shell can separate the path from the
arguments.

Fixes #11897
2026-03-28 08:57:30 -07:00
Mitchell Hashimoto
e20b50652a fix: replace hardcoded locale.h constants with build-system TranslateC (#11920)
Replace hardcoded locale.h constants and extern function declarations
with build-system TranslateC, following the same pattern as pty.c.

This fixes LC_ALL being hardcoded to 6 (the musl/glibc implementation
value), which is implementation-defined and differs on Windows MSVC
(where LC_ALL is 0), causing `setlocale()` to crash with an invalid
parameter error.

## Changes

- Added `src/os/locale.c` — includes `locale.h` for TranslateC
- Added TranslateC step in `src/build/SharedDeps.zig` (same pattern as
pty.c)
- Replaced hardcoded constants and extern declarations in
`src/os/locale.zig` with `@import("locale-c")`

## AI disclosure

Claude Code was used to assist with debugging and identifying this
issue.
2026-03-28 08:56:40 -07:00
Jeffrey C. Ollie
60c7e767a8 benchmark: disable test on windows
We don't appear to have a time source with enough resolution to get a
non-zero duration on the benchmark test so it fails.
2026-03-28 10:20:51 -05:00
i999rri
f0badd34d3 fix: replace hardcoded locale.h constants with build-system TranslateC
Replace hardcoded locale.h constants and extern function declarations
with build-system TranslateC, following the same pattern as pty.c.

This fixes LC_ALL being hardcoded to 6 (musl/glibc value), which is
implementation-defined and differs on Windows MSVC (where LC_ALL is 0),
causing setlocale() to crash with an invalid parameter error.
2026-03-28 22:59:10 +09:00