Commit Graph

8833 Commits

Author SHA1 Message Date
Mitchell Hashimoto
12f43dfb7d fix(terminal): bounds check params in DCS passthrough entry
When a DCS sequence has more than MAX_PARAMS parameters, entering
dcs_passthrough would write to params[params_idx] without a bounds
check, causing an out-of-bounds access. Drop the entire DCS hook
when params overflow, consistent with how csi_dispatch handles it.

Found by AFL fuzzing.
2026-02-28 21:11:40 -08:00
Kat
de62821973 Rename ko.po back to ko_KR.po.
While it was renamed from ko_KR.UTF-8.po to ko.po in #10976, @uhojin,
a Korean locale maintainer, notes [1] that “ko_KR [*South* Korean] makes
more sense in locale context just to avoid any potential confusion
between 한국어 vs 조선어”.

Despite ko_KP (North Korean) not being present in glibc (as of version
2.43), and the ISO639 maintainers expressing disapproval of ko_KP [2],
it is possible opinions may change in the future, and individual
opinions may be contested—disambiguating doesn't hurt.

[1]: https://github.com/ghostty-org/ghostty/pull/10976#discussion_r2861424171
[2]: https://github.com/ghostty-org/ghostty/pull/10976#discussion_r2861359240
2026-02-28 19:00:35 +11:00
Kat
9192276d3e Rename pt.po back to pt_BR.po.
Portugal exists! Wikipedia notes [1] it to be the main other dialect.
There's already a PR for pt_PT support too:
https://github.com/ghostty-org/ghostty/pull/9078.

It was renamed from pt_BR.UTF-8.po to pt.po in #10976.

[1]: https://en.wikipedia.org/wiki/Portuguese_dialects
2026-02-28 17:43:08 +11:00
Mitchell Hashimoto
c78d9cba9e config: disable palette-generate by default
Following the discussion at #10852, I believe this is the right default.
I'm willing to continue to revisit this decisions, but Ghostty 1.3 is
around the corner and I don't think such a change like this should be
pushed into it.

I think palette generation is best left as a _theme author_ tool. A
Ghostty color theme could include `palette-generate=true` if it wants
to customize the 256-color palette more easily. Of course, end users can
as well anytime.

