Commit Graph

1891 Commits

Author SHA1 Message Date
Mitchell Hashimoto
af9470b19b macos: Kitty clipboard reads support pw/name session grants 2026-08-24 08:18:36 -07:00
Mitchell Hashimoto
8c7a34d4c9 macos: Kitty clipboard reads serve all clipboard content types 2026-08-24 08:18:36 -07:00
Mitchell Hashimoto
0ce9054bf9 macos: implement Kitty clipboard protocol reads (OSC 5522) 2026-08-24 08:18:36 -07:00
Mitchell Hashimoto
7a9bca6a6e macOS: fix responsiveness for repeated new tab action (#13985)
Fixes #13725
2026-08-24 06:58:12 -07:00
Lukas
1d24eecb20 macOS: fix responsiveness for repeated new tab action 2026-08-24 11:37:34 +02:00
Lukas
6cf7e0cc54 macOS: fix swiftlint warnings
swiftlint 0.63.3 introduced a new rule called [`legacy_swiftui_aspect_ratio`](76363aa4d7/CHANGELOG.md (L314))
2026-08-24 11:34:38 +02:00
Lukas
6a508fd5e3 macos: translate physical menu shortcuts (#13888)
Translate printable physical keybindings through the current macOS
keyboard layout before assigning menu key equivalents. Previously these
bindings could not be represented because SwiftUI shortcuts are
character-based, so actions such as `super+backquote` had no native menu
shortcut.

Keep native keycodes as dispatch identity so translated display
characters do not change physical semantics or precedence over Unicode
bindings. Refresh shortcuts when the input source changes, and prevent
AppKit from transforming equivalents that are already localized.

**AI Usage:** The approach was suggested by GPT 5.6 Sol, but I wrote
most of the code and understand it all.
2026-08-24 09:55:02 +02:00
Lukas
10d7326889 macOS: clean up GlassViewModel 2026-08-21 11:17:54 +02:00
Lukas
fd17869d15 macOS: rework for #10943
Keep the background color as it is and apply glass effect on top of it
2026-08-20 13:30:33 +02:00
Jon Parise
f5ad3a0a4a macos: use AppKit for shortcut translation
Translate synthetic physical-key events with characters(byApplyingModifiers:).
This preserves current-layout and Command-table behavior while avoiding a
duplicate direct UCKeyTranslate implementation in Swift.
2026-08-19 14:14:12 -04:00
Lukas
043abc7b60 macOS: group settings menu in a separate group 2026-08-19 15:03:15 +02:00
Lukas
f6990690f0 Revert "macOS: hide settings menu icon on macOS 27 (#13664)"
This reverts commit 99c483f477, reversing
changes made to 33bdeed1cb.
2026-08-19 15:02:01 +02:00
Jon Parise
9886f4817c macos: enforce keyboard layout actor isolation
Text Input Sources APIs are not thread-safe, but shortcut translation could
be called outside a declared main-actor context.

Mark keyboard layout and shortcut conversion as main-actor isolated, update
their tests, and dispatch key-sequence UI notifications to the main queue
before translating their shortcuts.
2026-08-18 12:40:28 -04:00
Jon Parise
761696c349 macos: simplify menu shortcut identity
Separate menu shortcut presentation from lookup identity. Store either a
normalized key equivalent or a physical keycode in a private hashable enum,
allowing Swift to synthesize equality and hashing instead of maintaining
parallel optional-key logic.

Assign display characters directly from KeyboardShortcut and remove unused
NSMenuItem and SwiftUI conversion helpers.
2026-08-18 11:49:46 -04:00
Jon Parise
569ff3307c macos: translate physical menu shortcuts
Translate printable physical keybindings through the current macOS
keyboard layout before assigning menu key equivalents. Previously these
bindings could not be represented because SwiftUI shortcuts are
character-based, so actions such as super+backquote had no native menu
shortcut.

Keep native keycodes as dispatch identity so translated display characters
do not change physical semantics or precedence over Unicode bindings.
Refresh shortcuts when the input source changes, and prevent AppKit from
transforming equivalents that are already localized.
2026-08-18 11:27:06 -04:00
Jon Parise
5c952ac977 macos: simplify command palette sort keys
Store the Comparable ObjectIdentifier directly instead of wrapping the
only sort key type in AnySortKey.

The expected deterministic ordering of equal terminal command titles is
also now verified by a unit test.
2026-08-17 12:50:27 -04:00
Mitchell Hashimoto
faaf07e7c0 macos: remove unused hosting window helper (#13873)
Remove the unused SwiftUI environment key intended to expose a hosting
window. Nothing sets or reads the value.
2026-08-17 09:36:11 -07:00
Jon Parise
d19f8f7f9d macos: remove unused hosting window helper
Remove the unused SwiftUI environment key intended to expose a hosting
window. Nothing sets or reads the value.
2026-08-17 10:58:41 -04:00
Mitchell Hashimoto
f4309055fb macos: don't put 0x7F as text in key event
Fixes #13869

We already checked `< 0x20` but missed `0x7F` which causes similar
problems.
2026-08-17 06:44:16 -07:00
Mitchell Hashimoto
9009122953 macos: send all insertText commits as key events (#13817)
Partially addresses #13796. Extends #13222.

Previously, `insertText` commits without marked text were delivered via
`sendText`, which applies paste semantics and wraps the text in
bracketed
paste when the program enables it. macOS dictation and other input
methods often commit without marked text, so programs treated dictated
text as a paste: opencode collapsed it into a `"[Pasted ~N lines]"` chip
and Neovim applied paste-mode handling.

`insertText` is only invoked by input methods (IME, dictation, emoji
picker, character viewer); real paste operations use a separate path.
Every non-empty commit is now sent as a key event — the same path
already used for preedit commits since #13222 — so input method text
always arrives as typed input.

Typing is unaffected (the accumulator path returns earlier) and Cmd+V
pastes are unaffected. `committedPreeditTextAction` is renamed to
`committedTextAction` since it no longer only handles preedit commits.

Testing:

- 311 macOS unit tests pass.
- Manually verified on macOS 26: dictation into Opencode and Neovim
  arrives inline with no paste handling; emoji picker inserts inline;
  Chinese IME composition unchanged; dictation in Neovim normal mode now
  behaves as keystrokes, matching Terminal.app.

Notes:

- Dictated "new line" now matches Terminal.app behavior (no newline
  with typed-text semantics). The previous behavior came from the paste
  path preserving the newline; a follow-up could deliver it as an
  Enter keypress if desired.

AI usage: drafted with OMO + OpenCode + DeepSeek V4 Pro assistance;
reviewed, edited, and manually tested by the author.
2026-08-15 14:26:19 -07:00
Samuel Huang
ecbeb60ca5 macos: send all insertText commits as key events
Previously, insertText commits without marked text were delivered via
sendText, which applies paste semantics and wraps the text in bracketed
paste when the program enables it. macOS dictation and other input
methods often commit without marked text, so programs treated dictated
text as a paste and applied paste-specific handling.

insertText is only invoked by input methods (IME, dictation, emoji
picker, character viewer); real paste operations use a separate path.
Send every non-empty commit through the key event path so programs
interpret input method text as typed input. Typing is unaffected (the
accumulator path returns earlier) and Cmd+V pastes are unaffected.

The helper is renamed from committedPreeditTextAction to
committedTextAction since it no longer only handles preedit commits.
2026-08-14 11:29:38 -04:00
Lukas
f2022fe88d macOS: avoid holding SurfaceView when sending notifications 2026-08-14 10:00:15 +02:00
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