From cba722f8a207982ade9e941eca3e6070e8705749 Mon Sep 17 00:00:00 2001
From: Ariver <shanghai3168@gmail.com>
Date: Sat, 20 Jun 2026 13:01:49 +0800
Subject: [PATCH] Commit single-window app shortcuts on first key

---
 C1.source/Sources/Aligner/QuickSwitchRootView.swift |  294 +++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 266 insertions(+), 28 deletions(-)

diff --git a/C1.source/Sources/Aligner/QuickSwitchRootView.swift b/C1.source/Sources/Aligner/QuickSwitchRootView.swift
index f137091..3b0a67e 100644
--- a/C1.source/Sources/Aligner/QuickSwitchRootView.swift
+++ b/C1.source/Sources/Aligner/QuickSwitchRootView.swift
@@ -99,6 +99,8 @@
     private var windowIndexKeyPendingClearTask: Task<Void, Never>?
     private var lastWindowIndexKeyCommand: String?
     private var lastWindowIndexKeyCommitCode: String?
+    private var windowShortcutFilterPhase: WindowShortcutFilterPhase = .none
+    private var lastWindowShortcutPreCommitFilterSnapshot: WindowShortcutPreCommitFilterSnapshot?
     private var lastBoundaryBounceAxis: String?
     private var lastBoundaryBounceDirection: String?
     private var boundaryBounceCount = 0
@@ -343,6 +345,47 @@
         let appSymbol: String
         let appGroupIndex: Int
         let startedAt: CFTimeInterval
+    }
+
+    private enum WindowShortcutFilterPhase: String {
+        case none
+        case appPending
+        case targetPreCommit
+        case invalid
+        case expired
+    }
+
+    private enum WindowShortcutFilterState: String {
+        case none
+        case matched
+        case dimmed
+        case target
+    }
+
+    private struct WindowShortcutPreCommitFilterSnapshot {
+        let targetCode: String
+        let targetWindowID: UInt32
+        let matchedWindowIDs: [UInt32]
+        let dimmedWindowIDs: [UInt32]
+
+        var reportDictionary: [String: Any] {
+            [
+                "phase": WindowShortcutFilterPhase.targetPreCommit.rawValue,
+                "targetCode": targetCode,
+                "targetWindowID": Int(targetWindowID),
+                "matchedWindowIDs": matchedWindowIDs.map(Int.init),
+                "dimmedWindowIDs": dimmedWindowIDs.map(Int.init)
+            ]
+        }
+    }
+
+    private struct WindowShortcutFilterReport {
+        let active: Bool
+        let phase: WindowShortcutFilterPhase
+        let pendingAppGroupIndex: Int?
+        let prefix: String?
+        let matchedWindowIDs: [UInt32]
+        let dimmedWindowIDs: [UInt32]
     }
 
     private struct ProjectionLayerSnapshot {
@@ -1087,6 +1130,8 @@
             clearWindowIndexKeyPending()
             lastWindowIndexKeyCommand = nil
             lastWindowIndexKeyCommitCode = nil
+            windowShortcutFilterPhase = .none
+            lastWindowShortcutPreCommitFilterSnapshot = nil
             lastBoundaryBounceAxis = nil
             lastBoundaryBounceDirection = nil
             boundaryBounceCount = 0
@@ -1405,6 +1450,7 @@
         let firstFrameGatePassed = firstFrameP95.map { $0 < 150 } ?? false
         let keyboardGatePassed = keyboardP95.map { $0 < 50 } ?? false
         let hoverGatePassed = hoverP95.map { $0 <= 32 } ?? false
+        let shortcutFilterReport = makeWindowShortcutFilterReport()
 
         return [
             "viewClass": String(describing: Self.self),
@@ -1535,6 +1581,15 @@
             "windowIndexKeyPendingAppSymbol": windowIndexKeyPending?.appSymbol ?? NSNull(),
             "lastWindowIndexKeyCommand": lastWindowIndexKeyCommand ?? NSNull(),
             "lastWindowIndexKeyCommitCode": lastWindowIndexKeyCommitCode ?? NSNull(),
+            "windowShortcutFilterActive": shortcutFilterReport.active,
+            "windowShortcutFilterPhase": shortcutFilterReport.phase.rawValue,
+            "windowShortcutFilterPendingAppGroupIndex": shortcutFilterReport.pendingAppGroupIndex ?? NSNull(),
+            "windowShortcutFilterPrefix": shortcutFilterReport.prefix ?? NSNull(),
+            "windowShortcutFilterMatchedCount": shortcutFilterReport.matchedWindowIDs.count,
+            "windowShortcutFilterDimmedCount": shortcutFilterReport.dimmedWindowIDs.count,
+            "windowShortcutFilterMatchedWindowIDs": shortcutFilterReport.matchedWindowIDs.map(Int.init),
+            "windowShortcutFilterDimmedWindowIDs": shortcutFilterReport.dimmedWindowIDs.map(Int.init),
+            "lastWindowShortcutPreCommitFilterSnapshot": lastWindowShortcutPreCommitFilterSnapshot?.reportDictionary ?? NSNull(),
             "lastBoundaryBounceAxis": lastBoundaryBounceAxis ?? NSNull(),
             "lastBoundaryBounceDirection": lastBoundaryBounceDirection ?? NSNull(),
             "boundaryBounceCount": boundaryBounceCount,
@@ -1708,7 +1763,12 @@
                 recordKeyboardCommand("window:\(code)")
                 lastWindowIndexKeyCommand = "window:\(code)"
                 lastWindowIndexKeyCommitCode = code
-                clearWindowIndexKeyPending()
+                lastWindowShortcutPreCommitFilterSnapshot = makeWindowShortcutPreCommitFilterSnapshot(
+                    target: card,
+                    code: code
+                )
+                windowShortcutFilterPhase = .targetPreCommit
+                clearWindowIndexKeyPending(resetShortcutFilter: false)
                 commitKeyboardWindowCard(card, trigger: "windowIndexKey")
                 return true
             }
@@ -1716,8 +1776,10 @@
             recordKeyboardCommand("windowInvalid:\(code)")
             lastWindowIndexKeyCommand = "windowInvalid:\(code)"
             lastWindowIndexKeyCommitCode = nil
+            windowShortcutFilterPhase = .invalid
+            lastWindowShortcutPreCommitFilterSnapshot = nil
             selectionChangedByLastCommand = false
-            clearWindowIndexKeyPending()
+            clearWindowIndexKeyPending(resetShortcutFilter: false)
             return true
         }
 
