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)) } ) } }