blob: a7ecb5a91438a0ec659519df4adb243037ff8e07 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
import AppKit
import SwiftUI
@MainActor
final class AppDelegate: NSObject, NSApplicationDelegate {
private var windows: [BarWindow] = []
private var blocks: [Block] = Config.blocks.map(\.resolved)
private var tokens: [UnsafeMutableRawPointer] = []
func applicationDidFinishLaunching(_ notification: Notification) {
for screen in NSScreen.screens {
let frame = Screen.barFrame(screen, position: Config.position, height: Config.height)
let window = BarWindow(contentRect: frame)
window.contentView = NSHostingView(rootView: BarView(blocks: blocks))
window.orderFrontRegardless()
windows.append(window)
}
// Register one listener per unique name; a single post fans out to every
// block with that name (see Notifier).
for name in Set(blocks.map(\.name)) {
let token = Notifier.register(name) { [weak self] in
self?.handleRefresh(name)
}
tokens.append(token)
}
for block in blocks { block.start() }
}
func applicationWillTerminate(_ notification: Notification) {
for block in blocks { block.stop() }
for token in tokens { Notifier.cancel(token) }
}
/// Called from a Darwin notification handler. Marked `nonisolated` because
/// libnotify's delivery contract isn't statically visible to Swift, so we
/// hop back to the main actor explicitly.
nonisolated func handleRefresh(_ name: String) {
Task { @MainActor [weak self] in
guard let self else { return }
for block in self.blocks where block.name == name {
block.runScript()
}
}
}
}
|