Commit Graph

618 Commits

Author SHA1 Message Date
Lukas
daab08ec01 macOS: drop the cross-platform check and abstraction
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 14:00:03 +02:00
Mitchell Hashimoto
d695ffff3b macos: defer OSC52 clipboard read confirmations until focused
Fixes #10077

Clipboard read confirmations would immediately show a sheet which
grabbed focus. This could be used for a bunch of dumb reasons, including 
DoS attacks. But, it also caused focus/sheet loops for programs that did
OSC52 on focus changes (which was seen via some Neovim configs!).

Now, if a surface is unfocused, we bell the surface and show the confirmation
request on next focus. If the surface is not focused or another request
comes in, we cancel the prior one.

This also fixes some memory management issues around clipboard requests
that were likely small leaks (didn't verify the old bug, but verified
the new code, and eyeballed the old).
2026-08-11 06:44:23 -07:00
Mitchell Hashimoto
da745630be macos: only check for auto-tabbing when tabbing preference is always
windowDidLoad undoes macOS automatic window tabbing by inspecting
window.tabGroup. Accessing tabGroup on a fresh window materializes
AppKit's tab group machinery, which takes ~15-20ms and is on the
critical path of every window creation, including the first window at
app launch.

AppKit only auto-tabs a fresh window when the system tabbing
preference is "always": the tab bar "+" button goes through
newWindowForTab which we intercept and route through our own tab
logic, so it never auto-tabs. Guard the check on
NSWindow.userTabbingPreference == .always so everyone else skips the
tab group materialization entirely.

Measured on macOS (Apple Silicon) during app launch via the startup
timeline instrumentation:

  windowDidLoad tab group check: 17.8ms -> ~0ms
  main() -> window visible: median ~173ms -> ~165ms (n=7)
