diff --git a/macos/Ghostty.xcodeproj/project.pbxproj b/macos/Ghostty.xcodeproj/project.pbxproj index ea28a9ba4..68322756b 100644 --- a/macos/Ghostty.xcodeproj/project.pbxproj +++ b/macos/Ghostty.xcodeproj/project.pbxproj @@ -42,6 +42,7 @@ A54B0CE92D0CECD100CBEFF8 /* ColorizedGhosttyIconView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A54B0CE82D0CECD100CBEFF8 /* ColorizedGhosttyIconView.swift */; }; A54B0CEB2D0CFB4C00CBEFF8 /* NSImage+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A54B0CEA2D0CFB4A00CBEFF8 /* NSImage+Extension.swift */; }; A54B0CED2D0CFB7700CBEFF8 /* ColorizedGhosttyIcon.swift in Sources */ = {isa = PBXBuildFile; fileRef = A54B0CEC2D0CFB7300CBEFF8 /* ColorizedGhosttyIcon.swift */; }; + A54B0CEF2D0D2E2800CBEFF8 /* ColorizedGhosttyIconImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = A54B0CEE2D0D2E2400CBEFF8 /* ColorizedGhosttyIconImage.swift */; }; A54D786C2CA7978E001B19B1 /* BaseTerminalController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A54D786B2CA79788001B19B1 /* BaseTerminalController.swift */; }; A55685E029A03A9F004303CE /* AppError.swift in Sources */ = {isa = PBXBuildFile; fileRef = A55685DF29A03A9F004303CE /* AppError.swift */; }; A55B7BB829B6F53A0055DE60 /* Package.swift in Sources */ = {isa = PBXBuildFile; fileRef = A55B7BB729B6F53A0055DE60 /* Package.swift */; }; @@ -130,6 +131,7 @@ A54B0CE82D0CECD100CBEFF8 /* ColorizedGhosttyIconView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorizedGhosttyIconView.swift; sourceTree = ""; }; A54B0CEA2D0CFB4A00CBEFF8 /* NSImage+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSImage+Extension.swift"; sourceTree = ""; }; A54B0CEC2D0CFB7300CBEFF8 /* ColorizedGhosttyIcon.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorizedGhosttyIcon.swift; sourceTree = ""; }; + A54B0CEE2D0D2E2400CBEFF8 /* ColorizedGhosttyIconImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorizedGhosttyIconImage.swift; sourceTree = ""; }; A54D786B2CA79788001B19B1 /* BaseTerminalController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseTerminalController.swift; sourceTree = ""; }; A55685DF29A03A9F004303CE /* AppError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppError.swift; sourceTree = ""; }; A55B7BB729B6F53A0055DE60 /* Package.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Package.swift; sourceTree = ""; }; @@ -319,6 +321,7 @@ isa = PBXGroup; children = ( A54B0CEC2D0CFB7300CBEFF8 /* ColorizedGhosttyIcon.swift */, + A54B0CEE2D0D2E2400CBEFF8 /* ColorizedGhosttyIconImage.swift */, A54B0CE82D0CECD100CBEFF8 /* ColorizedGhosttyIconView.swift */, ); path = "Colorized Ghostty Icon"; @@ -640,6 +643,7 @@ A5CDF1932AAF9E0800513312 /* ConfigurationErrorsController.swift in Sources */, A53A6C032CCC1B7F00943E98 /* Ghostty.Action.swift in Sources */, A54B0CED2D0CFB7700CBEFF8 /* ColorizedGhosttyIcon.swift in Sources */, + A54B0CEF2D0D2E2800CBEFF8 /* ColorizedGhosttyIconImage.swift in Sources */, A59FB5D12AE0DEA7009128F3 /* MetalView.swift in Sources */, A55685E029A03A9F004303CE /* AppError.swift in Sources */, A599CDB02CF103F60049FA26 /* NSAppearance+Extension.swift in Sources */, diff --git a/macos/Sources/App/macOS/AppDelegate.swift b/macos/Sources/App/macOS/AppDelegate.swift index 895a53b67..87e56e8f0 100644 --- a/macos/Sources/App/macOS/AppDelegate.swift +++ b/macos/Sources/App/macOS/AppDelegate.swift @@ -98,6 +98,13 @@ class AppDelegate: NSObject, /// The observer for the app appearance. private var appearanceObserver: NSKeyValueObservation? = nil + /// The custom app icon image that is currently in use. + @Published private(set) var appIcon: NSImage? = nil { + didSet { + NSApplication.shared.applicationIconImage = appIcon + } + } + override init() { terminalManager = TerminalManager(ghostty) updaterController = SPUStandardUpdaterController( @@ -524,7 +531,9 @@ class AppDelegate: NSObject, screenColors: [.purple, .blue], ghostColor: .yellow ).makeImage() { - NSApplication.shared.applicationIconImage = colorizedIcon + self.appIcon = colorizedIcon + } else { + self.appIcon = nil } } diff --git a/macos/Sources/Features/About/AboutView.swift b/macos/Sources/Features/About/AboutView.swift index a011984d4..6ed3285ed 100644 --- a/macos/Sources/Features/About/AboutView.swift +++ b/macos/Sources/Features/About/AboutView.swift @@ -44,7 +44,7 @@ struct AboutView: View { var body: some View { VStack(alignment: .center) { - Image("AppIconImage") + ghosttyIconImage() .resizable() .aspectRatio(contentMode: .fit) .frame(height: 128) diff --git a/macos/Sources/Features/Colorized Ghostty Icon/ColorizedGhosttyIconImage.swift b/macos/Sources/Features/Colorized Ghostty Icon/ColorizedGhosttyIconImage.swift new file mode 100644 index 000000000..4d522067e --- /dev/null +++ b/macos/Sources/Features/Colorized Ghostty Icon/ColorizedGhosttyIconImage.swift @@ -0,0 +1,15 @@ +import SwiftUI + +extension View { + /// Returns the ghostty icon to use for views. + func ghosttyIconImage() -> Image { + #if os(macOS) + if let delegate = NSApplication.shared.delegate as? AppDelegate, + let nsImage = delegate.appIcon { + return Image(nsImage: nsImage) + } + #endif + + return Image("AppIconImage") + } +}