Commit Graph

1387 Commits (78e539d68453fcedb29b31c7a296a9a816c7858e)

Author SHA1 Message Date
Lukas 52d3329f84
macOS: use unobtrusive when quick terminal is visible 2025-11-09 13:32:50 +01:00
Lukas 84082c2b96
macOS: equalize splits when double tapping on SplitView divider (#9524)
Resolves Issue #8357 

### Implementation

Following the existing `onResize` callback pattern in
`TerminalSplitTreeView`, I added an `onEqualize` callback to
`SplitView`. When a divider is double-tapped, the callback retrieves a
surface from that `TerminalView`'s `SplitTree` and calls `splitEqualize`
to equalize the entire tree.

### Context

There is an existing PR #8364 that implements this feature but uses
`focusedSurface`, which doesn't work for unfocused windows. Since that
PR has been inactive for a few months after requested changes, I've
implemented this alternative approach.

Credit to @liby for that initial implementation!

### AI Usage

I chatted with Claude Code in Plan mode to understand the relationship
between surfaces and the split tree/split views, but I wrote all the
code myself.

### Screenshot


https://github.com/user-attachments/assets/0efd70ef-c90e-4b50-b853-b05e2ca2be67
2025-11-09 09:07:09 +01:00
Daniel Wennberg e3ff49e653 macOS: Update core surface size when config changes 2025-11-08 23:34:56 -08:00
Sean Kelly e298620828 macOS: equalize splits when double tapping on SplitView divider 2025-11-08 23:16:16 -08:00
Daniel Wennberg 5845a7bd29 macOS: Update core surface size when scroller style changes 2025-11-08 22:41:59 -08:00
Daniel Wennberg 3142c5aa60 macOS: Don't clip surfaceView to contentView
Fixes #9248
2025-11-08 09:34:02 -08:00
Mitchell Hashimoto 12c8b6c1aa
macOS: Refactor scrollview to preserve state across split tree changes (#9446)
Fixes #9444
2025-11-07 15:10:45 -08:00
Mitchell Hashimoto 04563a16b6
macos: simplify the code to a more understandable style 2025-11-07 14:24:56 -08:00
Lars 1eecd448e9 remove needsConfirm 2025-11-07 14:16:10 -08:00
Lars f94cb01ec8 macOS: attach close confirmation alert to the first window that actually needs it 2025-11-07 14:16:10 -08:00
Lars 3f20f153c5 macOS: fix undo new tab will cause a crash 2025-11-07 14:14:44 -08:00
Mitchell Hashimoto f54c3d9209
macOS: set the macos-icon from a separate thread (#9485)
Closes #8793
2025-11-06 09:55:57 -07:00
Mitchell Hashimoto ec2ef5cf21
macOS: fix Dictation icon starting above the text, not below (#9488)
Partially fixes #8493.

After dictating some texts, the icon still appears above, but it will
return to its right position after resizing or `\n` (saying newline, not
hitting enter).

This behaviour is better than before, where the icon always appeared
above.

> Quicklook doesn't seem to call this on Tahoe, but it still works well
anyway.

### Reference:


9e905357bb/src/nsterm.m (L7426)



https://github.com/user-attachments/assets/6bf818c3-a0bb-412f-ae06-673f67cdeae4
2025-11-06 09:55:36 -07:00
Lars c8c36a6035
macOS: fix funky resolution in quick terminal 2025-11-06 16:13:05 +01:00
Lars 98ae1dbd10
macOS: fix Dictation icon starting above the text, not below
Partially fixes #8493.

After dictating some texts, the icon still appears above, but it will return to its right position after resizing or `\n` (saying newline, not hitting enter).

This behaviour is better than before, where the icon always appeared above.

### Reference:

9e905357bb/src/nsterm.m (L7426)
2025-11-05 18:22:08 +01:00
Lars 7472fb7732
macOS: set the macos-icon from a separate thread 2025-11-05 12:27:35 +01:00
Daniel Wennberg afc64f6285 Refactor scrollview to preserve state across split tree changes 2025-11-04 00:02:21 -08:00
Daniel Wennberg 9002c5dbd2 Preserve surface content size across backing updates 2025-11-04 00:02:21 -08:00
Daniel Wennberg d678e2e305 Use notifications to deal with NSScrollPocket 2025-11-04 00:02:21 -08:00
Mitchell Hashimoto 901708e8da
input: write_*_file actions take an optional format
Fixes #9398
2025-10-31 09:49:59 -07:00
Daniel Wennberg 951374cd1c Fix documentView padding calculations 2025-10-31 00:39:03 -07:00
Mitchell Hashimoto 5c1f036613
macos: assert only one text-plain gets written to clipboard 2025-10-30 15:16:15 -07:00
Mitchell Hashimoto 0f1c46e4a4
macos: support setting multiple clipboard content types 2025-10-30 14:01:58 -07:00
Lukas c7d5d1b9fc
macOS: make text editor in clipboard confirmation non focusable (#9400)
With its being `focusable`(default), the first responder became the text
editor instead of the paste button.

This fixes the issue where one can't confirm with the keyboard.

This doesn't affect its selection.
2025-10-29 21:30:03 -07:00
Daniel Wennberg 88444d4bd7 macOS: Adjust documentView padding on layout changes 2025-10-27 10:43:47 -07:00
Dusk 27b0978cd5
macos: use system beep for bell (#9339)
This seems pretty straightforward. I've tested it and it does what I'd
expect it to do.

Fixes #9338
2025-10-26 03:24:52 +00:00
Lukas fd969b53a5
macOS: fix #8282 (#9343)
After `ghostty_app_update_config`, `ghostty_action_config_change_s` was
fired with the correct config. This happens synchronously, which will
update `App.config` in `App.configChange(_:target:v:)`.

Previously, after updating, `App.config` was set with the stale one,
which caused #8282.
2025-10-25 20:08:32 -07:00
Lars d39cc6d478
macOS: update window appearance based on `preferredBackgroundColor` 2025-10-25 19:35:34 +02:00
Mitchell Hashimoto 5c574e7745
macos: use TextEditor instead of Text for clipboard confirmation (#9324)
Fixes #9322

SwiftUI `Text` has huge performance issues. On my maxed out MBP it hangs
for any text more than 100KB (it took ~8s to display it!). `TextEditor`
with a constant value works much better and handles scrolling for us,
too!
2025-10-23 09:22:35 -07:00
Daniel Wennberg e2fe0cf53a
macOS: remove scroll edge styling with hidden titlebar (#9317)
With `macos-titlebar-style = hidden`, creating splits or cycling
fullscreen sometimes produces a transparent overlay in the titlebar
area, clipping the top of the surfaces:

<img width="504" height="272" alt="Screenshot 2025-10-22 at 21 27 28"
src="https://github.com/user-attachments/assets/e28c5226-2e47-4c1d-8c14-b286fdb261f3"
/>

This is actually SwiftUI styling for scroll views, and the fact that it
pops up even though the titlebar is hidden is possibly a SwiftUI bug; at
least it's causing frustration for others too, see
https://developer.apple.com/forums/thread/798392 and
https://stackoverflow.com/questions/79776037/strange-nsscrollpocket-height-on-my-nstableview-in-fullscreen-mode-on-macos-taho.

I tried setting `.scrollEdgeEffectHidden()` on various nodes in the
SwiftUI hierarchy, but couldn't get it to work, so I ended up resorting
to an old-fashioned game of imperative whack-a-mole. Now:

<img width="504" height="272" alt="Screenshot 2025-10-22 at 21 28 47"
src="https://github.com/user-attachments/assets/e4499f16-5bd0-43cd-a7de-37fbc56eb1c4"
/>

AI disclosure (my first!): I consulted copilot trying to figure out of
the whole SwiftUI/AppKit situation and whether there might be a
declarative solution on the SwiftUI side. Just chatting in general terms
without showing real-world code. No dice.
2025-10-23 08:33:39 -07:00
Mitchell Hashimoto b764055c33
macos: window-position-x/y works with window-width/height (#9313)
Fixes #9132

We were processing our window size defaults separate from our window
position and the result was that you'd get some incorrect behavior.
Unify the logic more to fix the positioning.

Note there is room to improve this further, I think that all initial
positioning could go into the controller completely. But I wanted to
minimize the diff for a backport.
2025-10-22 16:14:28 -07:00
Mitchell Hashimoto 014de2992e
macos: goto_split direction is performable (#9284)
Fixes #9283

There was a comment here noting this deficiency. GTK implements this
properly.
2025-10-19 20:29:36 -07:00
Mitchell Hashimoto ea505ec51d
macos: use stable display UUID for quick terminal screen tracking
NSScreen instances can be garbage collected at any time, even for
screens that remain connected, making NSMapTable with weak keys
unreliable for tracking per-screen state.

This changes the quick terminal to use CGDisplay UUIDs as stable
identifiers, keyed in a strong dictionary. Each entry stores the
window frame along with screen dimensions, scale factor, and last-seen
timestamp.

Rules for pruning:
- Entries are invalidated when screens shrink or change scale
- Entries persist and update when screens grow (allowing cached state
  to work with larger resolutions)
- Stale entries for disconnected screens expire after 14 days.
- Maximum of 10 screen entries to prevent unbounded growth
2025-10-17 21:04:23 -07:00
Mitchell Hashimoto 5b7f145640
macos: make terminal smaller to account for legacy scrollbar
When the preferred scrollbar style is "legacy", the scrollbar takes up
space that offsets the actual terminal. To prevent reflow, we detect
this before the scrollbar becomes visible and shrink our terminal width
to prepare for it.

This doesn't account for the style changing at runtime, yet.
2025-10-17 20:08:03 -07:00
Daniel Wennberg 51b2374616 Add window padding to scrollView document height 2025-10-17 00:14:21 -07:00
Daniel Wennberg ffead466c7 Remove hidden titlebar safe area for SurfaceScrollView 2025-10-17 00:06:00 -07:00
Lars cc91e2ad16
macOS: remove background from SurfaceScrollView 2025-10-16 23:52:07 +02:00
Mitchell Hashimoto 4b34b2389a
config: add `scrollbar` config to control when scrollbars appear 2025-10-16 14:06:48 -07:00
Mitchell Hashimoto 7207ff08d5
macos: SurfaceScrollView 2025-10-16 14:06:46 -07:00
Mitchell Hashimoto 3d837cbbce
macos: "Check for updates" cancels whatever the current update state is (#9203)
This mainly allows users who have a pending update but didn't install it
for some time to re-check to see if there is something newer in the mean
time.
2025-10-14 07:31:31 -07:00
Mitchell Hashimoto 75734a4d07
macos: clarify the "ready to install update" state
- The copy is updated to better explain what the user should do next.
- The symbol is updated to make it clear the update isn't yet installed.
2025-10-13 21:06:01 -07:00
Xiangbao Meng dafb9e89a3
macOS: use default app for `*.ghostty` files first (#9180)
A small improvement for #8885, tested `config` and `config.ghostty`

<img width="526" height="267" alt="image"
src="https://github.com/user-attachments/assets/d09305ab-4a87-4393-b09c-804e618968f3"
/>
2025-10-13 06:52:00 -07:00
Mitchell Hashimoto 8f1a014afd
macos: clean up the "installing" update state (#9170)
This includes multiple changes to clean up the "installing" state:

- Ghostty will not confirm quit, since the user has already confirmed
they want to restart to install the update.
- If termination fails for any reason, the popover has a button to retry
restarting.
- The copy and badge symbol have been updated to better match the
reality of the "installing" state.

<img width="1756" height="890" alt="CleanShot 2025-10-12 at 15 04 08@2x"
src="https://github.com/user-attachments/assets/1b769518-e15f-4758-be3b-c45163fa2603"
/>

AI written:
https://ampcode.com/threads/T-623d1030-419f-413f-a285-e79c86a4246b fully
understood.
2025-10-12 15:20:26 -07:00
Joshie cbeb6890c9
Add `.ghostty` extension to `config` (#8885)
Resolves #8689

For various reason, ghostty wants to have a unique file extension for
the config files. The name was settled on `config.ghostty`. This will
help with tooling. See #8438 (original discussion) for more details.

This PR introduces the preferred default of `.ghostty` while still
supporting the previous `config` file. If both files exist, a warning
log is sent.

The docs / website will need to be updated to reflect this change. 

> [!NOTE]
> Only tested on macOS 26.0.

---------

Co-authored-by: Mitchell Hashimoto <m@mitchellh.com>
2025-10-12 13:48:06 -07:00
Xiangbao Meng 03e71e86a4
macOS: distinguish between Debug and Release(Stable/Tip) (#9149)
### Background

Been running Ghostty locally for a while now, and I use the Finder
service a lot. It often confuses me which one is the official one, until
I actually open it.

### Changes

- Use blueprint to distinguish from release app, if no custom icon
specified
- Change BundleDisplayName to Ghostty[Debug]
- Enable Info.plist preprocessing for reading
`$(INFOPLIST_KEY_CFBundleDisplayName)` for providing different services
with different configurations
> (Preprocessing was once reverted
before](https://github.com/ghostty-org/ghostty/commit/6508fec), so I'm
not sure whether this follows the 'rules' here, but for now, there are
no links in the plist file, so I think it’s
[safe](https://developer.apple.com/library/archive/technotes/tn2175/_index.html#:~:text=can%20pass%20the-,%2Dtraditional,-flag%20to%20the)
to enable it
2025-10-12 13:07:29 -07:00
Xiangbao Meng 8d8821004e
macOS: fix title misalignment in tabs (#9168)
While I was testing #9166, noticed another edge case🤯. 

This appears both in Tahoe and Sequoia👇🏻


https://github.com/user-attachments/assets/9cecea35-1241-4f31-9c15-0f2a7a6f342a
2025-10-12 13:04:18 -07:00
Xiangbao Meng 47a8f8083d
macOS: Fix more `macos-titlebar-style` related issues (#9163)
### This PR depends on #9162 

#1691 doesn't seem to be an issue anymore, but changing appearance while
Ghosty is active will result in similar nastiness.



https://github.com/user-attachments/assets/fcd7761e-a521-4382-8d7a-9d93dc0806bc



### Changes

- [Sequoia/Ventura] Fix flickering new tab icon, and it also didn't
respond to window's key status change correctly
- [Sequoia/Ventura] Fix after changing appearance, tab bar may disappear
or have inconsistent background colour
- Fix initial tint of reset zoom button on Sequoia/Ventura with
`macos-titlebar-style=tabs` and all `native/transparent` titlebars
- Fix title alignment with custom font with `native/transparent`
titlebar
2025-10-12 07:31:42 -07:00
Xiangbao Meng cbc06a0abc
macOS: Support building with Xcode 16 (#9162)
With this you can test most of the old tab bar behaviour without using a
virtual machine
2025-10-12 07:25:18 -07:00
Mitchell Hashimoto d3ee3c5b8a
macos: update permission request response should move state back to idle (#9151)
Previously, the permission request response would not move the state so
it'd stay in the titlebar.
2025-10-11 14:49:31 -07:00
Mitchell Hashimoto ac2f040b31
macos: Show "Update and Restart" in the Command Palette (#9131)
If an update is available, you can now trigger the full download,
install, and restart from a single command palette action. This allows
for a fully keyboard-driven update process.

While an update is being installed, an option to cancel or skip the
current update is also shown as an option, so that can also be
keyboard-driven.

This currently can't be bound to a keyboard action, but that may be
added in the future if there's demand for it.

**AI Disclosure:** Amp was used considerably. I reviewed all the code
and understand it.

## Demo



https://github.com/user-attachments/assets/df6307f8-9967-40d4-9a62-04feddf00ac2
2025-10-10 13:40:35 -07:00
Mitchell Hashimoto cd7621167f
macos: update accessory in the titlebar should not move the window
This is annoyingly easy to trigger, just disable this.
2025-10-10 10:20:35 -07:00
Xiangbao Meng c8ea42b894
macOS: Fix New Tab behaviours (#9124)
- Fix `macos-dock-drop-behavior = new-tab` not working, which also
affects `open /path/to/directory -a Ghostty.app`
- Fix 'New Tab' in dock icon not working **when Ghostty's not active**

### Issue preview with `1.2.2(12187)`


https://github.com/user-attachments/assets/18068cc2-c25d-4360-97ab-cec22d5d3ff4
2025-10-10 09:31:55 -07:00
Mitchell Hashimoto 207eccffda
macos: Sparkle notFound acknowledgement should only be called on dismiss (#9126)
This was causing the "no update found" message to never really appear in
the real world.
2025-10-10 09:30:12 -07:00
Xiangbao Meng 2bf9c777d7
Fix `macos-titlebar-tabs` related issues (#9090)
### This pr fixes multiple issues related to `macos-titlebar-tabs`

- [Window title clipping **on
Tahoe**](https://github.com/ghostty-org/ghostty/discussions/9027#discussion-8981483)
- Clipped tab bar **on Tahoe** when creating new ones in fullscreen
> Sequoia doesn't seem to have this issue (at least I didn't reproduce
myself)
- [Title missing **on Tahoe** after dragging a tab into a separate
window](https://github.com/ghostty-org/ghostty/discussions/9027#discussioncomment-14617088)
- [Clipped tab bar **on Tahoe** after dragging from one tab group to
another](https://github.com/ghostty-org/ghostty/discussions/9027#discussioncomment-14626078)
- [Stretched tab bar after switching system
appearance](https://github.com/ghostty-org/ghostty/discussions/9027#discussioncomment-14626918)


### Related issues
I checked all of the open sub-issues in #2349 , most of them should be
fixed in latest main branch (I didn't reproduce)

- [#1692](https://github.com/ghostty-org/ghostty/issues/1692)
@peteschaffner
- [#1945](https://github.com/ghostty-org/ghostty/issues/1945) this one I
reproduce only on Tahoe, and fixed in this pr, @injust
- [#1813](https://github.com/ghostty-org/ghostty/issues/1813) @jacakira
- [#1787](https://github.com/ghostty-org/ghostty/issues/1787)
@roguesherlock
- [#1691](https://github.com/ghostty-org/ghostty/issues/1691) ~**haven't
found a solution yet**(building zig on VM is a pain**)~
> Tried commenting out `isOpaque` check in
`TitlebarTabsVenturaTerminalWindow`, which would fix the issue, but I
see the note there about transparency issue.
  >
> After commenting it out, it worked fine for me with blur and opacity
config, so **I might need some more background on this**. Didn't include
this change yet.
  > 
> [See screenshot
here](https://github.com/user-attachments/assets/eb17642d-b0de-46b2-b42a-19fb38a2c7f0)



### Minor improvements

- Match window title style with `window-title-font-family` and focus
state
  
<img width="843" height="198" alt="image"
src="https://github.com/user-attachments/assets/0138c4fa-1a4b-4bab-a415-b32695899ccf"
/>

---------

Co-authored-by: Mitchell Hashimoto <m@mitchellh.com>
2025-10-10 09:21:29 -07:00
Mitchell Hashimoto e0ee10e902
macos: re-enable real update check 2025-10-10 08:44:25 -07:00
Mitchell Hashimoto 9dac88248f
macos: ax for update info 2025-10-10 08:38:50 -07:00
Mitchell Hashimoto 6993947a3a
macOS: Make a lot of things more robust 2025-10-10 08:27:30 -07:00
Mitchell Hashimoto ba8eae027e
macos: fixed width for downloading/extracting, better padding 2025-10-10 07:19:25 -07:00
Mitchell Hashimoto f124bb4975
macos: Fallback to standard driver when no unobtrusive targets exist 2025-10-09 17:38:24 -07:00
Mitchell Hashimoto f2e5b8fb2d
macos: setup the standard sparkle driver for no-window scenario
If there are no windows, we use the standard sparkle driver to drive
the standard window-based update UI.
2025-10-09 08:57:48 -07:00
Mitchell Hashimoto bbf875216f
macos: fix driver for retry to trigger update check again 2025-10-09 08:51:33 -07:00
Mitchell Hashimoto a2fbaec613
macos: do not build updaters into iOS 2025-10-08 22:18:36 -07:00
Mitchell Hashimoto 49eb65df77
macos: show release notes link 2025-10-08 22:05:03 -07:00
Mitchell Hashimoto abab6899f9
macos: better update descriptions 2025-10-08 21:45:48 -07:00
Mitchell Hashimoto bce49a0843
macos: hook up our new update controller 2025-10-08 21:41:18 -07:00
Mitchell Hashimoto b4ab1cc1ed
macos: clean up the permission request 2025-10-08 21:21:27 -07:00
Mitchell Hashimoto 9e17255ca9
macos: "OK" should dismiss error 2025-10-08 21:16:07 -07:00
Mitchell Hashimoto 95a9e63401
macos: not found state dismisses on click, after 5s 2025-10-08 21:13:34 -07:00
Mitchell Hashimoto a55de09944
macos: update simulator to test various scenarios in UI 2025-10-08 21:09:06 -07:00
Mitchell Hashimoto 59829f5359
Sparkle user driver, drives updates to the view model. 2025-10-08 21:03:04 -07:00
Mitchell Hashimoto f975ac8019
macOS: only show the update overlay if window doesn't support it 2025-10-08 15:39:56 -07:00
Mitchell Hashimoto 81e3ff90a3
macOS: Show update information as an overlay 2025-10-08 13:29:39 -07:00
Mitchell Hashimoto fc347a6040
macOS: Move update view model over to App scope 2025-10-08 12:50:09 -07:00
Mitchell Hashimoto 09ba5a27a2
macOS: Unobtrusive update views 2025-10-08 12:50:09 -07:00
Daniel Wennberg 0b14026696 Expand `~` in `macos-custom-icon` 2025-10-04 00:13:23 -07:00
Mitchell Hashimoto 77114d7927
macos: avoid any zero-sized content size increments
Fixes #9016
2025-10-03 13:35:40 -07:00
Andreas Deininger a667b740ee Fix typos 2025-10-03 18:52:26 +02:00
Mitchell Hashimoto 0cc3728803
macOS: Focus Terminal App Intent (#8961)
Closes #8791 
Discussion: #8657 

### Summary
This adds the FocusTerminalIntent App Intent and related function
(focusSurface), allows external tools (such as Shortcuts/Siri) to
programmatically move focus to a specific terminal window or tab.

### Verification
This functionality has been tested across following scenarios,
confirming correct focus behavior for:

- Split Window
- Tab Group
- Quick Terminal

### Note
It is not supported to move focus to a split that is hidden by a zoomed
split. The same applies to the CloseTerminalIntent.

### AI Disclosure
This pull request was made with assistance from Claude Code.
I reviewed all AI-generated code and wrote the final output manually.
2025-09-30 06:55:49 -07:00
himura467 373be61482 docs 2025-09-30 06:36:29 +09:00
himura467 b3d0b6a965 refactor: no need to set from for moveFocus probably 2025-09-30 05:58:21 +09:00
himura467 bc3d0b7cbc fix: the renderer's cursor remains in an unfocused state (block_hollow) 2025-09-30 05:21:56 +09:00
himura467 a6dd7bbeee refactor: improve asynchronous delay by delegating window/app activation process to animateIn 2025-09-29 02:02:42 +09:00
himura467 7ab0a7814b docs(BaseTerminalController) 2025-09-29 01:56:00 +09:00
himura467 337ecdd0b3 refactor(focusSurface): check app status in advance 2025-09-29 00:02:43 +09:00
himura467 8151f4bbf5 feat: focusSurface for quick terminal 2025-09-29 00:00:41 +09:00
himura467 9d33545a55 feat: focus terminal in basic cases 2025-09-28 19:20:00 +09:00
Lars 8beeebc21d
Force Ghostty to be active if not 2025-09-22 15:27:27 +02:00
Lars 8600954526
Workaround for #8669 2025-09-22 14:52:10 +02:00
Mitchell Hashimoto 4d761c96e5
macos: quick terminal stores the last closed size by screen
Fixes #8713

This stores the last closed state of the quick terminal by screen
pointer. We use a weak mapping so if a screen is unplugged we'll clear
the memory. We will not remember the size if you unplug and replug in a
monitor.
2025-09-19 13:01:29 -07:00
Mitchell Hashimoto f60bdb0faa
macos: set the app icon in syncAppearance to delay the icon update
Fixes #8734

This forces the app icon to be set on another event loop tick from
the main startup. 

In the future, we should load and set the icon completely in another
thread. It appears that all the logic we have is totally thread-safe.
2025-09-19 12:07:28 -07:00
Mitchell Hashimoto d27bc69f2e
macos: correct SurfaceView supported send/receive types for services
Fixes #8785

This is the callback AppKit sends when it wants to know if our
application can handle sending and receiving certain types of data.

The prior implementaiton was incorrect and would erroneously claim
support over combinations that we couldn't handle (at least, at the
SurfaceView layer). 

This corrects the implementation. The services we expect still show up
and the error in 8785 goes away.
2025-09-19 11:44:46 -07:00
Mitchell Hashimoto 6143aa8ce0
macos: "new tab" service should set preferred parent to ensure tab
Fixes #8783

Our new tab flow will never have a previously focused window because its
triggered by a service so we need to use the "preferred parent" logic we
have to open this in the last focused window.
2025-09-19 09:58:27 -07:00
Mitchell Hashimoto fe55d90ec5
macos: implement bell-features=border on macOS 2025-09-18 14:43:09 -07:00
Mitchell Hashimoto ad92bf7ab5
macos: bell-features=title works again
This was a regression we didn't fix before 1.2.
2025-09-18 14:02:32 -07:00
Mitchell Hashimoto 4fa8b8f285
macos: opening filepaths should make proper file URLs
Fixes #8763
2025-09-18 13:28:27 -07:00
Mitchell Hashimoto 734d1a13b3
macos: set initial window in TerminalWindow awakeFromNib
Maybe fixes #8736

I thought `windowDidLoad` was early on because its before the window is
shown but apparently not. Let's try `awakeFromNib` which is called
just after the window is loaded from the nib. It is hard to get any
earlier than that.
2025-09-18 13:05:57 -07:00
Mitchell Hashimoto 773990ada3
macos: window-position-x/y are from top-left corner
Fixes #8672

Almost fully written by AI: https://ampcode.com/threads/T-86df68a3-578c-4a1c-91f3-788f8b8f0aae

I reviewed all the code.
2025-09-18 12:18:13 -07:00
Mitchell Hashimoto 058d6808c1
macos: custom progress bar to workaround macOS 26 ProgressView bugs
Fixes #8731

The progress view in macOS 26 is broken in ways we can't work around
directly. Instead, we must create our own custom progress bar. Luckily,
our usage of the progress view is very simple.

Amp threads:
https://ampcode.com/threads/T-88b550b7-5e0d-4ab9-97d9-36fb63d18f21
https://ampcode.com/threads/T-721d6085-21d5-497d-b6ac-9f203aae0b94
2025-09-18 10:22:54 -07:00
Caleb Hearth ac9f3b88aa
Pass config to splits in NewTerminalConfig
Config contains the command, working directory, and environment
variables intended to be passed to the new split, but it looks like we
forgot to include it as an argument in this branch.

Discussion: https://github.com/ghostty-org/ghostty/discussions/8637
2025-09-15 13:16:18 -06:00
Mitchell Hashimoto 431364cf16
macos: disable NSAutoFillHeuristicController on macOS 26
Fixes #8616

macOS 26 (as of RC1) has some pathological performance bug where the
terminal becomes unusably slow after some period of time. We aren't 100%
sure what triggers the slowdown, but it is app-wide (new tabs or windows
don't resolve it) and Instruments traces point directly to
NSAutoFillHeuristicController. Specifically, to the `debounceTextUpdate`
selector.

This is all not documented as far as I can find and also not open
source, so I have no idea what's going on.

The best I can tell is that the NSAutoFillHeuristicController has
something to do with enabling heuristic-based autofill such as SMS auth
codes in text input fields. I don't know what is causing it to go
haywire.

SMS autofill is not desirable in a terminal app, nor is any of the other
automatic autofill in macOS I know of (contact info, passwords, etc.).
So, we can just disable it.

This default isn't documented but I found it via a strings dump of the
AppKit binary blob and comparing it to the disassembly to see how it is
used. In my limited testing, this seems to work around the problem.
2025-09-14 13:05:01 -07:00
Mitchell Hashimoto d813d82da1
macOS 26: Always set titlebarview background color for transparent title
This fixes an issue where new tabs would not have the proper transparent
background set whilst in native fullscreen. This is because in native
fullscreen, the NSTitlebarView always is visible, so our guard was
preventing us from setting it before.
2025-09-12 20:41:02 -07:00
Mitchell Hashimoto eaaf5aa8cf
macos: always reset titlebar tab constraints on frame change
Fixes #8595

Whenever the titlebar frame changes, we should set up our constraints
again to force it to re-render properly.
2025-09-12 20:14:31 -07:00
Mitchell Hashimoto 09246780bb
macos 26: fix visual glitches with moving tabs and titlebar tabs
This is a hacky fix to fix some visual glitches when titlebar tabs is on
and we're using the `move_tab` keybinding action (I test via the command
palette).

There is probably a more graceful way to fix this but this might be good
enough for a 1.2 to fix a very obviously nasty UI render.
2025-09-11 14:51:01 -07:00
Mitchell Hashimoto 22ec755e75
macos: run change title dialog in a sheet modal
This fixes a macOS 26 issue where the OK button would not be visible. 

This MUST be an AppKit bug, but I'm trying to find workarounds.
2025-09-11 14:40:25 -07:00
Mitchell Hashimoto c9574ed0c7
macOS: grab text field focus of command palette after tick
Fixes #8497

This works on every other supported version of macOS but doesn't work on
macOS tahoe. Putting it on the next event loop tick works at least on
Sequoia and Tahoe so let's just do that.
2025-09-11 14:14:14 -07:00
Mitchell Hashimoto 6324f2b3d8
macOS: ghostty launched via CLI should come to front
This fixes an issue I noticed where manually launching the `ghostty`
binary in the app bundle via the CLI would open the app but not create a
window or bring it to the front.
2025-09-06 07:16:51 -07:00
Mitchell Hashimoto c8243ffd99
macOS: prevent focus loss in hidden titlebar + non-native fullscreen
When using hidden titlebar with non-native fullscreen, the window would
lose focus after entering the first command. This occurred because:

1. Shell commands update the window title
2. Title changes trigger reapplyHiddenStyle() 
3. reapplyHiddenStyle() re-adds .titled to the style mask
4. Style mask changes during fullscreen confuse AppKit, causing focus loss

Fixed by adding a guard to skip titlebar restyling while fullscreen is
active, using terminalController.fullscreenStyle.isFullscreen for
proper detection of both native and non-native fullscreen modes.

https://ampcode.com/threads/T-c4ef59cc-1232-4fa5-8f09-c65724ee84d3
2025-09-03 10:01:28 -07:00
Mitchell Hashimoto fe3dab9467
macOS: SurfaceView should implement Identifiable
This has no meaningful functionality yet, it was one of the paths I was
looking at for #8505 but didn't pursue further. But I still think that
this makes more sense in general for the macOS app and will likely be
more useful later.
2025-09-03 09:17:37 -07:00
Mitchell Hashimoto 508e36bc03
macOS: split tree zoom state should encode as path, not full node
Fixes #8356

Zoom state should encode as a path so that it can be mapped to a
reference to the node in `root`. Previously, we were encoding a full
node which was instantiating an extra terminal on restore.
2025-09-03 08:51:37 -07:00
Mitchell Hashimoto e8217aa007
macOS: firstRect should return full rect width/height
Fixes #2473

This commit changes `ghostty_surface_ime_point` to return a full rect
with the width/height calculated for the preedit.

The `firstRect` function, which calls `ghostty_surface_ime_point` was
previously setting the width/height to zero. macOS didn't like this. We
then changed it to just hardcode it to width/height of one cell. This
worked but made it so the IME cursor didn't follow the preedit.
2025-09-02 13:08:46 -07:00
Mitchell Hashimoto 2bf0d3f4c7
macOS: Notify macOS of cell width/height for firstRect
Related to #2473

This fixes an issue where the dictation icon didn't show the language 
picker.
2025-09-02 12:26:52 -07:00
Mitchell Hashimoto 650028fa9f
config: bind both physical digit plus unicode digit for `goto_tab`
Fixes #8478

The comments explain this.
2025-09-02 09:00:58 -07:00
Mitchell Hashimoto 0b58830882
macOS: Progress bar for OSC9 progress reports 2025-08-31 20:42:34 -07:00
Mitchell Hashimoto 04956f3dc1
macos: require confirmation to run any script 2025-08-28 12:34:04 -07:00
Mitchell Hashimoto f1ea30dcf1
macos: when executing a script directly, always wait after command 2025-08-28 11:26:33 -07:00
Mitchell Hashimoto 19a27383f8
macos: use visible frame for quick terminal sizing calculation
Fixes #8418

This fixes issues where left/right positions would be cut off from the
menu bar. And makes it so that size 100%,100% doesn't overflow into the
non-visible space of the edge of the screen.
2025-08-27 06:59:02 -07:00
Mitchell Hashimoto 520eaec61c
macos: fix quick terminal issue where closing while fullscreen 2025-08-26 10:40:41 -07:00
Alexander Lais e676eae640 macos: fix quick terminal fullscreen
Fullscreen on quick terminal was failing with a crash, when it tried
to save the state of a non-existent toolbar and its accessory view
controllers.
2025-08-26 10:36:06 -07:00
Mitchell Hashimoto ae48f323d7
macos: style changes for quick terminal sizing 2025-08-26 10:20:16 -07:00
Mitchell Hashimoto a90bf58080
config: change quick terminal size C layout to tagged union 2025-08-26 09:52:26 -07:00
Friedrich Stoltzfus 466fdfffe6 macOS: rename c struct, relocate QuickTerminalSize file
Renamed the ghostty_quick_terminal_size_u to
ghostty_quick_terminal_size_s and moved the QuickTerminalSize file to
the Ghostty folder as requested.
2025-08-26 09:47:31 -07:00
Friedrich Stoltzfus 58e7400ea5 macOS: Round quick terminal window position coordinates
This resolves an issue where the right side of the quick terminal would
not resize equally to the left side if adjusting the width from the left
side.
2025-08-26 09:47:31 -07:00
Friedrich Stoltzfus 7cc0728fe5 macOS: enable quick terminal manual resizing
You can now resize the quick terminal both vertically and horizontally. To incorporate adjusting the custom secondary size on the quick terminal we needed to have the ability to resize the width (if from top, bottom, or center), and height (if from right, left, or center). The quick terminal will retain the user's manually adjusted size while the app is open. A new feature with this is that when the secondary size is adjusted (or primary if the quick terminal is center), the size will increase or decrease on both sides of the terminal.
2025-08-26 09:47:31 -07:00
Friedrich Stoltzfus 17f7f204e1 macOS: update zig and c structs for quick terminal size
Applying the feedback given by @pluiedev to use an enum to specify the
type of quick terminal size configuration given (pixels or percentage).
Updated the Swift code to work with the enum as well.
2025-08-26 09:47:31 -07:00
Friedrich Stoltzfus 63cd424678 macOS: Add support for quick terminal sizing configuration
Added C bindings for the already existing quick-terminal-size
configuration. Created a new QuickTerminalSize struct to hold these
values in Swift. Updated the QuickTerminal implementation to use the
user's configuration if supplied. Retains defaults. Also adds support to
customize the width of the quick terminal (height if quick terminal is
set to right or left).
2025-08-26 09:47:31 -07:00
Jeffrey C. Ollie 52a25e9c69
parameterize close_tab
- Add mode (`this`/`other`) parameter to `close_tab` keybind/apprt action.
- Keybinds will default to `this` if not specified, eliminating backward
  compatibility issues (`keybind=x=close_tab` === `keybind=x=close_tab:this`).
- Remove `close_other_tabs` keybind and apprt action.
2025-08-25 11:00:26 -05:00
jamylak c26323d697 Close other tabs feature on Mac.
Supporting command line, file menu and keybindings.
Default mac shortcut of `super + alt + o` (other)

Not able to test on Linux so excluding `close_other_tabs` from `gtk` for now
make a default short cut for close other tabs
2025-08-24 07:55:08 -07:00
Mitchell Hashimoto 54f8dff308
macos: if parent window is fullscreen, new window is fullscreen too
Fixes #8229

This was a regression. 

The discussion noted in #8229 requests we create a new window on the 
non-fullscreen desktop but that isn't how Ghostty has behaved
historically. I bisected back and tried 1.1.3 as well and we always
created a new fullscreen window when the parent was fullscreen.

This behavior matches iTerm2. Its noteworthy that native tabbing and
Apple apps such as Terminal.app and Safari do NOT do this. For both of
these, new window creates a _tab_ when in fullscreen. I don't think
that's particularly desirable, though.
2025-08-22 14:31:50 -07:00
Tobias Pape 4fdf0b687e typo found typos, typo may keep them 2025-08-22 09:19:25 -07:00
Tobias Pape 85cba70c2e Work around strange SwiftUI behavior in "older" macOSen.
The Quick Terminal would not appear anymore, as somewhere
in the framework the Quick Terminal Window's geometry
gets corrupted when the window is added to the UI.

This works around by caching the windows geometry and
reusing it afterwards
2025-08-22 09:17:49 -07:00
Moeeze Hassan f4009721a1 macOS: order out alert sheets to avoid Stage Manager focus loss
Signed-off-by: Moeeze Hassan <fammas.maz@gmail.com>
2025-08-22 09:05:20 -07:00
Daniel Wennberg 7d60c7c75b macos: move activation to after new window/tab is created 2025-08-21 15:16:20 -07:00
Aljoscha Krettek f736ee8865 macos: in new_window action, activate App
This change makes sure that the new window is focused and visible.

When commit 33d128bcff removed the
TerminalManager class and moved its functionality into
TerminalController, it accidentally removed app activation for windows
triggered by global keybinds.

How the bug works:

   1. Menu actions (like File → New Window) call AppDelegate.newWindow()
      which:
      2. Calls TerminalController.newWindow()
      3. AND explicitly calls NSApp.activate(ignoringOtherApps: true) in
         the AppDelegate
   4. Global keybind actions trigger ghosttyNewWindow() notification
      handler which:
      5. Only calls TerminalController.newWindow()
      6. Does NOT call NSApp.activate(ignoringOtherApps: true)
   7. While TerminalController.newWindow() does call
      NSApp.activate(ignoringOtherApps: true) internally, this call
      happens before the async dispatch that shows the window, so the
      activation occurs but the window isn't focused when it's actually
      shown.
   8. In the old TerminalManager.newWindow(), the activation happened
      immediately before the async dispatch, ensuring proper timing for
      window focus.

The fix would be to either move the NSApp.activate() call back into
TerminalController.newWindow(), as it was for TerminalManager, or add
the activation call to the notification handlers in AppDelegate.
2025-08-21 14:03:00 -07:00
Mitchell Hashimoto e01ff4093a
macos: have macos-dock-drop-behavior apply to all drops 2025-08-21 10:45:17 -07:00
David Keegan f9ad061ea8 Add macos-dock-drop-folder-behavior configuration option
This adds a new configuration option that controls whether folders
dropped onto the Ghostty dock icon open in a new tab (default) or
a new window.

The option accepts two values:
- tab: Opens folders in a new tab in the main window (default)
- window: Opens folders in a new window

This is useful for users who prefer window-based workflows over
tab-based workflows when opening folders via drag and drop.
2025-08-21 10:30:26 -07:00
Mitchell Hashimoto f178f4419e
macos: fix iOS builds 2025-08-21 10:03:25 -07:00
Nicholas Mata f1c68f698b Correct Swift formatting inconsistencies 2025-08-21 10:00:15 -07:00
Nicholas Mata 5948bd3f02 Add support for 'custom' on 'macos_icon' to support a completely custom app icon 2025-08-21 10:00:15 -07:00
Nicholas Mata 29419e7aac Make macos icon persistent even when app is closed 2025-08-21 10:00:15 -07:00
Mitchell Hashimoto 63ca777e0f
macos: show the copy menu item if we have any text selected 2025-08-19 14:23:50 -07:00
Alexander Lais 1f378e6775
fix: capture screenshot for app intents views as NSImage
SwiftUI's ImageRenderer must not be called outside the main thread.

The `@MainActor` annotation is only relevant for our own code, not
for calls from frameworks. The machinations around Shortcuts end up
calling the displayRepresentation method outside the main thread.

By capturing the screenshot as NSImage, all data is retained and can
be processed outside the main thread.
2025-08-08 16:53:26 +02:00
Aaron Ruan 1f710768e9
Update Float on Top menu icon to square.filled.on.square 2025-07-28 09:26:54 +08:00
Weizhao Ouyang b7f6da7857 macos: add more Tahoe menu item icons from SF Symbols
Signed-off-by: Weizhao Ouyang <o451686892@gmail.com>
2025-07-25 22:14:13 +08:00
Bryan Lee 852eb2e0d5
Fix tab titles not being preserved with window-save-state
Add serialization for tab titles in SurfaceView to persist user-set titles across app restarts. Bump TerminalRestorableState version to 4 to handle the new format.
2025-07-23 23:21:44 +08:00
William Walker 7962651dd8
fix: rename tab title popup focus 2025-07-14 17:23:59 -04:00
Mitchell Hashimoto 02b08e0ec9
macos: restore tabs correctly into a single window
Fixes #7941

I don't fully understand the fix here. Its code we've had for awhile it
was just in the wrong place after I refactored our window management.
The comment clearly states why its there but I don't know why it is
required.
2025-07-14 11:22:38 -07:00
Jeffrey C. Ollie cd9174e7e8
show child exited: fix macos build 2025-07-11 22:56:20 -05:00
Jeffrey C. Ollie 033d8c3099
core/gtk: add apprt action to show native GUI warning when child exits
Addresses #7649 for the core and GTK. macOS support will need to be
added later.

This adds an apprt action to show a native GUI warning of some kind when
the child process of a terminal exits.

Also adds a basic GTK implementation of this. In GTK it overlays an
Adwaita banner at the bottom of the window (similar to the banner that
shows up in at the top of windows in debug builds).
2025-07-11 22:56:20 -05:00
Mitchell Hashimoto b7ffbf933f
macos: open URLs with NSWorkspace APIs instead of `open`
Fixes #5256

This updates the macOS apprt to implement the `OPEN_URL` apprt action to
use the NSWorkspace APIs instead of the `open` command line utility.

As part of this, we removed the `ghostty_config_open` libghostty API and
instead introduced a new `ghostty_config_open_path` API that returns the
path to open, and then we use the `NSWorkspace` APIs to open it (same
function as the `OPEN_URL` action).
2025-07-06 21:01:01 -07:00
Mitchell Hashimoto 984d123fe4
macos: support configuration via CLI arguments
This makes it so `zig build run` can take arguments such as
`--config-default-files=false` or any other configuration. Previously,
it only accepted commands such as `+version`.

Incidentally, this also makes it so that the app in general can now take
configuration arguments via the CLI if it is launched as a new instance
via `open`. For example:

    open -n Ghostty.app --args --config-default-files=false

This previously didn't work. This is kind of cool.

To make this work, the libghostty C API was modified so that
initialization requires the CLI args, and there is a new C API to try to
execute an action if it was set.
2025-07-05 21:31:23 -07:00