Commit Graph

827 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
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
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
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
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
Lukas
fd98370211 macOS: fix swiftlint 2026-08-07 16:51:19 +02: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
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
Lukas
18f06ef03c macOS: fix unsupported action falls through wrong handling 2026-08-06 16:17:11 +02: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
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
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
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
Uzair Aftab
ad96613a8c inspector: add copy and export for terminal IO events
Adds "Copy" and "Export to file" buttons to the Terminal IO inspector
so recorded VT events can be saved outside the app for sharing or
analysis.

Export is wired up through a new export_terminal_io apprt action,
handled with a native save dialog on both macOS and GTK.
2026-07-30 08:08:25 +02:00
Lukas
a6edca2d7c macOS: free surface synchronously in deinit on main thread 2026-07-26 16:12:34 +02:00
Lukas
91f66da245 macos: route IME preedit commits through key events (#13222) 2026-07-08 07:06:44 +02:00
qappell
751a60df61 macos: route IME preedit commits through key events 2026-07-07 13:00:39 -05:00
Lukas
6e267d3363 macOS: use the getOpinionatedStringContents same as paste 2026-07-06 09:04:24 +02:00
Mitchell Hashimoto
f52f8aab95 macos: avoid notification publisher retain cycle
Turns out combine's `publisher(for:,object:)` retains the object!
We verified this with a test script shown below. Fix this with a 
manual filter. Found by @mustafa0x.

```
import Combine
import Foundation

final class Token {
    deinit { print("Token deinitialized") }
}

weak var weakToken: Token?
var publisher: NotificationCenter.Publisher?

// Create scope that will free token.
do {
    let token = Token()
    weakToken = token
    publisher = NotificationCenter.default.publisher(
        for: Notification.Name("TestNotification"),
        object: token
    )
}

print("Retained:", weakToken != nil)
publisher = nil
print("Released:", weakToken == nil)
```
2026-06-25 11:21:21 -07:00
Jon Parise
c4e1ab8883 core: send selection_changed notification
The core had no signal to the apprt when the active selection changed,
so a consumer (e.g. a screen reader) kept reading a stale selection
until some unrelated query refreshed it.

This change adds a payload-less selection_changed action that's fired on
a selection state transition. The apprt reads the current selection
through the normal read path.

This consolidates selection state changes so the notification fires
consistently: all sites route through setSelection rather than calling
screen.select directly, including the mouse paths that previously
bypassed it for clipboard timing.

The new setSelectionAndCopy extends setSelection with the additional
'copy_on_select' behavior.

On macOS, this posts .ghosttySelectionDidChange, which is debounced
before posting a NSAccessibility .selectedTextChanged notification.

GTK has no consumer yet and no-ops the action.
2026-06-02 19:37:49 -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
e32d7abe6e macos: fix swiftlint opening_brace issue 2026-05-31 10:00:24 -04:00
Adam Bouker
57d202066d macOS: clear stale OSC 11 background cache on config change
SurfaceView caches the background color set by OSC 11 in
backgroundColor. TerminalWindow.preferredBackgroundColor consults
that cache before falling back to derivedConfig.backgroundColor,
so once OSC 11 has fired the cached value masks any later config
change. After a light/dark theme auto-switch this leaves the
window chrome on the previous theme's color until the application
next emits OSC 11.

In ghosttyConfigDidChange, after updating derivedConfig, drop the
cache when it no longer matches the new config-derived background.
A subsequent ghosttyColorDidChange repopulates it as before, so
within-config OSC 11 behavior is unchanged.
2026-05-26 14:11:45 -05:00
minorcell
da541bea63 fix stray brace from conflict resolution 2026-05-23 16:33:33 +08:00
minorcell
7a346dd8d4 macOS: fix search bar Enter key blocking IME composition
Use onSubmit for the plain Enter → next-match behavior, which respects
IME composition state. Keep onKeyPress only for Shift+Enter (previous
match), returning .ignored for plain Enter so the IME can process it.
2026-05-23 16:09:48 +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
Nolin McFarland
bf716a0c39 feat: add extension to normalize OSPasteboard string interface 2026-05-18 10:12:26 -04:00
Nolin McFarland
69cab3d808 feat: select needle when reading from pasteboard 2026-05-17 11:26:32 -04:00
Nolin McFarland
59eece9a8e feat: use find pasteboard to store search needle 2026-05-16 19:59:20 -04: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
Jon Parise
2b48045731 macos: simplify workingDirectory setter
This is a minor improvement to the computed property's `set` logic: we
can just use `.map {}` to unify the two optional paths.
2026-05-09 14:37:43 -04:00
Lukas
607152ec6d macOS: normalize working directory paths with FilePath
This fixes for nuShell when opening Ghostty via Finder service and Shortcuts, also makes path parsing more robust in AppleScript.
2026-05-09 12:47:46 +02:00
Akinori Musha
d60a16c146 macos: avoid replaying keys that commit preedit
Refs #10460
Related: #12518

When an input method commits all or part of marked text during keyDown,
AppKit returns the committed text through insertText. Treat that as
text committed by the input method instead of replaying the original key
event to the terminal.

Previously this path only handled arrow-key commits specially. A
control-key shortcut that commits preedit text could still be encoded as
the original control input after composition, such as ctrl+j becoming LF.

Send committed preedit text as a text-only event for any key that causes
the commit. Only replay arrow navigation keys that the existing Korean
IME handling expects, and keep plain left-arrow suppressed because AppKit
already leaves the caret in place.

AI usage: OpenAI Codex helped investigate, implement, test, and refine
this change. I reviewed and tested the resulting code.
2026-05-01 23:18:42 +09:00
Mitchell Hashimoto
4dcb09ada0 macos: suppress control-char input while composing (#12518)
macos: suppress control-char input while composing

When AppKit delivers a single C0 control character during marked-text
composition, Ghostty should treat it as input consumed by the composing
state instead of forwarding it to the terminal.

This prevents control-key IME actions, such as Japanese input shortcuts
like ctrl+h/j/m/n, from leaking into the terminal while composition is
still active. Printable text and non-composing control input continue
through the normal key path.

Refs #10460
Related: #2628, #4539
Vouched in #12169

Testing:
- xcodebuild test -scheme Ghostty -destination platform=macOS
-only-testing:GhosttyTests/SurfaceViewAppKitTests
- Manually tested Japanese IME control-key shortcuts on macOS

AI usage:
- OpenAI Codex helped investigate, implement, test, and refine this
change. I reviewed and tested the resulting code.
2026-04-30 06:48:58 -07:00
Lukas
6fdca6bb53 macOS: enable copy only when there’s actual selected text 2026-04-29 19:33:09 +02:00
Akinori Musha
a43cc02ebd macos: suppress control-char input while composing
When AppKit delivers a single C0 control character during
marked-text composition, Ghostty should treat it as input consumed by
the composing state instead of forwarding it to the terminal.

This prevents control-key IME actions, such as Japanese input
shortcuts like ctrl+h/j/m/n, from leaking into the terminal while
composition is still active. Printable text and non-composing control
input continue through the normal key path.

AI usage: OpenAI Codex helped investigate, implement, test, and refine
this change. I reviewed and tested the resulting code.
2026-04-29 22:50:35 +09:00
Lukas
97c5a21aba macOS: fix ending search in menu bar does focus on surface 2026-04-27 19:03:06 +02:00
dobbylee
fa141a7262 Fix Korean IME committed text handling for arrow keys 2026-04-26 00:59:45 +09: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
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
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