From 86f0b4bd20cdec86dfb5bdb7978d1f6ff4af111a Mon Sep 17 00:00:00 2001
From: Ariver <shanghai3168@gmail.com>
Date: Fri, 14 Aug 2026 22:41:54 +0800
Subject: [PATCH] [verified] feat: export performance diagnostics

---
 C1.source/Sources/Aligner/QuickSwitchSessionController.swift |  128 +++++++++++++++++++++++++++++++++++++++---
 1 files changed, 118 insertions(+), 10 deletions(-)

diff --git a/C1.source/Sources/Aligner/QuickSwitchSessionController.swift b/C1.source/Sources/Aligner/QuickSwitchSessionController.swift
index 18d84f0..79515d9 100644
--- a/C1.source/Sources/Aligner/QuickSwitchSessionController.swift
+++ b/C1.source/Sources/Aligner/QuickSwitchSessionController.swift
@@ -20,6 +20,7 @@
     private let systemCriticalWindowDetector: any SystemCriticalWindowDetecting
     private let disableScreenshotRefresh: Bool
     private var waterfallViewMode: QuickSwitchWaterfallViewMode
+    private var theme: ThemePreference
     private var closeConfirmationRequired: Bool
     private let onCloseConfirmationDisabled: (() -> Void)?
     private let debugOverlayWidth: CGFloat?
@@ -56,6 +57,7 @@
     private var lastActivationWindowID: UInt32?
     private var lastActivationResult: WindowActivationResult?
     private var lastActivationError: String?
+    private var lastActivationDurationMilliseconds: Double?
     private var lastSpaceActivationSpaceID: UInt64?
     private var lastSpaceActivationDidRequestFocus: Bool?
     private var lastSpaceActivationDisplayIdentifier: String?
@@ -69,6 +71,7 @@
     private var lastCloseError: String?
     private var pendingCloseVerification: PendingCloseVerification?
     private var suppressedCloseTargets: [SuppressedCloseTarget] = []
+    private var suppressedActivationWindowIDs = Set<UInt32>()
     private var lastDismissReason: DismissReason?
     private var lastSystemCriticalAction: String?
     private var lastSystemCriticalMonitorSource: String?
@@ -87,6 +90,7 @@
     private var lifecycleResidualVisibleOverlayWindows = 0
     var onSnapshotUpdated: (() -> Void)?
     var onToggleWaterfallViewMode: (() -> Void)?
+    var onToggleTheme: (() -> Void)?
 
     private struct PendingCloseVerification {
         let request: QuickSwitchCloseRequest
@@ -123,6 +127,7 @@
         systemCriticalWindowDetector: any SystemCriticalWindowDetecting = CGWindowSystemCriticalWindowDetector(),
         disableScreenshotRefresh: Bool = false,
         waterfallViewMode: QuickSwitchWaterfallViewMode = .verticalColumns,
+        theme: ThemePreference = .light,
         closeConfirmationRequired: Bool = true,
         onCloseConfirmationDisabled: (() -> Void)? = nil,
         debugHoveredAppGroupIndex: Int? = nil,
@@ -139,6 +144,7 @@
         self.systemCriticalWindowDetector = systemCriticalWindowDetector
         self.disableScreenshotRefresh = disableScreenshotRefresh
         self.waterfallViewMode = waterfallViewMode
+        self.theme = theme
         self.closeConfirmationRequired = closeConfirmationRequired
         self.onCloseConfirmationDisabled = onCloseConfirmationDisabled
         self.debugOverlayWidth = debugOverlayWidth
@@ -169,6 +175,7 @@
         lastActivationWindowID = nil
         lastActivationResult = nil
         lastActivationError = nil
+        lastActivationDurationMilliseconds = nil
         lastSpaceActivationSpaceID = nil
         lastSpaceActivationDidRequestFocus = nil
         lastSpaceActivationDisplayIdentifier = nil
@@ -182,6 +189,7 @@
         lastCloseError = nil
         pendingCloseVerification = nil
         suppressedCloseTargets = []
+        suppressedActivationWindowIDs = []
         cancelPendingLockedSpaceUnlock()
         lockedSpaceFilterID = nil
         selectionBeforeSpaceFilter = nil
@@ -216,6 +224,9 @@
         view.onToggleWaterfallViewMode = { [weak self] in
             self?.onToggleWaterfallViewMode?()
         }
+        view.onToggleTheme = { [weak self] in
+            self?.onToggleTheme?()
+        }
         view.setSuppressEventInput(!debugMouseSequence.isEmpty || !debugKeySequence.isEmpty)
         view.onRequestClose = { [weak self] request in
             self?.requestClose(request)
@@ -227,6 +238,7 @@
         }
         view.setCloseConfirmationRequired(closeConfirmationRequired)
         view.setWaterfallViewMode(waterfallViewMode)
+        view.setTheme(theme)
         view.apply(viewModel: nil)
         view.beginPerformanceFirstFrameMeasurement()
         coordinator.openQuickSwitch()
@@ -320,6 +332,20 @@
         onSnapshotUpdated?()
     }
 
