Commit Graph

90 Commits

Author SHA1 Message Date
Tim Culverhouse
6c8c07981d terminal: add visibility reports
Applications cannot infer whether an unfocused terminal remains visible, so
focus reports are insufficient for avoiding expensive rendering while a
view is hidden.

Implement private mode 2033 and the visibility query/report sequences.
Track conservative per-surface visibility, report every effective change
while enabled, and always answer explicit queries and mode enables. Keep
view visibility across terminal resets because it is owned by the host,
not terminal state.

Co-authored-by: Amp <amp@ampcode.com>
Amp-Thread-ID: https://ampcode.com/threads/T-019fa965-aa5f-7099-85b4-a9679d2c8bd3
2026-07-28 11:04:13 -05:00
Mitchell Hashimoto
1092204df1 config: support unlimited scrollback limits 2026-07-26 20:13:45 -07:00
Mitchell Hashimoto
65c48213b6 config: expose scrollback line limit 2026-07-26 20:13:45 -07:00
Mitchell Hashimoto
86f81fb5b1 terminal: expose scrollback line limit 2026-07-26 20:13:45 -07: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
Mitchell Hashimoto
c594031d50 terminal: move cursor defaults into terminal state
Cursor defaults were duplicated across stream handlers and it was a
pretty significant amount of simple and yet non-trivial logic to
understand.

Store these on Terminal itself and have methods to route things like
DECSCUSR through for consistent behaviors.
2026-07-17 15:27:34 -07:00
Mitchell Hashimoto
89b103dd5e terminal: more full featured resize (cell geo, sync rendering, etc.)
This makes the Terminal.resize handle more of the common elements that
a core terminal emulator should: cell geoemtry handling (if exists),
updates synchronized output modes.

This adds a new TerminalStream.resize that also handles the side effects
for more easy integration into downstream libghostty-vt consumers, namely
mode 2048 in-band signaling handling.
2026-07-17 10:20:14 -07:00
Mitchell Hashimoto
f00e906949 lib-vt: add color scheme report encoder
Add a shared encoder for CSI ? 997 ; Ps n color scheme reports and use 
it for both CSI ? 996 n replies and unsolicited Termio reports. Export the 
same encoder through the libghostty-vt C API with docs and an example.

This is a really light API, arguably easy for consumers to hardcode,
but it didn't match the rest of our style in the libghostty API so we 
should expose it.

