Commit Graph

13519 Commits

Author SHA1 Message Date
Mitchell Hashimoto
594195963d Update src/renderer/Metal.zig
Co-authored-by: Jon Parise <jon@indelible.org>
2025-12-19 09:31:10 -08:00
Mitchell Hashimoto
07b47b87fa renderer/metal: clamp texture sizes to the maximum allowed by the device
This prevents a crash in our renderer when it is larger.

I will pair this with apprt changes so that our mac app won't ever allow
a default window larger than the screen but we should be resilient at
the renderer level as well.
2025-12-19 09:24:49 -08:00
Mitchell Hashimoto
e2be65da8e macos: hide tab overview on escape (#9971)
This hides the macOS tab overview when the `escape` key is pressed.

Our solution is a bit blunt here and I don't think its right. I think we
have a first responder problem somewhere but I haven't been able to find
it and find the proper place to implement `cancel` (or equivalent) to
hide the overview. I tried implementing `cancel` in all the places I
expect the responder chain to go through but none worked.

For now let's do this since it is pretty tightly scoped!
2025-12-19 07:18:32 -08:00
Mitchell Hashimoto
86a0eb1a75 macos: hide tab overview on escape
This hides the macOS tab overview when the `escape` key is pressed.

Our solution is a bit blunt here and I don't think its right. I think we
have a first responder problem somewhere but I haven't been able to find
it and find the proper place to implement `cancel` (or equivalent) to
hide the overview. I tried implementing `cancel` in all the places I
expect the responder chain to go through but none worked.

For now let's do this since it is pretty tightly scoped!
2025-12-19 07:13:47 -08:00
Mitchell Hashimoto
fa0a982ff2 macos: remove the command palette appear/disappear animation (#9964)
Lots of people complained about this and I don't see value in it.
2025-12-18 15:41:55 -08:00
Mitchell Hashimoto
0ace736f46 macos: remove the command palette appear/disappear animation
Lots of people complained about this and I don't see value in it.
2025-12-18 15:36:11 -08:00
Mitchell Hashimoto
faa22c032e terminal: RenderState linkCells needs to use Page y not Viewport y (#9959)
Fixes #9957

Our `Page.getRowAndCell` uses a _page-relative_ x/y coordinate system
and we were passing in viewport x/y. This has the possibility to leading
to all sorts of bugs, including the crash found in #9957 but also simply
reading the wrong cell even in single-page scenarios.
2025-12-18 14:06:02 -08:00
Mitchell Hashimoto
5a2f5a6b9e terminal: RenderState linkCells needs to use Page y not Viewport y
Fixes #9957

Our `Page.getRowAndCell` uses a _page-relative_ x/y coordinate system
and we were passing in viewport x/y. This has the possibility to leading
to all sorts of bugs, including the crash found in #9957 but also simply
reading the wrong cell even in single-page scenarios.
2025-12-18 13:54:35 -08:00
Mitchell Hashimoto
5eb335d694 fix(macOS): re-apply icon after app update (#9951)
## macOS: Re-apply custom icon after app build changes

### Summary

Fixes the regression where custom icons are not re-applied after app
updates, particularly affecting users on the tip channel.

### Problem

PR #9670 introduced caching to avoid redundantly setting the app icon on
every launch. However when Ghostty updates, the app bundle is replaced
and the custom icon is reset by macOS. Since `UserDefaults` persists
across updates, the cached icon name still matches the desired icon
name, causing the icon update to be incorrectly skipped.

This was reported by users in #9670 comments as well, that after
updating Ghostty the custom icon would disappear and require manual
re-application.

### Solution

- Track the app build number (`CFBundleVersion`) alongside the icon name
in `UserDefaults`
- Re-apply the icon if either the icon config has changed OR the build
number has changed
- Only update `UserDefaults` if `NSWorkspace.setIcon()` succeeds,
preventing false-positive caching on failure

I used `CFBundleVersion` (build number, e.g. `13509`) rather than
`CFBundleShortVersionString` (e.g. `1.2.3`) because tip builds increment
the build number with each release while the short version string
remains constant. I considered combining both but this seemed redundant.

### Related

- Fixes regression mentioned in comments on #9670
- Original issue: #9666
- Original discussion: #9665
2025-12-18 13:10:23 -08:00
Jake Nelson
377bcddb46 fix(macOS): re-apply icon after app update 2025-12-18 12:55:49 +11:00
Mitchell Hashimoto
a4cb73db84 macOS: Session Search (#9945)
Replaces #9785 

This adds session search to the command palette on macOS. Session search
lets you jump to any running terminal based on title or working
directory. The command palette shows you the title, working directory,
and tab color (if any) to help you identify the terminal you care about.

This also enhances our command palette in general to support better
sorting, more stable sorts when keys are identical, etc.

## Demo


https://github.com/user-attachments/assets/602a9424-e182-4651-bf08-378e9c5e1616




## Future

Since this inherits the command palette infrastructure, we don't have
fuzzy search capabilities yet, but I still think this is useful already.
We should add fuzzy searching in the future.

Thanks @phaistonian for the inspiration here but I did do a full
rewrite.

**AI disclosure:** I used AI to assist with this in places, but I
understand everything and touched up almost everything manually.
2025-12-17 11:01:19 -08:00
Mitchell Hashimoto
e1d0b22029 macos: allow searching sessions by color too 2025-12-17 10:52:03 -08:00
Mitchell Hashimoto
842583b628 macos: fix uikit build 2025-12-17 10:26:02 -08:00
Mitchell Hashimoto
829dd1b9b2 macos: focus shenangians 2025-12-17 10:13:53 -08:00
Mitchell Hashimoto
e1356538ac macos: show a highlight animation when a terminal is presented 2025-12-17 10:12:44 -08:00
Mitchell Hashimoto
d23f7e051f macos: stable sort for surfaces 2025-12-17 09:52:06 -08:00
Mitchell Hashimoto
1fd3f27e26 macos: show pwd for jump options 2025-12-17 09:47:16 -08:00
Mitchell Hashimoto
b30e94c0ec macos: sort in the focus jumps in other commands 2025-12-17 09:34:30 -08:00
Mitchell Hashimoto
835fe3dd0f macos: add the active terminals to our command palette to jump 2025-12-17 09:30:39 -08:00
Mitchell Hashimoto
e1e782c617 macos: clean up the way command options are built up 2025-12-17 09:10:46 -08:00
Mitchell Hashimoto
5d11bdddc3 macos: implement the present terminal action so we can use that 2025-12-17 09:04:51 -08:00
Mitchell Hashimoto
7e46200d31 macos: command palette entries support leading color 2025-12-17 08:56:22 -08:00
Mitchell Hashimoto
c84113d199 font/coretext: Use positions to correct glyph placement (#9883)
This PR uses positions to get correct glyph placement, which affects a
small number of shaped runs but can even re-order glyphs from how
they're appearing on `main`. This came from an investigation in
https://github.com/jquast/wcwidth/issues/155#issuecomment-3630555803
that involved shaping text from the [Universal Declaration of Human
Rights](https://www.un.org/en/about-us/universal-declaration-of-human-rights)
in 500+ languages, taken from
[ucs-detect](https://github.com/jquast/ucs-detect) (but actually run
with [ttylang](https://github.com/jacobsandlund/ttylang) for more
consistent results).

The full result of running this with the commented out debug lines
enabled is here, showing 1704 differences (a small number compared to
the number of cells being rendered):
https://gist.github.com/jacobsandlund/9cb2c603308085fa03e758640583541e

Some positions are only a small offset that is applied to many letters
from a script (e.g. Syriac letters are getting offset by some small
amount).

There are more egregious cases, though. Consider Tai Tham vowels, that
[according to the Unicode core
spec](https://www.unicode.org/versions/Unicode17.0.0/core-spec/chapter-16/#G46437),
are rendered visually ahead of the consonant they follow in the text.
The Unicode spec oddly mentions this under the "New Tai Lue" section,
contrasting it with other Brahmi-derived scripts such as Tai Tham:

> This practice differs from the usual pattern for Brahmi-derived
scripts, in which all dependent vowels are stored in logical order after
their associated consonants, even when they are displayed to the left of
those consonants.

For example `"\u{1A2F}\u{1A70}"` renders like this on `main`:

<img width="608" height="90" alt="CleanShot 2025-12-12 at 09 25 16@2x"
src="https://github.com/user-attachments/assets/964063b7-59e7-43f7-b2c9-a0c0c827034a"
/>

And it now renders like this on the PR:

<img width="500" height="90" alt="CleanShot 2025-12-12 at 09 25 38@2x"
src="https://github.com/user-attachments/assets/b6dded0b-30cc-40d8-857d-06b64f7cf19d"
/>

This is the correct rendering as U+1A70 is "TAI THAM VOWEL SIGN OO" and
needs to render ahead of the U+1A2F "TAI THAM LETTER DA"

Note, this PR just fixes CoreText. I'll work on Harfbuzz right after
this, but I wanted to get this out first.

## vtebench

vtebench does show some potential impact on dense cells:


![output](https://github.com/user-attachments/assets/d6741f28-88b9-49a9-b8ef-1f5a61c346da)


![dense_cells](https://github.com/user-attachments/assets/ea18801c-4529-42db-b259-edbe4e4b939b)

This is the first time I've run `vtebench`, so to confirm it's
consistent I ran it again:


![output-2](https://github.com/user-attachments/assets/c418b4b2-18cc-47fd-8fc9-d1e4826942d3)


![dense_cells](https://github.com/user-attachments/assets/c70d573c-4282-4719-ac52-5121b0c155c6)

### AI disclaimer
I had been using Amp when I made this change, but looks like the thread
just fell off of recent threads (about a week ago). I think Amp was the
one to add the getPositionsPtr line and add `position` to the for loop.
I manually restructured the code around a separate `run_offset` and
`cell_offset`, and added the tests.
2025-12-17 08:46:12 -08:00
Mitchell Hashimoto
d820a633ee fix up typos 2025-12-17 08:34:31 -08:00
Jacob Sandlund
aecdacbe49 Merge remote-tracking branch 'origin/main' into shaping-positions 2025-12-17 10:02:06 -05:00
Jacob Sandlund
139a23a0a2 Pull out debugging into a separate function. 2025-12-17 09:57:32 -05:00
Mitchell Hashimoto
6b04f75037 Fix (#9921) link opening by resolving existing relative paths (#9942)
This PR fixes an issue in the change I merged yesterday (#9921), which
was reported by @quonb. Apology

I verified the fix by testing a wide range of URL schemes:
```
echo "https://example.com"
echo "http://example.com"
echo "mailto:test@example.com"
echo "ftp://example.com/file.txt"
echo "file:/Users/you/file.txt"
echo "ssh:user@example.com"
echo "git://github.com/user/repo.git"
echo "ssh://example.com/path"
echo "tel:+12123456789"
echo "ipns://example.com/path"
echo "gemini://example.com/"
echo "gopher://example.com/1menu"
echo "news:comp.lang.zig"
  ```
2025-12-17 06:24:57 -08:00
Jacob Sandlund
e28e4facf0 Merge remote-tracking branch 'origin/main' into shaping-positions 2025-12-17 09:18:10 -05:00
Elad Kaplan
67f9bb9e8a Fix link opening by resolving existing relative paths 2025-12-17 15:13:47 +02:00
Mitchell Hashimoto
50cb1bafd7 macOS: change window to new-window for macos-dock-drop-behavior (#9764)
Matches current option references and Swift implementation
2025-12-16 13:35:25 -08:00
Mitchell Hashimoto
072077d19d gtk/opengl: print an error when OpenGL version is too old (#9586)
#1123 added a warning when the OpenGL version is too old, but it is
never used because GTK enforces the version set with
gl_area.setRequiredVersion() before prepareContext() is called: we end
up with a generic "failed to make GL context" error:
```
warning(gtk_ghostty_surface): failed to make GL context current: Unable to create a GL context warning(gtk_ghostty_surface): this error is almost always due to a library, driver, or GTK issue warning(gtk_ghostty_surface): this is a common cause of this issue: https://ghostty.org/docs/help/gtk-opengl-context
```

This patch removes the requirement at the GTK level and lets the ghostty
renderer check, now failing as follow:
```
info(opengl): loaded OpenGL 4.2
error(opengl): OpenGL version is too old. Ghostty requires OpenGL 4.3 warning(gtk_ghostty_surface): failed to initialize surface err=error.OpenGLOutdated warning(gtk_ghostty_surface): surface failed to initialize err=error.SurfaceError
```

(Note that this does not render a ghostty window, unlike the previous
error which rendered the "Unable to acquire an OpenGL context for
rendering." view, so while the error itself is easier to understand it
might be harder to view)

-----------------------

I looked for why I couldn't get a context at all mostly to see what
OpenGL 4.3 functions were required to see if there'd be easy fallbacks,
but it also took me a good 15 minutes this morning to understand that
there was nothing wrong with my gtk/mesa versions and it's just my
hardware being old, so I think it'd good to take in itself even if the
displaying itself is a bit meh.

Happy to try to display it in the error page if you think it's important
and I can figure out how (haven't looked much yet)
2025-12-16 13:34:14 -08:00
Dominique Martinet
f37acdf6a0 gtk/opengl: print an error when OpenGL version is too old
#1123 added a warning when the OpenGL version is too old, but
it is never used because GTK enforces the version set with
gl_area.setRequiredVersion() before prepareContext() is called:
we end up with a generic "failed to make GL context" error:
warning(gtk_ghostty_surface): failed to make GL context current: Unable to create a GL context
warning(gtk_ghostty_surface): this error is almost always due to a library, driver, or GTK issue
warning(gtk_ghostty_surface): this is a common cause of this issue: https://ghostty.org/docs/help/gtk-opengl-context

This patch removes the requirement at the GTK level and lets the ghostty
renderer check, now failing as follow:
info(opengl): loaded OpenGL 4.2
error(opengl): OpenGL version is too old. Ghostty requires OpenGL 4.3
warning(gtk_ghostty_surface): failed to initialize surface err=error.OpenGLOutdated
warning(gtk_ghostty_surface): surface failed to initialize err=error.SurfaceError

(Note that this does not render a ghostty window, unlike the previous
error which rendered the "Unable to acquire an OpenGL context for
rendering." view, so while the error itself is easier to understand it
might be harder to view)
2025-12-16 13:30:37 -08:00
Mitchell Hashimoto
7d8bff27a0 ai: add /review-branch command (#9934)
This is a subcommand I've been using for some time. It takes an optional
issue/PR number as context and produces a prompt to review a branch for
how well it addresses the issue along with any isolated issues it spots.

Example:
https://ampcode.com/threads/T-019b2877-475f-758d-ae88-93c722561576
2025-12-16 13:27:14 -08:00
Mitchell Hashimoto
a25a5360f3 ai: add /review-branch command
This is a subcommand I've been using for some time. It takes an optional
issue/PR number as context and produces a prompt to review a branch for
how well it addresses the issue along with any isolated issues it spots.

Example: https://ampcode.com/threads/T-019b2877-475f-758d-ae88-93c722561576
2025-12-16 13:23:39 -08:00
Mitchell Hashimoto
ab3a3805aa Fix macOS log command for Ghostty (#9933)
Corrected the command for viewing Ghostty logs on macOS.
2025-12-16 13:17:29 -08:00
IceCodeNew
ccc2d32aa5 Fix macOS log command for Ghostty
Corrected the command for viewing Ghostty logs on macOS.
2025-12-17 05:16:27 +08:00
Mitchell Hashimoto
4827c7f53a macOS: add toggle_background_opacity keybind action (#9117)
Related Issue: #5047 
Discussion: #4664 

### Investigation
The behavior of iTerm mentioned on the Discussion thread was as follows:

- `cmd + u` can be used to toggle "Use Transparency"
- The "Use Transparency" toggle operates on a per-surface basis
- The "Use Transparency" state persists even after reloading the config

### Summary
Based on the investigation and discussions in the preceding pull
requests, this implements the `toggle_background_opacity` keybind action
for macOS with the following specifications:

- Switches background opacity on a per-surface basis
- The background opacity state persists even after reloading the config
- Background opacity switching functionality is also available in Quick
Terminal
- Does nothing if `background-opacity` is set to 1 or higher
- Does nothing if in fullscreen mode

### Verification
This functionality has been tested across following scenarios,
confirming correct action behavior for:

- Split Window
  - Each split window maintains synchronized background opacity states
- Tab Group
  - Background opacity states do not synchronize between tabs
- Quick Terminal
- Background opacity states remain synchronized even when windows are
closed
- Command Palette

### AI Disclosure
This pull request was made with assistance from Claude Code.
I reviewed all AI-generated code and wrote the final output manually.


https://github.com/user-attachments/assets/e46ff8f0-42f2-442f-97dd-d5f5c33b10f1
2025-12-16 13:11:51 -08:00
Mitchell Hashimoto
95f4093e96 macos: make syncAppearance a virtual method on BaseTerminalController 2025-12-16 12:59:56 -08:00
Mitchell Hashimoto
f9a1f526c8 update some copy for the background opacity toggle 2025-12-16 11:40:12 -08:00
himura467
ba2cbef1f1 apprt/gtk: list toggle_background_opacity as unimplemented 2025-12-16 11:32:10 -08:00
himura467
8d49c698e4 refactor(macos): do nothing if in fullscreen 2025-12-16 11:32:10 -08:00
himura467
ded3dd4cbc refactor(macos): do nothing if background-opacity >= 1 2025-12-16 11:32:10 -08:00
himura467
4c6d3f8ed2 macos: add toggle_background_opacity keybind action 2025-12-16 11:32:10 -08:00
Mitchell Hashimoto
4883fd938e config: better docs for split-preserve-zoom 2025-12-16 11:27:51 -08:00
Mitchell Hashimoto
a1ffac3c58 introduce split-preserve-zoom config to maintain zoomed splits during navigation (#9089)
Closes #8458.

- Adds the split-preserve-zoom config option with a navigation flag.
- GTK and macOS runtimes now respect the flag so zoomed splits stay
zoomed when using split navigation. I've tested this on macOS (video
below), but have not tested on GTK.

This PR was written primarily with Codex CLI, using the
[gh-issue](https://github.com/ghostty-org/ghostty/blob/main/.agents/commands/gh-issue)
command.

Here is a short video of the debug build:


https://github.com/user-attachments/assets/3abea255-98e1-4a4f-9196-7c1b2663b9d2
2025-12-16 11:21:56 -08:00
lorenries
d364e421a8 introduce split-preserve-zoom config to maintain zoomed splits during navigation 2025-12-16 11:14:09 -08:00
Mitchell Hashimoto
67eb480577 Adding keybind to the +list-themes TUI that would write out a file that contained themes (#8930)
This resolves issue: https://github.com/ghostty-org/ghostty/issues/8903,
so we can press 'w' when in TUI preview save mode to write a auto theme
config
2025-12-16 10:12:06 -08:00
greathongtu
f7d0d72f19 remove auto theme include in config-template 2025-12-17 01:50:53 +08:00
Mitchell Hashimoto
29c0f982c3 Fix cmd-click opening of relative/local paths (#9921)
This PR fixes an issue #9563 where relative file paths were not being
resolved against the terminal’s current working directory before
opening.


#### Verification
Tested with directories containing:
```
/tmp/test/test
❯ du -h .
  0B    ./spaces-end
  0B    ./with dot.
  0B    ./space middle
8.0K    .
```

Parent directory resolution also works as expected:
```
/tmp/test/test
❯ du -h ..
  0B    ../test/spaces-end
  0B    ../test/with dot.
  0B    ../test/space middle
8.0K    ../test
 16K    ..
 ```
 
@mitchellh  
In your original description you mentioned that “Links should work for all situations as they do in iTerm2.”  
I noticed that, for example, when running `ls`, the paths are not clickable, while they are clickable in iTerm2.
If you think this case should also be handled, I can open a separate PR for it once this one is accepted.
2025-12-16 09:07:16 -08:00
Mitchell Hashimoto
db4e8d76d8 macOS: save&restore quick terminal state (#9588)
Implements #8399. 

I didn't save `position` in this pr, since I don't see its necessity. 

Changing `quick-terminal-position` requires a relaunch; saving and
restoring this would have to deal with conflicts. I also don't see why a
user would change this frequently.

> [!NOTE]
> Used GPT to proofread my comments
2025-12-16 09:06:47 -08:00