// // AppAppearanceManager.swift // App for Indeed // import AppKit /// Persists and applies the user’s light / dark / system appearance preference. @MainActor final class AppAppearanceManager { static let shared = AppAppearanceManager() static let didChangeNotification = Notification.Name("AppAppearanceManager.didChange") enum Mode: String, CaseIterable { case light case dark case system var segmentIndex: Int { switch self { case .system: 0 case .light: 1 case .dark: 2 } } init?(segmentIndex: Int) { switch segmentIndex { case 0: self = .system case 1: self = .light case 2: self = .dark default: return nil } } } private enum UserDefaultsKey { static let appearanceMode = "com.appforindeed.appearanceMode" } private var systemThemeObserver: NSObjectProtocol? private init() { systemThemeObserver = DistributedNotificationCenter.default().addObserver( forName: Notification.Name("AppleInterfaceThemeChangedNotification"), object: nil, queue: .main ) { [weak self] _ in guard let self, self.mode == .system else { return } self.updateWindowChrome() } } var mode: Mode { get { guard let raw = UserDefaults.standard.string(forKey: UserDefaultsKey.appearanceMode), let stored = Mode(rawValue: raw) else { return .light } return stored } set { guard newValue != mode else { return } UserDefaults.standard.set(newValue.rawValue, forKey: UserDefaultsKey.appearanceMode) apply() NotificationCenter.default.post(name: Self.didChangeNotification, object: self) } } /// Window backing color aligned with dashboard chrome for the active appearance. var windowChromeColor: NSColor { let isDark = NSApp.effectiveAppearance.bestMatch(from: [.darkAqua, .aqua]) == .darkAqua if isDark { return NSColor(srgbRed: 28 / 255, green: 28 / 255, blue: 30 / 255, alpha: 1) } return NSColor(srgbRed: 247 / 255, green: 247 / 255, blue: 247 / 255, alpha: 1) } func apply() { switch mode { case .light: NSApp.appearance = NSAppearance(named: .aqua) case .dark: NSApp.appearance = NSAppearance(named: .darkAqua) case .system: NSApp.appearance = nil } updateWindowChrome() } private func updateWindowChrome() { let color = windowChromeColor for window in NSApp.windows where window.isVisible || window.canBecomeKey { window.backgroundColor = color } } }