From 3bd3e220be93991f6cac48f60dc5a0551204746f Mon Sep 17 00:00:00 2001
From: Ariver <shanghai3168@gmail.com>
Date: Sat, 20 Jun 2026 00:27:17 +0800
Subject: [PATCH] Freeze 0.1 release version

---
 C1.source/Sources/Aligner/QuickSwitchRootView.swift |  674 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 663 insertions(+), 11 deletions(-)

diff --git a/C1.source/Sources/Aligner/QuickSwitchRootView.swift b/C1.source/Sources/Aligner/QuickSwitchRootView.swift
index e7676c3..5fff479 100644
--- a/C1.source/Sources/Aligner/QuickSwitchRootView.swift
+++ b/C1.source/Sources/Aligner/QuickSwitchRootView.swift
@@ -11,6 +11,16 @@
 @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,
+        "A": 0, "B": 11, "C": 8, "D": 2, "E": 14, "F": 3,
+        "G": 5, "H": 4, "I": 34, "J": 38, "K": 40, "L": 37,
+        "M": 46, "N": 45, "O": 31, "P": 35, "Q": 12, "R": 15,
+        "S": 1, "T": 17, "U": 32, "V": 9, "W": 13, "X": 7,
+        "Y": 16, "Z": 6
+    ]
 
     private let backdropBlurView = NSVisualEffectView()
     private let layerHostView = NSView()
@@ -74,6 +84,12 @@
     private var keyboardCommandsApplied: [String] = []
     private var lastKeyboardCommand: String?
     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
@@ -230,6 +246,32 @@
         case keyboard
     }
 
