import AppKit import Combine /// Application delegate that bootstraps the notch overlay system. @MainActor class AppDelegate: NSObject, NSApplicationDelegate { private var cancellables = Set() func applicationDidFinishLaunching(_ notification: Notification) { NotchSettings.registerDefaults() NSApp.setActivationPolicy(.accessory) // Sync the launch-at-login toggle with the actual system state // in case the user toggled it from System Settings. UserDefaults.standard.set(LaunchAtLoginHelper.isEnabled, forKey: NotchSettings.Keys.launchAtLogin) ScreenManager.shared.start() observeDisplayPreference() observeSizePreferences() observeFontSizeChanges() observeTerminalThemeChanges() } func applicationWillTerminate(_ notification: Notification) { ScreenManager.shared.stop() } // MARK: - Preference observers /// Only rebuild windows when the display-count preference changes. private func observeDisplayPreference() { UserDefaults.standard.publisher(for: \.showOnAllDisplays) .removeDuplicates() .dropFirst() .sink { _ in ScreenManager.shared.rebuildWindows() } .store(in: &cancellables) } /// Reposition (not rebuild) when any sizing preference changes. private func observeSizePreferences() { NotificationCenter.default.publisher(for: UserDefaults.didChangeNotification) .debounce(for: .milliseconds(300), scheduler: RunLoop.main) .sink { _ in ScreenManager.shared.repositionWindows() } .store(in: &cancellables) } /// Live-update terminal font size across all sessions. private func observeFontSizeChanges() { UserDefaults.standard.publisher(for: \.terminalFontSize) .removeDuplicates() .sink { newSize in guard newSize > 0 else { return } TerminalManager.shared.updateAllFontSizes(CGFloat(newSize)) } .store(in: &cancellables) } /// Live-update terminal colors across all sessions. private func observeTerminalThemeChanges() { UserDefaults.standard.publisher(for: \.terminalTheme) .removeDuplicates() .sink { newTheme in TerminalManager.shared.updateAllThemes(TerminalTheme.resolve(newTheme)) } .store(in: &cancellables) } } // MARK: - KVO key paths private extension UserDefaults { @objc var terminalFontSize: Double { double(forKey: NotchSettings.Keys.terminalFontSize) } @objc var terminalTheme: String { string(forKey: NotchSettings.Keys.terminalTheme) ?? NotchSettings.Defaults.terminalTheme } @objc var showOnAllDisplays: Bool { bool(forKey: NotchSettings.Keys.showOnAllDisplays) } }