SecureEventInputSputnik // Also monitor hibernation status.

This commit is contained in:
ShikiSuen 2024-01-30 13:49:49 +08:00
parent 6b0353107f
commit 85833c40d9
1 changed files with 85 additions and 29 deletions

View File

@ -66,15 +66,27 @@ public class SecureEventInputSputnik {
} }
} }
public extension NSWorkspace {
struct ActivationFlags: OptionSet {
public let rawValue: Int
public init(rawValue: Int) {
self.rawValue = rawValue
}
public static let hibernating = ActivationFlags(rawValue: 1 << 0)
public static let desktopLocked = ActivationFlags(rawValue: 1 << 1)
public static let sesssionSwitchedOut = ActivationFlags(rawValue: 1 << 2)
public static let screenSaverRunning = ActivationFlags(rawValue: 1 << 3)
}
static var activationFlags: ActivationFlags = []
}
public extension NSRunningApplication { public extension NSRunningApplication {
var isLoginWindowWithLockedScreenOrScreenSaver: Bool { var isLoginWindowWithLockedScreenOrScreenSaver: Bool {
guard bundleIdentifier == "com.apple.loginwindow" else { return false } guard bundleIdentifier == "com.apple.loginwindow" else { return false }
return Self.isScreenSaverEngineRunning || Self.isDesktopLocked return !NSWorkspace.activationFlags.isEmpty
} }
fileprivate(set) static var isScreenSaverEngineRunning: Bool = false
fileprivate(set) static var isDesktopLocked: Bool = false
} }
extension SecureEventInputSputnik { extension SecureEventInputSputnik {
@ -87,41 +99,85 @@ extension SecureEventInputSputnik {
if #available(macOS 10.15, *) { if #available(macOS 10.15, *) {
DistributedNotificationCenter.default() DistributedNotificationCenter.default()
.publisher(for: .init(rawValue: "com.apple.screenIsLocked")) .publisher(for: .init(rawValue: "com.apple.screenIsLocked"))
.sink { _ in NSRunningApplication.isDesktopLocked = true } .sink { _ in NSWorkspace.activationFlags.insert(.desktopLocked) }
.store(in: &Self.combinePool) .store(in: &Self.combinePool)
DistributedNotificationCenter.default() DistributedNotificationCenter.default()
.publisher(for: .init(rawValue: "com.apple.screenIsUnlocked")) .publisher(for: .init(rawValue: "com.apple.screenIsUnlocked"))
.sink { _ in NSRunningApplication.isDesktopLocked = false } .sink { _ in NSWorkspace.activationFlags.remove(.desktopLocked) }
.store(in: &Self.combinePool) .store(in: &Self.combinePool)
DistributedNotificationCenter.default() DistributedNotificationCenter.default()
.publisher(for: .init(rawValue: "com.apple.screensaver.didstart")) .publisher(for: .init(rawValue: "com.apple.screensaver.didstart"))
.sink { _ in NSRunningApplication.isScreenSaverEngineRunning = true } .sink { _ in NSWorkspace.activationFlags.insert(.screenSaverRunning) }
.store(in: &Self.combinePool) .store(in: &Self.combinePool)
DistributedNotificationCenter.default() DistributedNotificationCenter.default()
.publisher(for: .init(rawValue: "com.apple.screensaver.didstop")) .publisher(for: .init(rawValue: "com.apple.screensaver.didstop"))
.sink { _ in NSRunningApplication.isScreenSaverEngineRunning = false } .sink { _ in NSWorkspace.activationFlags.remove(.screenSaverRunning) }
.store(in: &Self.combinePool)
NSWorkspace.shared.notificationCenter
.publisher(for: NSWorkspace.willSleepNotification)
.sink { _ in NSWorkspace.activationFlags.insert(.hibernating) }
.store(in: &Self.combinePool)
NSWorkspace.shared.notificationCenter
.publisher(for: NSWorkspace.didWakeNotification)
.sink { _ in NSWorkspace.activationFlags.remove(.hibernating) }
.store(in: &Self.combinePool)
NSWorkspace.shared.notificationCenter
.publisher(for: NSWorkspace.sessionDidResignActiveNotification)
.sink { _ in NSWorkspace.activationFlags.insert(.sesssionSwitchedOut) }
.store(in: &Self.combinePool)
NSWorkspace.shared.notificationCenter
.publisher(for: NSWorkspace.sessionDidBecomeActiveNotification)
.sink { _ in NSWorkspace.activationFlags.remove(.sesssionSwitchedOut) }
.store(in: &Self.combinePool) .store(in: &Self.combinePool)
} else { } else {
let lockObserver = DistributedNotificationCenter.default() Self.combinePoolCocoa.append(
.addObserver(forName: .init("com.apple.screenIsLocked"), object: nil, queue: .main) { _ in DistributedNotificationCenter.default()
NSRunningApplication.isDesktopLocked = true .addObserver(forName: .init("com.apple.screenIsLocked"), object: nil, queue: .main) { _ in
} NSWorkspace.activationFlags.insert(.desktopLocked)
let unlockObserver = DistributedNotificationCenter.default() }
.addObserver(forName: .init("com.apple.screenIsUnlocked"), object: nil, queue: .main) { _ in )
NSRunningApplication.isDesktopLocked = false Self.combinePoolCocoa.append(
} DistributedNotificationCenter.default()
let screenSaverDidStart = DistributedNotificationCenter.default() .addObserver(forName: .init("com.apple.screenIsUnlocked"), object: nil, queue: .main) { _ in
.addObserver(forName: .init("com.apple.screensaver.didstart"), object: nil, queue: .main) { _ in NSWorkspace.activationFlags.remove(.desktopLocked)
NSRunningApplication.isScreenSaverEngineRunning = true }
} )
let screenSaverDidStop = DistributedNotificationCenter.default() Self.combinePoolCocoa.append(
.addObserver(forName: .init("com.apple.screensaver.didstop"), object: nil, queue: .main) { _ in DistributedNotificationCenter.default()
NSRunningApplication.isScreenSaverEngineRunning = false .addObserver(forName: .init("com.apple.screensaver.didstart"), object: nil, queue: .main) { _ in
} NSWorkspace.activationFlags.insert(.screenSaverRunning)
Self.combinePoolCocoa.append(lockObserver) }
Self.combinePoolCocoa.append(unlockObserver) )
Self.combinePoolCocoa.append(screenSaverDidStart) Self.combinePoolCocoa.append(
Self.combinePoolCocoa.append(screenSaverDidStop) DistributedNotificationCenter.default()
.addObserver(forName: .init("com.apple.screensaver.didstop"), object: nil, queue: .main) { _ in
NSWorkspace.activationFlags.remove(.screenSaverRunning)
}
)
Self.combinePoolCocoa.append(
NSWorkspace.shared.notificationCenter
.addObserver(forName: NSWorkspace.willSleepNotification, object: nil, queue: .main) { _ in
NSWorkspace.activationFlags.insert(.hibernating)
}
)
Self.combinePoolCocoa.append(
NSWorkspace.shared.notificationCenter
.addObserver(forName: NSWorkspace.didWakeNotification, object: nil, queue: .main) { _ in
NSWorkspace.activationFlags.remove(.hibernating)
}
)
Self.combinePoolCocoa.append(
NSWorkspace.shared.notificationCenter
.addObserver(forName: NSWorkspace.sessionDidResignActiveNotification, object: nil, queue: .main) { _ in
NSWorkspace.activationFlags.insert(.sesssionSwitchedOut)
}
)
Self.combinePoolCocoa.append(
NSWorkspace.shared.notificationCenter
.addObserver(forName: NSWorkspace.sessionDidBecomeActiveNotification, object: nil, queue: .main) { _ in
NSWorkspace.activationFlags.remove(.sesssionSwitchedOut)
}
)
} }
} }
} }