From 9c898b0ca61c090e5e327f750f6c73e28475e10b Mon Sep 17 00:00:00 2001
From: Ariver <shanghai3168@gmail.com>
Date: Fri, 12 Jun 2026 19:30:19 +0800
Subject: [PATCH] Fix space filter visual and close verification

---
 C1.source/Sources/Aligner/Infrastructure/PrivateAPI/SkyLightSpaceEnumerator.swift |   93 ++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 93 insertions(+), 0 deletions(-)

diff --git a/C1.source/Sources/Aligner/Infrastructure/PrivateAPI/SkyLightSpaceEnumerator.swift b/C1.source/Sources/Aligner/Infrastructure/PrivateAPI/SkyLightSpaceEnumerator.swift
index 3a6065f..b5d9206 100644
--- a/C1.source/Sources/Aligner/Infrastructure/PrivateAPI/SkyLightSpaceEnumerator.swift
+++ b/C1.source/Sources/Aligner/Infrastructure/PrivateAPI/SkyLightSpaceEnumerator.swift
@@ -25,11 +25,20 @@
     private typealias CGSMainConnectionIDFunction = @convention(c) () -> UInt32
     private typealias CGSCopyManagedDisplaySpacesFunction = @convention(c) (UInt32) -> Unmanaged<CFArray>?
     private typealias CGSCopySpacesForWindowsFunction = @convention(c) (UInt32, UInt32, CFArray) -> Unmanaged<CFArray>?
+    private typealias CGSCopyWindowsWithOptionsAndTagsFunction = @convention(c) (
+        UInt32,
+        Int,
+        CFArray,
+        Int,
+        UnsafeMutablePointer<Int>,
+        UnsafeMutablePointer<Int>
+    ) -> Unmanaged<CFArray>?
 
     private let handle: UnsafeMutableRawPointer?
     private let mainConnectionID: CGSMainConnectionIDFunction
     private let copyManagedDisplaySpaces: CGSCopyManagedDisplaySpacesFunction
     private let copySpacesForWindows: CGSCopySpacesForWindowsFunction?
+    private let copyWindowsWithOptionsAndTags: CGSCopyWindowsWithOptionsAndTagsFunction?
 
     init() throws {
         guard let handle = dlopen("/System/Library/PrivateFrameworks/SkyLight.framework/SkyLight", RTLD_LAZY) else {
@@ -40,6 +49,7 @@
         self.mainConnectionID = try Self.symbol("CGSMainConnectionID", in: handle)
         self.copyManagedDisplaySpaces = try Self.symbol("CGSCopyManagedDisplaySpaces", in: handle)
         self.copySpacesForWindows = try? Self.symbol("CGSCopySpacesForWindows", in: handle)
+        self.copyWindowsWithOptionsAndTags = try? Self.symbol("CGSCopyWindowsWithOptionsAndTags", in: handle)
     }
 
     deinit {
@@ -115,6 +125,27 @@
     }
 
     func spaceIDsByWindowID(windowIDs: [UInt32]) -> [UInt32: [UInt64]] {
+        let directSpaceIDsByWindowID = directSpaceIDsByWindowID(windowIDs: windowIDs)
+        guard let orderedSpaceIDs = try? allManagedSpaceIDs(),
+              !orderedSpaceIDs.isEmpty
+        else {
+            return directSpaceIDsByWindowID
+        }
+
+        let windowIDsBySpaceID = windowIDsBySpaceID(spaceIDs: orderedSpaceIDs)
+        guard !windowIDsBySpaceID.isEmpty else {
+            return directSpaceIDsByWindowID
+        }
+
+        return WindowSpaceMappingPolicy.mergedSpaceIDsByWindowID(
+            requestedWindowIDs: windowIDs,
+            directSpaceIDsByWindowID: directSpaceIDsByWindowID,
+            windowIDsBySpaceID: windowIDsBySpaceID,
+            orderedSpaceIDs: orderedSpaceIDs
+        )
+    }
+
+    private func directSpaceIDsByWindowID(windowIDs: [UInt32]) -> [UInt32: [UInt64]] {
         guard let copySpacesForWindows else { return [:] }
 
         let connectionID = mainConnectionID()
@@ -138,6 +169,53 @@
 
         return result
     }
+
+    private func allManagedSpaceIDs() throws -> [UInt64] {
+        try managedDisplaySpaceRecords()
+            .flatMap { displayRecord -> [UInt64] in
+                let spaceRecords = displayRecord["Spaces"] as? [[String: Any]] ?? []
+                return spaceRecords.compactMap { spaceRecord in
+                    uint64Value(spaceRecord["id64"] ?? spaceRecord["id"])
+                }
+            }
+    }
+
+    private func windowIDsBySpaceID(spaceIDs: [UInt64]) -> [UInt64: [UInt32]] {
+        guard let copyWindowsWithOptionsAndTags else { return [:] }
+
+        let connectionID = mainConnectionID()
+        let options = Self.copyWindowsOptionIncludeInvisible
+        var result: [UInt64: [UInt32]] = [:]
+
+        for spaceID in spaceIDs {
+            let spaceIDArray = [NSNumber(value: spaceID)] as CFArray
+            var setTags = 0
+            var clearTags = 0
+            guard let unmanagedWindows = copyWindowsWithOptionsAndTags(
+                connectionID,
+                0,
+                spaceIDArray,
+                options,
+                &setTags,
+                &clearTags
+            ) else {
+                continue
+            }
+
+            let windowIDs = (unmanagedWindows.takeRetainedValue() as? [Any] ?? [])
+                .compactMap { item -> UInt32? in
+                    uint32Value(item)
+                }
+
+            if !windowIDs.isEmpty {
+                result[spaceID] = windowIDs
+            }
+        }
+
+        return result
+    }
+
+    private static let copyWindowsOptionIncludeInvisible = (1 << 0) | (1 << 1) | (1 << 2)
 
     private static func symbol<T>(_ name: String, in handle: UnsafeMutableRawPointer) throws -> T {
         guard let rawSymbol = dlsym(handle, name) else {
@@ -217,3 +295,18 @@
         return nil
     }
 }
+
+private func uint32Value(_ value: Any?) -> UInt32? {
+    switch value {
+    case let number as NSNumber:
+        return number.uint32Value
+    case let uint32 as UInt32:
+        return uint32
+    case let uint as UInt where uint <= UInt(UInt32.max):
+        return UInt32(uint)
+    case let int as Int where int >= 0 && int <= Int(UInt32.max):
+        return UInt32(int)
+    default:
+        return nil
+    }
+}

--
Gitblit v1.9.3