2026-08-09 19:54:28 -07:00
Mitchell Hashimoto
2602886144 macOS: fix quit alert missing when hidden (#13686)
Fixes https://github.com/ghostty-org/ghostty/discussions/13685.

Removed presumably deprecated check introduced in
8f1a014afd for update pill
> I checked for auto update as well, it works as before this, and for
manual updates we're not confirming anyway, so I think its safe to
remove it now.

Each BaseTerminalController already has quit check and confirming code
added in that review windows pr. It didn't cover QT before, overriding
it to animate in for showing alert.

[#5450](https://github.com/ghostty-org/ghostty/issues/5450) stays fixed.




https://github.com/user-attachments/assets/dbf36f16-e3ce-4f6a-bc25-367fe48739b9
2026-08-07 13:21:50 -07:00
Lukas
e83cf0b06f macOS: fix quit alert missing when hidden 2026-08-07 20:11:16 +02:00
Mitchell Hashimoto
4693e1b546 macos: sync appearance when new windows are created (#13675)
For new windows to get their appearance synced, we need to call
`syncAppearance` after `super.showWindow(sender)`. All previous calls to
`syncAppearance` on `TerminalWindow` will be ignored because the window
needs to have `isVisible` set to `true`.

This regression was introduced by:
5368adcd29

It added `.dropFirst()` to the `focusedSurface` appearance publishers in
`TerminalController.swift` which removes the initial call of the
subscription.

Fixes https://github.com/ghostty-org/ghostty/issues/13324

(landed on the same fix as @rasitakyol found here:
https://github.com/ghostty-org/ghostty/pull/13341)
2026-08-07 08:02:54 -07:00
Lukas
96826853bd macOS: fix window sizing after dragging a split into a window 2026-08-07 15:14:30 +02:00
Christoffer Winterkvist
e11bfb5139 macos: sync appearance when new windows are created (#13324)
call `syncAppearance` after `super.showWindow` has been called to
ensure that the window is visible.
2026-08-06 19:53:48 +02:00
Mitchell Hashimoto
57c1baf43a macos: defer overlapping clipboard completion
Fixes #/13074

Overlapping clipboard confirmations now defer denial until the next
main queue turn rather than completing inside the confirmation callback.

This prevents the native request state from being invalidated while its
callback is still active, avoiding the OSC 52 crash reported in #13074.

The deferred closure retains the originating surface view and completes
the ignored request with empty data, preserving the existing deny
behavior.
2026-08-05 14:24:37 -07:00
Mitchell Hashimoto
880eded158 macos: avoid IOSurface leak on automated surface creation (#13640)
Fixes #13444

A close while AppKit temporarily cleared/changed a surface's window
would leak the surface in the controller's pslit tree. This retained
surface kept a bunch of resources around, particularly large IOSurfaces.

This seems to only be reproducible under scripted load: rapid terminal
creation/destruction so that destruction happens just while there is a
nil window on a surface view.

Track surface ownership in a weak controller map updated alongside the
split tree, with validated fallbacks for existing attachment state.
Resolve scripted and App Intent operations through that ownership, and
route non-confirming root closes directly through the immediate tab or
window close path so teardown always reaches the renderer.
2026-08-05 14:18:22 -07:00
Mitchell Hashimoto
7a047553c7 macos: avoid IOSurface leak on automated surface creation
Fixes #13444

A close while AppKit temporarily cleared/changed a surface's window would
leak the surface in the controller's pslit tree. This retained surface kept
a bunch of resources around, particularly large IOSurfaces.

This seems to only be reproducible under scripted load: rapid terminal
creation/destruction so that destruction happens just while there is a nil
window on a surface view.

Track surface ownership in a weak controller map updated alongside the split
tree, with validated fallbacks for existing attachment state. Resolve
scripted and App Intent operations through that ownership, and route
non-confirming root closes directly through the immediate tab or window close
path so teardown always reaches the renderer.
2026-08-05 13:39:48 -07:00
Mitchell Hashimoto
8696bef644 macos: guard fullscreen tab presentation
#13611

Route new-tab window presentation through an Objective-C exception catcher.

AppKit can raise an NSInternalInconsistencyException while selecting a
new tab in native fullscreen.

Catch the presentation exception, report it through the existing error
logging path, and leave Ghostty running when AppKit’s fullscreen window
stack is inconsistent.

This was pretty hard to reproduce but I was able to reproduce it about
1/3rd of the time via AppleScript automation...
2026-08-05 11:25:18 -07:00
Mitchell Hashimoto
cfa0ca7106 macos: defer transparent titlebar KVO rebinding
Fixes #13386

Defer transparent-titlebar KVO rebinding to the next main-queue turn.
Track the observed tab group so unchanged bindings are preserved.

Previously, a tab-group callback could invalidate and recreate its own
observation before returning, leaving closed terminal windows registered
with AppKit after the undo timeout. These windows accumulated titlebar and
layer state, increasing memory use and WindowServer CPU with tab churn.

Validated with an AppDelegate change that sat and created/closed tabs
in a loop, then counted weak controllers/windows/nsapp window.

Co-authored-by: Mustafa J <mustafa.0x@gmail.com>
2026-08-04 06:40:41 -07:00
Lukas
35790a7e56 Revert "macOS: fix undo new tab will cause a crash (#9512)"
This reverts commit fbabafe8e3, reversing
changes made to 7f0468f910.
2026-07-26 16:08:46 +02:00
Lukas
2104e0749c macOS: hide visible NSScrollPocket for hidden title bar
Fixes https://github.com/ghostty-org/ghostty/issues/13390
2026-07-20 14:30:43 +02:00
Lukas
632aa67560 macOS: fix tabs frame on macOS 27 beta 2 2026-06-22 21:59:14 +02:00
Sahil Mishra
8e8a8dc113 added async fix in order to resolve first second tab issue 2026-06-15 20:51:35 -04:00
Sahil Mishra
c3ceb55f5f added comment explaining fix 2026-06-15 10:12:44 -04:00
Sahil Mishra
749d45490a fix swiftlint 2026-06-15 10:04:54 -04:00
Sahil Mishra
4668a371c1 overrode function syncAppearance in order to update the tab bar as well 2026-06-14 15:30:08 -04:00
Claude Opus 4.7
eb5c1c7220 fix(macos): mark Swift os.Logger interpolations as public 2026-05-31 16:35:11 +02:00
Jon Parise
33adb58bee macos: remove unneeded initializers
These will be automatically synthesized (they only do memberwise
initialization) and do not need to be manually defined.
2026-05-31 09:54:41 -04:00
Tunglies
5368adcd29 macos: avoid duplicate appearance sync on tab focus
Close #12825

Skip the initial emissions from the focused surface appearance publishers after a tab focus change. The focused surface is already synced immediately, so the initial Combine values only repeat the same titlebar and background updates. Subsequent derived config and OSC background changes still resync the window appearance.
2026-05-27 19:43:41 +08: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
Lukas
8f9b86afa8 macOS: add confirmCloseAsync to return the actual response 2026-05-19 20:00:10 +02:00
Lukas
7f5c233492 macOS: add windowCanBeClosedWithoutConfirmation without any side effects 2026-05-19 19:56:09 +02:00
Lukas
b6c6f7630a macos: opacity-toggle setting persists between tabs in a window and to a newly created window (#11583) 2026-05-17 00:45:24 +02:00
Lukas
2c6dd59406 macOS: fix render_thread "stuck" after dragging surface to another tab within the same window
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.
2026-05-12 09:18:52 +02:00
Lukas
366c34831a macOS: fix first responder after dragging a non-focused surface
This fixes a bug: 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.
2026-05-12 09:18:51 +02:00
Lukas
61595b5ec9 macOS: fix focus state when toggling command palette from inline title editor 2026-04-29 22:41:18 +02:00
Lukas
231f6f4c75 macOS: move the restoration logs 2026-04-25 21:06:20 +02:00
Lukas
bfe07bb99e macOS: add InternalState to cover migrations 2026-04-25 20:25:17 +02:00
Lukas
5b89671d51 macOS: make terminal restorable state compatible with 1.2.3(v5) 2026-04-25 20:22:59 +02:00
Lukas
8ebf4f70e5 macOS: make tab color optional 2026-04-25 20:09:55 +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
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
davidsanchez222
0e49204b95 refactor(macos): centralize background opacity toggling across controllers 2026-04-05 17:04:20 -04:00
davidsanchez222
e5c31e8b37 macos: opacity-toggle setting persists between tabs in a window and to a newly created window 2026-04-05 17:04:20 -04: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
Mitchell Hashimoto
1672e891b9 macOS: remove redundant tab event overrides (#11984)
- Revert 5540f5f249, middle click comes
out of box with native tabbing, but we override it wrong previous.
- Reverts 894e8d91ba, I check it the
commit right before it and all the way back to
ffe4afe538, right mouse down on tab bar
works well without any issue
- Add back reverted handling in #11150


https://github.com/user-attachments/assets/8660368e-05ae-45b0-aa81-6196f3434daf
2026-03-30 09:19:33 -07:00
Lukas
51cd63871d macos: passthrough right mouse down event to TabTitleEditor if needed (#11150) 2026-03-30 12:22:54 +02:00
Lukas
5de30c0dce Revert "macOS: fix tab context menu opens on macOS 26 with titlebar tabs (#9831)"
This reverts commit 894e8d91ba, reversing
changes made to 4a173052fb.
2026-03-30 12:09:51 +02:00
Lukas
5c5029b0c4 Revert "macos: add support for middle-click tab close for macos-titlebar-style = tabs (#11963)"
This reverts commit 5540f5f249, reversing
changes made to cca4c788ad.
2026-03-30 12:08:49 +02:00
Lukas
32920b6b2a macOS: handle surface focus more gracefully
This will fix surface focus state is not consistent with first responder state when the search bar is open
2026-03-30 10:03:09 +02:00
Nicholas Ochoa
3f6683df02 macos: add support for middle-click tab close 2026-03-29 15:19:35 -07:00
Lukas
5c51603b0b chore: make ci happy 2026-03-12 20:02:23 +01:00
Lukas
07bc888682 macOS: fix window position when dragging split into a new window 2026-03-12 19:54:41 +01:00
Lukas
5e3866381b macOS: fix window cascading for the second window 2026-03-12 18:32:04 +01:00
Lukas
ea262cdd34 macOS: fix window cascading for 3rd+ window 2026-03-12 18:32:04 +01:00
Lukas
08107d342a macOS: we don't need initialFrame anymore 2026-03-12 15:42:29 +01:00