Another part of my reasoning is that TUI programs who want this behavior
can already achieve it themselves by mixing dark/light theme detection
via CSI 996 (https://contour-terminal.org/vt-extensions/color-palette-update-notifications/)
with OSC 4/10/11 color query and change sequences, both of which are
decently supported in the terminal ecosystem and fully supported in
Ghostty.

I'm also open to considering some kind of new sequence to make this
easier for TUIs (probably a mode) where they can opt-in to palette
generation plus "harmonius" palettes (see `palette-harmonius`) and
Ghostty does it on demand then. I think that'd solve the legacy vs new
TUI argument where legacy programs can continue to make assumptions
about the palette and new programs can opt-in to a more dynamic palette
without having to do a lot of work themselves.
2026-02-27 11:32:15 -08:00
Mitchell Hashimoto
3a21305d09 fix(macOS): filter phantom mouse events that defeat mouse-hide-while-typing (#11066)
## Summary

Ports the phantom mouse-motion position-equality check from the GTK
runtime to the embedded runtime (used by macOS).

On macOS, TUI apps like Zellij that frequently update the window title
cause phantom `mouseMoved` events at the same coordinates. These flow
through `embedded.zig` → `Surface.zig` `cursorPosCallback` →
`showMouse()`, which explicitly calls
`NSCursor.setHiddenUntilMouseMoves(false)` and unhides the cursor,
defeating `mouse-hide-while-typing`.

The GTK runtime already filters these in PR #4973 (for #3345):

```zig
const is_cursor_still = @abs(priv.cursor_pos.x - pos.x) < 1 and
    @abs(priv.cursor_pos.y - pos.y) < 1;
if (is_cursor_still) return;
```

This PR adds the same check to `embedded.zig`'s `cursorPosCallback`,
using the already-stored `self.cursor_pos` field.

## Test plan

- [x] Enable `mouse-hide-while-typing = true` in Ghostty config
- [ ] Run a TUI app that updates the window title frequently (e.g.
Zellij)
- [ ] Type — cursor should hide and stay hidden despite title updates
- [ ] Move the mouse — cursor should reappear normally
- [ ] Verify no regressions with normal mouse movement,
focus-follows-mouse, or link hovering
2026-02-27 11:25:18 -08:00
Mitchell Hashimoto
0bdd3bb6b5 feat(vt): Parse UAPI OSC 3008 hierarchical context signalling (#11057)
Implements parsing for OSC 3008, which allows terminal emulators to keep
track of the stack of processes that have current control over the tty.
The implementation mirrors existing `semantic_prompt.zig` architecture
and natively maps UAPI definitions to Zig structures with lazy
evaluation for optional metadata.

Fixes #10900
2026-02-27 10:46:35 -08:00
Prakhar54-byte
eafdbaaada refactor: simplify Enum parse call and loop parsing logic 2026-02-27 22:58:08 +05:30
linustalacko
2a41401463 fix(macOS): filter phantom mouse events that defeat mouse-hide-while-typing
On macOS, TUI apps like Zellij that frequently update the window title
cause phantom mouse-move events to be generated at the same coordinates.
These phantom events reach cursorPosCallback in the core, which calls
showMouse() and explicitly unhides the cursor via
NSCursor.setHiddenUntilMouseMoves(false), defeating the
mouse-hide-while-typing feature.

This ports the same position-equality check already present in the GTK
runtime (added in PR #4973 for issue #3345) to the embedded runtime used
by macOS. If the cursor position hasn't changed by more than 1px, the
event is discarded.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 09:08:13 -08:00
Prakhar54-byte
3e1004717b refactor: apply PR feedback
- Use `std.meta.stringToEnum` in ContextType and ExitStatus
- Ensure `parseInt` only accepts digits for pids
- Use `@tagName` for string representation in Field
- Rename `fields_raw` to `metadata`
- Rename `readField` to `readOption`
2026-02-27 22:20:42 +05:30
Jeffrey C. Ollie
cdf0dd15e9 testing: use std.Build.TranslateC instead of @cImport 2026-02-27 10:13:03 -06:00
Prakhar54-byte
9da6588c16 feat(vt): Parse UAPI OSC 3008 hierarchical context signalling
Implements parsing for OSC 3008, which allows terminal emulators to keep track of the stack of processes that have current control over the tty. The implementation mirrors existing `semantic_prompt.zig` architecture and natively maps UAPI definitions to Zig structures with lazy evaluation for optional metadata.

Fixes #10900
2026-02-27 21:10:42 +05:30
Jeffrey C. Ollie
ea5b07d20f core: add tests for ghostty.h
* ensure that `ghostty.h` compiles during basic Zig tests
* ensure that non-exhaustive enums are kept synchronized between
  `ghostty.h` and their respective Zig counterpart.
* adjust some enums that varied from established conventions
2026-02-27 09:22:23 -06:00
Mitchell Hashimoto
f19d847f95 core: parse cmdline and cmdline_url semantic prompt options (#11046) 2026-02-26 19:36:38 -08:00
Kat
d5f621044d Update language config option's documentation.
Follow-up to #10976.
2026-02-27 11:08:19 +11:00
Jeffrey C. Ollie
3b4e2bbcbe core: parse cmdline and cmdline_url semantic prompt options 2026-02-26 17:52:09 -06:00
Mitchell Hashimoto
ca09c0ef2e macOS: add "command finished" notifications (#10934)
fixes https://github.com/ghostty-org/ghostty/issues/10840

Implement command finished notifications for MacOS. Building on the work
of #8992

### AI Tools Used
* Cursor
* Models
    * Opus 4.6
    * Composer 1.5
2026-02-26 13:47:24 -08:00
Jeffrey C. Ollie
62873f60c5 i18n: rename .po files (#10976)
This seems to be the defacto standard for naming `.po` files. See the
GTK source code [1] as an example. I was unable to find any definitive
documentation on the naming.

Replaces: #10905

[1] https://gitlab.gnome.org/GNOME/gtk/-/tree/main/po?ref_type=heads
2026-02-26 15:23:27 -06:00
Mitchell Hashimoto
39d163fee2 zsh: fix ssh-terminfo shell integration to not interpret escape characters (#11038)
With zsh, when installing the ghostty terminfo on a server via the
ssh-terminfo shell integration, parts of the terminfo get mangled. In
particular, the newline escape sequence in
```
> infocmp -0 -x xterm-ghostty | grep ind=
 ...,ind=\n,indn=...
 ```
gets interpreted by `print` as a literal newline, which then just gets ignored / does not have the intended effect.

Documentation for the `-r` flag of `print` used in the fix is [here](https://zsh.sourceforge.io/Doc/Release/Shell-Builtin-Commands.html#:~:text=Ignore%20the%20escape%20conventions%20of%20echo.).

### Testing locally
You can directly demonstrate this locally. This outputs a host of warning messages:
```
ssh_terminfo=$(infocmp -0 -x xterm-ghostty 2>/dev/null)
print "$ssh_terminfo" | tic -x -
```
Whereas
```print -r "$ssh_terminfo" | tic -x -```
or
```infocmp -0 -x xterm-ghostty | tic -x -```
work without issue.

### Testing remotely
The most visible way is to observe the output of `htop` before and after the change.

More directly, the output of `infocmp -x xterm-ghostty | grep " ind="` should be
```ich=\E[%p1%d@, ich1=\E[@, il=\E[%p1%dL, il1=\E[L, ind=\n,```
instead of 
```ich=\E[%p1%d@, ich1=\E[@, il=\E[%p1%dL, il1=\E[L, ind=,```

---

Discussed in #11031.

---
AI disclosure: I used Claude for parts of figuring out what was going on. The fix itself and the rest was written and tested by myself.
2026-02-26 13:17:24 -08:00
Joseph Martinsen
3b5a7b77d3 macos: implement notify on command finish 2026-02-26 13:12:29 -08:00
Jeffrey C. Ollie
45d1787eff i18n: rename .po files
This seems to be the defacto standard for naming `.po` files. See the
GTK source code [1] as an example. I was unable to find any definitive
documentation on the naming.

Replaces: #10905

[1] https://gitlab.gnome.org/GNOME/gtk/-/tree/main/po?ref_type=heads
2026-02-26 15:10:08 -06:00
Mitchell Hashimoto
dc514c9e11 build: don't build OpenGL support into imgui on iOS 2026-02-26 10:31:21 -08:00
Mitchell Hashimoto
9fe3cc125d apprt/gtk: use new get effective title 2026-02-26 07:19:26 -08:00
Noah Bernsohn
f38234bc5b apprt: show title override in command palette jump commands 2026-02-26 07:18:05 -08:00
Michael Engelhard
875985dbd7 zsh: fix ssh-terminfo shell integration to not interpret escape characters 2026-02-26 13:06:07 +01:00
markhuot
20351a71d0 Fix Palette.C array size typo: [265] → [256]
The C struct Palette.C declared colors as [265]Color.C, but the
terminal palette is 256 colors (terminal.color.Palette = [256]RGB)
and the C header ghostty_config_palette_s correctly uses colors[256].

The mismatch causes ghostty_config_get to write 265×3 = 795 bytes
through a pointer sized for 256×3 = 768 bytes, producing a 27-byte
buffer overflow. On macOS Release builds with stack protector enabled,
this triggers __stack_chk_fail → SIGABRT on launch.
2026-02-25 20:17:13 -05:00
Mitchell Hashimoto
7db8346fca apprt/gtk: fix SIGSEGV on ImGui GLArea re-realize
Fixes #10406

ImGui_ImplOpenGL3_Shutdown() calls imgl3wShutdown() which dlcloses the
GL library handles but does not zero out the imgl3w function pointer
table (imgl3wProcs). When a GLArea is re-realized (e.g. during
reparenting), ImGui_ImplOpenGL3_Init() calls ImGui_ImplOpenGL3_InitLoader()
which checks "if (glGetIntegerv == nullptr)". Since the stale pointers
are non-null, it skips re-initialization. The next GL call through a
dangling function pointer causes a SIGSEGV.

Fix this by introducing ImGui_ImplOpenGL3_ShutdownWithLoaderCleanup()
which calls the normal shutdown and then zeroes the imgl3wProcs table,
forcing the next Init to reload GL function pointers via imgl3wInit().

Also properly destroy the ImGui context and reset widget state in
glAreaUnrealize so re-realize starts clean. This was extra but was
probably leaking memory.
2026-02-25 15:25:22 -08:00
Jeffrey C. Ollie
57d570525b gtk: clean up title renaming and fix a small leak 2026-02-24 10:28:33 -06:00
ClearAspect
7a4bddd37b renderer: added cursor style and visibility uniforms
Specifically:
iCurrentCursorStyle
iPreviousCursorStyle
iCurrentCursorVisible
iPreviousCursorVisible

Visibility calculated and updated independently from the typical cursor
unifrom updates to preserve cursor style even when not in the viewport
or set to be hidden
2026-02-23 14:11:36 -08:00
Jacob Sandlund
f53e4b43c4 Merge remote-tracking branch 'upstream/main' into grapheme-width-changes 2026-02-23 08:39:10 -05:00
Mitchell Hashimoto
c6e7a7b85a input: Disallow table/chain= and make chain apply to the most recent table
Fixes #10039

(Context is all there)
2026-02-22 13:59:27 -08:00
Mitchell Hashimoto
861a9cf537 ci: Add lib-vt Android support (#10925)
The PR introduces `lib-vt` Android support as discussed in #10902. 

A few more notes:

- Introduces new CI for Android builds as a change requires NDK to be
configured.
- To build locally, it is required to have the NDK installed in the
system and either have the path exported via `ANDROID_NDK_HOME` pointing
to the exact NDK path or `ANDROID_HOME` or `ANDROID_SDK_ROOT` pointing
at the Android SDK path from which the build system will infer the NDK
path and version.
- 16kb page size alignment is configured for Android 15+. Builds are
backward compatible with 4kb page size devices.
2026-02-21 21:13:23 -08:00
Mitchell Hashimoto
cdfa73b403 config: selection-word-chars parses escape sequences
Fixes #10548

Escaped characters in selection-word-chars are now correctly parsed,
allowing for characters like `\t` to be included in the set of word
characters.
2026-02-21 14:52:28 -08:00
Mitchell Hashimoto
caec9e04d2 renderer: kitty image update requires draw_mutex
Fixes #10680

The image state is used for drawing, so when we update it, we need to
acquire the draw mutex. All our other state updates already acquire the
draw mutex but Kitty images are odd in that they happen in the critical
area (due to their size).
2026-02-21 14:28:39 -08:00
Elias Andualem
e7cfb17d5a build: support 16kb page sizes for Android 15+ 2026-02-21 22:48:36 +08:00
Elias Andualem
bd9611650f build: add support for Android NDK path configuration 2026-02-21 21:17:09 +08:00
Ēriks Remess
727446fa8b gtk: for a new window's first tab, inherit the parent's initial size hints 2026-02-20 20:01:22 +02:00
Jacob Sandlund
e06ac6d33e Force prepend to use wcwidth_standalone 2026-02-20 12:12:26 -05:00
Jeffrey C. Ollie
5008d7eb93 Add ghostty_config_get tests (#10891)
I mostly did this to familiarize myself with the codebase and figured it
doesn't hurt to cover this with tests if more added logic in this area,
despite this logic receiving indirect coverage elsewhere. [Here's my
related
proposal](https://github.com/ghostty-org/ghostty/discussions/10807).

I gave more thought around how to expose some of these config values and
their metadata in the C api to eventually drive a settings UI and was
hoping for feedback before I proceed.

The cleanest path forward feels like annotating config values with
formal metadata around things like: supported platforms, whether or not
a restart is required, presentation metadata like grouping + ordering,
tolerated ranges for values, possible enum values, etc. My intent is
that Swift & other consumers can enumerate potential settings values
with metadata such as to drive the UI from the metadata.

---

AI Disclosure: I used Codex 5.3 to help me understand how the config
subsystem in zig is exposed to Swift via the C API. Codex wrote these
tests; but we brainstormed on a pragmatic coverage balance and I
understand how the tests work.
2026-02-20 10:16:21 -06:00
Nico Ritschel
b0f00a65ed Add ghostty_config_get tests
I mostly did this to familiarize myself with the codebase and figured it
doesn't hurt to cover this with tests if I add more in this area,
despite receiving indirect coverage elsewhere.
2026-02-19 20:45:52 -08:00
Mitchell Hashimoto
0eaf77da5f WIP: Make palette inversion opt-in (#10877)
From #10554

> I can see there being space for some kind of new sequence that tells
the terminal that "hey, I want a semantic palette" or something, that is
better adjusted to themes automatically. But, I don't think we should
this by default.

> So my concrete proposal is to eliminate the inversion and bg => fg
ramp and do a more typical dark => light ramp (still taking into account
bg/fg, but keeping 16 black and 231 white). I think this is the only way
we can really make this a default on feature. I think this would address
all the negative reactions we've gotten to it.

This adds a new `palette-harmonious`, disabled by default, which allows
generated light themes to be inverted.
2026-02-19 20:24:42 -08:00
Jake Stewart
f66a84b18a improve light theme detection 2026-02-19 20:17:47 -08:00
Jake Stewart
c4c87f8c85 make palette inversion opt-in 2026-02-20 07:46:16 +08:00
benodiwal
3d0da44e15 feat(config): allow fullscreen config to specify non-native mode directly
Co-Authored-By: Sachin <sachinbeniwal0101@gmail.com>
2026-02-19 14:34:22 -08:00
Mitchell Hashimoto
2a62f21bf0 fix tests 2026-02-19 14:10:33 -08:00
Mitchell Hashimoto
eb335fb8dd cleanup by just scrolling in the renderer 2026-02-19 14:06:58 -08:00
benodiwal
263469755c refactor: remove unused stream handler scroll-to-bottom code
The renderer approach doesn't need termio changes.

Co-Authored-By: Sachin <sachinbeniwal0101@gmail.com>
2026-02-19 13:54:32 -08:00
benodiwal
e197b95c32 feat: scroll-to-bottom on output via renderer pin tracking
Co-Authored-By: Sachin <sachinbeniwal0101@gmail.com>
2026-02-19 13:53:27 -08:00
benodiwal
81f537e992 feat: implement scroll-to-bottom on output option
Implements the `output` option for the `scroll-to-bottom` configuration,
which scrolls the viewport to the bottom when new lines are printed.

Co-Authored-By: Sachin <sachinbeniwal0101@gmail.com>
2026-02-19 13:52:57 -08:00
Ben Kircher
f66064b0b0 url: fix regression with unified diff lines
Bare relative paths don't need space-continuation semantics.

Fixes #10773
2026-02-19 21:06:56 +01:00
Ben Kircher
c5488afc75 url: improve space in path handling
The space-segment patterns in the path regex (dotted_path_space_segments
and any_path_space_segments) greedily consume text after a space even
when we know that the text is the start of a new independent path (e.g.,
`/tmp/bar` in `/tmp/foo /tmp/bar`).

Fix: Add two negative lookaheads after the space in both patterns:
- `(?!\.{0,2}\/)` →  don't match if the next segment starts with `/`,
  `./`, or `../`
- `(?!~\/)` →  don't match if the next segment starts with `~/`
2026-02-19 21:06:56 +01:00