@@ -1728,11 +1790,21 @@
         if focusAppShelfItemForKeyboard(indexSymbol: symbol, commandLabel: recordedCommand),
            let ordinal = Self.appShelfIndexSymbols.firstIndex(of: symbol),
            ordinal < appShelfItems.count {
-            setWindowIndexKeyPending(
-                appSymbol: symbol,
-                appGroupIndex: appShelfItems[ordinal].item.appGroupIndex,
-                startedAt: now
-            )
+            let appGroupIndex = appShelfItems[ordinal].item.appGroupIndex
+            if let card = singleVisibleWaterfallCard(appGroupIndex: appGroupIndex) {
+                recordKeyboardCommand("windowSingle:\(symbol)")
+                lastWindowIndexKeyCommand = "windowSingle:\(symbol)"
+                lastWindowIndexKeyCommitCode = symbol
+                lastWindowShortcutPreCommitFilterSnapshot = nil
+                clearWindowIndexKeyPending()
+                commitKeyboardWindowCard(card, trigger: "windowIndexSingleApp")
+            } else {
+                setWindowIndexKeyPending(
+                    appSymbol: symbol,
+                    appGroupIndex: appGroupIndex,
+                    startedAt: now
+                )
+            }
         } else {
             selectionChangedByLastCommand = false
             clearWindowIndexKeyPending()
@@ -1783,6 +1855,9 @@
             appGroupIndex: appGroupIndex,
             startedAt: startedAt
         )
