This should be safe to delete now after #12461.
I tested saving 27 tabs, 4 with 2 splits,
`TerminalRestorable.encode(with:` finished successfully.
And I check the breakpoints when the Sparkle sends
`-[NSRunningApplication treminate]`. The call stack at `-[NSResponder
invalidateRestorableState]` is pretty much the same as quitting via
`cmd+q`.
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
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#11592Closes#10756
Session: 019d341c-a165-7843-a2f7-2f426114cf17
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
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>
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>
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`
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.