mirror of
https://github.com/ghostty-org/ghostty.git
synced 2026-01-01 03:02:15 +00:00
fix(macOS): re-apply icon after app update (#9951)
## macOS: Re-apply custom icon after app build changes ### Summary Fixes the regression where custom icons are not re-applied after app updates, particularly affecting users on the tip channel. ### Problem PR #9670 introduced caching to avoid redundantly setting the app icon on every launch. However when Ghostty updates, the app bundle is replaced and the custom icon is reset by macOS. Since `UserDefaults` persists across updates, the cached icon name still matches the desired icon name, causing the icon update to be incorrectly skipped. This was reported by users in #9670 comments as well, that after updating Ghostty the custom icon would disappear and require manual re-application. ### Solution - Track the app build number (`CFBundleVersion`) alongside the icon name in `UserDefaults` - Re-apply the icon if either the icon config has changed OR the build number has changed - Only update `UserDefaults` if `NSWorkspace.setIcon()` succeeds, preventing false-positive caching on failure I used `CFBundleVersion` (build number, e.g. `13509`) rather than `CFBundleShortVersionString` (e.g. `1.2.3`) because tip builds increment the build number with each release while the short version string remains constant. I considered combining both but this seemed redundant. ### Related - Fixes regression mentioned in comments on #9670 - Original issue: #9666 - Original discussion: #9665
This commit is contained in:
@@ -982,9 +982,15 @@ class AppDelegate: NSObject,
|
||||
appIconName = (colorStrings + [config.macosIconFrame.rawValue])
|
||||
.joined(separator: "_")
|
||||
}
|
||||
// Only change the icon if it has actually changed
|
||||
// from the current one
|
||||
guard UserDefaults.standard.string(forKey: "CustomGhosttyIcon") != appIconName else {
|
||||
|
||||
// Only change the icon if it has actually changed from the current one,
|
||||
// or if the app build has changed (e.g. after an update that reset the icon)
|
||||
let cachedIconName = UserDefaults.standard.string(forKey: "CustomGhosttyIcon")
|
||||
let cachedIconBuild = UserDefaults.standard.string(forKey: "CustomGhosttyIconBuild")
|
||||
let currentBuild = Bundle.main.infoDictionary?["CFBundleVersion"] as? String
|
||||
let buildChanged = cachedIconBuild != currentBuild
|
||||
|
||||
guard cachedIconName != appIconName || buildChanged else {
|
||||
#if DEBUG
|
||||
if appIcon == nil {
|
||||
await MainActor.run {
|
||||
@@ -1001,14 +1007,16 @@ class AppDelegate: NSObject,
|
||||
let newIcon = appIcon
|
||||
|
||||
let appPath = Bundle.main.bundlePath
|
||||
NSWorkspace.shared.setIcon(newIcon, forFile: appPath, options: [])
|
||||
guard NSWorkspace.shared.setIcon(newIcon, forFile: appPath, options: []) else { return }
|
||||
NSWorkspace.shared.noteFileSystemChanged(appPath)
|
||||
|
||||
await MainActor.run {
|
||||
self.appIcon = newIcon
|
||||
NSApplication.shared.applicationIconImage = newIcon
|
||||
}
|
||||
|
||||
UserDefaults.standard.set(appIconName, forKey: "CustomGhosttyIcon")
|
||||
UserDefaults.standard.set(currentBuild, forKey: "CustomGhosttyIconBuild")
|
||||
}
|
||||
|
||||
//MARK: - Restorable State
|
||||
|
||||
Reference in New Issue
Block a user