+        windowShortcutFilterPhase = .appPending
+        lastWindowShortcutPreCommitFilterSnapshot = nil
+        needsLayout = true
         windowIndexKeyPendingClearTask = Task { @MainActor [weak self] in
             do {
                 try await Task.sleep(nanoseconds: UInt64(Self.windowIndexKeyPendingInterval * 1_000_000_000))
@@ -1799,13 +1874,26 @@
             }
             self.windowIndexKeyPending = nil
             self.windowIndexKeyPendingClearTask = nil
+            self.windowShortcutFilterPhase = .expired
+            self.lastWindowShortcutPreCommitFilterSnapshot = nil
+            self.needsLayout = true
         }
     }
 
-    private func clearWindowIndexKeyPending() {
+    private func clearWindowIndexKeyPending(resetShortcutFilter: Bool = true) {
+        let hadFilterState = windowIndexKeyPending != nil
+            || windowShortcutFilterPhase != .none
+            || lastWindowShortcutPreCommitFilterSnapshot != nil
         windowIndexKeyPendingClearTask?.cancel()
         windowIndexKeyPendingClearTask = nil
         windowIndexKeyPending = nil
+        if resetShortcutFilter {
+            windowShortcutFilterPhase = .none
+            lastWindowShortcutPreCommitFilterSnapshot = nil
+        }
+        if hadFilterState {
+            needsLayout = true
+        }
     }
 
     @discardableResult
@@ -4454,17 +4542,41 @@
             )
             : nil
 
-        applySpaceLaneContentVisualState(segment, isLocked: isLocked)
+        applySpaceLaneContentVisualState(
+            segment,
+            isLocked: isLocked,
+            usesLightActiveFill: resolvedTheme == .dark && hasWindows && !isLocked && (isActive || isAssociated)
+        )
     }
 