Example: GHOSTTY_COLOR_SCHEME_DARK encodes to ESC [ ? 997 ; 1 n,
while GHOSTTY_COLOR_SCHEME_LIGHT encodes to ESC [ ? 997 ; 2 n.
2026-07-05 10:51:39 -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
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
Jeffrey C. Ollie
2ea6029c7a core: address getProcessInfo feedback
* consolidate *.c files into a single file
* consolidate ProcessInfo enums into a single enum
2026-03-19 22:01:16 -05:00
Jeffrey C. Ollie
89ae0ea6ef core: add function to get process info from the surface
This adds a function to the core surface to get process information
about the process(es) running in the terminal. Currently supported is
the PID of the foreground process and the name of the slave PTY.

If there is an error retrieving the information, or the platform does
not support retieving that information `null` is returned.

This will be useful in exposing the foreground PID and slave PTY name to
AppleScript or other APIs.
2026-03-19 22:01:15 -05:00
Mitchell Hashimoto
a1d7ad9243 terminal: extract size report encoder
Size report escape sequences were previously formatted inline in
Termio.sizeReportLocked, and termio.Message carried a duplicate enum for
report styles. That made the encoding logic harder to reuse and kept
the style type scoped to termio.

Move the encoding into terminal.size_report and export it through
terminal.main. The encoder now takes renderer.Size directly and derives
grid and pixel dimensions from one source of truth. termio.Message now
aliases terminal.size_report.Style, and Termio writes reports via the
shared encoder.
2026-03-17 16:21:34 -07:00
Mitchell Hashimoto
bed9d92f04 vt: expose focus encoding in C and Zig APIs
Add focus event encoding (CSI I / CSI O) to the libghostty-vt public
API, following the same patterns as key and mouse encoding.

The focus Event enum uses lib.Enum for C ABI compatibility. The C API
provides ghostty_focus_encode() which writes into a caller-provided
buffer and returns GHOSTTY_OUT_OF_SPACE with the required size when
the buffer is too small.

Also update key and mouse encoders to return GHOSTTY_OUT_OF_SPACE
instead of GHOSTTY_OUT_OF_MEMORY for buffer-too-small errors,
reserving OUT_OF_MEMORY for actual allocation failures. Update all
corresponding header documentation.
2026-03-16 14:38:19 -07:00
Kat
6fabf775bb Lots of duplicate word typos + typo. 2026-03-16 09:19:09 +11:00
Mitchell Hashimoto
2044e5030f terminal: make stream processing infallible
The terminal.Stream next/nextSlice functions can now no longer fail.
All prior failure modes were fully isolated in the handler `vt`
callbacks. As such, vt callbacks are now required to not return an error
and handle their own errors somehow.

Allowing streams to be fallible before was an incorrect design. It
caused problematic scenarios like in `nextSlice` early terminating
processing due to handler errors. This should not be possible.

There is no safe way to bubble up vt errors through the stream because
if nextSlice is called and multiple errors are returned, we can't
coalesce them. We could modify that to return a partial result but its
just more work for stream that is unnecessary. The handler can do all of
this.

This work was discovered due to cleanups to prepare for more C APIs.
Less errors make C APIs easier to implement! And, it helps clean up our
Zig, too.
2026-03-13 13:56:14 -07: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
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
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
Mitchell Hashimoto
b25edc3e93 termio: don't auto-generate palette if user didn't customize any
This fixes the issue where our palette generation was changing our
default palette. The default palette is based on some well known values
chosen from various terminals and it was a bit jarring to have it
change.

We now only auto-generate the palette if the user has customized at
least one entry.
2026-02-17 13:04:35 -08:00
Mitchell Hashimoto
f0a1b05f63 rename config 2026-02-17 09:54:34 -08:00
Mitchell Hashimoto
50698c5c72 fmt 2026-02-17 09:18:03 -08:00
Jake Stewart
7729714935 refactor 256 color gen 2026-02-17 09:17:54 -08:00
Jake Stewart
fad72e0ed1 generate 256 palette 2026-02-17 09:17:54 -08:00
Mitchell Hashimoto
1b2376d366 terminal: remove last semantic_prompt usage from Terminal 2026-01-31 11:01:03 -08:00
Mitchell Hashimoto
3e825dd608 inspector: clean up Inspector 2026-01-31 08:47:15 -08:00
Tobias Kohlbau
836d794b9e termio: report color scheme synchronously
The reporting of color scheme was handled asynchronously by queuing a
handler in the surface. This could lead to race conditions where the
DSR is reported after subsequent VT sequences.

Fixes #5922
2026-01-19 07:49:57 +01:00
Mitchell Hashimoto
29fdb541d5 make all IO message queueing go through queueIo so we can intercept 2025-12-12 12:00:28 -08:00
Mitchell Hashimoto
dbfc3eb679 Remove unused imports 2025-11-27 13:37:53 -08:00
Qwerasd
6d5b4a3426 perf: replace std.debug.assert with inlined version
See doc comment in `quirks.zig` for reasoning
2025-11-17 12:13:56 -07:00
Mitchell Hashimoto
580f9f057b convert t.screen to t.screens.active 2025-11-14 15:40:31 -08:00
Mitchell Hashimoto
3aff5f0aff ScreenSet 2025-11-14 15:08:10 -08:00
Mitchell Hashimoto
77343bb06e terminal: move color state fully into the terminal for fg/bg/cursor 2025-10-30 09:33:21 -07:00
Mitchell Hashimoto
cabca0aca8 terminal: unify palette functionality into shared type DynamicPalette 2025-10-30 09:15:43 -07:00
Mitchell Hashimoto
580262c96f terminal: add ReadonlyStream that updates terminal state (#9346)
This adds a new stream handler implementation that updates terminal
state in reaction to VT sequences, but doesn't perform any of the
actions that would require responses (e.g. queries).

This is exposed in two ways: first, as a standalone `ReadonlyStream` and
`ReadonlyHandler` type that contains all the implementation. Second, as
a convenience func on `Terminal` as `vtStream` and `vtHandler` which
return their respective types preconfigured to update the calling
terminal state.

This dramatically simplifies libghostty-vt usage from Zig (and will
eventually be exposed to C, too) since a Terminal on its own is ready to
go as a full VT parser and state machine without needing to build any
custom types!

There's a second big bonus here which is that our `stream_readonly.zig`
tests are true end-to-end tests for raw bytes to terminal state. This
will let us test a wider variety of situations more broadly. To start,
there are only a handful of tests implemented here.

**AI disclosure:** Amp wrote basically this whole thing, but I reviewed
it. https://ampcode.com/threads/T-3490efd2-1137-4112-96f6-4bf8a0141ff5
2025-10-25 14:52:33 -07:00
Mitchell Hashimoto
f7189d14b9 terminal: convert Stream to use Action tagged union 2025-10-23 15:50:56 -07:00
Mitchell Hashimoto
131f170f89 terminal: change OSC parser to explicit init to set undefined
This works around: https://github.com/ziglang/zig/issues/19148
This lets our `test-valgrind` command catch some issues. We'll have to
follow this pattern in more places but I want to do it incrementally so
things keep passing.

I **do not** want to blindly follow this pattern everywhere. I want to
start by focusing in only on the structs that set `undefined` as default
fields that we're also about to test in isolation with Valgrind. Its
just too much noise otherwise and not a general style I'm sure of; it's
worth it for Valgrind though.
2025-08-20 12:38:29 -07:00
Mitchell Hashimoto
465ac5b1b7 clean up some of the color usage, use exhaustive switches 2025-07-03 09:25:56 -07:00
Daniel
9e341a3d60 Created tagged union for selection colors, enabled parsing
Implemented cell color for Metal

Removed use of selection-invert-fg-bg

Mirrored feature to OpenGL

Added tests for SelectionColor

Fixed selection on inverted cell behavior

Implemented cell colors for cursor-text

Implemented cell colors for cursor-color, removed uses of cursor-invert-fg-bg during rendering

Updated docs for dynamically colored options

Updated docstrings, cleaned up awkward formatting, and moved style computation to avoid unnecssary invocations

Bump version in docstrings
2025-07-03 07:14:37 -07:00
James Holderness
7f0778bcf2 termio: indicate support for OSC 52 in primary DA report
This is an extension agreed upon by modern terminals to indicate that
they support copying to the clipboard with XTerm's OSC 52 sequence. It
is only reported when writing to the clipboard is actually allowed.
2025-06-29 15:32:17 +01:00
Mitchell Hashimoto
591ef0f40f Move child exit handling logic to apprt thread
Fixes #7500
Supersedes #7582

This commit moves the child exit handling logic from the IO thead to the
apprt thread. The IO thread now only sends a `child_exited` message to
the apprt thread with metadata about the exit conditions (exit code,
runtime).

From there, the apprt thread can handle the exit situation however is
necessary. This commit doesn't change the behavior but it does fix the
issue #7500. The behavior is: exit immediately, show abnormal exit
message, wait for user input, etc.

This also gets us closer to #7649.
2025-06-27 10:36:23 -07:00
Mitchell Hashimoto
1947afade9 input configuration to pass input as stdin on startup
This adds a new configuration `input` that allows passing either raw
text or file contents as stdin when starting the terminal.

The input is sent byte-for-byte to the terminal, so control characters
such as `\n` will be interpreted by the shell and can be used to run
programs in the context of the loaded shell.

Example: `ghostty --input="hello, world\n"` will start the your default
shell, run `echo hello, world`, and then show the prompt.
2025-06-22 18:18:16 -04:00
Mitchell Hashimoto
7e2286eb8c Zig 0.14 2025-03-11 14:39:04 -07:00
Mitchell Hashimoto
d532a6e260 Update libxev to use dynamic backend, support Linux configurability
Related to #3224

Previously, Ghostty used a static API for async event handling: io_uring
on Linux, kqueue on macOS. This commit changes the backend to be dynamic
on Linux so that epoll will be used if io_uring isn't available, or if
the user explicitly chooses it.

This introduces a new config `async-backend` (default "auto") which can
be set by the user to change the async backend in use. This is a
best-effort setting: if the user requests io_uring but it isn't
available, Ghostty will fall back to something that is and that choice
is up to us.

Basic benchmarking both in libxev and Ghostty (vtebench) show no
noticeable performance differences introducing the dynamic API, nor
choosing epoll over io_uring.
2025-02-21 15:04:37 -08:00
Tim Culverhouse
b7009202ce termio: use modified backend
In Termio.init, we make a copy of backend and modify it by calling
initTerminal. However, we used the original in the struct definition.
This lead to the pty being opened with a size 0,0.
2025-02-14 22:44:27 -06:00