+    func setTheme(_ theme: ThemePreference) {
+        guard self.theme != theme else { return }
+
+        self.theme = theme
+        DevelopmentDiagnostics.log("quickSwitch.session.themeChanged", [
+            "theme": theme.rawValue,
+            "visible": isVisible,
+            "hasViewModel": currentViewModel != nil
+        ])
+
+        view.setTheme(theme)
+        onSnapshotUpdated?()
+    }
+
     func reportDictionary() -> [String: Any] {
         let spaceCount = currentViewModel?.spaceCount ?? 0
         let appCount = currentViewModel?.appShelf.count ?? 0
@@ -354,6 +380,7 @@
             "lastActivationWindowID": lastActivationWindowID ?? NSNull(),
             "lastActivationResult": lastActivationResult.map(Self.activationResultString) ?? NSNull(),
             "lastActivationError": lastActivationError ?? NSNull(),
+            "lastActivationDurationMilliseconds": lastActivationDurationMilliseconds ?? NSNull(),
             "lastSpaceActivationSpaceID": lastSpaceActivationSpaceID ?? NSNull(),
             "lastSpaceActivationDidRequestFocus": lastSpaceActivationDidRequestFocus ?? NSNull(),
             "lastSpaceActivationDisplayIdentifier": lastSpaceActivationDisplayIdentifier ?? NSNull(),
@@ -366,6 +393,8 @@
             "lastCloseResult": lastCloseResult.map(Self.closeResultString) ?? NSNull(),
             "lastCloseError": lastCloseError ?? NSNull(),
             "suppressedCloseTargetCount": suppressedCloseTargets.count,
+            "suppressedActivationWindowCount": suppressedActivationWindowIDs.count,
+            "suppressedActivationWindowIDs": Array(suppressedActivationWindowIDs).sorted(),
             "lastDismissReason": lastDismissReason.map(Self.dismissReasonString) ?? NSNull(),
             "overlayLevel": Int(coordinator.currentLevel),
             "overlayMainMenuLevel": Int(CGWindowLevelForKey(.mainMenuWindow)),
@@ -394,6 +423,40 @@
                         && lifecycleResidualVisibleOverlayWindows == 0
                 ),
             "rootView": view.reportDictionary()
+        ]
+    }
+
+    func performanceDiagnosticSummary() -> [String: Any] {
+        let applications = currentSnapshot?.appGroups.map { group in
+            [
+                "name": group.app.name,
+                "bundleIdentifier": group.app.bundleIdentifier,
+                "processIdentifier": group.app.processIdentifier ?? NSNull(),
+                "windowCount": group.windows.count,
+                "minimizedWindowCount": group.windows.filter { $0.window.isMinimized }.count,
+                "fullscreenWindowCount": group.windows.filter { $0.window.isFullscreen }.count
+            ] as [String: Any]
+        } ?? []
+
+        return [
+            "snapshotLoaded": currentSnapshot != nil,
+            "snapshotError": lastSnapshotError ?? NSNull(),
+            "quickSwitchVisible": isVisible,
+            "displayCount": currentSnapshot?.displays.count ?? 0,
+            "spaceCount": currentSnapshot?.displays.flatMap(\.spaces).count ?? 0,
+            "applicationCount": applications.count,
+            "windowCount": currentSnapshot?.appGroups.flatMap(\.windows).count ?? 0,
+            "applications": applications,
+            "timingsMilliseconds": [
+                "overlayOpen": overlayOpenElapsedMilliseconds ?? NSNull(),
+                "snapshotStart": snapshotStartElapsedMilliseconds ?? NSNull(),
+                "snapshot": snapshotDurationMilliseconds ?? NSNull(),
+                "lastActivation": lastActivationDurationMilliseconds ?? NSNull()
+            ] as [String: Any],
+            "snapshotRanOnMainThread": snapshotRanOnMainThread ?? NSNull(),
+            "lastActivationResult": lastActivationResult.map(Self.activationResultString) ?? NSNull(),
+            "lastActivationError": lastActivationError ?? NSNull(),
+            "lastDismissReason": lastDismissReason.map(Self.dismissReasonString) ?? NSNull()
         ]
     }
 