-    private func applySpaceLaneContentVisualState(_ segment: SpaceLaneSegmentLayers, isLocked: Bool) {
-        let primaryTextColor: NSColor = isLocked ? .white : themePalette.spaceLanePrimaryText
+    private func applySpaceLaneContentVisualState(
+        _ segment: SpaceLaneSegmentLayers,
+        isLocked: Bool,
+        usesLightActiveFill: Bool
+    ) {
+        let primaryTextColor: NSColor = isLocked
+            ? .white
+            : usesLightActiveFill
+                ? NSColor.black.withAlphaComponent(0.82)
+                : themePalette.spaceLanePrimaryText
         let secondaryTextColor: NSColor = isLocked
             ? .white
-            : themePalette.spaceLaneSecondaryText
+            : usesLightActiveFill
+                ? NSColor.black.withAlphaComponent(0.58)
+                : themePalette.spaceLaneSecondaryText
+        let markerTextColor: NSColor = isLocked
+            ? .white
+            : usesLightActiveFill
+                ? NSColor.black.withAlphaComponent(0.62)
+                : themePalette.spaceLaneSecondaryText.withAlphaComponent(segment.space.isCurrent ? 0.72 : 0.54)
+        let blockColor: NSColor = isLocked
+            ? .white
+            : usesLightActiveFill
+                ? NSColor.black.withAlphaComponent(0.20)
+                : spaceLaneOccupiedColor.withAlphaComponent(segment.space.isCurrent ? 0.72 : 0.58)
 
         segment.labelLayer.foregroundColor = primaryTextColor.cgColor
-        segment.countLayer.foregroundColor = (isLocked ? NSColor.white : themePalette.spaceLaneSecondaryText).cgColor
+        segment.countLayer.foregroundColor = secondaryTextColor.cgColor
         segment.appLayer.foregroundColor = (segment.space.type == .fullscreen
             ? primaryTextColor
             : secondaryTextColor
@@ -4474,16 +4586,10 @@
         }
 
         for block in segment.windowBlocks {
-            block.backgroundColor = (isLocked
-                ? NSColor.white
-                : spaceLaneOccupiedColor.withAlphaComponent(segment.space.isCurrent ? 0.72 : 0.58)
-            ).cgColor
+            block.backgroundColor = blockColor.cgColor
         }
 
-        (segment.fullscreenMarkerLayer as? CAShapeLayer)?.strokeColor = (isLocked
-            ? NSColor.white
-            : themePalette.spaceLaneSecondaryText.withAlphaComponent(segment.space.isCurrent ? 0.72 : 0.54)
-        ).cgColor
+        (segment.fullscreenMarkerLayer as? CAShapeLayer)?.strokeColor = markerTextColor.cgColor
     }
 
     private func shouldScrollSpaceLane(for event: NSEvent) -> Bool {
@@ -5433,13 +5539,15 @@
         let isKeyboardFocused = card.item.window.id == keyboardFocusedWindowID
         let isHorizontalAppDefaultFocused = isHorizontalAppDefaultCard(card)
         let isAppLinked = isWaterfallCardAppLinked(card)
+        let shortcutFilterState = windowShortcutFilterState(for: card)
         applyWaterfallCardVisualState(
             card,
             selected: shouldShowSelectedVisual(isSelected: isSelected, isHovered: isHovered)
                 || isKeyboardFocused
                 || isHorizontalAppDefaultFocused,
             hovered: isHovered,
-            appLinked: isAppLinked
+            appLinked: isAppLinked,
+            shortcutFilterState: shortcutFilterState
         )
 
         let outerInset: CGFloat = 0
@@ -5494,7 +5602,7 @@
                 windowIndex: card.item.windowIndex,
                 windowID: card.item.window.id
             ),
-            visible: isHovered,
+            visible: isHovered && shortcutFilterState != .dimmed,
             anchorTopRight: CGPoint(x: bounds.maxX - 12, y: bounds.maxY - 12)
         )
         card.shineLayer.frame = CGRect(
@@ -5514,9 +5622,11 @@
         _ card: WaterfallCardLayers,
         selected: Bool,
         hovered: Bool,
-        appLinked: Bool
+        appLinked: Bool,
+        shortcutFilterState: WindowShortcutFilterState
     ) {
         let isSpaceFocused = isWaterfallCardSpaceFocused(card)
+        let isShortcutDimmed = shortcutFilterState == .dimmed
         card.containerLayer.backgroundColor = (selected
             ? themePalette.cardSelectedBackground
             : hovered
@@ -5527,6 +5637,7 @@
                     ? accentTintedWindowBackground(fraction: 0.10, alpha: 0.94)
                 : themePalette.cardBackground
         ).cgColor
+        card.containerLayer.opacity = isShortcutDimmed ? windowShortcutFilterDimOpacity : 1
         card.containerLayer.borderColor = (selected
             ? NSColor.controlAccentColor.withAlphaComponent(0.52)
             : hovered
@@ -5540,7 +5651,7 @@
         card.containerLayer.borderWidth = (selected || hovered || appLinked || isSpaceFocused) ? 1.5 : 1
         card.containerLayer.shadowColor = NSColor.black.cgColor
         let darkShadowBoost: Float = resolvedTheme == .dark ? 0.08 : 0
-        card.containerLayer.shadowOpacity = selected
+        let baseShadowOpacity: Float = selected
             ? 0.24 + darkShadowBoost
             : hovered
                 ? 0.14 + darkShadowBoost
@@ -5549,6 +5660,7 @@
                     : isSpaceFocused
                         ? 0.20 + darkShadowBoost
                         : 0
+        card.containerLayer.shadowOpacity = isShortcutDimmed ? min(baseShadowOpacity, 0.03) : baseShadowOpacity
         card.containerLayer.shadowRadius = selected ? 22 : hovered ? 17 : appLinked ? 18 : isSpaceFocused ? 24 : 0
         card.containerLayer.shadowOffset = selected
             ? CGSize(width: 0, height: -6)
@@ -5561,10 +5673,10 @@
                     : .zero
         card.containerLayer.zPosition = selected ? 20 : hovered ? 12 : appLinked ? 10 : isSpaceFocused ? 8 : 0
         let focusedScale: CGFloat = selected ? WaterfallMetrics.selectedCardScale : isSpaceFocused ? 1.012 : 1.008
-        card.containerLayer.transform = (selected || hovered || isSpaceFocused)
+        card.containerLayer.transform = (!isShortcutDimmed && (selected || hovered || isSpaceFocused))
             ? CATransform3DMakeScale(focusedScale, focusedScale, 1)
             : CATransform3DIdentity
-        card.containerLayer.shadowPath = (selected || hovered || appLinked || isSpaceFocused)
+        card.containerLayer.shadowPath = (!isShortcutDimmed && (selected || hovered || appLinked || isSpaceFocused))
             ? CGPath(
                 roundedRect: card.containerLayer.bounds,
                 cornerWidth: card.containerLayer.cornerRadius,
@@ -5580,7 +5692,7 @@
         ).cgColor
         card.titleBarLayer.borderColor = NSColor.clear.cgColor
         card.titleBarLayer.borderWidth = 0
-        card.shineLayer.opacity = selected ? 1 : 0
+        card.shineLayer.opacity = (!isShortcutDimmed && selected) ? 1 : 0
     }
 
     private func layoutCloseButton(
@@ -6320,6 +6432,110 @@
         return Self.appShelfIndexSymbols[ordinal]
     }
 
+    private var visibleWaterfallCards: [WaterfallCardLayers] {
+        waterfallColumns.flatMap(\.cards)
+    }
+
+    private func singleVisibleWaterfallCard(appGroupIndex: Int) -> WaterfallCardLayers? {
+        let cards = visibleWaterfallCards.filter { $0.item.appGroupIndex == appGroupIndex }
+        return cards.count == 1 ? cards[0] : nil
+    }
+
+    private var windowShortcutFilterDimOpacity: Float {
+        resolvedTheme == .dark ? 0.44 : 0.38
+    }
+
+    private func windowShortcutFilterState(for card: WaterfallCardLayers) -> WindowShortcutFilterState {
+        switch windowShortcutFilterPhase {
+        case .appPending:
+            guard let pending = windowIndexKeyPending else { return .none }
+            return card.item.appGroupIndex == pending.appGroupIndex ? .matched : .dimmed
+        case .targetPreCommit:
+            guard let snapshot = lastWindowShortcutPreCommitFilterSnapshot else { return .none }
+            if card.item.window.id == snapshot.targetWindowID {
+                return .target
+            }
+            if snapshot.dimmedWindowIDs.contains(card.item.window.id) {
+                return .dimmed
+            }
+            if snapshot.matchedWindowIDs.contains(card.item.window.id) {
+                return .matched
+            }
+            return .none
+        case .none, .invalid, .expired:
+            return .none
+        }
+    }
+
+    private func makeWindowShortcutPreCommitFilterSnapshot(
+        target card: WaterfallCardLayers,
+        code: String
+    ) -> WindowShortcutPreCommitFilterSnapshot {
+        let targetWindowID = card.item.window.id
+        let allWindowIDs = visibleWaterfallCards.map { $0.item.window.id }
+        return WindowShortcutPreCommitFilterSnapshot(
+            targetCode: code,
+            targetWindowID: targetWindowID,
+            matchedWindowIDs: [targetWindowID],
+            dimmedWindowIDs: allWindowIDs.filter { $0 != targetWindowID }.sorted()
+        )
+    }
+
+    private func makeWindowShortcutFilterReport() -> WindowShortcutFilterReport {
+        switch windowShortcutFilterPhase {
+        case .appPending:
+            guard let pending = windowIndexKeyPending else {
+                return emptyWindowShortcutFilterReport(phase: .none)
+            }
+            let cards = visibleWaterfallCards
+            let matched = cards
+                .filter { $0.item.appGroupIndex == pending.appGroupIndex }
+                .map { $0.item.window.id }
+                .sorted()
+            let dimmed = cards
+                .filter { $0.item.appGroupIndex != pending.appGroupIndex }
+                .map { $0.item.window.id }
+                .sorted()
+            return WindowShortcutFilterReport(
+                active: true,
+                phase: .appPending,
+                pendingAppGroupIndex: pending.appGroupIndex,
+                prefix: pending.appSymbol,
+                matchedWindowIDs: matched,
+                dimmedWindowIDs: dimmed
+            )
+        case .targetPreCommit:
+            guard let snapshot = lastWindowShortcutPreCommitFilterSnapshot else {
+                return emptyWindowShortcutFilterReport(phase: .none)
+            }
+            return WindowShortcutFilterReport(
+                active: true,
+                phase: .targetPreCommit,
+                pendingAppGroupIndex: nil,
+                prefix: snapshot.targetCode,
+                matchedWindowIDs: snapshot.matchedWindowIDs,
+                dimmedWindowIDs: snapshot.dimmedWindowIDs
+            )
+        case .invalid, .expired:
+            return emptyWindowShortcutFilterReport(phase: windowShortcutFilterPhase)
+        case .none:
+            return emptyWindowShortcutFilterReport(phase: .none)
+        }
+    }
+
+    private func emptyWindowShortcutFilterReport(
+        phase: WindowShortcutFilterPhase
+    ) -> WindowShortcutFilterReport {
+        WindowShortcutFilterReport(
+            active: false,
+            phase: phase,
+            pendingAppGroupIndex: nil,
+            prefix: nil,
+            matchedWindowIDs: [],
+            dimmedWindowIDs: []
+        )
+    }
+
     private func waterfallStateText(for card: QuickSwitchWindowCardViewModel) -> String {
         var states: [String] = []
         if card.window.isMinimized {
@@ -6826,6 +7042,10 @@
                 dy: column.containerLayer.frame.minY + column.cardsClipLayer.frame.minY
             )
             let screenshotSource = screenshotSourcesByWindowID[card.item.window.id]
+            let shortcutFilterState = windowShortcutFilterState(for: card)
+            let shortcutFilterOpacity = shortcutFilterState == .dimmed
+                ? windowShortcutFilterDimOpacity
+                : Float(1)
 
             var report = [
                 "appGroupIndex": card.item.appGroupIndex,
@@ -6844,6 +7064,8 @@
                 "isSelected": card.item.window.id == effectiveSelection?.windowID,
                 "isKeyboardFocused": card.item.window.id == keyboardFocusedWindowID,
                 "isHorizontalAppDefault": isHorizontalAppDefaultCard(card),
+                "windowShortcutFilterState": shortcutFilterState.rawValue,
+                "windowShortcutFilterOpacity": Double(shortcutFilterOpacity),
                 "visualStates": waterfallCardVisualStates(for: card),
                 "thumbnailStrategy": thumbnailStrategyString(for: card.item.window),
                 "screenshotSource": screenshotSourceString(screenshotSource, for: card.item.window),
@@ -6988,6 +7210,16 @@
         if isWaterfallCardSpaceFocused(card) {
             states.append("spaceFocused")
         }
+        switch windowShortcutFilterState(for: card) {
+        case .matched:
+            states.append("shortcutMatched")
+        case .dimmed:
+            states.append("shortcutDimmed")
+        case .target:
+            states.append("shortcutTarget")
+        case .none:
+            break
+        }
         if card.item.window.isMinimized {
             states.append("minimized")
         }
@@ -7035,6 +7267,10 @@
                 }
                 let isAppAssociated = appHoverAssociatedSpaceIDs.contains(space.id)
                 let isWindowAssociated = space.id == windowHoverAssociatedSpaceID
+                let isLocked = space.id == currentViewModel?.lockedSpaceID
+                let isActive = space.id == activeSpaceFocusID || isLocked
+                let isAssociated = (isAppAssociated || isWindowAssociated) && !isActive
+                let usesLightActiveFill = resolvedTheme == .dark && space.windowCount > 0 && !isLocked && (isActive || isAssociated)
                 let group = spaceLaneDisplayGroup(containingSpaceID: space.id)
                 let visibleFrame = segment.containerLayer.frame.offsetBy(
                     dx: (group?.containerLayer.frame.minX ?? 0) + spaceLaneContentLayer.frame.minX,
@@ -7053,6 +7289,8 @@
                     "label": space.label,
                     "type": spaceTypeName(space.type),
                     "visualStates": visualStates(for: space),
+                    "usesLightActiveFill": usesLightActiveFill,
+                    "foregroundContrastStyle": usesLightActiveFill ? "darkOnLight" : "themeDefault",
                     "fullscreenMarkerVisible": segment.fullscreenMarkerLayer != nil,
                     "fullscreenMarkerKind": fullscreenMarkerKind(
                         markerLayer: segment.fullscreenMarkerLayer,

--
Gitblit v1.9.3