Commit Graph

15166 Commits

Author SHA1 Message Date
Mitchell Hashimoto
86c2a2e87f input: add direct set_surface_title and set_tab_title actions
Fixes #11316

This mirrors the `prompt` actions (hence why there is no window action
here) and enables setting titles via keybind actions which importantly
lets this work via command palettes, App Intents, AppleScript, etc.
2026-03-11 09:25:08 -07:00
Mitchell Hashimoto
660767c77d bash: fix multiline PS1 with command substitutions (#11369)
Only replace the \n prompt escape when inserting secondary prompt marks,
not literal newlines `($'\n')`. Literal newlines may appear inside
`$(...)` or `...` command substitutions, and inserting escape sequences
there breaks the shell syntax. For example:

      PS1='$(if [ $? -eq 0 ]; then echo -e "P";
                    else echo -e "F";
                    fi) $ '

The literal newlines between the if/else/fi are part of the shell syntax
inside the command substitution. The previous code replaced all literal
newlines in PS1 with newline + OSC 133 escape sequences, which injected
terminal escapes into the middle of the command substitution and caused
bash to report a syntax error when evaluating it.

The \n prompt escape is PS1-specific and safe to replace globally. This
means prompts using literal newlines for line breaks (rather than \n)
won't get per-line secondary marks, but this is the conventional form
and avoids the need for complex shell parsing.

Fixes: #11267
2026-03-11 08:36:36 -07:00
Jon Parise
26d8bd9e71 bash: fix multiline PS1 with command substitutions
Only replace the \n prompt escape when inserting secondary prompt marks,
not literal newlines ($'\n'). Literal newlines may appear inside $(...)
or `...` command substitutions, and inserting escape sequences there
breaks the shell syntax. For example:

      PS1='$(if [ $? -eq 0 ]; then echo -e "P";
                    else echo -e "F";
                    fi) $ '

The literal newlines between the if/else/fi are part of the shell syntax
inside the command substitution. The previous code replaced all literal
newlines in PS1 with newline + OSC 133 escape sequences, which injected
terminal escapes into the middle of the command substitution and caused
bash to report a syntax error when evaluating it.

The \n prompt escape is PS1-specific and safe to replace globally. This
means prompts using literal newlines for line breaks (rather than \n)
won't get per-line secondary marks, but this is the conventional form
and avoids the need for complex shell parsing.