@@ -546,9 +609,11 @@
         lastCommitSource = source
         lastActivationWindowID = selection.windowID
         lastActivationError = nil
+        lastActivationDurationMilliseconds = nil
 
         guard let window = window(for: selection, in: viewModel ?? currentViewModel) else {
             lastActivationResult = .windowNotFound
+            suppressActivationWindowID(selection.windowID, reason: "selectionMissing")
             DevelopmentDiagnostics.log("quickSwitch.activation.commit.windowNotFound", [
                 "source": source.rawValue,
                 "appGroupIndex": selection.appGroupIndex,
@@ -565,8 +630,10 @@
         ])
         hide(reason: .userClosed)
 
+        let activationStartedAt = CACurrentMediaTime()
         do {
             lastActivationResult = try windowActivationService.activate(window: window)
+            lastActivationDurationMilliseconds = (CACurrentMediaTime() - activationStartedAt) * 1_000
             DevelopmentDiagnostics.log("quickSwitch.activation.commit.result", [
                 "source": source.rawValue,
                 "windowID": window.id,
@@ -575,9 +642,11 @@
                 "titleHash": DevelopmentDiagnostics.stableFingerprint(window.title),
                 "titleLength": window.title.count,
                 "titleIsEmpty": window.title.isEmpty,
-                "result": lastActivationResult.map(Self.activationResultString)
+                "result": lastActivationResult.map(Self.activationResultString),
+                "durationMilliseconds": lastActivationDurationMilliseconds
             ])
         } catch {
+            lastActivationDurationMilliseconds = (CACurrentMediaTime() - activationStartedAt) * 1_000
             let errorSummary = DevelopmentDiagnostics.errorSummaryString(error)
             lastActivationResult = .failed(errorSummary)
             lastActivationError = errorSummary
@@ -587,10 +656,15 @@
                 "appName": window.app.name,
                 "titleHash": DevelopmentDiagnostics.stableFingerprint(window.title),
                 "titleLength": window.title.count,
-                "titleIsEmpty": window.title.isEmpty
+                "titleIsEmpty": window.title.isEmpty,
+                "durationMilliseconds": lastActivationDurationMilliseconds
             ]
             DevelopmentDiagnostics.errorSummaryFields(error).forEach { fields[$0.key] = $0.value }
             DevelopmentDiagnostics.log("quickSwitch.activation.commit.error", fields)
+        }
+
+        if shouldSuppressAfterActivationResult(lastActivationResult) {
+            suppressActivationWindowID(window.id, reason: lastActivationResult.map(Self.activationResultString) ?? "unknown")
         }
 
         if shouldCloseAfterActivation(lastActivationResult) {
@@ -607,7 +681,7 @@
 
     private func handleSpaceLaneClick(_ spaceID: UInt64, clickCount: Int) {
         if clickCount >= 2 {
-            if pendingLockedSpaceUnlockSpaceID == spaceID {
+            if pendingLockedSpaceUnlockSpaceID == spaceID || lockedSpaceFilterID == spaceID {
                 cancelPendingLockedSpaceUnlock()
                 activateLockedSpace(spaceID)
             } else {
@@ -939,18 +1013,37 @@
         ])
     }
 
+    private func suppressActivationWindowID(_ windowID: UInt32, reason: String) {
+        guard windowID != 0 else { return }
+        suppressedActivationWindowIDs.insert(windowID)
+
+        guard let sourceViewModel else { return }
+        let visibleViewModel = projectedViewModel(from: sourceViewModel, preferredSelection: view.effectiveSelectionForProjection())
+        self.currentViewModel = visibleViewModel
+        view.applyProjected(viewModel: visibleViewModel)
+        DevelopmentDiagnostics.log("quickSwitch.activation.suppressWindow", [
+            "windowID": windowID,
+            "reason": reason,
+            "remainingWindowCount": visibleViewModel.windowCount,
+            "suppressedActivationWindowCount": suppressedActivationWindowIDs.count
+        ])
+    }
+
     private func viewModel(
         _ viewModel: QuickSwitchViewModel,
-        excluding suppressedTargets: [SuppressedCloseTarget]
+        excluding suppressedTargets: [SuppressedCloseTarget],
+        suppressedActivationWindowIDs: Set<UInt32> = []
     ) -> QuickSwitchViewModel {
-        guard !suppressedTargets.isEmpty else { return viewModel }
+        guard !suppressedTargets.isEmpty || !suppressedActivationWindowIDs.isEmpty else { return viewModel }
 
         var nextGlobalIndex = 0
         let columns = viewModel.waterfallColumns.compactMap { column -> QuickSwitchWaterfallColumnViewModel? in
             let windows = column.windows.filter { card in
-                !suppressedTargets.contains { target in
+                let isActivationSuppressed = suppressedActivationWindowIDs.contains(card.window.id)
+                let isCloseSuppressed = suppressedTargets.contains { target in
                     suppressedTarget(target, matches: card)
                 }
+                return !isActivationSuppressed && !isCloseSuppressed
             }
             guard !windows.isEmpty else { return nil }
 
@@ -999,7 +1092,11 @@
         from sourceViewModel: QuickSwitchViewModel,
         preferredSelection: QuickSwitchSelection? = nil
     ) -> QuickSwitchViewModel {
-        let closeProjectedViewModel = viewModel(sourceViewModel, excluding: suppressedCloseTargets)
+        let closeProjectedViewModel = viewModel(
+            sourceViewModel,
+            excluding: suppressedCloseTargets,
+            suppressedActivationWindowIDs: suppressedActivationWindowIDs
+        )
         return QuickSwitchSpaceFilterPolicy.projectedViewModel(
             from: closeProjectedViewModel,
             lockedSpaceID: lockedSpaceFilterID,
@@ -1056,9 +1153,18 @@
 
     private func shouldCloseAfterActivation(_ result: WindowActivationResult?) -> Bool {
         switch result {
-        case .activated, .restored, .appActivatedOnly:
+        case .activated, .restored:
             return true
-        case .windowNotFound, .unsupported, .activationFailed, .failed, nil:
+        case .appActivatedOnly, .windowNotFound, .unsupported, .activationFailed, .failed, nil:
+            return false
+        }
+    }
+
+    private func shouldSuppressAfterActivationResult(_ result: WindowActivationResult?) -> Bool {
+        switch result {
+        case .windowNotFound, .unsupported, .activationFailed, .failed:
+            return true
+        case .activated, .restored, .appActivatedOnly, nil:
             return false
         }
     }
@@ -1512,6 +1618,7 @@
     let lifecycleCycles: Int?
     let lifecycleInterval: TimeInterval
     let lifecycleVisibleDuration: TimeInterval
+    let simulateDockReopenAfter: TimeInterval?
 
     static func parse(arguments: [String]) -> Round1QuickSwitchLaunchOptions {
         Round1QuickSwitchLaunchOptions(
@@ -1541,7 +1648,8 @@
             waterfallViewMode: waterfallViewModeValue(for: "--round01-waterfall-view-mode", in: arguments),
             lifecycleCycles: intValue(for: "--round01-quick-switch-lifecycle-cycles", in: arguments),
             lifecycleInterval: timeInterval(for: "--round01-quick-switch-lifecycle-interval", in: arguments) ?? 0.02,
-            lifecycleVisibleDuration: timeInterval(for: "--round01-quick-switch-lifecycle-visible-duration", in: arguments) ?? 0.16
+            lifecycleVisibleDuration: timeInterval(for: "--round01-quick-switch-lifecycle-visible-duration", in: arguments) ?? 0.16,
+            simulateDockReopenAfter: timeInterval(for: "--round01-simulate-dock-reopen-after", in: arguments)
         )
     }
 

--
Gitblit v1.9.3