70 lines
2.2 KiB
Swift
70 lines
2.2 KiB
Swift
import AppKit
|
|
|
|
@MainActor
|
|
final class PHBarDelegate: NSObject, NSApplicationDelegate {
|
|
/// One window per attached screen — the single source of truth. The matching
|
|
/// controllers are reached through `windows[i].barController`.
|
|
var windows: [BarWindow] = []
|
|
|
|
/// Convenience accessor over `windows`.
|
|
var controllers: [BarController] { windows.map(\.barController) }
|
|
|
|
/// Resolves a controller for any screen from the current config. Swapped by
|
|
/// `reloadAll()` so a live reload re-reads theme/blocks from disk.
|
|
var factory: PHBarFactory
|
|
|
|
private var observers: [IPCObserver] = []
|
|
private var screenObserver: NSObjectProtocol?
|
|
|
|
/// `config` is captured here (not re-read per screen) so all bars share one
|
|
/// resolved config + environment for their lifetime. Live reload swaps the
|
|
/// whole factory via `reloadAll()`.
|
|
init(config: PHConfig, debug: Bool) {
|
|
let environment = PHEnvironment.process.merging(config.env)
|
|
self.factory = PHBarFactory(config: config, environment: environment, debug: debug)
|
|
super.init()
|
|
}
|
|
|
|
func applicationDidFinishLaunching(_ notification: Notification) {
|
|
syncScreens()
|
|
|
|
// React to monitor connect/disconnect and resolution changes. macOS
|
|
// delivers a single app-level notification for any of these; `syncScreens`
|
|
// diffs so unchanged bars are left untouched.
|
|
screenObserver = NotificationCenter.default.addObserver(
|
|
forName: NSApplication.didChangeScreenParametersNotification,
|
|
object: nil,
|
|
queue: .main
|
|
) { [weak self] _ in
|
|
Task { @MainActor in self?.syncScreens() }
|
|
}
|
|
|
|
// Listen for refresh notifications from `phbar refresh`.
|
|
let token = IPC.observe(.refresh) { [weak self] _ in
|
|
Task { @MainActor in self?.refresh() }
|
|
}
|
|
observers.append(token)
|
|
}
|
|
|
|
func refresh() {
|
|
for controller in controllers {
|
|
controller.refresh()
|
|
}
|
|
}
|
|
|
|
func applicationWillTerminate(_ notification: Notification) {
|
|
for controller in controllers {
|
|
controller.stopAutoRefresh()
|
|
}
|
|
observers.removeAll()
|
|
if let screenObserver {
|
|
NotificationCenter.default.removeObserver(screenObserver)
|
|
self.screenObserver = nil
|
|
}
|
|
}
|
|
|
|
func stderr(_ message: String) {
|
|
FileHandle.standardError.write(Data("phbar: \(message)\n".utf8))
|
|
}
|
|
}
|