mirror of
https://github.com/ghostty-org/ghostty.git
synced 2026-04-06 07:38:21 +00:00
moving lots of files, removing unused stuff
This commit is contained in:
committed by
Lukas
parent
a79557f521
commit
2c28c27ca5
@@ -97,9 +97,13 @@
|
||||
8193245D2F24E80800A9ED8F /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = {
|
||||
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
|
||||
membershipExceptions = (
|
||||
App/macOS/AppIcon.swift,
|
||||
"Features/Colorized Ghostty Icon/ColorizedGhosttyIcon.swift",
|
||||
Ghostty/SharedPackage.swift,
|
||||
"Features/Dock Tile Plugin/AppIcon.swift",
|
||||
"Features/Dock Tile Plugin/DockTilePlugin.swift",
|
||||
"Features/Dock Tile Plugin/Notification+AppIcon.swift",
|
||||
"Features/Dock Tile Plugin/UserDefaults+AppIcon.swift",
|
||||
Ghostty/Ghostty.ConfigTypes.swift,
|
||||
Ghostty/GhosttyPackageMeta.swift,
|
||||
Helpers/CrossKit.swift,
|
||||
"Helpers/Extensions/NSImage+Extension.swift",
|
||||
"Helpers/Extensions/OSColor+Extension.swift",
|
||||
@@ -111,7 +115,6 @@
|
||||
membershipExceptions = (
|
||||
App/macOS/AppDelegate.swift,
|
||||
"App/macOS/AppDelegate+Ghostty.swift",
|
||||
App/macOS/AppIcon.swift,
|
||||
App/macOS/main.swift,
|
||||
App/macOS/MainMenu.xib,
|
||||
Features/About/About.xib,
|
||||
@@ -139,6 +142,10 @@
|
||||
"Features/Colorized Ghostty Icon/ColorizedGhosttyIconView.swift",
|
||||
"Features/Command Palette/CommandPalette.swift",
|
||||
"Features/Command Palette/TerminalCommandPalette.swift",
|
||||
"Features/Dock Tile Plugin/AppIcon.swift",
|
||||
"Features/Dock Tile Plugin/DockTilePlugin.swift",
|
||||
"Features/Dock Tile Plugin/Notification+AppIcon.swift",
|
||||
"Features/Dock Tile Plugin/UserDefaults+AppIcon.swift",
|
||||
"Features/Global Keybinds/GlobalEventTap.swift",
|
||||
Features/QuickTerminal/QuickTerminal.xib,
|
||||
Features/QuickTerminal/QuickTerminalController.swift,
|
||||
@@ -238,6 +245,7 @@
|
||||
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
|
||||
membershipExceptions = (
|
||||
App/iOS/iOSApp.swift,
|
||||
"Features/Dock Tile Plugin/DockTilePlugin.swift",
|
||||
"Ghostty/Surface View/SurfaceView_UIKit.swift",
|
||||
);
|
||||
target = A5B30530299BEAAA0047F10C /* Ghostty */;
|
||||
@@ -246,7 +254,6 @@
|
||||
|
||||
/* Begin PBXFileSystemSynchronizedRootGroup section */
|
||||
810ACCA02E9D3302004F8F92 /* GhosttyUITests */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = GhosttyUITests; sourceTree = "<group>"; };
|
||||
8193245A2F24E7D000A9ED8F /* DockTilePlugIn */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = DockTilePlugIn; sourceTree = "<group>"; };
|
||||
81F82BC72E82815D001EDFA7 /* Sources */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (81F82CB12E8281F9001EDFA7 /* PBXFileSystemSynchronizedBuildFileExceptionSet */, 81F82CB02E8281F5001EDFA7 /* PBXFileSystemSynchronizedBuildFileExceptionSet */, 8193245D2F24E80800A9ED8F /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = Sources; sourceTree = "<group>"; };
|
||||
A54F45F42E1F047A0046BD5C /* Tests */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = Tests; sourceTree = "<group>"; };
|
||||
/* End PBXFileSystemSynchronizedRootGroup section */
|
||||
@@ -321,7 +328,6 @@
|
||||
A51BFC282B30F26D00E92F16 /* GhosttyDebug.entitlements */,
|
||||
3B39CAA42B33949B00DABEB8 /* GhosttyReleaseLocal.entitlements */,
|
||||
81F82BC72E82815D001EDFA7 /* Sources */,
|
||||
8193245A2F24E7D000A9ED8F /* DockTilePlugIn */,
|
||||
A54F45F42E1F047A0046BD5C /* Tests */,
|
||||
810ACCA02E9D3302004F8F92 /* GhosttyUITests */,
|
||||
A5D495A3299BECBA00DD1313 /* Frameworks */,
|
||||
@@ -389,9 +395,6 @@
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
fileSystemSynchronizedGroups = (
|
||||
8193245A2F24E7D000A9ED8F /* DockTilePlugIn */,
|
||||
);
|
||||
name = DockTilePlugin;
|
||||
packageProductDependencies = (
|
||||
);
|
||||
@@ -845,13 +848,14 @@
|
||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = "Ghostty Dock Tile Plugin";
|
||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||
INFOPLIST_KEY_NSPrincipalClass = "";
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Bundles";
|
||||
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 26.2;
|
||||
MARKETING_VERSION = 1.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.mitchellh.DockTilePlugin;
|
||||
MACOSX_DEPLOYMENT_TARGET = 13.0;
|
||||
MARKETING_VERSION = 0.1;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.mitchellh.ghostty-dock-tile";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SKIP_INSTALL = YES;
|
||||
@@ -873,13 +877,14 @@
|
||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = "Ghostty Dock Tile Plugin";
|
||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||
INFOPLIST_KEY_NSPrincipalClass = "";
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Bundles";
|
||||
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 26.2;
|
||||
MARKETING_VERSION = 1.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.mitchellh.DockTilePlugin;
|
||||
MACOSX_DEPLOYMENT_TARGET = 13.0;
|
||||
MARKETING_VERSION = 0.1;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.mitchellh.ghostty-dock-tile";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SKIP_INSTALL = YES;
|
||||
@@ -901,13 +906,14 @@
|
||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = "Ghostty Dock Tile Plugin";
|
||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||
INFOPLIST_KEY_NSPrincipalClass = "";
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Bundles";
|
||||
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 26.2;
|
||||
MARKETING_VERSION = 1.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.mitchellh.DockTilePlugin;
|
||||
MACOSX_DEPLOYMENT_TARGET = 13.0;
|
||||
MARKETING_VERSION = 0.1;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.mitchellh.ghostty-dock-tile";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SKIP_INSTALL = YES;
|
||||
|
||||
@@ -928,6 +928,7 @@ class AppDelegate: NSObject,
|
||||
} else {
|
||||
GlobalEventTap.shared.disable()
|
||||
}
|
||||
|
||||
updateAppIcon(from: config)
|
||||
}
|
||||
|
||||
@@ -941,9 +942,9 @@ class AppDelegate: NSObject,
|
||||
// clean it up here to trigger a correct update of the current config.
|
||||
UserDefaults.standard.removeObject(forKey: "CustomGhosttyIcon")
|
||||
DispatchQueue.global().async {
|
||||
UserDefaults.standard.appIcon = Ghostty.CustomAppIcon(config: config)
|
||||
UserDefaults.standard.appIcon = AppIcon(config: config)
|
||||
DistributedNotificationCenter.default()
|
||||
.postNotificationName(Ghostty.Notification.ghosttyIconDidChange, object: nil, userInfo: nil, deliverImmediately: true)
|
||||
.postNotificationName(.ghosttyIconDidChange, object: nil, userInfo: nil, deliverImmediately: true)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,187 +0,0 @@
|
||||
import AppKit
|
||||
import System
|
||||
|
||||
#if !DOCK_TILE_PLUGIN
|
||||
import GhosttyKit
|
||||
#endif
|
||||
|
||||
extension Ghostty {
|
||||
/// For DockTilePlugin to generate icon
|
||||
/// without relying on ``Ghostty/Ghostty/Config``
|
||||
enum CustomAppIcon: Equatable, Codable {
|
||||
case official
|
||||
case blueprint
|
||||
case chalkboard
|
||||
case glass
|
||||
case holographic
|
||||
case microchip
|
||||
case paper
|
||||
case retro
|
||||
case xray
|
||||
/// Save image data to avoid sandboxing issues
|
||||
case custom(fileData: Data)
|
||||
case customStyle(ghostColorHex: String, screenColorHexes: [String], iconFrame: Ghostty.MacOSIconFrame)
|
||||
|
||||
/// Restore the icon from previously saved values
|
||||
init?(string: String) {
|
||||
switch string {
|
||||
case MacOSIcon.official.rawValue:
|
||||
self = .official
|
||||
case MacOSIcon.blueprint.rawValue:
|
||||
self = .blueprint
|
||||
case MacOSIcon.chalkboard.rawValue:
|
||||
self = .chalkboard
|
||||
case MacOSIcon.glass.rawValue:
|
||||
self = .glass
|
||||
case MacOSIcon.holographic.rawValue:
|
||||
self = .holographic
|
||||
case MacOSIcon.microchip.rawValue:
|
||||
self = .microchip
|
||||
case MacOSIcon.paper.rawValue:
|
||||
self = .paper
|
||||
case MacOSIcon.retro.rawValue:
|
||||
self = .retro
|
||||
case MacOSIcon.xray.rawValue:
|
||||
self = .xray
|
||||
default:
|
||||
/*
|
||||
let colorStrings = ([ghostColor] + screenColors).compactMap(\.hexString)
|
||||
appIconName = (colorStrings + [config.macosIconFrame.rawValue])
|
||||
.joined(separator: "_")
|
||||
*/
|
||||
var parts = string.split(separator: "_").map(String.init)
|
||||
if
|
||||
let _ = parts.first.flatMap(NSColor.init(hex:)),
|
||||
let frame = parts.last.flatMap(Ghostty.MacOSIconFrame.init(rawValue:))
|
||||
{
|
||||
let ghostC = parts.removeFirst()
|
||||
_ = parts.removeLast()
|
||||
self = .customStyle(
|
||||
ghostColorHex: ghostC,
|
||||
screenColorHexes: parts,
|
||||
iconFrame: frame
|
||||
)
|
||||
} else {
|
||||
// Due to sandboxing with `com.apple.dock.external.extra.arm64`,
|
||||
// we can’t restore custom icon file automatically.
|
||||
// The user must open the app to update it.
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func image(in bundle: Bundle) -> NSImage? {
|
||||
switch self {
|
||||
case .official:
|
||||
return nil
|
||||
case .blueprint:
|
||||
return bundle.image(forResource: "BlueprintImage")!
|
||||
case .chalkboard:
|
||||
return bundle.image(forResource: "ChalkboardImage")!
|
||||
case .glass:
|
||||
return bundle.image(forResource: "GlassImage")!
|
||||
case .holographic:
|
||||
return bundle.image(forResource: "HolographicImage")!
|
||||
case .microchip:
|
||||
return bundle.image(forResource: "MicrochipImage")!
|
||||
case .paper:
|
||||
return bundle.image(forResource: "PaperImage")!
|
||||
case .retro:
|
||||
return bundle.image(forResource: "RetroImage")!
|
||||
case .xray:
|
||||
return bundle.image(forResource: "XrayImage")!
|
||||
case let .custom(file):
|
||||
if let userIcon = NSImage(data: file) {
|
||||
return userIcon
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
case let .customStyle(ghostColorHex, screenColorHexes, macosIconFrame):
|
||||
let screenColors = screenColorHexes.compactMap(NSColor.init(hex:))
|
||||
guard
|
||||
let ghostColor = NSColor(hex: ghostColorHex),
|
||||
let icon = ColorizedGhosttyIcon(
|
||||
screenColors: screenColors,
|
||||
ghostColor: ghostColor,
|
||||
frame: macosIconFrame
|
||||
).makeImage(in: bundle)
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
return icon
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if !DOCK_TILE_PLUGIN
|
||||
extension Ghostty.CustomAppIcon {
|
||||
init?(config: Ghostty.Config) {
|
||||
switch config.macosIcon {
|
||||
case .official:
|
||||
return nil
|
||||
case .blueprint:
|
||||
self = .blueprint
|
||||
case .chalkboard:
|
||||
self = .chalkboard
|
||||
case .glass:
|
||||
self = .glass
|
||||
case .holographic:
|
||||
self = .holographic
|
||||
case .microchip:
|
||||
self = .microchip
|
||||
case .paper:
|
||||
self = .paper
|
||||
case .retro:
|
||||
self = .retro
|
||||
case .xray:
|
||||
self = .xray
|
||||
case .custom:
|
||||
if let data = try? Data(contentsOf: URL(filePath: config.macosCustomIcon, relativeTo: nil)) {
|
||||
self = .custom(fileData: data)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
case .customStyle:
|
||||
// Discard saved icon name
|
||||
// if no valid colours were found
|
||||
guard
|
||||
let ghostColor = config.macosIconGhostColor?.hexString,
|
||||
let screenColors = config.macosIconScreenColor?.compactMap(\.hexString)
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
self = .customStyle(ghostColorHex: ghostColor, screenColorHexes: screenColors, iconFrame: config.macosIconFrame)
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
extension UserDefaults {
|
||||
var appIcon: Ghostty.CustomAppIcon? {
|
||||
get {
|
||||
defer {
|
||||
removeObject(forKey: "CustomGhosttyIcon")
|
||||
}
|
||||
if let previous = string(forKey: "CustomGhosttyIcon"), let newIcon = Ghostty.CustomAppIcon(string: previous) {
|
||||
// update new storage once
|
||||
self.appIcon = newIcon
|
||||
return newIcon
|
||||
}
|
||||
guard let data = data(forKey: "NewCustomGhosttyIcon") else {
|
||||
return nil
|
||||
}
|
||||
return try? JSONDecoder().decode(Ghostty.CustomAppIcon.self, from: data)
|
||||
}
|
||||
set {
|
||||
guard let newData = try? JSONEncoder().encode(newValue) else {
|
||||
return
|
||||
}
|
||||
set(newData, forKey: "NewCustomGhosttyIcon")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension Ghostty.Notification {
|
||||
static let ghosttyIconDidChange = Notification.Name("com.mitchellh.ghostty.iconDidChange")
|
||||
}
|
||||
144
macos/Sources/Features/Dock Tile Plugin/AppIcon.swift
Normal file
144
macos/Sources/Features/Dock Tile Plugin/AppIcon.swift
Normal file
@@ -0,0 +1,144 @@
|
||||
import AppKit
|
||||
import System
|
||||
|
||||
/// The icon style for the Ghostty App.
|
||||
enum AppIcon: Equatable, Codable {
|
||||
case official
|
||||
case blueprint
|
||||
case chalkboard
|
||||
case glass
|
||||
case holographic
|
||||
case microchip
|
||||
case paper
|
||||
case retro
|
||||
case xray
|
||||
/// Save full image data to avoid sandboxing issues
|
||||
case custom(fileData: Data)
|
||||
case customStyle(ghostColorHex: String, screenColorHexes: [String], iconFrame: Ghostty.MacOSIconFrame)
|
||||
|
||||
#if !DOCK_TILE_PLUGIN
|
||||
init?(config: Ghostty.Config) {
|
||||
switch config.macosIcon {
|
||||
case .official:
|
||||
return nil
|
||||
case .blueprint:
|
||||
self = .blueprint
|
||||
case .chalkboard:
|
||||
self = .chalkboard
|
||||
case .glass:
|
||||
self = .glass
|
||||
case .holographic:
|
||||
self = .holographic
|
||||
case .microchip:
|
||||
self = .microchip
|
||||
case .paper:
|
||||
self = .paper
|
||||
case .retro:
|
||||
self = .retro
|
||||
case .xray:
|
||||
self = .xray
|
||||
case .custom:
|
||||
if let data = try? Data(contentsOf: URL(filePath: config.macosCustomIcon, relativeTo: nil)) {
|
||||
self = .custom(fileData: data)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
case .customStyle:
|
||||
// Discard saved icon name
|
||||
// if no valid colours were found
|
||||
guard
|
||||
let ghostColor = config.macosIconGhostColor?.hexString,
|
||||
let screenColors = config.macosIconScreenColor?.compactMap(\.hexString)
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
self = .customStyle(ghostColorHex: ghostColor, screenColorHexes: screenColors, iconFrame: config.macosIconFrame)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/// Restore the icon from previously saved values
|
||||
init?(string: String) {
|
||||
switch string {
|
||||
case Ghostty.MacOSIcon.official.rawValue:
|
||||
self = .official
|
||||
case Ghostty.MacOSIcon.blueprint.rawValue:
|
||||
self = .blueprint
|
||||
case Ghostty.MacOSIcon.chalkboard.rawValue:
|
||||
self = .chalkboard
|
||||
case Ghostty.MacOSIcon.glass.rawValue:
|
||||
self = .glass
|
||||
case Ghostty.MacOSIcon.holographic.rawValue:
|
||||
self = .holographic
|
||||
case Ghostty.MacOSIcon.microchip.rawValue:
|
||||
self = .microchip
|
||||
case Ghostty.MacOSIcon.paper.rawValue:
|
||||
self = .paper
|
||||
case Ghostty.MacOSIcon.retro.rawValue:
|
||||
self = .retro
|
||||
case Ghostty.MacOSIcon.xray.rawValue:
|
||||
self = .xray
|
||||
default:
|
||||
var parts = string.split(separator: "_").map(String.init)
|
||||
if
|
||||
let _ = parts.first.flatMap(NSColor.init(hex:)),
|
||||
let frame = parts.last.flatMap(Ghostty.MacOSIconFrame.init(rawValue:))
|
||||
{
|
||||
let ghostC = parts.removeFirst()
|
||||
_ = parts.removeLast()
|
||||
self = .customStyle(
|
||||
ghostColorHex: ghostC,
|
||||
screenColorHexes: parts,
|
||||
iconFrame: frame
|
||||
)
|
||||
} else {
|
||||
// Due to sandboxing with `com.apple.dock.external.extra.arm64`,
|
||||
// we can’t restore custom icon file automatically.
|
||||
// The user must open the app to update it.
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func image(in bundle: Bundle) -> NSImage? {
|
||||
switch self {
|
||||
case .official:
|
||||
return nil
|
||||
case .blueprint:
|
||||
return bundle.image(forResource: "BlueprintImage")!
|
||||
case .chalkboard:
|
||||
return bundle.image(forResource: "ChalkboardImage")!
|
||||
case .glass:
|
||||
return bundle.image(forResource: "GlassImage")!
|
||||
case .holographic:
|
||||
return bundle.image(forResource: "HolographicImage")!
|
||||
case .microchip:
|
||||
return bundle.image(forResource: "MicrochipImage")!
|
||||
case .paper:
|
||||
return bundle.image(forResource: "PaperImage")!
|
||||
case .retro:
|
||||
return bundle.image(forResource: "RetroImage")!
|
||||
case .xray:
|
||||
return bundle.image(forResource: "XrayImage")!
|
||||
case let .custom(file):
|
||||
if let userIcon = NSImage(data: file) {
|
||||
return userIcon
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
case let .customStyle(ghostColorHex, screenColorHexes, macosIconFrame):
|
||||
let screenColors = screenColorHexes.compactMap(NSColor.init(hex:))
|
||||
guard
|
||||
let ghostColor = NSColor(hex: ghostColorHex),
|
||||
let icon = ColorizedGhosttyIcon(
|
||||
screenColors: screenColors,
|
||||
ghostColor: ghostColor,
|
||||
frame: macosIconFrame
|
||||
).makeImage(in: bundle)
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
return icon
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,14 @@
|
||||
import AppKit
|
||||
|
||||
/// This class lives as long as the app is in the Dock.
|
||||
/// If the user pins the app to the Dock, it will not be deallocated.
|
||||
/// Be careful when storing state in this class.
|
||||
class DockTilePlugin: NSObject, NSDockTilePlugIn {
|
||||
// WARNING: An instance of this class is alive as long as Ghostty's icon is
|
||||
// in the doc (running or not!), so keep any state and processing to a
|
||||
// minimum to respect resource usage.
|
||||
|
||||
private let pluginBundle = Bundle(for: DockTilePlugin.self)
|
||||
|
||||
// Separate defaults based on debug vs release builds so we can test icons
|
||||
// without messing up releases.
|
||||
#if DEBUG
|
||||
private let ghosttyUserDefaults = UserDefaults(suiteName: "com.mitchellh.ghostty.debug")
|
||||
#else
|
||||
@@ -21,7 +25,7 @@ class DockTilePlugin: NSObject, NSDockTilePlugIn {
|
||||
// Try to restore the previous icon on launch.
|
||||
iconDidChange(ghosttyUserDefaults.appIcon, dockTile: dockTile)
|
||||
|
||||
iconChangeObserver = DistributedNotificationCenter.default().publisher(for: Ghostty.Notification.ghosttyIconDidChange)
|
||||
iconChangeObserver = DistributedNotificationCenter.default().publisher(for: .ghosttyIconDidChange)
|
||||
.map { [weak self] _ in
|
||||
self?.ghosttyUserDefaults?.appIcon
|
||||
}
|
||||
@@ -41,7 +45,7 @@ class DockTilePlugin: NSObject, NSDockTilePlugIn {
|
||||
return url.path
|
||||
}
|
||||
|
||||
func iconDidChange(_ newIcon: Ghostty.CustomAppIcon?, dockTile: NSDockTile) {
|
||||
func iconDidChange(_ newIcon: AppIcon?, dockTile: NSDockTile) {
|
||||
guard let appIcon = newIcon?.image(in: pluginBundle) else {
|
||||
resetIcon(dockTile: dockTile)
|
||||
return
|
||||
@@ -80,6 +84,7 @@ class DockTilePlugin: NSObject, NSDockTilePlugIn {
|
||||
appIcon = pluginBundle.image(forResource: "AppIconImage")!
|
||||
NSWorkspace.shared.setIcon(appIcon, forFile: appBundlePath)
|
||||
}
|
||||
|
||||
NSWorkspace.shared.noteFileSystemChanged(appBundlePath)
|
||||
dockTile.setIcon(appIcon)
|
||||
}
|
||||
@@ -99,17 +104,3 @@ private extension NSDockTile {
|
||||
}
|
||||
|
||||
extension NSDockTile: @unchecked @retroactive Sendable {}
|
||||
|
||||
#if DEBUG
|
||||
private extension NSAlert {
|
||||
static func notify(_ message: String, image: NSImage?) {
|
||||
DispatchQueue.main.async {
|
||||
let alert = NSAlert()
|
||||
alert.messageText = message
|
||||
alert.icon = image
|
||||
_ = alert.runModal()
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
import AppKit
|
||||
|
||||
extension Notification.Name {
|
||||
static let ghosttyIconDidChange = Notification.Name("com.mitchellh.ghostty.iconDidChange")
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
import AppKit
|
||||
|
||||
extension UserDefaults {
|
||||
private static let customIconKeyOld = "CustomGhosttyIcon"
|
||||
private static let customIconKeyNew = "CustomGhosttyIcon2"
|
||||
|
||||
var appIcon: AppIcon? {
|
||||
get {
|
||||
// Always remove our old pre-docktileplugin values.
|
||||
defer {
|
||||
removeObject(forKey: Self.customIconKeyOld)
|
||||
}
|
||||
|
||||
// If we have an old, pre-docktileplugin value, then we parse the
|
||||
// the old value (try) and set it.
|
||||
if let previous = string(forKey: Self.customIconKeyOld), let newIcon = AppIcon(string: previous) {
|
||||
// update new storage once
|
||||
self.appIcon = newIcon
|
||||
return newIcon
|
||||
}
|
||||
|
||||
// Check if we have the new key for our dock tile plugin format.
|
||||
guard let data = data(forKey: Self.customIconKeyNew) else {
|
||||
return nil
|
||||
}
|
||||
return try? JSONDecoder().decode(AppIcon.self, from: data)
|
||||
}
|
||||
|
||||
set {
|
||||
guard let newData = try? JSONEncoder().encode(newValue) else {
|
||||
return
|
||||
}
|
||||
|
||||
set(newData, forKey: Self.customIconKeyNew)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,22 +1,5 @@
|
||||
import Foundation
|
||||
import os
|
||||
|
||||
enum Ghostty {
|
||||
// The primary logger used by the GhosttyKit libraries.
|
||||
static let logger = Logger(
|
||||
subsystem: Bundle.main.bundleIdentifier!,
|
||||
category: "ghostty"
|
||||
)
|
||||
|
||||
// All the notifications that will be emitted will be put here.
|
||||
struct Notification {}
|
||||
|
||||
// The user notification category identifier
|
||||
static let userNotificationCategory = "com.mitchellh.ghostty.userNotification"
|
||||
|
||||
// The user notification "Show" action
|
||||
static let userNotificationActionShow = "com.mitchellh.ghostty.userNotification.Show"
|
||||
}
|
||||
// This file contains the configuration types for Ghostty so that alternate targets
|
||||
// can get typed information without depending on all the dependencies of GhosttyKit.
|
||||
|
||||
extension Ghostty {
|
||||
/// macos-icon
|
||||
@@ -11,6 +11,14 @@ extension ghostty_command_s: @unchecked @retroactive Sendable {}
|
||||
/// may be unsafe but the value itself is safe to send across threads.
|
||||
extension ghostty_surface_t: @unchecked @retroactive Sendable {}
|
||||
|
||||
extension Ghostty {
|
||||
// The user notification category identifier
|
||||
static let userNotificationCategory = "com.mitchellh.ghostty.userNotification"
|
||||
|
||||
// The user notification "Show" action
|
||||
static let userNotificationActionShow = "com.mitchellh.ghostty.userNotification.Show"
|
||||
}
|
||||
|
||||
// MARK: Build Info
|
||||
|
||||
extension Ghostty {
|
||||
16
macos/Sources/Ghostty/GhosttyPackageMeta.swift
Normal file
16
macos/Sources/Ghostty/GhosttyPackageMeta.swift
Normal file
@@ -0,0 +1,16 @@
|
||||
import Foundation
|
||||
import os
|
||||
|
||||
// This defines the minimal information required so all other files can do
|
||||
// `extension Ghostty` to add more to it. This purposely has minimal
|
||||
// dependencies so things like our dock tile plugin can use it.
|
||||
enum Ghostty {
|
||||
// The primary logger used by the GhosttyKit libraries.
|
||||
static let logger = Logger(
|
||||
subsystem: Bundle.main.bundleIdentifier!,
|
||||
category: "ghostty"
|
||||
)
|
||||
|
||||
// All the notifications that will be emitted will be put here.
|
||||
struct Notification {}
|
||||
}
|
||||
Reference in New Issue
Block a user