Commit Graph

16241 Commits

Author SHA1 Message Date
Mitchell Hashimoto
9b00bb436a terminal: better SelectionGesture docs 2026-05-27 06:20:22 -07:00
Mitchell Hashimoto
f5f9d32d0a terminal: SelectionGesture deep press 2026-05-26 21:36:22 -07:00
Mitchell Hashimoto
df98b6d983 terminal: SelectionGesture autoscrollTick 2026-05-26 21:26:49 -07:00
Mitchell Hashimoto
141c7d44d2 SelectionGesture: release event 2026-05-26 21:17:03 -07:00
Mitchell Hashimoto
229f4c1f4f terminal: SelectionGesture handles word/line drag 2026-05-26 21:04:22 -07:00
Mitchell Hashimoto
c00cdd886b SelectionGesture: drag events 2026-05-26 20:56:49 -07:00
Mitchell Hashimoto
33f1558801 core: mouse left release renderer lock made more coarse
This will make our selection gesture extraction a bit easier.
2026-05-26 17:02:20 -07:00
Mitchell Hashimoto
14df684a70 core: adapt Surface to use SelectionGesture with press only 2026-05-25 15:48:20 -07:00
Mitchell Hashimoto
d86ff37a58 terminal: SelectionGesture, but only with mouse press 2026-05-25 15:48:16 -07:00
ghostty-vouch[bot]
2d0fb81751 Update VOUCHED list (#12813)
Triggered by [discussion
comment](https://github.com/ghostty-org/ghostty/discussions/12793#discussioncomment-17052752)
from @bo2themax.

Vouch: @LePips

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-05-25 17:54:35 +00:00
Mitchell Hashimoto
cb28160b5a elvish: remove community maintenance note (#12812)
The Elvish integration is currently actively maintained by the Ghostty
maintainers. Contributions are of course still welcome.
2026-05-25 09:07:19 -07:00
Mitchell Hashimoto
53e400ad85 cli: fix readEntries leak and double-free (#12811)
readEntries had two memory bugs on the allocation failure path, both
only reachable under OOM:

- The map itself was never freed if we ran into an allocation failure
- The unconditional `errdefer`s for the dupe'd hostname and terminfo
values could double-free if there was a later allocation failure.

This change restructures this function so that these values are dupe'd
up-front, and then their ownership is tracked using optionals that can
be null'ed out once their ownership is transferred into the map.

Both of these cases are now covered by unit tests.
2026-05-25 09:07:09 -07:00
Jon Parise
16d7c8f2b4 elvish: remove community maintenance note
The Elvish integration is currently actively maintained by the Ghostty
maintainers. Contributions are of course still welcome.
2026-05-25 11:56:37 -04:00
Jon Parise
a5550a2dcb cli: fix readEntries leak and double-free
readEntries had two memory bugs on the allocation failure path, both
only reachable under OOM:

- The map itself was never freed if we ran into an allocation failure
- The unconditional `errdefer`s for the dupe'd hostname and terminfo
  values could double-free if there was a later allocation failure.

This change restructures this function so that these values are dupe'd
up-front, and then their ownership is tracked using optionals that can
be null'ed out once their ownership is transferred into the map.

Both of these cases are now covered by unit tests.
2026-05-25 11:49:01 -04:00
ghostty-vouch[bot]
ae52f97dca Update VOUCHED list (#12809)
Triggered by
[comment](https://github.com/ghostty-org/ghostty/issues/12807#issuecomment-4534655288)
from @pluiedev.

Denounce: @eric-assetpass

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-05-25 13:31:49 +00:00
Mitchell Hashimoto
b869a6e5ab libghostty: expose per-cell selection state (#12798)
Render-state rows already expose their selected range, but cell-oriented
C API consumers had to fetch that row range separately and duplicate the
containment check while rendering.

Add a SELECTED row-cells data kind that carries the row selection into
the row-cells wrapper and returns whether the current cell column is in
that inclusive range. The field remains separate from cell colors and
style so selection stays an explicit render overlay policy.

For performance reasons, the span-based row getter is recommended still
but this is a convenient thing to do for cell-oriented folks.
2026-05-24 20:28:58 -07:00
Mitchell Hashimoto
edf2da0157 libghostty: expose per-cell selection state
Render-state rows already expose their selected range, but
cell-oriented C API consumers had to fetch that row range separately
and duplicate the containment check while rendering.

Add a SELECTED row-cells data kind that carries the row selection into
the row-cells wrapper and returns whether the current cell column is in
that inclusive range. The field remains separate from cell colors and
style so selection stays an explicit render overlay policy.

For performance reasons, the span-based row getter is recommended still
but this is a convenient thing to do for cell-oriented folks.
2026-05-24 20:24:16 -07:00
Mitchell Hashimoto
cf9e85ecd7 deal with large outputs from xdg-open/rundll32/open (#12797)
Depending on your system config, `xdg-open` may stay open for extended
periods, and potentially log more than the 50kb of output that we were
previously able to deal with. This changes `open()` so that output on
`stdout` is just directly ignored. Any output from `stderr` is immedialy
logged rather than collected for later logging.

Note that this will generally occur if your system is not configured
with the DBus portals that `xdg-open` uses to open URLs rather than
launching programs like your web browser directly. This could be seen as
user misconfiguration but we should deal with it robustly anyway.
2026-05-24 19:49:04 -07:00
Jeffrey C. Ollie
bb375a2f75 deal with large outputs from xdg-open/rundll32/open
Depending on your system config, `xdg-open` may stay open for extended
periods, and potentially log more than the 50kb of output that we were
previously able to deal with. This changes `open()` so that output on
`stdout` is just directly ignored. Any output from `stderr` is immedialy
logged rather than collected for later logging.

Note that this will generally occur if your system is not configured
with the DBus portals that `xdg-open` uses to open URLs rather than
launching programs like your web browser directly. This could be seen as
user misconfiguration but we should deal with it robustly anyway.
2026-05-24 20:35:39 -05:00
Mitchell Hashimoto
c5946f4fef libghostty: detach tracked grid refs on free (#12795)
Tracked grid references previously held a raw terminal wrapper pointer
and were required to be freed before the terminal. If callers kept one
past terminal destruction, later tracked-ref calls could dereference
freed terminal or page-list memory before detecting that the reference
was no longer meaningful.

Track live C tracked-grid-ref handles from the terminal wrapper and
detach them before tearing down terminal storage. Detached refs now
report no value through the tracked-ref APIs and can still be freed by
the caller. Update the C API docs to describe this lifetime behavior and
add a regression test for using a tracked ref after terminal free.

This introduces some overhead but tracked pins shouldn't be numerous and
this dramatically improves safety.

No API changes due to this (just more safety).
2026-05-24 14:21:58 -07:00
Mitchell Hashimoto
5f08694759 libghostty: selection APIs for C (#12794)
Adds libghostty-vt selection APIs read/write, formatting, inspecting,
and rendering selection state from C.

| Introduced type/function | Purpose |
| --- | --- |
| `GhosttyRenderStateRowSelection` | Row-local inclusive selection range
returned by render row queries. |
| `GhosttyTerminalSelectWordOptions` | Options for deriving a word
selection from a grid ref. |
| `GhosttyTerminalSelectWordBetweenOptions` | Options for finding the
nearest selectable word between two refs. |
| `GhosttyTerminalSelectLineOptions` | Options for deriving line
selections, including semantic prompt boundaries. |
| `GhosttyTerminalSelectionFormatOptions` | Options for formatting the
active or caller-provided selection. |
| `GhosttySelectionOrder` | Describes endpoint ordering, including
rectangular mirrored orders. |
| `GhosttySelectionAdjust` | Operations for moving a selection endpoint.
|
| `ghostty_terminal_select_word` | Derive a word selection snapshot. |
| `ghostty_terminal_select_word_between` | Derive the nearest word
selection between two refs. |
| `ghostty_terminal_select_line` | Derive a line selection snapshot. |
| `ghostty_terminal_select_all` | Derive a selection covering all
selectable content. |
| `ghostty_terminal_select_output` | Derive a semantic command-output
selection. |
| `ghostty_terminal_selection_format_buf` | Format a selection into a
caller-provided buffer. |
| `ghostty_terminal_selection_format_alloc` | Format a selection into an
allocated buffer. |
| `ghostty_terminal_selection_adjust` | Mutate a selection snapshot
endpoint. |
| `ghostty_terminal_selection_order` | Query selection endpoint order. |
| `ghostty_terminal_selection_ordered` | Return a selection with
normalized endpoint order. |
| `ghostty_terminal_selection_contains` | Test whether a point is inside
a selection. |
| `ghostty_terminal_selection_equal` | Compare two selection snapshots
using terminal semantics. |
2026-05-24 14:14:54 -07:00
Mitchell Hashimoto
03df613e39 libghostty: detach tracked grid refs on free
Tracked grid references previously held a raw terminal wrapper pointer and
were required to be freed before the terminal. If callers kept one past
terminal destruction, later tracked-ref calls could dereference freed
terminal or page-list memory before detecting that the reference was no
longer meaningful.

Track live C tracked-grid-ref handles from the terminal wrapper and detach
them before tearing down terminal storage. Detached refs now report no
value through the tracked-ref APIs and can still be freed by the caller.
Update the C API docs to describe this lifetime behavior and add a
regression test for using a tracked ref after terminal free.

This introduces some overhead but tracked pins shouldn't be numerous
and this dramatically improves safety.
2026-05-24 14:13:26 -07:00
Mitchell Hashimoto
2ce5db29ca libghostty: selection formatting 2026-05-24 14:01:35 -07:00
Mitchell Hashimoto
eb777b8036 libghostty: selectWordBetween in C 2026-05-24 13:53:31 -07:00
Mitchell Hashimoto
e8f5353912 example/c-vt-selection 2026-05-24 13:48:10 -07:00
Mitchell Hashimoto
cc48312c08 libghostty: selection word/line/output/all helpers 2026-05-24 13:42:20 -07:00
Mitchell Hashimoto
847b8afc87 libghostty: remove selection validation, way too expensive 2026-05-23 18:31:20 -07:00
Mitchell Hashimoto
7b49d1f129 terminal: PageList.reset needs to reset page serial mins 2026-05-23 15:32:15 -07:00
Mitchell Hashimoto
ae839393d9 libghostty: add Selection equal and validate 2026-05-23 15:23:39 -07:00
Mitchell Hashimoto
2512fad940 libghostty: move selection functions to selection doxygen group 2026-05-23 15:20:45 -07:00
Mitchell Hashimoto
671c12fad9 libghostty: add selection contains API
Expose a C API for checking whether a GhosttyPoint is inside a
GhosttySelection. The new terminal helper validates the selection snapshot
against the active screen, resolves the point to a grid pin, and delegates
to the internal Selection.contains implementation so C consumers get the
same linear and rectangular selection semantics as Ghostty.

Wire the symbol through the C API exports and public headers, and add a
focused test covering linear containment and rectangular selection behavior.
2026-05-23 15:17:59 -07:00
Mitchell Hashimoto
4a77e81967 libghostty: add selection ordering APIs
Expose selection endpoint ordering through the libghostty-vt C API so
embedders can safely normalize selections whose start and end refs may be
reversed. The new APIs report the current order and return a fresh
untracked selection with forward or reverse bounds.

Selection.Order now uses lib.Enum, matching the existing adjustment enum
pattern and keeping the C ABI enum generated from the same Zig source of
truth. The new functions are wired through the C API re-export and lib-vt
export paths, with coverage for mirrored rectangular selection ordering.
2026-05-23 15:16:04 -07:00
Mitchell Hashimoto
15d8963681 libghostty: add selection adjustment api 2026-05-23 15:12:32 -07:00
Mitchell Hashimoto
545a5aef66 libghostty: document selection snapshot lifetime
Clarify that GhosttySelection is a snapshot type whose endpoints are
untracked GhosttyGridRef values. The previous documentation described the
range shape but did not repeat the grid reference lifetime caveat, which
made it easy to keep selections across terminal mutations incorrectly.
2026-05-23 15:05:23 -07:00
Mitchell Hashimoto
24048ffd47 libghostty: expose row-local render selections
Render state already tracks the selected cell range for each viewport row,
but C renderers could only get the full terminal selection. That required
consumers to map global selection pins back into row-local spans themselves.

Add row selection data to the render-state row API. Querying the new row
data returns GHOSTTY_NO_VALUE for unselected rows and writes the inclusive
start and end columns for selected rows. The render example now demonstrates
setting a selection and reading the row-local range while iterating rows.
2026-05-23 15:03:51 -07:00
Mitchell Hashimoto
ae03d3cae4 libghostty: expose get/set active selection state
Add terminal set/get support for the active screen selection through the
existing option and data APIs. Setting a selection copies the C snapshot
into terminal-owned tracked state, while passing NULL clears the current
selection.

Getting the selection now returns an untracked GhosttySelection snapshot
or GHOSTTY_NO_VALUE when there is no selection. The C header documents
the different lifetimes for set and get so embedders know when input and
returned grid references remain valid.
2026-05-23 14:56:39 -07:00
Mitchell Hashimoto
d5d8cef4d3 macOS: fix search bar Enter key blocking IME composition (#12781)
Closes https://github.com/ghostty-org/ghostty/discussions/12774

`.onKeyPress(.return)` unconditionally returns `.handled`, so when IME
is composing the return key never reaches the IME to confirm the
candidate. The search bar gets stuck.

The fix: use `.onSubmit` for the next-match navigation — it only fires
when there is no composing text. In `.onKeyPress` only intercept
shift+return (previous match), return `.ignored` otherwise.

Tested on macOS 26.5, Ghostty 1.3.1, built from source. Chinese Pinyin
input in the search bar works correctly after the fix.
2026-05-23 14:51:12 -07:00
Mitchell Hashimoto
7c3d9502dc Update VOUCHED list (#12779)
Triggered by [discussion
comment](https://github.com/ghostty-org/ghostty/discussions/12775#discussioncomment-17030265)
from @bo2themax.

Vouch: @minorcell
2026-05-23 14:50:45 -07:00
Mitchell Hashimoto
af94eac1e1 libghostty: add tracked grid ref API (#12785)
Add a C API for tracked pins, known as a tracked grid ref in C.

The new API can create tracked refs from terminal points, snapshot them
back to regular grid refs for cell access, convert them to coordinates,
move them to a new point, report when their semantic location was lost,
and free the tracked pin bookkeeping. This is backed by PageList tracked
pins and exposed through the libghostty-vt export layer and headers.
2026-05-23 14:50:19 -07:00
Mitchell Hashimoto
60f767dd84 core: guard surface left-click pins with screen generations
Left-click mouse state stored a tracked pin with only the screen key that
owned it. If the alternate screen was removed and later recreated, the key
could match again even though the stored pin belonged to destroyed PageList
storage.

Store the screen generation alongside the left-click pin and resolve the
pin through helpers that require both the key and generation to match. This
keeps selection scrolling, link hover checks, pressure selection, and drag
selection from dereferencing stale tracked pins after screen teardown.
2026-05-23 14:45:13 -07:00
Mitchell Hashimoto
2355550a94 libghostty: add tracked grid ref API
Add a C API for tracked pins, known as a tracked grid ref in C.

The new API can create tracked refs from terminal points, snapshot them
back to regular grid refs for cell access, convert them to coordinates,
move them to a new point, report when their semantic location was lost,
and free the tracked pin bookkeeping. This is backed by PageList tracked
pins and exposed through the libghostty-vt export layer and headers.
2026-05-23 14:37:59 -07:00
minorcell
da541bea63 fix stray brace from conflict resolution 2026-05-23 16:33:33 +08:00
minorcell
7a346dd8d4 macOS: fix search bar Enter key blocking IME composition
Use onSubmit for the plain Enter → next-match behavior, which respects
IME composition state. Keep onKeyPress only for Shift+Enter (previous
match), returning .ignored for plain Enter so the IME can process it.
2026-05-23 16:09:48 +08:00
ghostty-vouch[bot]
a968e120dd Update VOUCHED list (#12780)
Triggered by [discussion
comment](https://github.com/ghostty-org/ghostty/discussions/12775#discussioncomment-17030265)
from @bo2themax.

Vouch: @minorcell

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-05-23 07:58:07 +00:00
github-actions[bot]
1b3c5b57ff Update VOUCHED list
https://github.com/ghostty-org/ghostty/discussions/12775#discussioncomment-DC_kwDOHFhdAs4BA9x5
2026-05-23 07:25:16 +00:00
Mitchell Hashimoto
3e3705b932 macOS: fix surface focus/render state after dragging in to to another window/tab (#12338)
Fixes 2 bugs

1. After dragging a non-focused surface from window A to window B
**quickly without making B the key window**, the focused surface in
window A is not receiving `keyDown` events.


https://github.com/user-attachments/assets/a8861c0a-9300-470d-bf7e-0f32a9ab2cd1

2. #12343 After dragging a surface from tab A to tab B within the same
window, the dragged surface is not rendering input correctly.
> The reason the thread is stuck is because the surface's occlusion
state is set to invisible after target tab's activate while dragging,
since the dragged surface is still in previous tree before dropping, and
after dropping the occlusion state of this surface is not updated to
visible, which causing the surface is accepting input but not rendering.



https://github.com/user-attachments/assets/d67f5dba-8609-4f67-a956-921982faf796
2026-05-22 09:05:11 -07:00
Mitchell Hashimoto
f5aa271d07 cli: add an ssh-wrapping +ssh action (#12582)
Add a drop-in `ssh` wrapper that sets up the remote environment for
Ghostty. Anything not consumed as one of our own flags is forwarded to
the real, wrapped `ssh` binary. It can be used directly (`ghostty +ssh
user@host`), aliased (`alias ssh='ghostty +ssh --'`), or invoked through
Ghostty's shell integration.

Before exec'ing ssh, `+ssh`:

- Forwards Ghostty environment to the remote (`--forward-env`): sets
TERM=xterm-256color and requests SendEnv forwarding of COLORTERM,
TERM_PROGRAM, and TERM_PROGRAM_VERSION.
- Installs Ghostty's terminfo on the remote (`--terminfo`), informed by
our existing `ssh-cache` system and using our internal xterm-ghostty
terminfo representation.

A third flag, `--cache`, controls cache use; `--cache=false` bypasses
both read and write, which is useful for scripting and for debugging
install failures without polluting the cache.

For shell integration, this replaces the per-shell logic (which made up
roughly a third of our shell integration scripts) with a simple wrapper
function that translates GHOSTTY_SHELL_FEATURES into a `ghostty +ssh`
command line.
2026-05-22 09:04:36 -07:00
Mitchell Hashimoto
a03b52e18b fix: preserve active cursor position during reflow (#12598)
This PR fixes an issue where reflowing could leave the active cursor
attached to a clipped trailing blank cell instead of following the
current write position.
2026-05-22 09:03:52 -07:00
Mitchell Hashimoto
24d664f0ba fix: apply variation selectors to preceding codepoint (#12596)
This fixes a bug where the variation selectors (VS15 & VS16) were
checked against the first codepoint in a cell instead of the previous
codepoint in the cell's grapheme cluster, causing them to be dropped if
that first codepoint was not a valid base.
2026-05-22 09:02:48 -07:00
Mitchell Hashimoto
b78174a68f macOS: update window appearance for About and ConfigurationErrors (#12601)
<img width="1224" height="696" alt="Xnip2026-05-06_19-13-31"
src="https://github.com/user-attachments/assets/ab090dc0-7c06-4a01-8e7c-5d48ca6ccca3"
/>
2026-05-22 08:58:26 -07:00