From fe5c1fa0d397938511e6102bbe5562f03f02607f Mon Sep 17 00:00:00 2001
From: Ariver <shanghai3168@gmail.com>
Date: Wed, 10 Jun 2026 16:40:24 +0800
Subject: [PATCH] Fix Quick Switch space mapping fallback

---
 C1.source/Tests/AlignerCoreTests/AlignerCoreTests.swift |  198 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 196 insertions(+), 2 deletions(-)

diff --git a/C1.source/Tests/AlignerCoreTests/AlignerCoreTests.swift b/C1.source/Tests/AlignerCoreTests/AlignerCoreTests.swift
index 9eca644..a6c3447 100644
--- a/C1.source/Tests/AlignerCoreTests/AlignerCoreTests.swift
+++ b/C1.source/Tests/AlignerCoreTests/AlignerCoreTests.swift
@@ -212,12 +212,25 @@
         let record = makeWindowRecord(
             title: "Closed Document.md",
             hasAXBacking: false,
-            isOnscreen: false,
-            spaceIDs: [5]
+            isOnscreen: false
         )
 
         XCTAssertFalse(WindowEnumerationPolicy.shouldInclude(record))
         XCTAssertNil(WindowEnumerationPolicy.window(from: record))
+    }
+
+    func testWindowEnumerationPolicyKeepsCGOnlyOffscreenWindowsWithKnownSpaceIDs() {
+        let record = makeWindowRecord(
+            title: "Other Space Document.md",
+            hasAXBacking: false,
+            isOnscreen: false,
+            spaceIDs: [5]
+        )
+
+        let window = WindowEnumerationPolicy.window(from: record)
+
+        XCTAssertEqual(window?.title, "Other Space Document.md")
+        XCTAssertEqual(window?.spaceIDs, [5])
     }
 
     func testWindowEnumerationPolicyKeepsAXBackedOffscreenWindows() {
@@ -242,6 +255,126 @@
         let window = WindowEnumerationPolicy.window(from: record)
 
         XCTAssertEqual(window?.title, "Visible Document.md")
+    }
+
+    func testWindowEnumerationPolicyKeepsKnownCGOnlyOffscreenMainWindows() {
+        let hbuilderApp = AlignerApp(
+            bundleIdentifier: "io.dcloud.HBuilderX",
+            name: "HBuilderX",
+            category: .editorIDE
+        )
+        let record = WindowEnumerationRecord(
+            id: 55_388,
+            app: hbuilderApp,
+            title: "lm-app - HBuilder X 5.07",
+            size: CGSize(width: 1048, height: 796),
+            subrole: .standard,
+            hasAXBacking: false,
+            isOnscreen: false
+        )
+        let emptyTitleRecord = WindowEnumerationRecord(
+            id: 55_389,
+            app: hbuilderApp,
+            title: "",
+            size: CGSize(width: 1048, height: 796),
+            subrole: .standard,
+            hasAXBacking: false,
+            isOnscreen: false
+        )
+        let tinyRecord = WindowEnumerationRecord(
+            id: 55_390,
+            app: hbuilderApp,
+            title: "HBuilderX Utility",
+            size: CGSize(width: 80, height: 40),
+            subrole: .standard,
+            hasAXBacking: false,
+            isOnscreen: false
+        )
+
+        XCTAssertEqual(WindowEnumerationPolicy.window(from: record)?.title, "lm-app - HBuilder X 5.07")
+        XCTAssertNil(WindowEnumerationPolicy.window(from: emptyTitleRecord))
+        XCTAssertNil(WindowEnumerationPolicy.window(from: tinyRecord))
+    }
+
+    func testWindowEnumerationPolicyExcludesClosedShottrCGPlaceholderButKeepsVisibleWindow() {
+        let shottrApp = AlignerApp(
+            bundleIdentifier: "cc.ffitch.shottr",
+            name: "Shottr",
+            category: .generic
+        )
+        let closedPlaceholderRecord = WindowEnumerationRecord(
+            id: 78,
+            app: shottrApp,
+            activationPolicy: .accessory,
+            title: "Shottr",
+            size: CGSize(width: 1710, height: 997),
+            subrole: .standard,
+            hasAXBacking: false,
+            isOnscreen: false
+        )
+        let visibleRecord = WindowEnumerationRecord(
+            id: 79,
+            app: shottrApp,
+            activationPolicy: .accessory,
+            title: "Shottr",
+            size: CGSize(width: 1710, height: 997),
+            subrole: .standard,
+            hasAXBacking: false,
+            isOnscreen: true
+        )
+        let utilityRecord = WindowEnumerationRecord(
+            id: 102,
+            app: shottrApp,
+            activationPolicy: .accessory,
+            title: "Colors",
+            size: CGSize(width: 250, height: 397),
+            subrole: .standard,
+            hasAXBacking: false,
+            isOnscreen: false
+        )
+
+        XCTAssertNil(WindowEnumerationPolicy.window(from: closedPlaceholderRecord))
+        XCTAssertEqual(WindowEnumerationPolicy.window(from: visibleRecord)?.title, "Shottr")
+        XCTAssertNil(WindowEnumerationPolicy.window(from: utilityRecord))
+    }
+
+    func testWindowEnumerationPolicyKeepsFinderCGOnlyOffscreenMainWindows() {
+        let finderApp = AlignerApp(
+            bundleIdentifier: "com.apple.finder",
+            name: "访达",
+            category: .finder
+        )
+        let record = WindowEnumerationRecord(
+            id: 83_664,
+            app: finderApp,
+            title: "Screencapture",
+            size: CGSize(width: 920, height: 436),
+            subrole: .standard,
+            hasAXBacking: false,
+            isOnscreen: false
+        )
+        let emptyTitleRecord = WindowEnumerationRecord(
+            id: 83_665,
+            app: finderApp,
+            title: "",
+            size: CGSize(width: 920, height: 436),
+            subrole: .standard,
+            hasAXBacking: false,
+            isOnscreen: false
+        )
+        let tinyRecord = WindowEnumerationRecord(
+            id: 83_666,
+            app: finderApp,
+            title: "Finder Utility",
+            size: CGSize(width: 80, height: 40),
+            subrole: .standard,
+            hasAXBacking: false,
+            isOnscreen: false
+        )
+
+        XCTAssertEqual(WindowEnumerationPolicy.window(from: record)?.title, "Screencapture")
+        XCTAssertNil(WindowEnumerationPolicy.window(from: emptyTitleRecord))
+        XCTAssertNil(WindowEnumerationPolicy.window(from: tinyRecord))
     }
 
     func testWindowEnumerationPolicyKeepsMinimizedAndFullscreenCGOnlyOffscreenWindows() {
@@ -1041,6 +1174,50 @@
         XCTAssertEqual(snapshot.appGroups.single?.windows.map(\.primarySpaceID), [10, 11, 12, 12, nil])
     }
 
