Commit Graph
1739 Commits
Author SHA1 Message Date
Lukas 7c91cef28d config: use Config to check key binding instead of App
Previously `ghostty_app_key_is_binding` (unlike Surface) is just using `config.keybind` to check whether a KeyEvent is in the set or not.

After this, I can add unit tests for keybinding more easily, with dummy configs.
2026-04-24 18:26:56 +02:00
Mitchell Hashimoto 7629c4ba84 macOS: fix command parsing in NewTerminalIntent (#12392)
Fixes #12391, regression from #10765
2026-04-23 06:34:54 -07:00
Lukas b0b23f53a7 macOS: check abnormal-command-exit-runtime when process exits
Signed-off-by: Lukas <134181853+bo2themax@users.noreply.github.com>
2026-04-23 11:35:51 +02:00
Lukas a8ed37a791 macOS: fix command parsing in NewTerminalIntent
Fixes #12391, regression from #10765

Signed-off-by: Lukas <134181853+bo2themax@users.noreply.github.com>
2026-04-23 11:35:34 +02:00
Mitchell Hashimoto 62fdd885e0 macOS: open preferred config if exists (#12321)
This helps developers like me to use a separate config for debugging
(which is already supported by the environment variable
`GHOSTTY_CONFIG_PATH`).

I can already use the local scheme to load a debugging config file, but
when opening the config file through Ghostty, it will still open the
default config.

This changes doesn't affect the release build, since `configPath` is
only set in the DEBUG build.
2026-04-21 09:23:29 -07:00
Mitchell Hashimoto 61363e80d1 macOS: fix App Icon update in Finder (#12344)
Looks like `NSWorkspace.shared.setIcon` can only be called from the main
App, DockTilePlugin is sandboxed and doesn't have the permission to
`file-write-finderinfo`.

<img width="1186" height="144" alt="image"
src="https://github.com/user-attachments/assets/e5ea4f1c-718c-493a-bda2-32787881881e"
/>


It works fine in debug, but not in release. This fixes #11489
2026-04-20 11:52:43 -07:00
Christo Wilken 9a9002202b macos: add pid and tty properties to AppleScript terminal class
Expose the foreground process PID and TTY device path as read-only properties on the AppleScript terminal class and App Intents TerminalEntity. This enables reliable process-to-terminal mapping for automation tools when multiple terminals share the same CWD.

Closes #11592
Closes #10756

Session: 019d341c-a165-7843-a2f7-2f426114cf17
2026-04-20 15:16:03 +02:00
Lukas c7a73076e9 macOS: fix App Icon update in Finders
Looks like  `NSWorkspace.shared.setIcon` can only be called from the main App, DockTilePlugin is sandboxed and doesn't have the permission to `file-write-finderinfo`.

It works fine in debug, but not in release. This fixes #11489, #11290
2026-04-20 12:56:55 +02:00
Lukas 5939b8c1be macOS: fix 12266 by using the correct coordinates for the hitTest
Regression of #11872
2026-04-17 20:05:18 +02:00
Lukas 9bad9365b0 macOS: open preferred config if exists 2026-04-17 15:29:29 +02:00
Mitchell Hashimoto ca7516bea6 macOS: move KeyStateIndicator on top of exit bar (#12282) 2026-04-16 20:33:48 -07:00
Lukas b7d0be8e74 macOS: move KeyStateIndicator on top of exit bar 2026-04-14 19:55:46 +02:00
Lukas 858e856e2e macOS: fix shortcuts not showing on menu item for scroll_to_selection and search_selection
Incorrect link after 9b6a3be993 and 7d0157e69a
2026-04-14 19:21:16 +02:00
Lukas 6033c12790 macOS: reset menu shortcuts when its not updated 2026-04-13 19:59:20 +02:00
Lukas fe8a6464b9 macOS: update MenuShortcutKey 2026-04-13 19:56:56 +02:00
Mitchell Hashimoto 4f36896ddb macOS: add bottom bar when child exits (#12251)
### Closes #7649

The bar lives alongside URL Hover in VStack at the bottom. The current
body of SurfaceView is becoming rather long and complicated, so this pr
also contains some refactors:

- Move URL Hover to a separate file

> The text is copied from previous input string to keep it consistent,
also I’m confused with text on GTK so this is my first choice, but it
can be changed as the same as GTK.

Separate prs will be opened for:
1. Set to Read-only after exits
2. Hide cursor when in Read-only

### Preview


https://github.com/user-attachments/assets/eb44e211-eac5-4f40-836c-4912b18dfb01
2026-04-13 06:47:47 -07:00
Lukas 073dd8a399 macOS: trim query before filtering commands 2026-04-13 12:47:48 +02:00
LukasandClaude Opus 4.6 2e169c42e8 macOS: Support initials matching in command palette search
Extend String.matchedIndices(for:) to fall back to initials
matching when no substring match is found. Typing the first letter
of each word now matches commands, e.g. "tbo" matches "Toggle
Background Opacity", with each matched initial highlighted.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 12:47:47 +02:00
LukasandClaude Opus 4.6 2bdc6bb1f7 macOS: Highlight matching text in command palette search results
Add String.matchedIndices(for:) to find substring matches and use
it to bold and tint matched characters with the accent color in
both titles and subtitles. Title matches take priority — subtitles
are only highlighted when the title didn't match.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 12:47:47 +02:00
Lukas 38e64c3706 macOS: add bottom bar when child exits 2026-04-13 10:08:13 +02:00
Lukas c2a93db591 macOS: move url hover to a separate file 2026-04-13 08:18:11 +02:00
Mitchell Hashimoto d2b79bea77 macOS: fix the arrow alignment of the secure input popover (#12249) 2026-04-12 13:16:15 -07:00
Mitchell Hashimoto 7f6d2a44b8 macOS: fix cannot rebind super+up and super+down (#12245)
Fix: #11989
Cause identified to: ab352b5af9
Original PR: #10003
Problem: I don't think it is OK to hard code the keybind like this at
all. Ghostty's config is flexible enough to achieve this.
Proposal: Revert the above commit via this PR.

@yasuf @bo2themax
2026-04-12 13:16:06 -07:00
Lukas 53019991f7 macOS: fix the arrow alignment of the secure input popover 2026-04-12 16:04:41 +02:00
Lukas bf6fd4abe5 macOS: add focusDidChange & sizeDidChange placeholders to OSSurfaceView 2026-04-12 14:23:46 +02:00
Lukas 90ea604a7c macOS: move searchState to OSSurfaceView 2026-04-12 14:23:46 +02:00
Lukas a541e23120 macOS: move surface to OSSurfaceView 2026-04-12 14:23:46 +02:00
Lukas 1665755a93 macOS: move highlighted to OSSurfaceView 2026-04-12 14:23:46 +02:00
Lukas 2efe851cda macOS: move readonly to OSSurfaceView 2026-04-12 14:23:45 +02:00
Lukas 3834751aef macOS: move surfaceSize to OSSurfaceView 2026-04-12 12:08:56 +02:00
Lukas 7c83561f9e macOS: move focusInstant to OSSurfaceView 2026-04-12 12:07:22 +02:00
Lukas 56b505cbb0 macOS: move keyTables to OSSurfaceView 2026-04-12 12:06:28 +02:00
Lukas 19af8e9ce2 macOS: move progressReport to OSSurfaceView 2026-04-12 12:04:09 +02:00
Lukas 8b99c77bf7 macOS: update title comments 2026-04-12 12:02:59 +02:00
Lukas 619e12dc75 macOS: move hoverUrl to OSSurfaceView 2026-04-12 11:59:51 +02:00
Lukas 3936069297 macOS: move healthy and error to OSSurfaceView 2026-04-12 11:59:04 +02:00
Lukas d38301bb9f macOS: move cellSize to OSSurfaceView 2026-04-12 11:58:04 +02:00
Lukas 46fef7718c macOS: move pwd to OSSurfaceView 2026-04-12 11:57:15 +02:00
Lukas 8bd1aba40a macOS: add shared OSSurfaceView 2026-04-12 11:54:16 +02:00
Lukas 650cd96646 macOS: fix memory leak of TerminalController
Regression of #12119, this memory leak affects new tabs, since the terminal controller is not deallocated correctly. Hitting `cmd+t` will create a new window with two tabs, but only one actually contains usable surface.

You can reproduce by:
1. Quit and Reopen Ghostty
2. Open a new window if no window is created (initial-window = false)
3. Close the window
4. Hit `cmd+t`
2026-04-11 21:20:16 +02:00
Mitchell Hashimoto 19b0ed2bdf macOS: double click title to enlarge window (#12219)
Previously with `macos-titlebar-style = tabs`, double clicking title
would do nothing
2026-04-10 06:18:11 -07:00
Lukas 41c872c1f4 macOS: fix tab title editor frame update during winding resizing 2026-04-10 13:57:09 +02:00
Lukas e7f58ad72e macOS: double click title to enlarge window
Previously with `macos-titlebar-style	= tabs`, double clicking title will do nothing
2026-04-10 13:41:53 +02:00
Lukas 363cb9560e macOS: fix icon style not updating on Tahoe 2026-04-08 13:12:37 +02:00
Mitchell Hashimoto 0043e665f5 macos: cancel deferred tab presentation on close (#12119)
The 👻 Ghost Tab Issue


https://github.com/user-attachments/assets/cb91cd85-4a08-4c16-9efb-1a9ab30fc2bc

Previous failure scenario (User perspective):

1. Open a new tab
2. Instantly trigger close other tabs (eg. through custom user keyboard
shortcut)
3. Now you will see an empty Ghost Tab (Only a window bar with empty
content)

The previous failure mode is:

1. Create a tab or window now in `newTab(...)` / `newWindow(...)`.
2. Queue its initial show/focus work with `DispatchQueue.main.async`.
3. Close that tab or window with `closeTabImmediately()` /
`closeWindowImmediately()` before the queued callback runs.
4. The queued callback still runs anyway and calls `showWindow(...)` /
`makeKeyAndOrderFront(...)` on stale state.
5. The tab can be resurrected as a half-closed blank ghost tab.

The fix:

- Store deferred presentation work in a cancellable DispatchWorkItem and
cancel it from the close paths before AppKit finishes tearing down the
tab or window.
- This prevents the stale show/focus callback from running after close.

## AI Usage

I used GPT 5.4 to find the initial issue and fix it. I cleaned up and
narrowed down the commit afterwards.

-----

Additional Notes:

I use `cmd+o` to `close_tab:other`

https://github.com/jamylak/dotfiles/blob/main/ghostty/config#L106C1-L106C34

Try it for your self if you want to reproduce, just do a quick `cmd+t`
`cmd+o` and you will see
2026-04-07 05:41:23 -07:00
Mitchell Hashimoto 8ae80892ba macos: fix dock icon badge permission (#12133)
The previous version requested general notification permissions but
omitted the `.badge` option. Because the initial request was granted,
`settings.authorizationStatus` returns `.authorized`, leading the app to
believe it has full notification privileges when it actually lacks the
authority to update the dock icon badge.

Debug hint:
You can reset the notification settings by right-clicking on the app
name.
<img width="307" height="85" alt=""
src="https://github.com/user-attachments/assets/660cd332-eda6-45d6-8bfd-a6f9e28e21e8"
/>
2026-04-06 07:31:36 -07:00
fru1tworld 13f7d23145 macOS: force layout sync when frame size mismatches GeometryReader 2026-04-06 19:22:47 +09:00
Kay Leung e390937867 macos: fix badge permission
The previous version requested general notification permissions but omitted the `.badge` option. Because the initial request was granted, `settings.authorizationStatus` returns `.authorized`, leading the app to believe it has full notification privileges when it actually lacks the authority to update the dock icon badge.
2026-04-06 05:19:25 +08:00
jamylak 355aecb6ba macos: cancel deferred tab presentation on close
The 👻 Ghost Tab Issue

Previous failure scenario (User perspective):

1. Open a new tab
2. Instantly trigger close other tabs
   (eg. through custom user keyboard shortcut)
3. Now you will see an empty Ghost Tab
   (Only a window bar with empty content)

The previous failure mode is:

1. Create a tab or window now in `newTab(...)` / `newWindow(...)`.
2. Queue its initial show/focus work with `DispatchQueue.main.async`.
3. Close that tab or window with `closeTabImmediately()` /
 `closeWindowImmediately()` before the queued callback runs.
4. The queued callback still runs anyway and calls `showWindow(...)` /
 `makeKeyAndOrderFront(...)` on stale state.
5. The tab can be resurrected as a half-closed blank ghost tab.

The fix:

- Store deferred presentation work in a cancellable
  DispatchWorkItem and cancel it from the close paths
  before AppKit finishes tearing down the tab or window.
- This prevents the stale show/focus callback from
  running after close.
2026-04-05 17:43:41 +10:00
Toby She 30fdc8f4c8 macOS: fix cannot rebind super+up and super+down 2026-04-02 22:58:19 -04:00