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