Ariver
2026-06-19 6f2856fa70722dad7f7c69a3addaa05ea9fd6e94
C1.source/Sources/Aligner/QuickSwitchRootView.swift
@@ -11,6 +11,7 @@
@MainActor
final class QuickSwitchRootView: NSView {
    private static let appShelfIndexSymbols = Array("1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ").map(String.init)
    private static let windowIndexKeyPendingInterval: CFTimeInterval = 0.8
    private static let appShelfIndexKeyCodes: [String: UInt16] = [
        "1": 18, "2": 19, "3": 20, "4": 21, "5": 23,
        "6": 22, "7": 26, "8": 28, "9": 25, "0": 29,
@@ -85,6 +86,10 @@
    private var lastKeyboardAppIndexCommand: String?
    private var appShelfIndexKeyDownCount = 0
    private var lastAppShelfIndexKeySymbol: String?
    private var windowIndexKeyPending: WindowIndexKeyPending?
    private var windowIndexKeyPendingClearTask: Task<Void, Never>?
    private var lastWindowIndexKeyCommand: String?
    private var lastWindowIndexKeyCommitCode: String?
    private var lastBoundaryBounceAxis: String?
    private var lastBoundaryBounceDirection: String?
    private var boundaryBounceCount = 0
@@ -324,6 +329,12 @@
        let closeButton: CloseButtonLayers
    }
    private struct WindowIndexKeyPending {
        let appSymbol: String
        let appGroupIndex: Int
        let startedAt: CFTimeInterval
    }
    private struct ProjectionLayerSnapshot {
        let layer: CALayer
        let frame: CGRect
@@ -505,6 +516,7 @@
    }
    override func scrollWheel(with event: NSEvent) {
        clearWindowIndexKeyPending()
        refreshHoverTarget(at: event.locationInWindow)
        let dominantDelta = abs(event.scrollingDeltaX) >= abs(event.scrollingDeltaY)
@@ -560,6 +572,7 @@
    override func mouseMoved(with event: NSEvent) {
        guard debugHoveredAppGroupIndex == nil else { return }
        clearWindowIndexKeyPending()
        let toggleHovered = viewModeToggleButtonContains(windowLocation: event.locationInWindow)
        if !toggleHovered {
@@ -586,6 +599,7 @@
    override func mouseExited(with event: NSEvent) {
        guard debugHoveredAppGroupIndex == nil else { return }
        clearWindowIndexKeyPending()
        isViewModeToggleButtonHovered = false
        suppressViewModeToggleHoverPreview = false
        hoveredCloseTarget = nil
@@ -601,6 +615,7 @@
            ])
            return
        }
        clearWindowIndexKeyPending()
        if handleCloseConfirmationMouseDown(at: event.locationInWindow) {
            return
@@ -920,6 +935,11 @@
            keyboardCommandsApplied = []
            lastKeyboardCommand = nil
            lastKeyboardAppIndexCommand = nil
            appShelfIndexKeyDownCount = 0
            lastAppShelfIndexKeySymbol = nil
            clearWindowIndexKeyPending()
            lastWindowIndexKeyCommand = nil
            lastWindowIndexKeyCommitCode = nil
            lastBoundaryBounceAxis = nil
            lastBoundaryBounceDirection = nil
            boundaryBounceCount = 0
@@ -1350,6 +1370,10 @@
            "lastKeyboardAppIndexCommand": lastKeyboardAppIndexCommand ?? NSNull(),
            "appShelfIndexKeyDownCount": appShelfIndexKeyDownCount,
            "lastAppShelfIndexKeySymbol": lastAppShelfIndexKeySymbol ?? NSNull(),
            "windowIndexKeyPendingAppGroupIndex": windowIndexKeyPending?.appGroupIndex ?? NSNull(),
            "windowIndexKeyPendingAppSymbol": windowIndexKeyPending?.appSymbol ?? NSNull(),
            "lastWindowIndexKeyCommand": lastWindowIndexKeyCommand ?? NSNull(),
            "lastWindowIndexKeyCommitCode": lastWindowIndexKeyCommitCode ?? NSNull(),
            "lastBoundaryBounceAxis": lastBoundaryBounceAxis ?? NSNull(),
            "lastBoundaryBounceDirection": lastBoundaryBounceDirection ?? NSNull(),
            "boundaryBounceCount": boundaryBounceCount,
@@ -1429,6 +1453,7 @@
        if let indexSymbol = appShelfIndexSymbol(fromKeyboardCommand: command) {
            let recordedCommand = "app:\(indexSymbol)"
            recordKeyboardCommand(recordedCommand)
            clearWindowIndexKeyPending()
            if !focusAppShelfItemForKeyboard(indexSymbol: indexSymbol, commandLabel: recordedCommand) {
                selectionChangedByLastCommand = false
            }
@@ -1437,6 +1462,7 @@
        switch command {
        case "left":
            clearWindowIndexKeyPending()
            recordKeyboardCommand("left")
            if isHorizontalMasonryMode {
                moveSelection(.left)
@@ -1444,6 +1470,7 @@
                selectionChangedByLastCommand = false
            }
        case "right":
            clearWindowIndexKeyPending()
            recordKeyboardCommand("right")
            if isHorizontalMasonryMode {
                moveSelection(.right)
@@ -1451,6 +1478,7 @@
                selectionChangedByLastCommand = false
            }
        case "up":
            clearWindowIndexKeyPending()
            recordKeyboardCommand("up")
            if isHorizontalMasonryMode {
                moveSelection(.up)
@@ -1458,6 +1486,7 @@
                moveVerticalSelectionWithinFocusedColumn(.up)
            }
        case "down":
            clearWindowIndexKeyPending()
            recordKeyboardCommand("down")
            if isHorizontalMasonryMode {
                moveSelection(.down)
@@ -1465,10 +1494,12 @@
                moveVerticalSelectionWithinFocusedColumn(.down)
            }
        case "enter", "return", "commit":
            clearWindowIndexKeyPending()
            recordKeyboardCommand("enter")
            selectionChangedByLastCommand = false
            commitCurrentSelection()
        case "tab":
            clearWindowIndexKeyPending()
            if isHorizontalMasonryMode {
                recordKeyboardCommand("tab")
                moveHorizontalMasonryTabSelection()
@@ -1478,6 +1509,7 @@
                selectionChangedByLastCommand = false
            }
        default:
            clearWindowIndexKeyPending()
            recordKeyboardCommand("unknown:\(command)")
            selectionChangedByLastCommand = false
        }
@@ -1499,7 +1531,51 @@
        appShelfIndexKeyDownCount += 1
        lastAppShelfIndexKeySymbol = symbol
        if flags.contains(.option), handleWindowIndexKey(symbol: symbol) {
            return true
        }
        clearWindowIndexKeyPending()
        performKeyboardCommand(symbol)
        return true
    }
    private func handleWindowIndexKey(symbol: String) -> Bool {
        let now = CACurrentMediaTime()
        if let pending = validWindowIndexKeyPending(now: now) {
            let code = "\(pending.appSymbol)\(symbol)"
            if let card = waterfallCard(appGroupIndex: pending.appGroupIndex, windowIndexSymbol: symbol) {
                recordKeyboardCommand("window:\(code)")
                lastWindowIndexKeyCommand = "window:\(code)"
                lastWindowIndexKeyCommitCode = code
                clearWindowIndexKeyPending()
                commitKeyboardWindowCard(card, trigger: "windowIndexKey")
                return true
            }
            recordKeyboardCommand("windowInvalid:\(code)")
            lastWindowIndexKeyCommand = "windowInvalid:\(code)"
            lastWindowIndexKeyCommitCode = nil
            selectionChangedByLastCommand = false
            clearWindowIndexKeyPending()
            return true
        }
        let recordedCommand = "app:\(symbol)"
        recordKeyboardCommand(recordedCommand)
        lastWindowIndexKeyCommand = nil
        lastWindowIndexKeyCommitCode = nil
        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
            )
        } else {
            selectionChangedByLastCommand = false
            clearWindowIndexKeyPending()
        }
        return true
    }
@@ -1528,6 +1604,47 @@
            appGroupIndex: appShelfItems[ordinal].item.appGroupIndex,
            appIndexCommand: commandLabel
        )
    }
    private func validWindowIndexKeyPending(now: CFTimeInterval) -> WindowIndexKeyPending? {
        guard let pending = windowIndexKeyPending else { return nil }
        guard now - pending.startedAt <= Self.windowIndexKeyPendingInterval else {
            clearWindowIndexKeyPending()
            return nil
        }
        return pending
    }
    private func setWindowIndexKeyPending(appSymbol: String, appGroupIndex: Int, startedAt: CFTimeInterval) {
        windowIndexKeyPendingClearTask?.cancel()
        windowIndexKeyPending = WindowIndexKeyPending(
            appSymbol: appSymbol,
            appGroupIndex: appGroupIndex,
            startedAt: startedAt
        )
        windowIndexKeyPendingClearTask = Task { @MainActor [weak self] in
            do {
                try await Task.sleep(nanoseconds: UInt64(Self.windowIndexKeyPendingInterval * 1_000_000_000))
            } catch {
                return
            }
            guard let self,
                  let pending = self.windowIndexKeyPending,
                  pending.appSymbol == appSymbol,
                  pending.appGroupIndex == appGroupIndex,
                  pending.startedAt == startedAt
            else {
                return
            }
            self.windowIndexKeyPending = nil
            self.windowIndexKeyPendingClearTask = nil
        }
    }
    private func clearWindowIndexKeyPending() {
        windowIndexKeyPendingClearTask?.cancel()
        windowIndexKeyPendingClearTask = nil
        windowIndexKeyPending = nil
    }
    @discardableResult
