macOS: fix icon style not updating properly on Tahoe (#12180)

This is a regression from #9983. When resetting to default, we shouldn't
use the representation of the icon, which will prevent the icon from
updating after system settings change.

1. Delete `macos-icon` config if it exists and reload.
2. Go to **System Settings -> Appearance** and change **Icon & widget
style** to any one other than Default, and observe the app icon.


<img width="228" height="179" alt="image"
src="https://github.com/user-attachments/assets/e53274f8-b679-4d6f-8e0b-edfd7d17811d"
/>

> A temporary workaround to this issue is to reload the config.

This pr resets the `NSDockTile.contentView`, which will let AppKit
revert back to `Ghostty.icon`.



https://github.com/user-attachments/assets/06ab0519-225b-45e1-85a5-a22832a36177
This commit is contained in:
Mitchell Hashimoto
2026-04-08 10:59:57 -07:00
committed by GitHub

View File

@@ -82,7 +82,7 @@ class DockTilePlugin: NSObject, NSDockTilePlugIn {
/// Reset the application icon and dock tile icon to the default.
private func resetIcon(dockTile: NSDockTile) {
let appBundlePath = self.ghosttyAppURL?.path
let appIcon: NSImage
let appIcon: NSImage?
if #available(macOS 26.0, *) {
// Reset to the default (glassy) icon.
if let appBundlePath {
@@ -93,21 +93,8 @@ class DockTilePlugin: NSObject, NSDockTilePlugIn {
// Use the `Blueprint` icon to distinguish Debug from Release builds.
appIcon = pluginBundle.image(forResource: "BlueprintImage")!
#else
// Get the composed icon from the app bundle.
if let appBundlePath,
let iconRep = NSWorkspace.shared.icon(forFile: appBundlePath)
.bestRepresentation(
for: CGRect(origin: .zero, size: dockTile.size),
context: nil,
hints: nil
) {
appIcon = NSImage(size: dockTile.size)
appIcon.addRepresentation(iconRep)
} else {
// If something unexpected happens on macOS 26,
// fall back to a bundled icon.
appIcon = pluginBundle.image(forResource: "AppIconImage")!
}
// Reset to Ghostty.icon
appIcon = nil
#endif
} else {
// Use the bundled icon to keep the corner radius consistent with pre-Tahoe apps.
@@ -126,9 +113,14 @@ class DockTilePlugin: NSObject, NSDockTilePlugIn {
}
private extension NSDockTile {
func setIcon(_ newIcon: NSImage) {
func setIcon(_ newIcon: NSImage?) {
// Update the Dock tile on the main thread.
DispatchQueue.main.async {
guard let newIcon else {
self.contentView = nil
self.display()
return
}
let iconView = NSImageView(frame: CGRect(origin: .zero, size: self.size))
iconView.wantsLayer = true
iconView.image = newIcon