aboutsummaryrefslogtreecommitdiff
path: root/Sources/phbar/Models/Notifier.swift
diff options
context:
space:
mode:
authorTommaso Negri <me@tommasongr.com>2026-08-09 23:58:42 +0200
committerTommaso Negri <me@tommasongr.com>2026-08-09 23:58:44 +0200
commitd59b22e557fa5d69ea6be725a7e5bcd829588225 (patch)
tree618e20ef2b648e46eac3d51e14b8e0fcc1faba3c /Sources/phbar/Models/Notifier.swift
parent62ce97dcb63d61c8db739c1b32bd387042ca66a0 (diff)
downloadbar-d59b22e557fa5d69ea6be725a7e5bcd829588225.tar.gz
bar-d59b22e557fa5d69ea6be725a7e5bcd829588225.zip
rename project and add documentation guides
Diffstat (limited to 'Sources/phbar/Models/Notifier.swift')
-rw-r--r--Sources/phbar/Models/Notifier.swift90
1 files changed, 0 insertions, 90 deletions
diff --git a/Sources/phbar/Models/Notifier.swift b/Sources/phbar/Models/Notifier.swift
deleted file mode 100644
index a428c49..0000000
--- a/Sources/phbar/Models/Notifier.swift
+++ /dev/null
@@ -1,90 +0,0 @@
-import Foundation
-
-/// Retains the handler for the lifetime of the registration.
-///
-/// The raw pointer returned by ``Notifier/register(_:handler:)``
-/// is a retained reference to this box; it is released when
-/// the registration is cancelled.
-private final class NotifyBox {
- let handler: @Sendable () -> Void
- init(_ handler: @escaping @Sendable () -> Void) { self.handler = handler }
-}
-
-/// Delivers refresh triggers via Darwin notifications.
-///
-/// Wraps CoreFoundation notifications — the macOS-native,
-/// signal-like way to trigger behaviour from the shell with
-/// no client binary, using `notifyutil`:
-///
-/// ```
-/// notifyutil -p <prefix><name>
-/// ```
-///
-/// Each category of events uses a different ``prefix``
-/// to avoid collisions. For example, block refresh
-/// notifications use ``touchPrefix``:
-///
-/// ```
-/// notifyutil -p house.panini.phbar.touch.<name>
-/// ```
-///
-/// > Note: `notify.h` isn't part of Swift's Darwin module,
-/// > so we go through `CFNotificationCenter`, which talks
-/// > to the same subsystem.
-/// >
-/// > The callback fires on an arbitrary thread; handlers
-/// > must hop to the main actor themselves (see ``AppDelegate``).
-enum Notifier {
- /// Prefix for block refresh notifications.
- ///
- /// Use `notifyutil -p house.panini.phbar.touch.<name>` to trigger
- /// a block update from the shell.
- static let touchPrefix = "house.panini.phbar.touch."
-
- /// Register `handler` to fire whenever the notification is posted.
- ///
- /// - Parameters:
- /// - name: The notification name suffix.
- /// - prefix: The full notification name will be `prefix + name`.
- /// Defaults to ``touchPrefix``.
- /// - handler: Closure to invoke when the notification fires.
- ///
- /// The returned token is a retained pointer used to keep the handler
- /// alive and to cancel the registration later. The handler runs on an
- /// arbitrary thread, so hop to the main actor inside it if you touch
- /// UI or published state.
- @discardableResult
- static func register(
- _ name: String,
- prefix: String = Notifier.touchPrefix,
- handler: @escaping @Sendable () -> Void
- ) -> UnsafeMutableRawPointer {
- let fullName = prefix + name
- let ctx = Unmanaged.passRetained(NotifyBox(handler)).toOpaque()
-
- CFNotificationCenterAddObserver(
- CFNotificationCenterGetDarwinNotifyCenter(),
- ctx,
- { _, observer, _, _, _ in
- guard let observer else { return }
- let box = Unmanaged<NotifyBox>.fromOpaque(observer).takeUnretainedValue()
- box.handler()
- },
- fullName as CFString,
- nil,
- .deliverImmediately
- )
-
- return ctx
- }
-
- /// Remove and release a registration.
- ///
- /// Pass the token returned by ``Notifier/register(_:handler:)``.
- /// Optional: process exit clears all pending registrations anyway.
- static func cancel(_ token: UnsafeMutableRawPointer) {
- let center = CFNotificationCenterGetDarwinNotifyCenter()
- CFNotificationCenterRemoveEveryObserver(center, token)
- Unmanaged<NotifyBox>.fromOpaque(token).release()
- }
-}