From 81b5a5f847e74fe1106829b13db2cccda8dd5798 Mon Sep 17 00:00:00 2001
From: Ariver <shanghai3168@gmail.com>
Date: Fri, 19 Jun 2026 19:48:59 +0800
Subject: [PATCH] Fix horizontal app index key handling

---
 C1.source/Sources/Aligner/QuickSwitchSnapshotLoader.swift |  305 ++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 289 insertions(+), 16 deletions(-)

diff --git a/C1.source/Sources/Aligner/QuickSwitchSnapshotLoader.swift b/C1.source/Sources/Aligner/QuickSwitchSnapshotLoader.swift
index 7421c9f..121e38f 100644
--- a/C1.source/Sources/Aligner/QuickSwitchSnapshotLoader.swift
+++ b/C1.source/Sources/Aligner/QuickSwitchSnapshotLoader.swift
@@ -1,3 +1,4 @@
+import CoreGraphics
 import Foundation
 import AlignerCore
 
@@ -14,6 +15,9 @@
     case layout
     case candidateFiltering
     case activation
+    case spaceFilter
+    case splitView
+    case multiPageIdentity
 }
 
 final class LiveQuickSwitchSnapshotLoader: QuickSwitchSnapshotLoading {
@@ -62,11 +66,18 @@
     private let appCount: Int
     private let windowsPerApp: Int
     private let mode: FixtureQuickSwitchMode
+    private let usesMultipleDisplays: Bool
 
-    init(appCount: Int, windowsPerApp: Int = 1, mode: FixtureQuickSwitchMode = .layout) {
+    init(
+        appCount: Int,
+        windowsPerApp: Int = 1,
+        mode: FixtureQuickSwitchMode = .layout,
+        usesMultipleDisplays: Bool = false
+    ) {
         self.appCount = max(1, appCount)
         self.windowsPerApp = max(1, windowsPerApp)
         self.mode = mode
+        self.usesMultipleDisplays = usesMultipleDisplays
     }
 
     func snapshot() throws -> QuickSwitchSnapshotLoad {
@@ -76,23 +87,22 @@
         if mode == .activation {
             return activationSnapshot()
         }
+        if mode == .spaceFilter {
+            return spaceFilterSnapshot()
+        }
+        if mode == .splitView {
+            return splitViewSnapshot()
+        }
+        if mode == .multiPageIdentity {
+            return multiPageIdentitySnapshot()
+        }
 
         return layoutSnapshot()
     }
 
     private func layoutSnapshot() -> QuickSwitchSnapshotLoad {
-        let displayUUID = "fixture-display-a"
-        let displays = [
-            AlignerDisplay(
-                uuid: displayUUID,
-                physical: true,
-                spaces: [
-                    AlignerSpace(id: 1, type: .user, displayUUID: displayUUID, index: 1),
-                    AlignerSpace(id: 2, type: .fullscreen, displayUUID: displayUUID, index: 2),
-                    AlignerSpace(id: 3, type: .user, displayUUID: displayUUID, index: 3)
-                ]
-            )
-        ]
+        let displays = layoutDisplays()
+        let spaceIDs: [UInt64] = usesMultipleDisplays ? [1, 2, 3, 4, 5] : [1, 2, 3]
         let windows = (0..<appCount).flatMap { index in
             let app = AlignerApp(
                 bundleIdentifier: "com.example.fixture.\(String(format: "%03d", index))",
@@ -103,7 +113,9 @@
 
             return (0..<windowsPerApp).map { windowIndex in
                 let spaceSeed = index + windowIndex
-                let spaceID = spaceSeed % 5 == 0 ? UInt64(2) : UInt64(spaceSeed % 2 == 0 ? 1 : 3)
+                let spaceID = usesMultipleDisplays
+                    ? spaceIDs[spaceSeed % spaceIDs.count]
+                    : UInt64(spaceSeed % 5 == 0 ? 2 : spaceSeed % 2 == 0 ? 1 : 3)
                 return AlignerWindow(
                     id: UInt32(10_000 + index * 100 + windowIndex),
                     app: app,
@@ -116,8 +128,46 @@
 
         return QuickSwitchSnapshotLoad(
             snapshot: QuickSwitchSnapshotBuilder.snapshot(displays: displays, windows: windows),
-            currentSpaceIDs: [2]
+            currentSpaceIDs: usesMultipleDisplays ? [2, 4] : [2]
         )
+    }
+
+    private func layoutDisplays() -> [AlignerDisplay] {
+        let displayAUUID = "fixture-display-a"
+        guard usesMultipleDisplays else {
+            return [
+                AlignerDisplay(
+                    uuid: displayAUUID,
+                    physical: true,
+                    spaces: [
+                        AlignerSpace(id: 1, type: .user, displayUUID: displayAUUID, index: 1),
+                        AlignerSpace(id: 2, type: .fullscreen, displayUUID: displayAUUID, index: 2),
+                        AlignerSpace(id: 3, type: .user, displayUUID: displayAUUID, index: 3)
+                    ]
+                )
+            ]
+        }
+
+        let displayBUUID = "fixture-display-b"
+        return [
+            AlignerDisplay(
+                uuid: displayAUUID,
+                physical: true,
+                spaces: [
+                    AlignerSpace(id: 1, type: .user, displayUUID: displayAUUID, index: 1),
+                    AlignerSpace(id: 2, type: .fullscreen, displayUUID: displayAUUID, index: 2),
+                    AlignerSpace(id: 3, type: .user, displayUUID: displayAUUID, index: 3)
+                ]
+            ),
+            AlignerDisplay(
+                uuid: displayBUUID,
+                physical: true,
+                spaces: [
+                    AlignerSpace(id: 4, type: .user, displayUUID: displayBUUID, index: 1),
+                    AlignerSpace(id: 5, type: .user, displayUUID: displayBUUID, index: 2)
+                ]
+            )
+        ]
     }
 
     private func candidateFilteringSnapshot() -> QuickSwitchSnapshotLoad {
@@ -287,7 +337,7 @@
             WindowEnumerationRecord(
                 id: 20_015,
                 app: app,
-                title: "CG-only Offscreen Rejected",
+                title: "CG-only Space-backed Candidate",
                 size: CGSize(width: 900, height: 600),
                 subrole: .standard,
                 hasAXBacking: false,
@@ -358,4 +408,227 @@
             currentSpaceIDs: [1]
         )
     }
+
+    private func spaceFilterSnapshot() -> QuickSwitchSnapshotLoad {
+        let displayAUUID = "fixture-display-a"
+        let displayBUUID = "fixture-display-b"
+        let displays = [
+            AlignerDisplay(
+                uuid: displayAUUID,
+                physical: true,
+                spaces: [
+                    AlignerSpace(id: 1, type: .user, displayUUID: displayAUUID, index: 1),
+                    AlignerSpace(id: 2, type: .user, displayUUID: displayAUUID, index: 2),
+                    AlignerSpace(id: 3, type: .user, displayUUID: displayAUUID, index: 3)
+                ]
+            ),
+            AlignerDisplay(
+                uuid: displayBUUID,
+                physical: true,
+                spaces: [
+                    AlignerSpace(id: 4, type: .user, displayUUID: displayBUUID, index: 1),
+                    AlignerSpace(id: 5, type: .fullscreen, displayUUID: displayBUUID, index: 2)
+                ]
+            )
+        ]
+
+        let alphaApp = AlignerApp(
+            bundleIdentifier: "com.example.spacefilter.alpha",
+            name: "Alpha Space App",
+            category: .finder,
+            processIdentifier: 50_001
+        )
+        let betaApp = AlignerApp(
+            bundleIdentifier: "com.example.spacefilter.beta",
+            name: "Beta Space App",
+            category: .documentNotes,
+            processIdentifier: 50_002
+        )
+        let fullscreenApp = AlignerApp(
+            bundleIdentifier: "com.example.spacefilter.fullscreen",
+            name: "Fullscreen Solo App",
+            category: .generic,
+            processIdentifier: 50_003
+        )
+        let noSpaceApp = AlignerApp(
+            bundleIdentifier: "com.example.spacefilter.nospace",
+            name: "No Space App",
+            category: .generic,
+            processIdentifier: 50_004
+        )
+
+        let windows = [
+            AlignerWindow(
+                id: 50_101,
+                app: alphaApp,
+                title: "Alpha A1 Primary",
+                spaceIDs: [1]
+            ),
+            AlignerWindow(
+                id: 50_102,
+                app: alphaApp,
+                title: "Alpha A1 Secondary",
+                isMinimized: true,
+                spaceIDs: [1]
+            ),
+            AlignerWindow(
+                id: 50_201,
+                app: betaApp,
+                title: "Beta A1 Shared",
+                spaceIDs: [1]
+            ),
+            AlignerWindow(
+                id: 50_202,
+                app: betaApp,
+                title: "Beta A2 Only",
+                spaceIDs: [2]
+            ),
+            AlignerWindow(
+                id: 50_501,
+                app: fullscreenApp,
+                title: "Fullscreen B2 Solo",
+                isFullscreen: true,
+                spaceIDs: [5]
+            ),
+            AlignerWindow(
+                id: 50_901,
+                app: noSpaceApp,
+                title: "No Space Diagnostic",
+                spaceIDs: []
+            )
+        ]
+
+        return QuickSwitchSnapshotLoad(
+            snapshot: QuickSwitchSnapshotBuilder.snapshot(displays: displays, windows: windows),
+            currentSpaceIDs: [1, 4]
+        )
+    }
+
+    private func splitViewSnapshot() -> QuickSwitchSnapshotLoad {
+        let displayUUID = "fixture-display-a"
+        let displays = [
+            AlignerDisplay(
+                uuid: displayUUID,
+                physical: true,
+                spaces: [
+                    AlignerSpace(id: 1, type: .user, displayUUID: displayUUID, index: 1),
+                    AlignerSpace(id: 2, type: .fullscreen, displayUUID: displayUUID, index: 2),
+                    AlignerSpace(id: 3, type: .fullscreen, displayUUID: displayUUID, index: 3)
+                ]
+            )
+        ]
+
+        let normalApp = AlignerApp(
+            bundleIdentifier: "com.example.split.normal",
+            name: "普通窗口",
+            category: .generic,
+            processIdentifier: 60_001
+        )
+        let leftApp = AlignerApp(
+            bundleIdentifier: "com.example.split.left",
+            name: "左侧应用",
+            category: .finder,
+            processIdentifier: 60_002
+        )
+        let rightApp = AlignerApp(
+            bundleIdentifier: "com.example.split.right",
+            name: "右侧应用",
+            category: .documentNotes,
+            processIdentifier: 60_003
+        )
+        let singleFullscreenApp = AlignerApp(
+            bundleIdentifier: "com.example.split.single",
+            name: "单全屏",
+            category: .generic,
+            processIdentifier: 60_004
+        )
+
+        let windows = [
+            AlignerWindow(
+                id: 60_101,
+                app: normalApp,
+                title: "普通窗口",
+                frame: CGRect(x: 80, y: 120, width: 900, height: 620),
+                spaceIDs: [1]
+            ),
+            AlignerWindow(
+                id: 60_202,
+                app: rightApp,
+                title: "右侧 Split View",
+                isFullscreen: true,
+                frame: CGRect(x: 960, y: 0, width: 960, height: 1080),
+                spaceIDs: [2]
+            ),
+            AlignerWindow(
+                id: 60_201,
+                app: leftApp,
+                title: "左侧 Split View",
+                isFullscreen: true,
+                frame: CGRect(x: 0, y: 0, width: 960, height: 1080),
+                spaceIDs: [2]
+            ),
+            AlignerWindow(
+                id: 60_301,
+                app: singleFullscreenApp,
+                title: "单全屏",
+                isFullscreen: true,
+                frame: CGRect(x: 0, y: 0, width: 1920, height: 1080),
+                spaceIDs: [3]
+            )
+        ]
+
+        return QuickSwitchSnapshotLoad(
+            snapshot: QuickSwitchSnapshotBuilder.snapshot(displays: displays, windows: windows),
+            currentSpaceIDs: [1]
+        )
+    }
+
+    private func multiPageIdentitySnapshot() -> QuickSwitchSnapshotLoad {
+        let displayUUID = "fixture-display-a"
+        let displays = [
+            AlignerDisplay(
+                uuid: displayUUID,
+                physical: true,
+                spaces: [
+                    AlignerSpace(id: 1, type: .user, displayUUID: displayUUID, index: 1)
+                ]
+            )
+        ]
+
+        let app = AlignerApp(
+            bundleIdentifier: "com.example.multipage.identity",
+            name: "Multi Page App",
+            category: .generic,
+            processIdentifier: 70_001
+        )
+
+        let windows = [
+            AlignerWindow(
+                id: 70_101,
+                app: app,
+                title: "Shared Page",
+                frame: CGRect(x: 120, y: 120, width: 920, height: 640),
+                spaceIDs: [1]
+            ),
+            AlignerWindow(
+                id: 70_102,
+                app: app,
+                title: "Shared Page",
+                frame: CGRect(x: 160, y: 140, width: 920, height: 640),
+                spaceIDs: [1]
+            ),
+            AlignerWindow(
+                id: 70_103,
+                app: app,
+                title: "Shared Page",
+                frame: CGRect(x: 200, y: 160, width: 920, height: 640),
+                spaceIDs: [1]
+            )
+        ]
+
+        return QuickSwitchSnapshotLoad(
+            snapshot: QuickSwitchSnapshotBuilder.snapshot(displays: displays, windows: windows),
+            currentSpaceIDs: [1]
+        )
+    }
 }

--
Gitblit v1.9.3