Atoll/DynamicIsland/managers/LockScreenDisplayContextProvider.swift
2026-01-09 12:32:00 +05:30

83 lines
2.3 KiB
Swift

import AppKit
struct LockScreenDisplayContext {
let screen: NSScreen
let frame: NSRect
let identifier: String
}
@MainActor
final class LockScreenDisplayContextProvider {
static let shared = LockScreenDisplayContextProvider()
private(set) var context: LockScreenDisplayContext?
private var screenChangeObserver: NSObjectProtocol?
private var workspaceObservers: [NSObjectProtocol] = []
private init() {
refresh(reason: "init")
registerObservers()
}
deinit {
if let screenChangeObserver {
NotificationCenter.default.removeObserver(screenChangeObserver)
}
let workspaceCenter = NSWorkspace.shared.notificationCenter
workspaceObservers.forEach { workspaceCenter.removeObserver($0) }
}
@discardableResult
func refresh(reason: String) -> LockScreenDisplayContext? {
guard let screen = NSScreen.main ?? NSScreen.screens.first else {
context = nil
return nil
}
let snapshot = LockScreenDisplayContext(
screen: screen,
frame: screen.frame,
identifier: screen.localizedName
)
context = snapshot
return snapshot
}
func contextSnapshot() -> LockScreenDisplayContext? {
if let context {
return context
}
return refresh(reason: "snapshot-miss")
}
private func registerObservers() {
screenChangeObserver = NotificationCenter.default.addObserver(
forName: NSApplication.didChangeScreenParametersNotification,
object: nil,
queue: .main
) { [weak self] _ in
self?.refresh(reason: "screen-parameters")
}
let workspaceCenter = NSWorkspace.shared.notificationCenter
let wakeObserver = workspaceCenter.addObserver(
forName: NSWorkspace.screensDidWakeNotification,
object: nil,
queue: .main
) { [weak self] _ in
self?.refresh(reason: "screens-did-wake")
}
let spaceObserver = workspaceCenter.addObserver(
forName: NSWorkspace.activeSpaceDidChangeNotification,
object: nil,
queue: .main
) { [weak self] _ in
self?.refresh(reason: "space-changed")
}
workspaceObservers = [wakeObserver, spaceObserver]
}
}