+    private enum HorizontalKeyboardFocusKind: String {
+        case app
+        case window
+    }
+
+    private struct HorizontalKeyboardFocusNode {
+        let kind: HorizontalKeyboardFocusKind
+        let appGroupIndex: Int
+        let windowIndex: Int?
+        let windowID: UInt32?
+        let spaceID: UInt64?
+        let frame: CGRect
+        let order: Int
+
+        var center: CGPoint {
+            CGPoint(x: frame.midX, y: frame.midY)
+        }
+
+        func matches(_ other: HorizontalKeyboardFocusNode) -> Bool {
+            kind == other.kind
+                && appGroupIndex == other.appGroupIndex
+                && windowIndex == other.windowIndex
+                && windowID == other.windowID
+        }
+    }
+
     private struct SpaceLaneSegmentLayers {
         let space: QuickSwitchSpaceViewModel
         let containerLayer: CALayer
@@ -285,6 +327,12 @@
         let stateLayer: CATextLayer
         let shineLayer: CAGradientLayer
         let closeButton: CloseButtonLayers
+    }
+
+    private struct WindowIndexKeyPending {
+        let appSymbol: String
+        let appGroupIndex: Int
+        let startedAt: CFTimeInterval
     }
 
     private struct ProjectionLayerSnapshot {
@@ -468,6 +516,7 @@
     }
 
     override func scrollWheel(with event: NSEvent) {
+        clearWindowIndexKeyPending()
         refreshHoverTarget(at: event.locationInWindow)
 
         let dominantDelta = abs(event.scrollingDeltaX) >= abs(event.scrollingDeltaY)
@@ -523,6 +572,7 @@
 
     override func mouseMoved(with event: NSEvent) {
         guard debugHoveredAppGroupIndex == nil else { return }
+        clearWindowIndexKeyPending()
 
         let toggleHovered = viewModeToggleButtonContains(windowLocation: event.locationInWindow)
         if !toggleHovered {
@@ -549,6 +599,7 @@
 
     override func mouseExited(with event: NSEvent) {
         guard debugHoveredAppGroupIndex == nil else { return }
+        clearWindowIndexKeyPending()
         isViewModeToggleButtonHovered = false
         suppressViewModeToggleHoverPreview = false
         hoveredCloseTarget = nil
@@ -564,6 +615,7 @@
             ])
             return
         }
+        clearWindowIndexKeyPending()
 
         if handleCloseConfirmationMouseDown(at: event.locationInWindow) {
             return
@@ -618,11 +670,49 @@
         layoutSubtreeIfNeeded()
         for command in commands {
             let measurementStart = CACurrentMediaTime()
-            performKeyboardCommand(command)
+            if !performDebugPhysicalIndexKeyCommand(command) {
+                performKeyboardCommand(command)
+            }
             layoutSubtreeIfNeeded()
             CATransaction.flush()
             keyboardResponseLatencyMilliseconds.append(milliseconds(since: measurementStart))
         }
+    }
+
+    private func performDebugPhysicalIndexKeyCommand(_ rawCommand: String) -> Bool {
+        let command = rawCommand.trimmingCharacters(in: .whitespacesAndNewlines)
+        let uppercased = command.uppercased()
+        let prefixes = ["PHYSICAL-INDEX:", "PHYSICAL-INDEX-", "KEYDOWN:", "KEYDOWN-"]
+        guard let prefix = prefixes.first(where: { uppercased.hasPrefix($0) }) else {
+            return false
+        }
+
+        let symbolStart = command.index(command.startIndex, offsetBy: prefix.count)
+        guard let symbol = appShelfIndexSymbol(fromKeyboardCommand: String(command[symbolStart...])),
+              let keyCode = Self.appShelfIndexKeyCodes[symbol],
+              let event = NSEvent.keyEvent(
+                with: .keyDown,
+                location: .zero,
+                modifierFlags: [.option],
+                timestamp: ProcessInfo.processInfo.systemUptime,
+                windowNumber: window?.windowNumber ?? 0,
+                context: nil,
+                characters: symbol.lowercased(),
+                charactersIgnoringModifiers: symbol.lowercased(),
+                isARepeat: false,
+                keyCode: keyCode
+              )
+        else {
+            recordKeyboardCommand("invalidPhysicalIndex:\(command)")
+            selectionChangedByLastCommand = false
+            return true
+        }
+
+        let previousSuppressEventInput = suppressEventInput
+        suppressEventInput = false
+        keyDown(with: event)
+        suppressEventInput = previousSuppressEventInput
+        return true
     }
 
     func performDebugMouseCommands(_ commands: [String]) {
@@ -845,6 +935,11 @@
             keyboardCommandsApplied = []
             lastKeyboardCommand = nil
             lastKeyboardAppIndexCommand = nil
+            appShelfIndexKeyDownCount = 0
+            lastAppShelfIndexKeySymbol = nil
+            clearWindowIndexKeyPending()
+            lastWindowIndexKeyCommand = nil
+            lastWindowIndexKeyCommitCode = nil
             lastBoundaryBounceAxis = nil
             lastBoundaryBounceDirection = nil
             boundaryBounceCount = 0
@@ -1269,9 +1364,16 @@
             "selectedWindowID": effectiveSelection?.windowID ?? NSNull(),
             "keyboardFocusedAppGroupIndex": keyboardFocusedAppGroupIndex ?? NSNull(),
             "keyboardFocusedWindowID": keyboardFocusedWindowID ?? NSNull(),
+            "horizontalAppDefaultWindowID": horizontalAppDefaultWindowID ?? NSNull(),
             "keyboardCommandsApplied": keyboardCommandsApplied,
             "lastKeyboardCommand": lastKeyboardCommand ?? NSNull(),
             "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,
@@ -1351,6 +1453,7 @@
         if let indexSymbol = appShelfIndexSymbol(fromKeyboardCommand: command) {
             let recordedCommand = "app:\(indexSymbol)"
             recordKeyboardCommand(recordedCommand)
+            clearWindowIndexKeyPending()
             if !focusAppShelfItemForKeyboard(indexSymbol: indexSymbol, commandLabel: recordedCommand) {
                 selectionChangedByLastCommand = false
             }
@@ -1359,6 +1462,7 @@
 
         switch command {
         case "left":
+            clearWindowIndexKeyPending()
             recordKeyboardCommand("left")
             if isHorizontalMasonryMode {
                 moveSelection(.left)
@@ -1366,6 +1470,7 @@
                 selectionChangedByLastCommand = false
             }
         case "right":
+            clearWindowIndexKeyPending()
             recordKeyboardCommand("right")
             if isHorizontalMasonryMode {
                 moveSelection(.right)
@@ -1373,6 +1478,7 @@
                 selectionChangedByLastCommand = false
             }
         case "up":
+            clearWindowIndexKeyPending()
             recordKeyboardCommand("up")
             if isHorizontalMasonryMode {
                 moveSelection(.up)
@@ -1380,6 +1486,7 @@
                 moveVerticalSelectionWithinFocusedColumn(.up)
             }
         case "down":
+            clearWindowIndexKeyPending()
             recordKeyboardCommand("down")
             if isHorizontalMasonryMode {
                 moveSelection(.down)
@@ -1387,19 +1494,22 @@
                 moveVerticalSelectionWithinFocusedColumn(.down)
             }
         case "enter", "return", "commit":
+            clearWindowIndexKeyPending()
             recordKeyboardCommand("enter")
             selectionChangedByLastCommand = false
             commitCurrentSelection()
         case "tab":
+            clearWindowIndexKeyPending()
             if isHorizontalMasonryMode {
                 recordKeyboardCommand("tab")
-                moveSelection(.right)
+                moveHorizontalMasonryTabSelection()
             } else {
                 tabIgnoredCount += 1
                 recordKeyboardCommand("tabIgnored")
                 selectionChangedByLastCommand = false
             }
         default:
+            clearWindowIndexKeyPending()
             recordKeyboardCommand("unknown:\(command)")
             selectionChangedByLastCommand = false
         }
@@ -1411,7 +1521,6 @@
     }
 
     private func handleAppShelfIndexKey(_ event: NSEvent) -> Bool {
-        guard !isHorizontalMasonryMode else { return false }
         let flags = event.modifierFlags.intersection(.deviceIndependentFlagsMask)
         guard flags.isDisjoint(with: [.command, .control]) else { return false }
         guard let characters = event.charactersIgnoringModifiers,
@@ -1420,7 +1529,53 @@
             return false
         }
 
+        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
     }
 
@@ -1451,6 +1606,47 @@
         )
     }
 