@@ -1770,6 +1887,7 @@
            .trimmingCharacters(in: .whitespacesAndNewlines)
            .lowercased()
        guard !command.isEmpty else { return }
        clearWindowIndexKeyPending()
        let parts = command.split(separator: ":").map(String.init)
        switch parts.first {
@@ -2078,6 +2196,34 @@
    private func clickWindowCard(_ card: WaterfallCardLayers) {
        hoverWindowCard(card)
        commitWindowCard(card, trigger: "windowCard")
    }
    private func commitKeyboardWindowCard(_ card: WaterfallCardLayers, trigger: String) {
        let selection = QuickSwitchSelection(
            appGroupIndex: card.item.appGroupIndex,
            windowIndex: card.item.windowIndex,
            windowID: card.item.window.id
        )
        DevelopmentDiagnostics.log("quickSwitch.view.commitKeyboardWindow", [
            "trigger": trigger,
            "appGroupIndex": selection.appGroupIndex,
            "windowIndex": selection.windowIndex,
            "windowID": selection.windowID,
            "appName": card.item.window.app.name,
            "appPID": card.item.window.app.processIdentifier,
            "titleHash": DevelopmentDiagnostics.stableFingerprint(card.item.window.title),
            "titleLength": card.item.window.title.count,
            "titleIsEmpty": card.item.window.title.isEmpty,
            "isMinimized": card.item.window.isMinimized,
            "isFullscreen": card.item.window.isFullscreen,
            "identifierSource": String(describing: card.item.window.identifierSource)
        ])
        currentSelection = selection
        columnSelectionHistory[selection.appGroupIndex] = selection.windowIndex
        lastCommittedSelection = selection
        lastCommitSource = .keyboard
        ensureCurrentSelectionVisible()
        onCommitSelection?(selection, .keyboard)
    }
    private func commitWindowCard(_ card: WaterfallCardLayers, trigger: String) {
@@ -3305,7 +3451,8 @@
                    string: waterfallMetaText(for: window),
                    fontSize: 10,
                    weight: .regular,
                    color: .secondaryLabelColor
                    color: .secondaryLabelColor,
                    alignment: .right
                )
                let appIcon = CALayer()
                appIcon.contentsGravity = .resizeAspect
@@ -4101,6 +4248,15 @@
            .first(where: { $0.column.appGroupIndex == appGroupIndex })?
            .cards
            .first(where: { $0.item.windowIndex == windowIndex })
    }
    private func waterfallCard(appGroupIndex: Int, windowIndexSymbol: String) -> WaterfallCardLayers? {
        guard let ordinal = Self.appShelfIndexSymbols.firstIndex(of: windowIndexSymbol),
              ordinal < Self.appShelfIndexSymbols.count
        else {
            return nil
        }
        return waterfallCard(appGroupIndex: appGroupIndex, windowIndex: ordinal)
    }
    private func waterfallCard(windowID: UInt32) -> WaterfallCardLayers? {
@@ -5658,7 +5814,26 @@
    }
    private func waterfallMetaText(for card: QuickSwitchWindowCardViewModel) -> String {
        card.primarySpaceLabel ?? "No Space"
        windowShortcutCode(for: card) ?? ""
    }
    private func windowShortcutCode(for card: QuickSwitchWindowCardViewModel) -> String? {
        guard let appOrdinal = appShelfItems.firstIndex(where: { $0.item.appGroupIndex == card.appGroupIndex }),
              let appSymbol = singleIndexSymbol(forOrdinal: appOrdinal),
              let windowSymbol = singleIndexSymbol(forOrdinal: card.windowIndex)
        else {
            return nil
        }
        return "\(appSymbol)\(windowSymbol)"
    }
    private func singleIndexSymbol(forOrdinal ordinal: Int) -> String? {
        guard ordinal >= 0,
              ordinal < Self.appShelfIndexSymbols.count
        else {
            return nil
        }
        return Self.appShelfIndexSymbols[ordinal]
    }
    private func waterfallStateText(for card: QuickSwitchWindowCardViewModel) -> String {
@@ -6178,6 +6353,7 @@
                "titleIsEmpty": card.item.window.title.isEmpty,
                "primarySpaceID": card.item.primarySpaceID ?? NSNull(),
                "primarySpaceLabel": card.item.primarySpaceLabel ?? NSNull(),
                "windowShortcutCode": waterfallMetaText(for: card.item),
                "isMinimized": card.item.window.isMinimized,
                "isFullscreen": card.item.window.isFullscreen,
                "identifierSource": "\(card.item.window.identifierSource)",