+    func testWindowSpaceMappingFillsUnresolvedWindowsFromSpaceInverseMap() {
+        let mapping = WindowSpaceMappingPolicy.mergedSpaceIDsByWindowID(
+            requestedWindowIDs: [10, 20, 30],
+            directSpaceIDsByWindowID: [10: [100]],
+            windowIDsBySpaceID: [
+                100: [10, 20],
+                101: [30]
+            ],
+            orderedSpaceIDs: [100, 101]
+        )
+
+        XCTAssertEqual(mapping[10], [100])
+        XCTAssertEqual(mapping[20], [100])
+        XCTAssertEqual(mapping[30], [101])
+    }
+
+    func testWindowSpaceMappingDoesNotOverwriteDirectSpaceAssignments() {
+        let mapping = WindowSpaceMappingPolicy.mergedSpaceIDsByWindowID(
+            requestedWindowIDs: [10],
+            directSpaceIDsByWindowID: [10: [101]],
+            windowIDsBySpaceID: [
+                100: [10]
+            ],
+            orderedSpaceIDs: [100, 101]
+        )
+
+        XCTAssertEqual(mapping[10], [101])
+    }
+
+    func testWindowSpaceMappingLeavesAmbiguousNoSpaceWindowsUnassigned() {
+        let mapping = WindowSpaceMappingPolicy.mergedSpaceIDsByWindowID(
+            requestedWindowIDs: [10, 20],
+            directSpaceIDsByWindowID: [:],
+            windowIDsBySpaceID: [
+                100: [10, 99]
+            ],
+            orderedSpaceIDs: [100]
+        )
+
+        XCTAssertEqual(mapping[10], [100])
+        XCTAssertNil(mapping[20])
+        XCTAssertNil(mapping[99])
+    }
+
     func testQuickSwitchSnapshotKeepsMinimizedAndFullscreenWindows() {
         let app = makeApp()
         let snapshot = QuickSwitchSnapshotBuilder.snapshot(
@@ -1085,6 +1262,23 @@
         XCTAssertEqual(viewModel.initialSelection, QuickSwitchSelection(appGroupIndex: 0, windowIndex: 0, windowID: 1))
     }
 
+    func testQuickSwitchViewModelBuilderUsesNumericSpaceLabelsForSingleDisplay() {
+        let app = AlignerApp(bundleIdentifier: "com.example.Alpha", name: "Alpha", category: .generic)
+        let snapshot = QuickSwitchSnapshotBuilder.snapshot(
+            displays: [makeDisplay(spaceIDs: [10, 11, 12])],
+            windows: [
+                AlignerWindow(id: 1, app: app, title: "A1", spaceIDs: [10]),
+                AlignerWindow(id: 2, app: app, title: "A2", spaceIDs: [11])
+            ]
+        )
+
+        let viewModel = QuickSwitchViewModelBuilder.viewModel(from: snapshot, currentSpaceIDs: [11])
+
+        XCTAssertEqual(viewModel.displays.flatMap { $0.spaces.map(\.label) }, ["01", "02", "03"])
+        XCTAssertEqual(viewModel.displays.flatMap { $0.spaces.filter(\.isCurrent).map(\.label) }, ["02"])
+        XCTAssertEqual(viewModel.waterfallColumns.flatMap { $0.windows.map(\.primarySpaceLabel) }, ["01", "02"])
+    }
+
     func testQuickSwitchFocusPolicySelectsFirstStableWindowInitially() {
         let app = makeApp()
         let snapshot = QuickSwitchSnapshotBuilder.snapshot(

--
Gitblit v1.9.3