| | |
| | | @MainActor |
| | | final class QuickSwitchRootView: NSView { |
| | | private static let appShelfIndexSymbols = Array("1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ").map(String.init) |
| | | 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() |
| | |
| | | private var keyboardCommandsApplied: [String] = [] |
| | | private var lastKeyboardCommand: String? |
| | | private var lastKeyboardAppIndexCommand: String? |
| | | private var appShelfIndexKeyDownCount = 0 |
| | | private var lastAppShelfIndexKeySymbol: String? |
| | | private var lastBoundaryBounceAxis: String? |
| | | private var lastBoundaryBounceDirection: String? |
| | | private var boundaryBounceCount = 0 |
| | |
| | | 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]) { |
| | |
| | | "keyboardCommandsApplied": keyboardCommandsApplied, |
| | | "lastKeyboardCommand": lastKeyboardCommand ?? NSNull(), |
| | | "lastKeyboardAppIndexCommand": lastKeyboardAppIndexCommand ?? NSNull(), |
| | | "appShelfIndexKeyDownCount": appShelfIndexKeyDownCount, |
| | | "lastAppShelfIndexKeySymbol": lastAppShelfIndexKeySymbol ?? NSNull(), |
| | | "lastBoundaryBounceAxis": lastBoundaryBounceAxis ?? NSNull(), |
| | | "lastBoundaryBounceDirection": lastBoundaryBounceDirection ?? NSNull(), |
| | | "boundaryBounceCount": boundaryBounceCount, |
| | |
| | | } |
| | | |
| | | 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, |
| | |
| | | return false |
| | | } |
| | | |
| | | appShelfIndexKeyDownCount += 1 |
| | | lastAppShelfIndexKeySymbol = symbol |
| | | performKeyboardCommand(symbol) |
| | | return true |
| | | } |