Ariver
2026-06-12 63128a870cbedb841cb19cdfbf2bf54e3dfbc25c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import AppKit
import CoreGraphics
import AlignerCore
 
struct SystemCriticalWindowRecord: Equatable {
    let ownerName: String
    let title: String
    let processIdentifier: Int32
    let layer: Int
    let bounds: CGRect
}
 
protocol SystemCriticalWindowDetecting: AnyObject {
    func visibleSystemCriticalWindows() -> [SystemCriticalWindowRecord]
}
 
final class CGWindowSystemCriticalWindowDetector: SystemCriticalWindowDetecting {
    func visibleSystemCriticalWindows() -> [SystemCriticalWindowRecord] {
        guard let windowInfo = CGWindowListCopyWindowInfo(
            [.optionOnScreenOnly, .excludeDesktopElements],
            kCGNullWindowID
        ) as? [[String: Any]] else {
            return []
        }
 
        return windowInfo.compactMap { rawWindow in
            let ownerName = stringValue(rawWindow[kCGWindowOwnerName as String]) ?? ""
            guard ownerName != "Aligner" else { return nil }
 
            let title = stringValue(rawWindow[kCGWindowName as String]) ?? ""
            let descriptor = SystemCriticalWindowDescriptor(ownerName: ownerName, title: title)
            guard SystemCriticalWindowClassifier.isSystemCritical(descriptor) else {
                return nil
            }
 
            let bounds = rectValue(rawWindow[kCGWindowBounds as String])
            guard bounds.width > 0, bounds.height > 0 else { return nil }
 
            return SystemCriticalWindowRecord(
                ownerName: ownerName,
                title: title,
                processIdentifier: Int32(intValue(rawWindow[kCGWindowOwnerPID as String])),
                layer: intValue(rawWindow[kCGWindowLayer as String]),
                bounds: bounds
            )
        }
    }
 
    private func stringValue(_ value: Any?) -> String? {
        value as? String
    }
 
    private func intValue(_ value: Any?) -> Int {
        switch value {
        case let number as NSNumber:
            return number.intValue
        case let int as Int:
            return int
        default:
            return 0
        }
    }
 
    private func doubleValue(_ value: Any?) -> Double {
        switch value {
        case let number as NSNumber:
            return number.doubleValue
        case let double as Double:
            return double
        case let int as Int:
            return Double(int)
        default:
            return 0
        }
    }
 
    private func rectValue(_ value: Any?) -> CGRect {
        guard let dictionary = value as? [String: Any] else {
            return .zero
        }
 
        return CGRect(
            x: doubleValue(dictionary["X"]),
            y: doubleValue(dictionary["Y"]),
            width: doubleValue(dictionary["Width"]),
            height: doubleValue(dictionary["Height"])
        )
    }
}