import Foundation
|
|
public enum MinimizedWindowFallbackPolicy {
|
public static let syntheticWindowIDMarker: UInt32 = 0x8000_0000
|
|
public static func shouldCreateAXOnlyFallback(hasCGWindowID: Bool, isMinimized: Bool) -> Bool {
|
!hasCGWindowID && isMinimized
|
}
|
|
public static func isSyntheticWindow(_ window: AlignerWindow) -> Bool {
|
window.identifierSource == .syntheticAX
|
}
|
|
public static func syntheticWindowID(
|
processIdentifier: Int32,
|
windowIndex: Int,
|
title: String,
|
subroleDescription: String,
|
occupiedWindowIDs: Set<UInt32> = []
|
) -> UInt32 {
|
let key = "\(processIdentifier)|\(windowIndex)|\(title)|\(subroleDescription)"
|
var candidate = syntheticWindowIDMarker | (fnv1a32(key) & ~syntheticWindowIDMarker)
|
|
while candidate == 0 || occupiedWindowIDs.contains(candidate) {
|
candidate = syntheticWindowIDMarker | ((candidate &+ 1) & ~syntheticWindowIDMarker)
|
}
|
|
return candidate
|
}
|
|
private static func fnv1a32(_ value: String) -> UInt32 {
|
var hash: UInt32 = 2_166_136_261
|
for byte in value.utf8 {
|
hash ^= UInt32(byte)
|
hash = hash &* 16_777_619
|
}
|
return hash
|
}
|
}
|