+    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
     private func focusAppShelfItemForKeyboard(
         appGroupIndex: Int,
@@ -1469,6 +1665,9 @@
         clearKeyboardBoundaryFeedback()
         ensureAppShelfItemVisible(appGroupIndex)
         layoutSubtreeIfNeeded()
+        if isHorizontalMasonryMode {
+            _ = selectHorizontalMasonryDefaultWindowForApp(appGroupIndex)
+        }
         hoverAppGroup(appGroupIndex, source: .keyboard)
         needsLayout = true
         return true
@@ -1496,6 +1695,53 @@
     private var appHoverTargetAppGroupIndex: Int? {
         guard case .app(let appGroupIndex) = hoverTarget else { return nil }
         return appGroupIndex
+    }
+
+    private var horizontalAppDefaultWindowID: UInt32? {
+        guard isHorizontalMasonryMode,
+              case .app(let appGroupIndex) = hoverTarget
+        else {
+            return nil
+        }
+        return firstHorizontalMasonryCard(for: appGroupIndex)?.item.window.id
+    }
+
+    private func firstHorizontalMasonryCard(for appGroupIndex: Int) -> WaterfallCardLayers? {
+        waterfallColumns
+            .first { $0.column.appGroupIndex == appGroupIndex }?
+            .cards
+            .sorted { $0.item.windowIndex < $1.item.windowIndex }
+            .first
+    }
+
+    private func isHorizontalAppDefaultCard(_ card: WaterfallCardLayers) -> Bool {
+        guard isHorizontalMasonryMode,
+              card.item.window.id == horizontalAppDefaultWindowID
+        else {
+            return false
+        }
+        return true
+    }
+
+    @discardableResult
+    private func selectHorizontalMasonryDefaultWindowForApp(
+        _ appGroupIndex: Int,
+        recordsSelectionChange: Bool = false
+    ) -> QuickSwitchSelection? {
+        guard isHorizontalMasonryMode,
+              let card = firstHorizontalMasonryCard(for: appGroupIndex)
+        else {
+            return nil
+        }
+
+        let previousSelection = effectiveSelection
+        let selection = selectionForCard(card)
+        currentSelection = selection
+        columnSelectionHistory[selection.appGroupIndex] = selection.windowIndex
+        if recordsSelectionChange {
+            selectionChangedByLastCommand = previousSelection != selection
+        }
+        return selection
     }
 
     private func moveVerticalSelectionWithinFocusedColumn(_ direction: QuickSwitchKeyboardDirection) {
@@ -1641,6 +1887,7 @@
             .trimmingCharacters(in: .whitespacesAndNewlines)
             .lowercased()
         guard !command.isEmpty else { return }
+        clearWindowIndexKeyPending()
 
         let parts = command.split(separator: ":").map(String.init)
         switch parts.first {
@@ -1951,6 +2198,34 @@
         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) {
         let selection = QuickSwitchSelection(
             appGroupIndex: card.item.appGroupIndex,
@@ -2040,6 +2315,11 @@
         hoveredSpaceID = target.spaceID
         hoveredSpaceLaneID = target.spaceLaneID
 
+        if case .app(let appGroupIndex) = target, isHorizontalMasonryMode {
+            keyboardFocusedWindowID = nil
+            _ = selectHorizontalMasonryDefaultWindowForApp(appGroupIndex)
+        }
+
         if alignsWaterfallWithAppShelf, let appGroupIndex = target.appGroupIndex {
             alignWaterfallColumnWithAppShelfIcon(appGroupIndex: appGroupIndex, animated: true)
         }
@@ -2089,29 +2369,360 @@
     }
 
     private func moveHorizontalMasonrySelection(_ direction: QuickSwitchKeyboardDirection) {
-        guard let current = currentSelection ?? currentViewModel?.initialSelection,
-              let next = nextHorizontalMasonrySelection(from: current, direction: direction)
+        layoutSubtreeIfNeeded()
+
+        let nodes = horizontalKeyboardFocusNodes()
+        guard !nodes.isEmpty,
+              let current = currentHorizontalKeyboardFocusNode(in: nodes),
+              let next = nextHorizontalKeyboardFocusNode(from: current, direction: direction, in: nodes)
         else {
             DevelopmentDiagnostics.log("quickSwitch.view.moveHorizontalMasonrySelection.blocked", [
                 "direction": String(describing: direction),
+                "hasNodes": !nodes.isEmpty,
                 "hasSelection": (currentSelection ?? currentViewModel?.initialSelection) != nil
             ])
+            selectionChangedByLastCommand = false
+            return
+        }
+
+        focusHorizontalKeyboardNode(next, direction: direction)
+        DevelopmentDiagnostics.log("quickSwitch.view.moveHorizontalMasonrySelection", [
+            "direction": String(describing: direction),
+            "kind": next.kind.rawValue,
+            "appGroupIndex": next.appGroupIndex,
+            "windowIndex": next.windowIndex ?? -1,
+            "windowID": next.windowID ?? 0
+        ])
+    }
+
+    private func moveHorizontalMasonryTabSelection() {
+        guard let current = currentSelection ?? currentViewModel?.initialSelection,
+              let next = nextHorizontalMasonrySelection(from: current, direction: .right)
+        else {
+            DevelopmentDiagnostics.log("quickSwitch.view.moveHorizontalMasonryTabSelection.blocked", [
+                "hasSelection": (currentSelection ?? currentViewModel?.initialSelection) != nil
+            ])
+            selectionChangedByLastCommand = false
             return
         }
 
         columnSelectionHistory[current.appGroupIndex] = current.windowIndex
         let previousSelection = effectiveSelection
         currentSelection = next
+        keyboardFocusedAppGroupIndex = next.appGroupIndex
+        keyboardFocusedWindowID = next.windowID
         columnSelectionHistory[next.appGroupIndex] = next.windowIndex
         selectionChangedByLastCommand = previousSelection != next
         clearKeyboardBoundaryFeedback()
+        setHoverTarget(
+            .window(appGroupIndex: next.appGroupIndex, windowID: next.windowID, spaceID: nil),
+            source: .keyboard
+        )
         ensureCurrentSelectionVisible(horizontalIntent: .alignWithAppShelf(animated: true))
-        DevelopmentDiagnostics.log("quickSwitch.view.moveHorizontalMasonrySelection", [
-            "direction": String(describing: direction),
+        DevelopmentDiagnostics.log("quickSwitch.view.moveHorizontalMasonryTabSelection", [
             "appGroupIndex": next.appGroupIndex,
             "windowIndex": next.windowIndex,
             "windowID": next.windowID
         ])
+        needsLayout = true
+    }
+
+    private func horizontalKeyboardFocusNodes() -> [HorizontalKeyboardFocusNode] {
+        var nodes: [HorizontalKeyboardFocusNode] = []
+        nodes.reserveCapacity(appShelfItems.count + waterfallColumns.reduce(0) { $0 + $1.cards.count })
+
+        for (index, item) in appShelfItems.enumerated() {
+            let frame = item.iconLayer.frame.offsetBy(
+                dx: shelfLayer.frame.minX
+                    + appShelfContentLayer.frame.minX
+                    + item.containerLayer.frame.minX,
+                dy: shelfLayer.frame.minY
+                    + appShelfContentLayer.frame.minY
+                    + item.containerLayer.frame.minY
+            )
+            nodes.append(HorizontalKeyboardFocusNode(
+                kind: .app,
+                appGroupIndex: item.item.appGroupIndex,
+                windowIndex: nil,
+                windowID: nil,
+                spaceID: nil,
+                frame: frame,
+                order: index
+            ))
+        }
+
+        var order = appShelfItems.count
+        for column in waterfallColumns.sorted(by: { $0.column.appGroupIndex < $1.column.appGroupIndex }) {
+            for card in column.cards.sorted(by: { $0.item.windowIndex < $1.item.windowIndex }) {
+                let frame = card.containerLayer.frame.offsetBy(
+                    dx: waterfallLayer.frame.minX
+                        + waterfallContentLayer.frame.minX
+                        + column.containerLayer.frame.minX
+                        + column.cardsClipLayer.frame.minX,
+                    dy: waterfallLayer.frame.minY
+                        + waterfallContentLayer.frame.minY
+                        + column.containerLayer.frame.minY
+                        + column.cardsClipLayer.frame.minY
+                )
+                nodes.append(HorizontalKeyboardFocusNode(
+                    kind: .window,
+                    appGroupIndex: card.item.appGroupIndex,
+                    windowIndex: card.item.windowIndex,
+                    windowID: card.item.window.id,
+                    spaceID: card.item.primarySpaceID,
+                    frame: frame,
+                    order: order
+                ))
+                order += 1
+            }
+        }
+
+        return nodes
+    }
+
+    private func currentHorizontalKeyboardFocusNode(
+        in nodes: [HorizontalKeyboardFocusNode]
+    ) -> HorizontalKeyboardFocusNode? {
+        if case .app(let appGroupIndex) = hoverTarget,
+           let node = nodes.first(where: { $0.kind == .app && $0.appGroupIndex == appGroupIndex }) {
+            return node
+        }
+
+        if let keyboardFocusedWindowID,
+           let node = nodes.first(where: { $0.kind == .window && $0.windowID == keyboardFocusedWindowID }) {
+            return node
+        }
+
+        if case .window(_, let windowID, _) = hoverTarget,
+           let node = nodes.first(where: { $0.kind == .window && $0.windowID == windowID }) {
+            return node
+        }
+
+        if let selection = effectiveSelection,
+           let node = nodes.first(where: { $0.kind == .window && $0.windowID == selection.windowID }) {
+            return node
+        }
+
+        return nodes.min { $0.order < $1.order }
+    }
+
+    private func nextHorizontalKeyboardFocusNode(
+        from current: HorizontalKeyboardFocusNode,
+        direction: QuickSwitchKeyboardDirection,
+        in nodes: [HorizontalKeyboardFocusNode]
+    ) -> HorizontalKeyboardFocusNode? {
+        let candidates = nodes.filter { !$0.matches(current) }
+        guard !candidates.isEmpty else { return current }
+
+        if current.kind == .app,
+           direction == .down,
+           let firstWindow = firstHorizontalWindowNode(for: current.appGroupIndex, in: nodes) {
+            return firstWindow
+        }
+
+        if current.kind == .window,
+           direction == .up,
+           current.windowID == firstHorizontalMasonryCard(for: current.appGroupIndex)?.item.window.id,
+           let appNode = nodes.first(where: { $0.kind == .app && $0.appGroupIndex == current.appGroupIndex }) {
+            return appNode
+        }
+
+        switch direction {
+        case .left, .right:
+            let sameKindCandidates = candidates.filter { $0.kind == current.kind }
+            return nextHorizontalFocusByX(
+                from: current,
+                direction: direction,
+                candidates: sameKindCandidates.isEmpty ? candidates : sameKindCandidates
+            )
+        case .up, .down:
+            return nextHorizontalFocusByY(from: current, direction: direction, candidates: candidates)
+        }
+    }
+
+    private func firstHorizontalWindowNode(
+        for appGroupIndex: Int,
+        in nodes: [HorizontalKeyboardFocusNode]
+    ) -> HorizontalKeyboardFocusNode? {
+        nodes
+            .filter { $0.kind == .window && $0.appGroupIndex == appGroupIndex }
+            .min { lhs, rhs in
+                (lhs.windowIndex ?? .max, lhs.order) < (rhs.windowIndex ?? .max, rhs.order)
+            }
+    }
+
+    private func nextHorizontalFocusByX(
+        from current: HorizontalKeyboardFocusNode,
+        direction: QuickSwitchKeyboardDirection,
+        candidates: [HorizontalKeyboardFocusNode]
+    ) -> HorizontalKeyboardFocusNode? {
+        let epsilon: CGFloat = 0.5
+        let forward = direction == .right
+        let directional = candidates.filter { node in
+            forward
+                ? node.center.x > current.center.x + epsilon
+                : node.center.x < current.center.x - epsilon
+        }
+        let sameBand = directional.filter { isHorizontalFocusSameBand($0, current) }
+        let pool = sameBand.isEmpty ? directional : sameBand
+        if let next = pool.sorted(by: horizontalFocusXSort(from: current, forward: forward)).first {
+            return next
+        }
+
+        let wrapSameBand = candidates.filter { isHorizontalFocusSameBand($0, current) }
+        let wrapPool = wrapSameBand.isEmpty ? candidates : wrapSameBand
+        return wrapPool.sorted(by: horizontalFocusXWrapSort(from: current, forward: forward)).first
+    }
+
+    private func nextHorizontalFocusByY(
+        from current: HorizontalKeyboardFocusNode,
+        direction: QuickSwitchKeyboardDirection,
+        candidates: [HorizontalKeyboardFocusNode]
+    ) -> HorizontalKeyboardFocusNode? {
+        let epsilon: CGFloat = 0.5
+        let upward = direction == .up
+        let directional = candidates.filter { node in
+            upward
+                ? node.center.y > current.center.y + epsilon
+                : node.center.y < current.center.y - epsilon
+        }
+        if let next = directional.sorted(by: horizontalFocusYSort(from: current, upward: upward)).first {
+            return next
+        }
+        return candidates.sorted(by: horizontalFocusYWrapSort(from: current, upward: upward)).first
+    }
+
+    private func isHorizontalFocusSameBand(
+        _ lhs: HorizontalKeyboardFocusNode,
+        _ rhs: HorizontalKeyboardFocusNode
+    ) -> Bool {
+        let tolerance = max(lhs.frame.height, rhs.frame.height) * 0.75
+        return abs(lhs.center.y - rhs.center.y) <= tolerance
+    }
+
+    private func horizontalFocusXSort(
+        from current: HorizontalKeyboardFocusNode,
+        forward: Bool
+    ) -> (HorizontalKeyboardFocusNode, HorizontalKeyboardFocusNode) -> Bool {
+        { lhs, rhs in
+            let lhsPrimary = abs(lhs.center.x - current.center.x)
+            let rhsPrimary = abs(rhs.center.x - current.center.x)
+            if abs(lhsPrimary - rhsPrimary) > 0.5 {
+                return lhsPrimary < rhsPrimary
+            }
+
+            let lhsSecondary = abs(lhs.center.y - current.center.y)
+            let rhsSecondary = abs(rhs.center.y - current.center.y)
+            if abs(lhsSecondary - rhsSecondary) > 0.5 {
+                return lhsSecondary < rhsSecondary
+            }
+
+            return forward ? lhs.order < rhs.order : lhs.order > rhs.order
+        }
+    }
+
+    private func horizontalFocusXWrapSort(
+        from current: HorizontalKeyboardFocusNode,
+        forward: Bool
+    ) -> (HorizontalKeyboardFocusNode, HorizontalKeyboardFocusNode) -> Bool {
+        { lhs, rhs in
+            if abs(lhs.center.x - rhs.center.x) > 0.5 {
+                return forward ? lhs.center.x < rhs.center.x : lhs.center.x > rhs.center.x
+            }
+
+            let lhsSecondary = abs(lhs.center.y - current.center.y)
+            let rhsSecondary = abs(rhs.center.y - current.center.y)
+            if abs(lhsSecondary - rhsSecondary) > 0.5 {
+                return lhsSecondary < rhsSecondary
+            }
+
+            return forward ? lhs.order < rhs.order : lhs.order > rhs.order
+        }
+    }
+
+    private func horizontalFocusYSort(
+        from current: HorizontalKeyboardFocusNode,
+        upward: Bool
+    ) -> (HorizontalKeyboardFocusNode, HorizontalKeyboardFocusNode) -> Bool {
+        { lhs, rhs in
+            let lhsPrimary = abs(lhs.center.y - current.center.y)
+            let rhsPrimary = abs(rhs.center.y - current.center.y)
+            if abs(lhsPrimary - rhsPrimary) > 0.5 {
+                return lhsPrimary < rhsPrimary
+            }
+
+            let lhsSecondary = abs(lhs.center.x - current.center.x)
+            let rhsSecondary = abs(rhs.center.x - current.center.x)
+            if abs(lhsSecondary - rhsSecondary) > 0.5 {
+                return lhsSecondary < rhsSecondary
+            }
+
+            return upward ? lhs.order < rhs.order : lhs.order > rhs.order
+        }
+    }
+
+    private func horizontalFocusYWrapSort(
+        from current: HorizontalKeyboardFocusNode,
+        upward: Bool
+    ) -> (HorizontalKeyboardFocusNode, HorizontalKeyboardFocusNode) -> Bool {
+        { lhs, rhs in
+            if abs(lhs.center.y - rhs.center.y) > 0.5 {
+                return upward ? lhs.center.y < rhs.center.y : lhs.center.y > rhs.center.y
+            }
+
+            let lhsSecondary = abs(lhs.center.x - current.center.x)
+            let rhsSecondary = abs(rhs.center.x - current.center.x)
+            if abs(lhsSecondary - rhsSecondary) > 0.5 {
+                return lhsSecondary < rhsSecondary
+            }
+
+            return upward ? lhs.order < rhs.order : lhs.order > rhs.order
+        }
+    }
+
+    private func focusHorizontalKeyboardNode(
+        _ node: HorizontalKeyboardFocusNode,
+        direction _: QuickSwitchKeyboardDirection
+    ) {
+        switch node.kind {
+        case .app:
+            keyboardFocusedAppGroupIndex = node.appGroupIndex
+            keyboardFocusedWindowID = nil
+            clearKeyboardBoundaryFeedback()
+            ensureAppShelfItemVisible(node.appGroupIndex)
+            _ = selectHorizontalMasonryDefaultWindowForApp(
+                node.appGroupIndex,
+                recordsSelectionChange: true
+            )
+            hoverAppGroup(node.appGroupIndex, source: .keyboard)
+        case .window:
+            guard let windowIndex = node.windowIndex,
+                  let windowID = node.windowID
+            else {
+                selectionChangedByLastCommand = false
+                return
+            }
+
+            let previousSelection = effectiveSelection
+            let next = QuickSwitchSelection(
+                appGroupIndex: node.appGroupIndex,
+                windowIndex: windowIndex,
+                windowID: windowID
+            )
+            keyboardFocusedAppGroupIndex = node.appGroupIndex
+            keyboardFocusedWindowID = windowID
+            currentSelection = next
+            columnSelectionHistory[next.appGroupIndex] = next.windowIndex
+            selectionChangedByLastCommand = previousSelection != next
+            clearKeyboardBoundaryFeedback()
+            ensureAppShelfItemVisible(node.appGroupIndex)
+            setHoverTarget(
+                .window(appGroupIndex: node.appGroupIndex, windowID: windowID, spaceID: node.spaceID),
+                source: .keyboard
+            )
+            ensureCurrentSelectionVisible(horizontalIntent: .alignWithAppShelf(animated: true))
+        }
+
         needsLayout = true
     }
 
@@ -2840,7 +3451,8 @@
                     string: waterfallMetaText(for: window),
                     fontSize: 10,
                     weight: .regular,
-                    color: .secondaryLabelColor
+                    color: .secondaryLabelColor,
+                    alignment: .right
                 )
                 let appIcon = CALayer()
                 appIcon.contentsGravity = .resizeAspect
@@ -3638,6 +4250,15 @@
             .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? {
         waterfallColumns
             .lazy
@@ -4403,10 +5024,13 @@
         let isSelected = card.item.window.id == effectiveSelection?.windowID
         let isHovered = card.item.window.id == hoveredWindowID
         let isKeyboardFocused = card.item.window.id == keyboardFocusedWindowID
+        let isHorizontalAppDefaultFocused = isHorizontalAppDefaultCard(card)
         let isAppLinked = isWaterfallCardAppLinked(card)
         applyWaterfallCardVisualState(
             card,
-            selected: shouldShowSelectedVisual(isSelected: isSelected, isHovered: isHovered) || isKeyboardFocused,
+            selected: shouldShowSelectedVisual(isSelected: isSelected, isHovered: isHovered)
+                || isKeyboardFocused
+                || isHorizontalAppDefaultFocused,
             hovered: isHovered,
             appLinked: isAppLinked
         )
@@ -5190,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 {
@@ -5710,11 +6353,13 @@
                 "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)",
                 "isSelected": card.item.window.id == effectiveSelection?.windowID,
                 "isKeyboardFocused": card.item.window.id == keyboardFocusedWindowID,
+                "isHorizontalAppDefault": isHorizontalAppDefaultCard(card),
                 "visualStates": waterfallCardVisualStates(for: card),
                 "thumbnailStrategy": thumbnailStrategyString(for: card.item.window),
                 "screenshotSource": screenshotSourceString(screenshotSource, for: card.item.window),
@@ -5739,6 +6384,7 @@
                 "closeButtonGlyphLineWidth": Double(card.closeButton.glyphLayer.lineWidth),
                 "shineVisible": card.shineLayer.opacity > 0,
                 "zPosition": Double(card.containerLayer.zPosition),
+                "bounds": dictionary(from: card.containerLayer.bounds),
                 "frame": dictionary(from: card.containerLayer.frame),
                 "visibleFrame": dictionary(from: visibleFrame),
                 "titleTruncationMode": "middle"
@@ -5834,8 +6480,11 @@
         let isSelected = card.item.window.id == effectiveSelection?.windowID
         let isHovered = card.item.window.id == hoveredWindowID
         let isKeyboardFocused = card.item.window.id == keyboardFocusedWindowID
+        let isHorizontalAppDefaultFocused = isHorizontalAppDefaultCard(card)
         let isAppLinked = isWaterfallCardAppLinked(card)
-        if shouldShowSelectedVisual(isSelected: isSelected, isHovered: isHovered) || isKeyboardFocused {
+        if shouldShowSelectedVisual(isSelected: isSelected, isHovered: isHovered)
+            || isKeyboardFocused
+            || isHorizontalAppDefaultFocused {
             states.append("selected")
         } else if isSelected {
             states.append("selectedVisualSuppressed")
@@ -5843,6 +6492,9 @@
         if isKeyboardFocused {
             states.append("keyboardFocused")
         }
+        if isHorizontalAppDefaultFocused {
+            states.append("appDefault")
+        }
         if isHovered {
             states.append("hover")
         }

--
Gitblit v1.9.3