Fixes#10406
ImGui_ImplOpenGL3_Shutdown() calls imgl3wShutdown() which dlcloses the
GL library handles but does not zero out the imgl3w function pointer
table (imgl3wProcs). When a GLArea is re-realized (e.g. during
reparenting), ImGui_ImplOpenGL3_Init() calls ImGui_ImplOpenGL3_InitLoader()
which checks "if (glGetIntegerv == nullptr)". Since the stale pointers
are non-null, it skips re-initialization. The next GL call through a
dangling function pointer causes a SIGSEGV.
Fix this by introducing ImGui_ImplOpenGL3_ShutdownWithLoaderCleanup()
which calls the normal shutdown and then zeroes the imgl3wProcs table,
forcing the next Init to reload GL function pointers via imgl3wInit().
Also properly destroy the ImGui context and reset widget state in
glAreaUnrealize so re-realize starts clean. This was extra but was
probably leaking memory.
Fixes#10935
This is a more robust way to detect "is my surface focused" because that
question usually means "is my surface the last focused surface" if a
_different_ surface is not focused. We already have used this pattern
all over but we should extend it to SwiftUI too.
Fixes#10935
This is a more robust way to detect "is my surface focused" because that
question usually means "is my surface the last focused surface" if a
_different_ surface is not focused. We already have used this pattern
all over but we should extend it to SwiftUI too.
(moved from #11008)
I have this branch up to fix#10252. It was written with AI (in Cursor),
but only after I made sure I thoroughly understood what was happening
(almost to an excessive extent). I had already determined that an
Objective-C helper was necessary, I just asked GPT 5.3 Codex in Cursor
to write it for me.
**TL;DR: deep within AppKit, there is an Objective-C exception that is
_always_ thrown when opening a new tab from the visual tab picker ("tab
overview"). [Objective-C exceptions *cannot* be safely recovered from in
Swift.](http://developer.apple.com/documentation/swift/handling-cocoa-errors-in-swift#Handle-Exceptions-in-Objective-C-Only)
As Ghostty is primarily Swift, we must introduce some Objective-C
wrapper around tab creation to safely swallow this exception.**
There is a lot more I know about this than the above, and can discuss it
at length if desired. Interestingly, it seems debug builds of Ghostty
(`zig build run`) *do* gracefully recover and don't crash. Release
builds (`zig build run -Doptimize=ReleaseFast`), however, *do* crash.
The crashing seems to be expected behavior and **_I don't think there's
any feasible way to get release builds to recover as debug builds do._**
The debug builds do, arguably, have better animation behavior. Not sure
how I can approach that part.
Release build off of my commit:
https://github.com/user-attachments/assets/c81927be-b2d2-48b3-a18f-30b389a90f04
Debug build off `db1e31c7a69924913e8faafcedb290de3cb4a8b6` (current
`main`, as of writing):
https://github.com/user-attachments/assets/76367154-b039-4453-8d39-8a0465973deb
* Using MAP prohibited `NSDockTilePlugIn` to update custom icons more
reliably. And it also fixes the corner radius issue on older os: #8870
* Changes in AboutWindow cc @jparise
* Start cycling with current icon
* Stop cycling icons when AboutWindow is closed
* Add menu to copy icon config
<img width="166" height="63" alt="Xnip2025-12-20_18-40-58"
src="https://github.com/user-attachments/assets/52fc1215-909e-49c7-a37a-b7c73eef61f1"
/>
> [!WARNING]
> Upgrading from `macOS-custom-icon` needs to manually open the app once
to update the icon, since this plugin is running under
`com.apple.dock.external.extra.arm64`, which has sandbox enabled.
>
> When first upgraded to this commit, a notification about the dock
plugin will pop up. The user has to enable this to change the icon
smoothly.
> <img width="389" height="159" alt="image"
src="https://github.com/user-attachments/assets/a883ac6b-0b4d-4794-8c61-50b60707f6a2"
/>
Here are the testing results on
[Tahoe](https://github.com/user-attachments/assets/e5fc8354-5f5c-4280-805f-88f043ceadca)
and
[Sequoia](https://github.com/user-attachments/assets/633d9a07-7d9d-4806-8496-82ddaffb8833):
> When you see some pause in the recording, that's when I rebuild or
replace the older version with the latest.
This also fixes some issues when changing between different styles,
consistency issues, and resetting from others to `official`.
### Developer's Note
This shouldn't affect current CI flow, since this new target is just a
bundle not runnable, and I tested with archiving, exporting and signing
in Xcode, nothing big changed.
> [!NOTE]
> AI helped me to write the typo ignore-re and proofread my comments
Fixes: #9416
Specifically:
iCurrentCursorStyle
iPreviousCursorStyle
iCurrentCursorVisible
iPreviousCursorVisible
Visibility calculated and updated independently from the typical cursor
uniform updates to preserve cursor style even when not in the viewport
or set to be hidden
I used Claude-Code to initially navigate and gauge an understanding of
the rendering system. Otherwise I authored the rest of the PR
Specifically:
iCurrentCursorStyle
iPreviousCursorStyle
iCurrentCursorVisible
iPreviousCursorVisible
Visibility calculated and updated independently from the typical cursor
unifrom updates to preserve cursor style even when not in the viewport
or set to be hidden
<img width="638" height="476" alt="Screenshot 2026-01-11 at 1 41 52 PM"
src="https://github.com/user-attachments/assets/bf3457e8-1b1c-4b2d-b6d1-312d48739108"
/>
This PR makes 3 small changes:
1. Makes the surface move grab handle present when the surface is
hovered and the mouse cursor is not hidden.
2. Makes the grab handle partial width, allowing space to more easily
grab the divider for resize (anywhere but the center) and increasing the
grabbable area for the grab handle.
3. Adds appropriate padding to the top of the surface (in the metal
stack so shaders can apply) to give space for the header so that text is
not occluded by the grab handle.
I think it looks good and works well, but I suggest trying it out since
the interaction is the most important part.
Problems I was trying to solve:
1. The old grab bar overlays actual clickable area on TUIs and can make
them hard to use
2. The old bar makes the entire divider also a grab area, making divider
resizing more difficult.
3. The old bar is not always present, making it hard to discover until
you're going to resize something, which then is confusing
4. The old bar is not colored with the style.
https://github.com/user-attachments/assets/588a35b5-ba2f-4074-8edb-e090e0006224
AI Disclosure: I originally did this with Claude, but at this point I've
gone over this code manually enough to feel somewhat familiar. I think
the video and design speak for themselves and the code change is
minimal, but I'm not a Swift programmer, so I can't evaluate whether
this is the best possible solution.
Human Disclosure: I don't have a linux machine to check that the padding
doesn't apply outside of MacOS. I find it hard to believe that it
wouldn't work, but worth calling out.
Namespace now supports cache volumes on macOS.
This enables caching for Zig and Xcode artifacts. We can't do Nix yet
because we can't create `/nix` and there's a chicken/egg with how Nix
installation works on macOS. I'm emailing Namespace support about it...
But still, a big win for Zig and Xcode!
Namespace now supports cache volumes on macOS.
This enables caching for Zig and Xcode artifacts. We can't do Nix yet because
we can't create `/nix` and there's a chicken/egg with how Nix installation
works on macOS. I'm emailing Namespace support about it... But still, a big
win for Zig and Xcode!
**Summary:**
- Add tint overlay to dim terminal windows when inactive, fixes
https://github.com/ghostty-org/ghostty/discussions/10040
- Refactor the liquid glass effect into a dedicated `TerminalGlassView`
class
Note: The tint overlay color and opacity values may not be ideal —
feedback is welcome.
**AI Disclosure:** I used Claude Code to read the macos repo and
understand the liquid glass implementation. Implemented basic tint
overlay mainly by hand. Refactor the code and review changes with Claude
Code.