Commit Graph

17384 Commits

Author SHA1 Message Date
Mitchell Hashimoto
619555d1cc pkg/wuffs: build without libc
This modifies our wuffs dependency so that it no longer requires libc.

This unblocks using wuffs from libghostty-vt on freestanding targets,
which we'll eventually want for some Kitty graphics stuff.
2026-08-20 21:34:45 -07:00
Mitchell Hashimoto
08450e21e5 kitty graphics: support relative placements (#13939)
This adds full support for relative placements:
https://sw.kovidgoyal.net/kitty/graphics-protocol/#relative-placements
(`R=` and `Q=`). The high-level description is that this allows images
to be placed relative to other images. For more details, the spec
explains it better than I can, or the demo video below.

The implementation here was pretty straightforward. It mainly revolved
around adding parent resolution logic to puts (and validation), and
proper unparented placement reaping in the right points, and then the
various tests around that. The renderer logic itself was also
straigthforward, I had to add some offset resolution to the core
graphics storage but we can reuse that. The main complexity -- as always
-- (MY OWN EMDASHES) is Unicode placeholders. But... also not too hard.

After this, the only feature we don't support from the protocol is
animation.

**AI usage:** Test writing, validation against spec/reference, judging,
and some "fill in the function/block". I setup the overall shape of the
implementation.

## Demo

Ghostty on the left, Kitty on the right



https://github.com/user-attachments/assets/dc2ec3ac-480a-4587-94e4-06a842f9b3f4
2026-08-20 15:46:33 -07:00
Mitchell Hashimoto
9490f71342 renderer: position relative kitty image placements 2026-08-20 15:16:17 -07:00
Mitchell Hashimoto
33ca9e5ddc terminal/kitty: create relative placements from put commands 2026-08-20 15:16:11 -07:00
Mitchell Hashimoto
f5b3efe452 terminal/c: resolve relative placement viewport positions 2026-08-20 15:16:03 -07:00
Mitchell Hashimoto
cd5f9eef0a terminal/kitty: add relative placement storage 2026-08-20 15:15:55 -07:00
Mitchell Hashimoto
a32a100d4b terminal/kitty: centralize placeholder placement lookup 2026-08-20 15:15:54 -07:00
Mitchell Hashimoto
d30a9c424d terminal: clear cursor pin garbage flag on screen reset 2026-08-20 15:15:48 -07:00
Mitchell Hashimoto
16b39f45a8 fix up recent Valgrind errors (#13938)
No issues in actual shipped code found.

- ci: valgrind runs now fail when Memcheck finds an unsuppressed error.
- fix real memory issues in unit tests
- add a suppression for Zig's flate compression which documents as
purposely using undefined memory
2026-08-20 14:17:14 -07:00
Mitchell Hashimoto
04d6954ebf os: remove flaky TempDir handle checks (#13937)
The TempDir tests saved directory descriptors before close and expected
`fcntl(F_GETFD)` to return `EBADF` afterward. A descriptor number
becomes available for reuse as soon as it is closed.

Unrelated I/O could reuse either number before the assertion, causing
the Valgrind job to report a leak even though TempDir closed both
handles correctly [1].

Remove the raw descriptor assertions and keep coverage of observable
delete and retain behavior. Explain at both close sites why descriptor
numbers cannot identify the original handles after close.

[1]:
https://github.com/ghostty-org/ghostty/actions/runs/32410237002/job/96561246487
2026-08-20 14:17:02 -07:00
Mitchell Hashimoto
c5f4f00ed3 fix up recent Valgrind errors
- ci: valgrind runs now fail when Memcheck finds an unsuppressed error.
- fix real memory issues in unit tests
- add a suppression for Zig's flate compression which documents as
  purposely using undefined memory
2026-08-20 13:56:12 -07:00
Mitchell Hashimoto
1ffdd7415a os: remove flaky TempDir handle checks
The TempDir tests saved directory descriptors before close and expected
`fcntl(F_GETFD)` to return `EBADF` afterward. A descriptor number
becomes available for reuse as soon as it is closed.

Unrelated I/O could reuse either number before the assertion, causing
the Valgrind job to report a leak even though TempDir closed both
handles correctly [1].

Remove the raw descriptor assertions and keep coverage of observable
delete and retain behavior. Explain at both close sites why descriptor
numbers cannot identify the original handles after close.

[1]: https://github.com/ghostty-org/ghostty/actions/runs/32410237002/job/96561246487
2026-08-20 13:32:30 -07:00
Mitchell Hashimoto
1ffa77c90b terminal/kitty: scroll and clip image placements within margins (#13935)
Fixes #4323

The Kitty graphics protocol requires that when margins are defined and
index commands are used, only images entirely within the scroll region
are scrolled, and that they are clipped when scrolling would cause them
to extend outside the region [1].

This implements that part of the spec.

Benchmarked pure `\n` terminal streams to ensure that the no-image case
is not regressed. Our branch hints plus checks on placements keep that
true. When images are present, things get a lot slower but thats
acceptable for now.

## Demo



https://github.com/user-attachments/assets/22e23c8b-ffd4-48fb-9e86-31e810d36ea0



[1]:
https://sw.kovidgoyal.net/kitty/graphics-protocol/#interaction-with-other-terminal-actions
2026-08-20 12:43:40 -07:00
Mitchell Hashimoto
90bce0d2dd terminal/kitty: scroll and clip image placements within margins
Fixes #4323

The Kitty graphics protocol requires that when margins are defined
and index commands are used, only images entirely within the scroll
region are scrolled, and that they are clipped when scrolling would
cause them to extend outside the region [1]. 

This implements that part of the spec.

Benchmarked pure `\n` terminal streams to ensure that the no-image case
is not regressed. Our branch hints plus checks on placements keep that
true. When images are present, things get a lot slower but thats
acceptable for now.

[1]: https://sw.kovidgoyal.net/kitty/graphics-protocol/#interaction-with-other-terminal-actions
2026-08-20 12:30:15 -07:00
Mitchell Hashimoto
e6605009bb terminal/kitty: prevent auto-assigned image ID collisions (#13934)
Fixes #2197

Image transmissions without an explicit ID (i=) were assigned IDs from a
wrapping counter starting with no collision check. The protocol allows
clients to choose IDs anywhere in the u32 range, so an auto-assigned ID
could collide.

Number-based transmissions (I= without i=) now receive the smallest ID
not currently in use. This probes the image map in an `O(N)` fashion but
performance issues here require a pathological client and this
implementation matches Kitty's performance as well.
2026-08-20 10:12:14 -07:00
Mitchell Hashimoto
6b23c584ca terminal/kitty: prevent auto-assigned image ID collisions
Fixes #2197

Image transmissions without an explicit ID (i=) were assigned IDs from
a wrapping counter starting with no collision check. The protocol allows
clients to choose IDs anywhere in the u32 range, so an auto-assigned ID could
collide.

Number-based transmissions (I= without i=) now receive the smallest ID
not currently in use. This probes the image map in an `O(N)` fashion but
performance issues here require a pathological client and this implementation
matches Kitty's performance as well.
2026-08-20 09:45:28 -07:00
Mitchell Hashimoto
b6cbaf54ef terminal/kitty: fix various validation behaviors to match Kitty (#13933)
There are various validation behaviors we did that matched the spec but
didn't match Kitty, because Kitty is written in C (these parts) and does
a lot of C-ish things (like bool is any non-zero value, despite the spec
saying 1/0).

This also fixes a more major issue where invalid formats should be
deferred until transmission finishes so we send a proper response. Right
now we send no response which can cause a client to hang!
2026-08-20 09:27:55 -07:00
Mitchell Hashimoto
242723223f terminal/kitty: fix various validation behaviors to match Kitty
There are various validation behaviors we did that matched the spec but
didn't match Kitty, because Kitty is written in C (these parts) and does
a lot of C-ish things (like bool is any non-zero value, despite the spec
saying 1/0). 

This also fixes a more major issue where invalid formats should be
deferred until transmission finishes so we send a proper response. Right
now we send no response which can cause a client to hang!
2026-08-20 09:19:53 -07:00
Mitchell Hashimoto
48c7006b9a terminal/kitty: accept empty graphics delete ranges (#13932)
The `d=r`/`d=R` delete parser required a `y` key and enforced `x <= y`,
rejecting the entire command with `error.InvalidFormat` otherwise. Both
bounds now default to zero and neither is validated.

This matches upstream reference implementation.
2026-08-20 09:09:45 -07:00
Mitchell Hashimoto
f7d29b19e8 terminal/kitty: accept empty graphics delete ranges
The `d=r`/`d=R` delete parser required a `y` key and enforced `x <= y`,
rejecting the entire command with `error.InvalidFormat` otherwise. Both
bounds now default to zero and neither is validated.

This matches upstream reference implementation.
2026-08-20 08:57:20 -07:00
Mitchell Hashimoto
af150144e2 terminal: clear progress bar on full reset (#13901)
Emit a `progress_report` remove effect from the `full_reset` arm,
matching kitty and WezTerm which both clear progress on reset.

Previously, only the termio `StreamHandler` removed the progress bar on
RIS (#10178) - but the terminal stream handler used by `libghostty-vt`
did not, so an embedder's progress bar would outlive the reset.
2026-08-20 08:02:42 -07:00
Mitchell Hashimoto
956a687d63 macOS: refine liquid glass styles (#13928)
Rework for https://github.com/ghostty-org/ghostty/pull/10943;

Keep the background color as it is and apply glass effect on top of it.
Remove the color modification and keep our implementation relatively
simple and more straightforward.

This fixes https://github.com/ghostty-org/ghostty/issues/13914 and also
ofc the linked issue in previous pr.

### Regular


https://github.com/user-attachments/assets/b44e0af1-0a03-4773-8bfa-03ba48804235


https://github.com/user-attachments/assets/83ab0ef5-6791-412d-b260-e7c55e7f890c

### Clear


https://github.com/user-attachments/assets/8970b97c-7866-45dd-a122-dc9c8bdc7ec0


https://github.com/user-attachments/assets/4105dc8f-f531-4a77-b193-b914c46d3075
2026-08-20 06:57:16 -07:00
Mitchell Hashimoto
aea03011d0 termio: release initial input resources (#13931)
Initial input files remained open and their fully read buffers remained
allocated after queueWrite copied their contents. Close these files on
both startup success and failure, free their contents after queueing,
and borrow raw values already owned by the arena.

**AI Usage:** This was spotted by GPT 5.6 Sol. I reworked the code a bit
and understand it all.
2026-08-20 06:56:43 -07:00
Mitchell Hashimoto
0de91eee32 font: render glyf directly into output bitmap (#13929)
Glyf rasterization previously let z2d allocate its alpha surface, then
duplicated the completed pixels into caller-owned storage. Back the z2d
surface with the final bitmap instead, eliminating one allocation and a
full bitmap copy for each non-empty glyph.
2026-08-20 06:54:17 -07:00
Jon Parise
9566a1a87e termio: release initial input resources
Initial input files remained open and their fully read buffers remained
allocated after queueWrite copied their contents. Close these files on
both startup success and failure, free their contents after queueing, and
borrow raw values already owned by the arena.
2026-08-20 09:02:54 -04:00
Jon Parise
6f02d9aad6 font: render glyf directly into output bitmap
Glyf rasterization previously let z2d allocate its alpha surface, then
duplicated the completed pixels into caller-owned storage. Back the z2d
surface with the final bitmap instead, eliminating one allocation and a
full bitmap copy for each non-empty glyph.
2026-08-20 08:12:34 -04:00
Lukas
fd17869d15 macOS: rework for #10943
Keep the background color as it is and apply glass effect on top of it
2026-08-20 13:30:33 +02:00
Fredrik Fornwall
b7ee3ab6b3 Revert "terminal: only clear the progress bar on full reset if there is one"
This reverts commit b56c6d88f8.
2026-08-20 11:34:43 +02:00
Mitchell Hashimoto
9ae02a326f terminal: transfer selection text into string maps (#13923)
Selection strings previously duplicated formatted text when callers
requested a `StringMap`, even though the regex-link caller immediately
freed the returned copy.

Add a dedicated `selectionStringMap` path that transfers the formatter
output and pin map directly into the returned map. This removes the
extra allocation and copy while making ownership explicit.

**AI Usage:** GTP 5.6 Sol identified and implemented this opportunity. I
reviewed and understand it all.
2026-08-19 19:40:18 -07:00
Kris
fc5ac17a68 i18n: complete Dutch (nl) translation for v1.4 (#13853)
Fills the 181 untranslated strings in `po/nl.po`, bringing it to
252/252. Most of them are the command palette actions from
`src/input/command.zig`; the rest are the new context menu items, global
keybind notifications, and config editing strings.

**Style.** Ten of the new command palette strings had already been
translated by previous translators, and those settle the verb form, so
the rest follows them: imperative for verb+object action titles (`Split
Left` → `Splits naar links`, `Close Tab` → `Sluit tabblad`), noun
phrases left as noun phrases (`New Window` → `Nieuw venster`), no title
case, informal "je". Descriptions are full imperative sentences. Dialog
headings keep the noun-first infinitive form of the existing `Change
Terminal Title` → `Titel van de terminal wijzigen`.

A few translation notes:

- `ANSI Sequences` → `ANSI-reeksen` in titles, `ANSI escape sequences` →
`ANSI-escapereeksen` in descriptions, mirroring the distinction the
source makes.
- `Toggle X` titles use the idiomatic `X aan/uit`; their descriptions
stay imperative (`Schakel … in of uit.`).
- `surface` is rendered as `terminal` - the Dutch UI has no equivalent
concept.
- `scrollback` → `scrollbuffer`.

**No existing translation was modified.** The diff only touches empty
`msgstr` lines plus `PO-Revision-Date` and `Last-Translator`.

Checked with `msgfmt -c --statistics` (252 translated, no warnings, no
fuzzy) and `msgcat` (formatting is idempotent, so no rewrap noise for
the next translator). No `X-Generator` field added.

---------

Co-authored-by: Nico Geesink <126799020+nwehg@users.noreply.github.com>
2026-08-20 01:43:41 +00:00
Jon Parise
f1948d5054 terminal: transfer selection text into string maps
Selection strings previously duplicated formatted text when callers
requested a StringMap, even though the regex-link caller immediately
freed the returned copy.

Add a dedicated selectionStringMap path that transfers the formatter
output and pin map directly into the returned map. This removes the
extra allocation and copy while making ownership explicit.
2026-08-19 21:14:19 -04:00
Mitchell Hashimoto
9154efcbd3 macos: avoid temporary path component allocation (#13921)
The common directory helper previously allocated a temporary slice to
prepend the base directory before joining path components. Pass the
three known components directly to std.fs.path.join, leaving only the
allocation for the returned path.
2026-08-19 17:04:55 -07:00
Jon Parise
a436a9edcc macos: avoid temporary path component allocation
The common directory helper previously allocated a temporary slice to
prepend the base directory before joining path components. Pass the
three known components directly to std.fs.path.join, leaving only the
allocation for the returned path.
2026-08-19 19:31:18 -04:00
Mitchell Hashimoto
50d3ac8ed6 shell-integration: avoid owning temporary commands (#13919)
Some shell setup functions previously converted their stack-backed
command builders to owned sentinel slices before duplicating them into
the result arena. Duplicate the builders' written bytes directly
instead, avoiding unnecessary ownership transfer and sentinel handling.
2026-08-19 15:18:05 -07:00
Mitchell Hashimoto
49e503fd40 surface: parse text bindings with stack fallback (#13918)
Text binding actions previously allocated a temporary buffer for every
escaped string. Use a 256-byte stack fallback allocator so typical
bindings avoid the transient heap allocation while larger values
continue to use the existing heap-backed behavior.
2026-08-19 15:09:45 -07:00
Jon Parise
8e8d76b634 shell-integration: avoid owning temporary commands
Some shell setup functions previously converted their stack-backed
command builders to owned sentinel slices before duplicating them into
the result arena. Duplicate the builders' written bytes directly
instead, avoiding unnecessary ownership transfer and sentinel handling.
2026-08-19 17:46:14 -04:00
Jon Parise
a9f7f6d212 surface: parse text bindings with stack fallback
Text binding actions previously allocated a temporary buffer for every
escaped string. Use a 256-byte stack fallback allocator so typical
bindings avoid the transient heap allocation while larger values
continue to use the existing heap-backed behavior.
2026-08-19 17:36:43 -04:00
Mitchell Hashimoto
a4edca2a90 surface: keep clipboard content list on stack (#13916)
Use a two element stack-based buffer for the one or two ClipboardContent
entries rather than the (arena-based) heap allocator.
2026-08-19 14:19:56 -07:00
Mitchell Hashimoto
4d646bae0c macOS: group settings menu in a separate group (#13906)
**Reverted https://github.com/ghostty-org/ghostty/pull/13664 with a
second thought.**

This keeps the consistency with other first-party apps like Terminal,
Finder, and Music. It seems that most of the first-party apps show the
standard icons on macOS 27 for "Settings...", "Find", "AutoFill" and
etc., but in a separate group.

<img width="1060" height="375" alt="image"
src="https://github.com/user-attachments/assets/d3017865-a443-4c14-ace9-1c6b5acb3f56"
/>


I believe this still follows
[HIG](https://developer.apple.com/design/human-interface-guidelines/menus#Icons).
2026-08-19 14:11:28 -07:00
Jon Parise
5a8921ecb5 surface: keep clipboard content list on stack
Use a two element stack-based buffer for the one or two ClipboardContent
entries rather than the (arena-based) heap allocator.
2026-08-19 17:06:14 -04:00
trag1c
3e7230bf5d i18n: update pt_BR translations (#13819)
Update all missing Portuguese/BR translations for 1.4.

Part of https://github.com/ghostty-org/ghostty/issues/13766
2026-08-19 22:01:27 +02:00
Guilherme Tiscoski
959c0daeaa i18n: update revision date 2026-08-19 13:44:25 -05:00
Guilherme Tiscoski
e8a7097f65 i18: use "aplicativo" instead of "aplicação" for "application" 2026-08-19 11:57:49 -05:00
Guilherme Nandi Tiscoski
5a55a345aa Update po/pt_BR.po
Co-authored-by: Micael Jarniac <micael@jarniac.com>
2026-08-19 11:52:13 -05:00
Guilherme Nandi Tiscoski
4302020990 Update po/pt_BR.po
Co-authored-by: Micael Jarniac <micael@jarniac.com>
2026-08-19 11:52:04 -05:00
Guilherme Nandi Tiscoski
9581f7dd45 Update po/pt_BR.po
Co-authored-by: Micael Jarniac <micael@jarniac.com>
2026-08-19 11:51:56 -05:00
Guilherme Nandi Tiscoski
65621664ed Update po/pt_BR.po
Co-authored-by: Micael Jarniac <micael@jarniac.com>
2026-08-19 11:51:44 -05:00
Guilherme Nandi Tiscoski
ae7080e6cc Update po/pt_BR.po
Co-authored-by: Micael Jarniac <micael@jarniac.com>
2026-08-19 11:51:31 -05:00
Mitchell Hashimoto
d9ffbbf17c chore(vt): expose snapshot api (#13912)
Link:
https://discord.com/channels/1005603569187160125/1420009803173859449/1539649787748417667
2026-08-19 08:32:12 -07:00
Lukas
043abc7b60 macOS: group settings menu in a separate group 2026-08-19 15:03:15 +02:00