Fixes: #11267
2026-03-11 10:46:43 -04:00
Mitchell Hashimoto
61865bc37f zsh: improve prompt marking with dynamic themes (#11367)
Replace the strip-in-preexec / re-add-in-precmd pattern for OSC 133
marks with a save/restore approach. Instead of pattern-matching marks
out of PS1 (which exposes PS1 in intermediate states to other hooks), we
save the original PS1/PS2 before adding marks and then restore them.

This also adds dynamic theme detection: if PS1 changed between cycles
(e.g., a theme rebuilt it), we skip injecting continuation marks into
newlines. This prevents breaking plugins like Pure that use pattern
matching to strip/rebuild the prompt.

Additionally, move _ghostty_precmd to the end of precmd_functions in
_ghostty_deferred_init (instead of substituting in-place) so that the
first prompt is properly marked even when other hooks were appended
after our auto-injection.

There's one scenario that we still don't complete cover:

    precmd_functions+=(_test_overwrite_ps1)
    _test_overwrite_ps1() {
        PS1="test> "
    }

... which results in the first prompt not printing its prompt marks
because _test_overwrite_ps1 becomes the last thing to run, overwriting
our marks, but this will be fixed for subsequent prompts when we move
our handler back to the last index.

Fixes: #11282
2026-03-11 07:30:02 -07:00
Mitchell Hashimoto
048a2d043a Merge fix-fullscreen-tab-title-rename-hit into main 2026-03-11 07:25:02 -07:00
ydah
c2206542d3 macos: fix tab title rename hit testing and focus handling in fullscreen mode 2026-03-11 07:24:49 -07:00
ghostty-vouch[bot]
87e496b30f Update VOUCHED list (#11368)
Triggered by
[comment](https://github.com/ghostty-org/ghostty/issues/11365#issuecomment-4039534706)
from @mitchellh.

Vouch: @ydah

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-03-11 14:17:51 +00:00
Jon Parise
23f3cd5f10 zsh: improve prompt marking with dynamic themes
Replace the strip-in-preexec / re-add-in-precmd pattern for OSC 133
marks with a save/restore approach. Instead of pattern-matching marks
out of PS1 (which exposes PS1 in intermediate states to other hooks), we
save the original PS1/PS2 before adding marks and then restore them.

This also adds dynamic theme detection: if PS1 changed between cycles
(e.g., a theme rebuilt it), we skip injecting continuation marks into
newlines. This prevents breaking plugins like Pure that use pattern
matching to strip/rebuild the prompt.

Additionally, move _ghostty_precmd to the end of precmd_functions in
_ghostty_deferred_init (instead of substituting in-place) so that the
first prompt is properly marked even when other hooks were appended
after our auto-injection.

There's one scenario that we still don't complete cover:

    precmd_functions+=(_test_overwrite_ps1)
    _test_overwrite_ps1() {
        PS1="test> "
    }

... which results in the first prompt not printing its prompt marks
because _test_overwrite_ps1 becomes the last thing to run, overwriting
our marks, but this will be fixed for subsequent prompts when we move
our handler back to the last index.

Fixes: #11282
2026-03-11 10:07:54 -04:00
Leah Amelia Chen
76e9ee7d37 gtk: fix +new-window --working-directory inferrence. (#11357) 2026-03-11 17:16:06 +08:00
Leah Amelia Chen
b992b66050 docs: fix backtick rendering in selection-word-chars default value (#11361) 2026-03-11 17:02:33 +08:00
Paul Oliver
82a805296c docs: fix backtick rendering in selection-word-chars default value
The default value contains a literal backtick which broke inline code
rendering on the website. Use double backtick delimiters to properly
contain it.
2026-03-11 21:15:20 +13:00
ghostty-vouch[bot]
a644fca5c5 Update VOUCHED list (#11360)
Triggered by [discussion
comment](https://github.com/ghostty-org/ghostty/discussions/11358#discussioncomment-16080010)
from @jcollie.

Vouch: @puzza007

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-03-11 08:02:29 +00:00
Jeffrey C. Ollie
ad6d3665c2 gtk: fix +new-window --working-directory inferrence.
If the CLI argument `--working-directory` is not used with
`+new-window`, the current working directory that `ghostty +new-window`
is run from will be appended to the list of configuration data sent
to the main Ghostty process. If `-e` _was_ used on the CLI, the
`--working-directory` that was appended will be interpreted as part of
the command to be executed, likely causing it to fail.

Instead, insert `--working-directory` at the beginning of the list of
configuration that it sent to the main Ghostty process.

Fixes #11356
2026-03-11 02:23:12 -05:00
Mitchell Hashimoto
dc18b25f86 macos: disable Tahoe one-time codes (#11351)
This disables all the automatic one-time code inputs in Ghostty. It'd be
really neat to actually dynamically change this (not sure if it's
possible with NSTextContext or how often thats cached) but for now we
should just fully disable it.

Thanks to Ricky Mondello for the heads up on this.
2026-03-10 19:52:30 -07:00
Mitchell Hashimoto
6dd5b856b0 macos: disable Tahoe one-time codes
This disables all the automatic one-time code inputs in Ghostty.
It'd be really neat to actually dynamically change this (not sure if its
possible with NSTextContext or how often thats cached) but for now we
should just fully disable it.
2026-03-10 19:41:22 -07:00
Mitchell Hashimoto
2a170b50c3 macos: add test cases for Ghostty.Config properties (#11263)
### AI Disclosure

Test cases is written using the Claude Agent in Xcode
2026-03-10 19:34:49 -07:00
Jeffrey C. Ollie
d5dab554aa build(deps): bump cachix/install-nix-action from 31.10.0 to 31.10.1 (#11347)
Bumps
[cachix/install-nix-action](https://github.com/cachix/install-nix-action)
from 31.10.0 to 31.10.1.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/cachix/install-nix-action/releases">cachix/install-nix-action's
releases</a>.</em></p>
<blockquote>
<h2>v31.10.1</h2>
<h2>What's Changed</h2>
<ul>
<li>nix: 2.34.0 -&gt; 2.34.1 by <a
href="https://github.com/github-actions"><code>@​github-actions</code></a>[bot]
in <a
href="https://redirect.github.com/cachix/install-nix-action/pull/269">cachix/install-nix-action#269</a>
Fixes a bug introduced in 2.34.0 that made the Nix daemon fail to load
authentication keys configured by <code>cachix-action</code>.</li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/cachix/install-nix-action/compare/v31.10.0...v31.10.1">https://github.com/cachix/install-nix-action/compare/v31.10.0...v31.10.1</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="1ca7d21a94"><code>1ca7d21</code></a>
Merge pull request <a
href="https://redirect.github.com/cachix/install-nix-action/issues/269">#269</a>
from cachix/create-pull-request/patch</li>
<li><a
href="b613734327"><code>b613734</code></a>
nix: 2.34.0 -&gt; 2.34.1</li>
<li>See full diff in <a
href="19effe9fe7...1ca7d21a94">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=cachix/install-nix-action&package-manager=github_actions&previous-version=31.10.0&new-version=31.10.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>
2026-03-10 21:23:32 -05:00
dependabot[bot]
85bec80334 build(deps): bump cachix/install-nix-action from 31.10.0 to 31.10.1
Bumps [cachix/install-nix-action](https://github.com/cachix/install-nix-action) from 31.10.0 to 31.10.1.
- [Release notes](https://github.com/cachix/install-nix-action/releases)
- [Changelog](https://github.com/cachix/install-nix-action/blob/master/RELEASE.md)
- [Commits](19effe9fe7...1ca7d21a94)

---
updated-dependencies:
- dependency-name: cachix/install-nix-action
  dependency-version: 31.10.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-11 00:14:04 +00:00
Jeffrey C. Ollie
818e170ec0 GTK does support scrollbars (#11345)
Native GTK scrollbars are supported in 1.3.0:
https://ghostty.org/docs/install/release-notes/1-3-0#scrollbars
2026-03-10 18:46:20 -05:00
ghostty-vouch[bot]
615af975f3 Update VOUCHED list (#11344)
Triggered by [discussion
comment](https://github.com/ghostty-org/ghostty/discussions/11343#discussioncomment-16075282)
from @jcollie.

Vouch: @hulet

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-03-10 23:26:26 +00:00
Steve Hulet
f9862cd4e2 GTK does support scrollbars 2026-03-10 16:14:18 -07:00
Mitchell Hashimoto
0cb189bfbb config: working-directory expands ~/ prefix (#11337)
Fixes #11336

Introduce a proper WorkingDirectory tagged union type with home,
inherit, and path variants. The field is now an optional
(?WorkingDirectory) where null represents "use platform default" which
is resolved during Config.finalize to .inherit (CLI) or .home (desktop
launcher).
2026-03-10 14:40:43 -07:00
Mitchell Hashimoto
04d5efc8eb config: working-directory expands ~/ prefix
Fixes #11336

Introduce a proper WorkingDirectory tagged union type with home, inherit,
and path variants. The field is now an optional (?WorkingDirectory) where
null represents "use platform default" which is resolved during Config.finalize
to .inherit (CLI) or .home (desktop launcher).
2026-03-10 14:33:40 -07:00
Lukas
90dc4315e2 macos: add test cases for Ghostty.Config properties
Test boolean, string, enum, and numeric config properties using
TemporaryConfig to verify defaults and parsed values.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-10 20:03:17 +01:00
Mitchell Hashimoto
a4cc37db72 tests: disable tests that fail if you have locally installed fonts (#11285)
If you have "Noto Sans Tai Tham" and/or "Noto Sans Javanese" installed
locally on Linux, three tests fail. This PR disables those tests until a
more permanent solution can be found.
2026-03-10 11:53:23 -07:00
Lukas
32934445cf macos: add TemporaryConfig for AI to write test cases 2026-03-10 19:45:52 +01:00
Jeffrey C. Ollie
c1313294cd add comments about why tests are disabled 2026-03-10 13:29:50 -05:00
Mitchell Hashimoto
8784636547 macos: remove IntrinsicSizeTimingTests temporarily (#11332)
These were too flaky.

cc @bo2themax
2026-03-10 11:23:16 -07:00
Mitchell Hashimoto
71f81527ad macos: remove IntrinsicSizeTimingTests temporarily
These were too flaky.
2026-03-10 11:08:47 -07:00
Mitchell Hashimoto
f88b42ad39 macos: add enum type for macos-titlebar-style (#11262) 2026-03-10 10:58:47 -07:00
Mitchell Hashimoto
7fb8e0ac90 fix jump_to_prompt forward behavior for multiline prompts (#11331)
Fixes #11330.

When jumping forward from prompt content, skip prompt continuation rows
so a multiline prompt is treated as a single prompt block.
2026-03-10 10:51:17 -07:00
Mitchell Hashimoto
53637ec7b2 fix jump_to_prompt forward behavior for multiline prompts
Fixes #11330.

When jumping forward from prompt content, skip prompt continuation rows so a 
multiline prompt is treated as a single prompt block.
2026-03-10 10:47:18 -07:00
ghostty-vouch[bot]
f8d7876203 Update VOUCHED list (#11329)
Triggered by
[comment](https://github.com/ghostty-org/ghostty/issues/11313#issuecomment-4033213188)
from @mitchellh.

Vouch: @VaughanAndrews

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-03-10 17:31:32 +00:00
Mitchell Hashimoto
c06ede5849 macos: make paste_from_clipboard performable on macos (#11328)
Fixes #10751
2026-03-10 10:31:22 -07:00
Mitchell Hashimoto
aaad43c235 macos: make paste_from_clipboard performable on macos
Fixes #10751
2026-03-10 10:25:14 -07:00
Mitchell Hashimoto
119ce0bc1d macos: reset mouse state on focus loss to prevent phantom drag (#11276)
Fixes https://github.com/ghostty-org/ghostty/discussions/11203

The `suppressNextLeftMouseUp` flag from #11167 wasn't being reset on
focus loss, causing stale state that led to phantom drags/selections and
scrolls if you're lucky enough.

I've followed the #11167 's path and made it reset on focus loss.

As I stated in the [vouch
request](https://github.com/ghostty-org/ghostty/discussions/11274); I'm
not experienced in Swift, just following the prior PR's steps to reset
the state. I've been using this patch for couple days and the change
looks trivial to me tho not 100% sure if I'm missing anything.

> [!NOTE]
> Used Claude Code -Opus 4.6- for navigating the codebase and reviewing
the change.
2026-03-10 09:56:39 -07:00
Selman Kayrancioglu
6092c299d5 macos: reset mouse state on focus loss to prevent phantom drag
Fixes phantom mouse drag/selection when switching splits or apps.
The suppressNextLeftMouseUp flag and core mouse click_state were not
being reset on focus transitions, causing stale state that led to
unexpected drag behavior.

- Reset suppressNextLeftMouseUp in focusDidChange when losing focus
- Defensively reset the flag when processing normal clicks
- Reset core mouse.click_state and left_click_count on focus loss
2026-03-10 09:54:08 -07:00
Mitchell Hashimoto
4e24adf717 ci: skip xcode tests for freetype build 2026-03-10 09:40:28 -07:00
Mitchell Hashimoto
9759787847 config: don't double load app support path on macOS (#11326)
Fixes #11323
2026-03-10 09:28:59 -07:00
Mitchell Hashimoto
d9039eb85a config: don't double load app support path on macOS
Fixes #11323
2026-03-10 09:23:51 -07:00
Lukas
de0f2ab22d macos: add enum type for macos-titlebar-style 2026-03-10 17:15:14 +01:00
Mitchell Hashimoto
3782d118e1 macOS: restore keyboard focus after inline tab title edit (#11320)
## Summary

- After finishing an inline tab title edit (via keybind or
double-click), all keyboard input is lost because
`TabTitleEditor.finishEditing()` sets `makeFirstResponder(nil)`, leaving
the window itself as first responder with no path back to the terminal
surface.
- Adds a `tabTitleEditorDidFinishEditing` delegate callback to
`TabTitleEditorDelegate` that fires after every edit (commit or cancel).
- `TerminalWindow` implements it by calling
`makeFirstResponder(focusedSurface)` to restore keyboard focus to the
terminal.

Fixes https://github.com/ghostty-org/ghostty/discussions/11315

## Testing

- [x] Bind `prompt_tab_title` to a keybind (e.g. `keybind =
cmd+shift+i=prompt_tab_title`)
- [x] Trigger inline tab title edit via keybind, press Enter — verify
keyboard input works immediately
- [x] Trigger inline tab title edit via keybind, press Escape — verify
keyboard input works immediately
- [x] Double-click a tab title, press Enter — verify keyboard input
works immediately
- [x] Double-click a tab title, press Escape — verify keyboard input
works immediately
- [x] Verify Cmd+number tab switching works after all of the above
- [x] Verify split pane focus is correct after editing tab title with
splits open

AI disclosure: Codebase exploration and review via [Claude
Code](https://claude.com/claude-code)
2026-03-10 08:59:51 -07:00
Mitchell Hashimoto
85f0972b39 macOS: fix intrinsicContentSize race in windowDidLoad (#11322)
This should fix #11256 and #11271. 

Tested manually with various combination of `window-width/height` and
`macos-titlebar-style`.


https://github.com/user-attachments/assets/90c12728-b195-47bf-abfd-8a4034b1e7a2


### AI Disclosure

All the commits are generated by Claude, but orchestrated and manually
tested by myself.
2026-03-10 08:59:40 -07:00
chronologos
7629130fb4 macOS: restore keyboard focus after inline tab title edit
After finishing an inline tab title edit (via keybind or double-click),
`TabTitleEditor.finishEditing()` calls `makeFirstResponder(nil)` to
clear focus from the text field, leaving the window itself as first
responder. No code path restores focus to the terminal surface, so all
keyboard input is lost until the user clicks into a pane.

Add a `tabTitleEditorDidFinishEditing` delegate callback that fires
after every edit (commit or cancel). TerminalWindow implements it by
calling `makeFirstResponder(focusedSurface)` to hand focus back to the
terminal.

Fixes https://github.com/ghostty-org/ghostty/discussions/11315

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-10 08:52:00 -07:00
Mitchell Hashimoto
1592cafa32 Update AGENTS.md 2026-03-10 08:48:24 -07:00
Lukas
a6cd1b08af macOS: fix intrinsicContentSize race in windowDidLoad (#11256)
Add initialContentSize fallback on TerminalViewContainer so
intrinsicContentSize returns the correct value immediately,
without waiting for @FocusedValue to propagate. This removes
the need for the DispatchQueue.main.asyncAfter 40ms delay.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 15:35:49 +01:00
Lukas
cfedda1a0e macOS: add regression tests for intrinsicContentSize race (#11256)
Tests that validate intrinsicContentSize returns a correct value when
TerminalController.windowDidLoad() reads it. Currently fail, proving
the race condition where @FocusedValue hasn't propagated
lastFocusedSurface before the 40ms timer fires.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 15:27:38 +01:00
ghostty-vouch[bot]
6c7309196f Update VOUCHED list (#11321)
Triggered by
[comment](https://github.com/ghostty-org/ghostty/issues/11320#issuecomment-4031703556)
from @mitchellh.

Vouch: @chronologos

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-03-10 14:15:21 +00:00
Mitchell Hashimoto
e11f350e8e docs: update bell-features docs for macOS (#11279)
PR #11154 didn't fully update the docs regarding `bell-features=audio`
on macOS.
2026-03-10 07:12:02 -07:00
ghostty-vouch[bot]
c83dea49fd Update VOUCHED list (#11318)
Triggered by [discussion
comment](https://github.com/ghostty-org/ghostty/discussions/11309#discussioncomment-16069391)
from @mitchellh.

Vouch: @dzhlobo

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-03-10 14:09:14 +00:00