Commit Graph

1869 Commits

Author SHA1 Message Date
Leah Amelia Chen
1eaf457b18 gtk: add window title renaming (#10999)
Fixes #10469 for GTK.
2026-08-13 01:11:12 +08:00
Lukas
cb7eaa059d macOS: silent weak ownership difference warnings
UpdateViewModel doesn't own the Task, we don't actually need it here.
2026-08-12 15:34:55 +02:00
Lukas
c78226bfae macOS: fix Main actor-isolated static property 'find' warnings 2026-08-12 15:34:54 +02:00
Lukas
97ae257497 macOS: fix warnings in showUserNotification 2026-08-12 15:26:31 +02:00
Lukas
da8b171265 macOS: fix Sendable warning for UnsafeMutablePointer
Swift explicitly [marked UnsafeMutablePointer as non sendable](0568dbf903). Moving from `@unchecked @retroactive` to `nonisolated(unsafe)` is safe for us as per the previous comments
2026-08-12 15:26:30 +02:00
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
Lukas
400be4cc1d macOS: adjust file tree 2026-08-12 14:00:02 +02:00
Lukas
3901168b16 macOS: remove iOS target 2026-08-12 14:00:02 +02:00
Mitchell Hashimoto
b0b9fbc8d5 macOS: support decoding the surrogate pair with UnicodeHexInput (#13737)
Not yet a perfect fix for
https://github.com/ghostty-org/ghostty/discussions/13730
2026-08-11 11:03:01 -07:00
Mitchell Hashimoto
d1937d63e4 macOS: remove unused menu validations (#13726)
UpdateController isn't the target of any menu item, we don't need add
menu validation here.
2026-08-11 11:02:28 -07:00
Mitchell Hashimoto
8c9fd7aa79 macos: normalize command paths as file URLs
#13319
#13748

Normalize command-line file arguments as file URLs internally while
keeping the AppKit and FileManager string boundaries unchanged.

This handles relative paths, URL-sensitive characters, and trailing
directory separators consistently when matching duplicate open-file
events.
2026-08-11 09:15:05 -07:00
Mitchell Hashimoto
a858bd4d35 macos: ignore -e arguments as open files (#13748)
Fixes #13319

AppKit treats existing positional arguments as documents, causing paths
passed to a child command after -e to open an extra terminal surface.

We now process args ourselves during openFile callbacks to ignore file
paths after `-e`. There isn't a way to avoid this I can find because
AppKit processes argc/argv from the main entrypoint and that can't be
overridden.
2026-08-11 09:04:38 -07:00
Mitchell Hashimoto
90154e2895 macos: ignore -e arguments as open files
Fixes #13319

AppKit treats existing positional arguments as documents, causing paths
passed to a child command after -e to open an extra terminal surface.

We now process args ourselves during openFile callbacks to ignore 
file paths after `-e`. There isn't a way to avoid this I can find
because AppKit processes argc/argv from the main entrypoint and that
can't be overridden.
2026-08-11 08:30:32 -07:00
Mitchell Hashimoto
046b8fcc2a macos: defer OSC52 clipboard read confirmations until focused (#13744)
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).

To implement this, I decided to reorient the whole clipboard
confirmation thing around state on SurfaceView (which simplifies memory
management) and using Combine on BaseTerminalController to get notified.
2026-08-11 06:55:25 -07: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
44f06d4e4f macOS: rework for #12712 and #13645 (#13717)
`needleSelection` was introduced in #12712 to select all texts when
syncing pasteboard, the crash happens most on macOS 15 in
`readPasteboardNeedle`. It seems that `objectWillChange` fires
differently there, and it's hard to reproduce on macOS 26/27. I think
guaranteeing from ourside is enough, I believe SwiftUI already as its
own when updating the binding.

**Confirmed with a simple example on macOS 15, it seems a SwiftUI
issue🫪. So I changed the minimal macOS version for text selection to
macOS 26. I don't see an elegant way to fix it.**

<img width="1352" height="849" alt="image"
src="https://github.com/user-attachments/assets/1dfef3f5-ceaa-41dd-bb91-c23dbc5e4ad3"
/>


```swift
struct ContentView: View {
    @State private var text = ""
    @State private var selection: TextSelection?
    var body: some View {
        TextField("Search", text: $text, selection: $selection)
    }
}
```
2026-08-10 18:08:42 -07:00
Lukas
f0e3be3eef macOS: support decoding the surrogate pair with UnicodeHexInput 2026-08-10 22:55:57 +02:00
Jeffrey C. Ollie
8b7c57c756 gtk: add window title renaming
Fixes #10469 for GTK.
2026-08-10 10:07:11 -05:00
Lukas
0c8ec225b5 macOS: remove unused menu validations 2026-08-10 12:12:25 +02:00
Lukas
4b9d589bcb macOS: disable text selection on macOS 15 2026-08-10 11:44:43 +02: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
4b1e02c7c3 macos: do not load the config errors window when there are no errors
Measured on macOS (Apple Silicon) during app launch, via a startup
timeline instrumented across the Swift app and libghostty:

  config apply, errors step:      35.5ms -> 0.1ms
  main() -> first frame rendered: ~126ms -> ~93ms
  main() -> window visible:       ~193ms -> ~173ms
2026-08-09 19:54:28 -07:00
Lukas
49e4df7833 macOS: rework for #12712 and #13645 2026-08-09 23:19:47 +02:00
Lukas
74f91d1b43 macOS: support drag-handle config 2026-08-09 15:14:50 +02: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
fd98370211 macOS: fix swiftlint 2026-08-07 16:51:19 +02:00
Mitchell Hashimoto
faeac91fa5 macOS: fix window sizing after dragging a split into a window (#13682)
Regression from
[#13601](https://github.com/ghostty-org/ghostty/issues/13601), but I
don't see why it matters. But the surface's bounds changes after
window's created.
2026-08-07 07:38:48 -07:00
Mitchell Hashimoto
fcee19819e macos: discard debounced selection notification (#13676)
Discard the selection notification payload before debouncing
accessibility changes.

The debouncer previously retained the notification and its surface
object, keeping a closed tab's view and PTY alive after the undo
timeout.
2026-08-07 07:14:54 -07:00
Lukas
96826853bd macOS: fix window sizing after dragging a split into a window 2026-08-07 15:14:30 +02:00
Mitchell Hashimoto
44a05a88aa macos: discard debounced selection notification
Discard the selection notification payload before debouncing
accessibility changes.

The debouncer previously retained the notification and its surface
object, keeping a closed tab's view and PTY alive after the undo
timeout.
2026-08-06 13:05:37 -07: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
Lukas
18f06ef03c macOS: fix unsupported action falls through wrong handling 2026-08-06 16:17:11 +02:00
Lukas
301bd6f8b0 macOS: hide settings menu icon on macOS 27
Settings appears to be somehow special and it's not hidden previously.
2026-08-06 12:21:36 +02:00
Mitchell Hashimoto
e88601239d macOS: update command options match order (#13624)
Matches are sorted in the following order:
leadingColor > title > subtitle > description.

Ranking is lexicographic on (colorScore, textScore)

<img height="300" alt="image"
src="https://github.com/user-attachments/assets/1ec99e67-537e-4fc6-b595-d7eec8cbf31d"
/>


### AI Disclosure

Claude reviewed and added unit tests, also did some refactoring of my
original implementation.
2026-08-05 15:29:50 -07:00
Mitchell Hashimoto
ae0ff51c42 macos: defer overlapping clipboard completion (#13648)
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 15:19:34 -07:00
Mitchell Hashimoto
c9ef382fc9 macos: synchronize cached value access (#13646)
Fixes #13276

Make CachedValue safe for concurrent terminal content reads and expiry.

The expiry task could previously release cached Swift String storage
while another thread retained it, aborting the process during otherwise
normal terminal use.

Protect cached values and task handles with an NSLock, and exercise
concurrent reads across repeated expiration in a regression test.
2026-08-05 15:19:03 -07:00
Mitchell Hashimoto
947e839930 macos: prevent stale search selection crash (#13645)
Fixes #13266

Keep search text and its selection range synchronized as a single state
transition.

Deleting or replacing a search term could leave a String.Index range
from the old value attached to the text field. Applying that range could
crash the app.

Clear selection before publishing new text.
2026-08-05 14:55:37 -07: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
d28bc121a8 macos: synchronize cached value access
Fixes #13276

Make CachedValue safe for concurrent terminal content reads and expiry.

The expiry task could previously release cached Swift String storage
while another thread retained it, aborting the process during otherwise
normal terminal use.

Protect cached values and task handles with an NSLock, and exercise
concurrent reads across repeated expiration in a regression test.
2026-08-05 14:18:33 -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
74f01cf5df macos: prevent stale search selection crash
Fixes #13266

Keep search text and its selection range synchronized as a single
state transition.

Deleting or replacing a search term could leave a String.Index range
from the old value attached to the text field. Applying that range
could crash the app.

Clear selection before publishing new text.
2026-08-05 14:02:46 -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
77537c8065 macos: handled untrusted OSC8 hyperlinks more carefully
OSC8 hyperlinks previously executed directly via the NSWorkspace opener
so a malicious application can just do whatever it wanted and trick the
user into opening something through Launch Services.

This PR notifies apprt of OSC8 hyperlinks so they can be handled
specially. In this PR, I added macOS-specific handling of OSC8 through a
variety of improvements:

  - Preview text is sanitized, so invisible Unicode characters now show.
  - Questionable-looking URLs require confirmation to open, but a user
    can confirm to open.
  - Very questionable or definitely unsafe URLs are blocked with an 
    alert that only allows the user to copy the link. The alert also
    notifies the user why.
2026-08-05 10:22:28 -07:00
Claude Fable 5
d02ad967b6 macOS: update command options match order
Matches are sorted in the following order:
leadingColor > title > subtitle > description.

Ranking is lexicographic on (colorScore, textScore)
2026-08-05 16:15:01 +02:00
Lukas
c93752a008 macOS: suppress restart tips for auto update 2026-08-05 15:15:40 +02:00
Mitchell Hashimoto
d7f7a4e736 macOS: rename UpdateState.isIdle to isHidden (#13613) 2026-08-04 19:28:05 -07:00
Lukas
a86c49d7af macOS: rename UpdateState.isIdle to isHidden 2026-08-04 22:38:35 +02:00