diff --git a/macos/Assets.xcassets/Custom Icon/CustomIconBase.imageset/Contents.json b/macos/Assets.xcassets/Custom Icon/CustomIconBaseAluminum.imageset/Contents.json similarity index 100% rename from macos/Assets.xcassets/Custom Icon/CustomIconBase.imageset/Contents.json rename to macos/Assets.xcassets/Custom Icon/CustomIconBaseAluminum.imageset/Contents.json diff --git a/macos/Assets.xcassets/Custom Icon/CustomIconBase.imageset/base.png b/macos/Assets.xcassets/Custom Icon/CustomIconBaseAluminum.imageset/base.png similarity index 100% rename from macos/Assets.xcassets/Custom Icon/CustomIconBase.imageset/base.png rename to macos/Assets.xcassets/Custom Icon/CustomIconBaseAluminum.imageset/base.png diff --git a/macos/Assets.xcassets/Custom Icon/CustomIconBaseBeige.imageset/Contents.json b/macos/Assets.xcassets/Custom Icon/CustomIconBaseBeige.imageset/Contents.json new file mode 100644 index 000000000..db7850446 --- /dev/null +++ b/macos/Assets.xcassets/Custom Icon/CustomIconBaseBeige.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "beige.png", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "original" + } +} diff --git a/macos/Assets.xcassets/Custom Icon/CustomIconBaseBeige.imageset/beige.png b/macos/Assets.xcassets/Custom Icon/CustomIconBaseBeige.imageset/beige.png new file mode 100644 index 000000000..20c081611 Binary files /dev/null and b/macos/Assets.xcassets/Custom Icon/CustomIconBaseBeige.imageset/beige.png differ diff --git a/macos/Assets.xcassets/Custom Icon/CustomIconBaseChrome.imageset/Contents.json b/macos/Assets.xcassets/Custom Icon/CustomIconBaseChrome.imageset/Contents.json new file mode 100644 index 000000000..3889bd273 --- /dev/null +++ b/macos/Assets.xcassets/Custom Icon/CustomIconBaseChrome.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "chrome.png", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "original" + } +} diff --git a/macos/Assets.xcassets/Custom Icon/CustomIconBaseChrome.imageset/chrome.png b/macos/Assets.xcassets/Custom Icon/CustomIconBaseChrome.imageset/chrome.png new file mode 100644 index 000000000..66f2f86dd Binary files /dev/null and b/macos/Assets.xcassets/Custom Icon/CustomIconBaseChrome.imageset/chrome.png differ diff --git a/macos/Assets.xcassets/Custom Icon/CustomIconBasePlastic.imageset/Contents.json b/macos/Assets.xcassets/Custom Icon/CustomIconBasePlastic.imageset/Contents.json new file mode 100644 index 000000000..37ca4585c --- /dev/null +++ b/macos/Assets.xcassets/Custom Icon/CustomIconBasePlastic.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "plastic.png", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "original" + } +} diff --git a/macos/Assets.xcassets/Custom Icon/CustomIconBasePlastic.imageset/plastic.png b/macos/Assets.xcassets/Custom Icon/CustomIconBasePlastic.imageset/plastic.png new file mode 100644 index 000000000..a73470481 Binary files /dev/null and b/macos/Assets.xcassets/Custom Icon/CustomIconBasePlastic.imageset/plastic.png differ diff --git a/macos/Sources/App/macOS/AppDelegate.swift b/macos/Sources/App/macOS/AppDelegate.swift index 438ccfda2..b38a019f0 100644 --- a/macos/Sources/App/macOS/AppDelegate.swift +++ b/macos/Sources/App/macOS/AppDelegate.swift @@ -532,12 +532,13 @@ class AppDelegate: NSObject, self.appIcon = nil break - case .customColor: + case .customStyle: guard let ghostColor = config.macosIconGhostColor else { break } guard let screenColors = config.macosIconScreenColor else { break } guard let icon = ColorizedGhosttyIcon( screenColors: screenColors, - ghostColor: ghostColor + ghostColor: ghostColor, + frame: config.macosIconFrame ).makeImage() else { break } self.appIcon = icon } diff --git a/macos/Sources/Features/Colorized Ghostty Icon/ColorizedGhosttyIcon.swift b/macos/Sources/Features/Colorized Ghostty Icon/ColorizedGhosttyIcon.swift index 0de33deea..58de8f771 100644 --- a/macos/Sources/Features/Colorized Ghostty Icon/ColorizedGhosttyIcon.swift +++ b/macos/Sources/Features/Colorized Ghostty Icon/ColorizedGhosttyIcon.swift @@ -7,16 +7,26 @@ struct ColorizedGhosttyIcon { /// The color of the ghost. let ghostColor: NSColor + /// The frame type to use + let frame: Ghostty.MacOSIconFrame + /// Make a custom colorized ghostty icon. func makeImage() -> NSImage? { - // All of our layers (in order) - guard let base = NSImage(named: "CustomIconBase") else { return nil } + // All of our layers (not in order) guard let screen = NSImage(named: "CustomIconScreen") else { return nil } guard let screenMask = NSImage(named: "CustomIconScreenMask") else { return nil } guard let ghost = NSImage(named: "CustomIconGhost") else { return nil } guard let crt = NSImage(named: "CustomIconCRT") else { return nil } guard let gloss = NSImage(named: "CustomIconGloss") else { return nil } + let baseName = switch (frame) { + case .aluminum: "CustomIconBaseAluminum" + case .beige: "CustomIconBaseBeige" + case .chrome: "CustomIconBaseChrome" + case .plastic: "CustomIconBasePlastic" + } + guard let base = NSImage(named: baseName) else { return nil } + // Apply our color in various ways to our layers. // NOTE: These functions are not built-in, they're implemented as an extension // to NSImage in NSImage+Extension.swift. diff --git a/macos/Sources/Features/Colorized Ghostty Icon/ColorizedGhosttyIconView.swift b/macos/Sources/Features/Colorized Ghostty Icon/ColorizedGhosttyIconView.swift index 3d37e1356..8fbebfdc8 100644 --- a/macos/Sources/Features/Colorized Ghostty Icon/ColorizedGhosttyIconView.swift +++ b/macos/Sources/Features/Colorized Ghostty Icon/ColorizedGhosttyIconView.swift @@ -6,7 +6,8 @@ struct ColorizedGhosttyIconView: View { var body: some View { Image(nsImage: ColorizedGhosttyIcon( screenColors: [.purple, .blue], - ghostColor: .yellow + ghostColor: .yellow, + frame: .aluminum ).makeImage()!) } } diff --git a/macos/Sources/Ghostty/Ghostty.Config.swift b/macos/Sources/Ghostty/Ghostty.Config.swift index 6437e3bbd..af76ca2c3 100644 --- a/macos/Sources/Ghostty/Ghostty.Config.swift +++ b/macos/Sources/Ghostty/Ghostty.Config.swift @@ -263,6 +263,17 @@ extension Ghostty { return MacOSIcon(rawValue: str) ?? defaultValue } + var macosIconFrame: MacOSIconFrame { + let defaultValue = MacOSIconFrame.aluminum + guard let config = self.config else { return defaultValue } + var v: UnsafePointer? = nil + let key = "macos-icon-frame" + guard ghostty_config_get(config, &v, key, UInt(key.count)) else { return defaultValue } + guard let ptr = v else { return defaultValue } + let str = String(cString: ptr) + return MacOSIconFrame(rawValue: str) ?? defaultValue + } + var macosIconGhostColor: OSColor? { guard let config = self.config else { return nil } var v: ghostty_config_color_s = .init() diff --git a/macos/Sources/Ghostty/Package.swift b/macos/Sources/Ghostty/Package.swift index cb3615e2d..65f928443 100644 --- a/macos/Sources/Ghostty/Package.swift +++ b/macos/Sources/Ghostty/Package.swift @@ -198,7 +198,15 @@ extension Ghostty { /// macos-icon enum MacOSIcon: String { case official - case customColor = "custom-color" + case customStyle = "custom-style" + } + + /// macos-icon-frame + enum MacOSIconFrame: String { + case aluminum + case beige + case plastic + case chrome } /// Enum for the macos-titlebar-proxy-icon config option diff --git a/src/config/Config.zig b/src/config/Config.zig index ff8b0beaf..0efae159a 100644 --- a/src/config/Config.zig +++ b/src/config/Config.zig @@ -16,7 +16,6 @@ const build_config = @import("../build_config.zig"); const assert = std.debug.assert; const Allocator = std.mem.Allocator; const ArenaAllocator = std.heap.ArenaAllocator; -const build_config = @import("../build_config.zig"); const global_state = &@import("../global.zig").state; const fontpkg = @import("../font/main.zig"); const inputpkg = @import("../input.zig"); @@ -1688,11 +1687,11 @@ keybind: Keybinds = .{}, /// Valid values: /// /// * `official` - Use the official Ghostty icon. -/// * `custom-color` - Use the official Ghostty icon but with custom -/// colors applied to various layers. The custom colors must be -/// specified using the additional `macos-icon-x-color` configurations. -/// Note that all colors are required. If any are missing, the icon -/// will not be changed. +/// * `custom-style` - Use the official Ghostty icon but with custom +/// styles applied to various layers. The custom styles must be +/// specified using the additional `macos-icon`-prefixed configurations. +/// The `macos-icon-ghost-color` and `macos-icon-screen-color` +/// configurations are required for this style. /// /// Other caveats: /// @@ -1703,12 +1702,27 @@ keybind: Keybinds = .{}, /// @"macos-icon": MacAppIcon = .official, +/// The material to use for the frame of the macOS app icon. +/// +/// Valid values: +/// +/// * `aluminum` - A brushed aluminum frame. This is the default. +/// * `beige` - A classic 90's computer beige frame. +/// * `plastic` - A glossy, dark plastic frame. +/// * `chrome` - A shiny chrome frame. +/// +/// This only has an effect when `macos-icon` is set to `custom-style`. +@"macos-icon-frame": MacAppIconFrame = .aluminum, + /// The color of the ghost in the macOS app icon. /// /// The format of the color is the same as the `background` configuration; /// see that for more information. /// -/// This only has an effect when `macos-icon` is set to `custom-color`. +/// Note: This configuration is required when `macos-icon` is set to +/// `custom-style`. +/// +/// This only has an effect when `macos-icon` is set to `custom-style`. @"macos-icon-ghost-color": ?Color = null, /// The color of the screen in the macOS app icon. @@ -1718,7 +1732,10 @@ keybind: Keybinds = .{}, /// format of the color is the same as the `background` configuration; /// see that for more information. /// -/// This only has an effect when `macos-icon` is set to `custom-color`. +/// Note: This configuration is required when `macos-icon` is set to +/// `custom-style`. +/// +/// This only has an effect when `macos-icon` is set to `custom-style`. @"macos-icon-screen-color": ?ColorList = null, /// Put every surface (tab, split, window) into a dedicated Linux cgroup. @@ -5107,7 +5124,15 @@ pub const MacTitlebarProxyIcon = enum { /// format at all. pub const MacAppIcon = enum { official, - @"custom-color", + @"custom-style", +}; + +/// See macos-icon-frame +pub const MacAppIconFrame = enum { + aluminum, + beige, + plastic, + chrome, }; /// See gtk-single-instance