refresh the bars on screen changes

This commit is contained in:
2026-07-12 19:51:42 +02:00
parent 27fad1d67c
commit 3c5222d800
6 changed files with 305 additions and 49 deletions
+31
View File
@@ -0,0 +1,31 @@
import AppKit
/// Which screens to keep, remove, or add when reconciling live bars against the
/// current `NSScreen.screens`.
///
/// Pure and identity-based (it never reads `NSScreen` properties), so it can be
/// unit-tested with any `[NSScreen]` without driving real window lifecycle.
enum PHScreenSync {
struct Diff: Equatable {
/// Screens that already have a bar and are still attached. Their window
/// frame is recomputed since geometry may have changed.
let kept: [NSScreen]
/// Screens whose bar must be torn down (monitor disconnected).
let removed: [NSScreen]
/// Screens with no bar yet that need one (monitor connected).
let added: [NSScreen]
}
/// Compare the screens now attached (`current`) against the screens currently
/// occupied by bars (`occupied`). A disconnected monitor reappears as a new
/// `NSScreen` instance, so it is reported as remove + add, never a keep.
static func diff(current: [NSScreen], occupied: [NSScreen]) -> Diff {
let currentIDs = Set(current.map(ObjectIdentifier.init))
let occupiedIDs = Set(occupied.map(ObjectIdentifier.init))
return Diff(
kept: occupied.filter { currentIDs.contains(ObjectIdentifier($0)) },
removed: occupied.filter { !currentIDs.contains(ObjectIdentifier($0)) },
added: current.filter { !occupiedIDs.contains(ObjectIdentifier($0)) }
)
}
}