diff --git a/Packages/Qwertyyb_ShiftKeyUpChecker/Sources/ShiftKeyUpChecker/ShiftKeyUpChecker.swift b/Packages/Qwertyyb_ShiftKeyUpChecker/Sources/ShiftKeyUpChecker/ShiftKeyUpChecker.swift index 6181ae84..e37f46b9 100644 --- a/Packages/Qwertyyb_ShiftKeyUpChecker/Sources/ShiftKeyUpChecker/ShiftKeyUpChecker.swift +++ b/Packages/Qwertyyb_ShiftKeyUpChecker/Sources/ShiftKeyUpChecker/ShiftKeyUpChecker.swift @@ -3,7 +3,6 @@ // This code is released under the MIT license (SPDX-License-Identifier: MIT) import AppKit -import Carbon private extension Date { static func - (lhs: Date, rhs: Date) -> TimeInterval { @@ -12,6 +11,8 @@ private extension Date { } public struct ShiftKeyUpChecker { + // MARK: - 威注音輸入法專有部分 + public init(useLShift: Bool = false, useRShift: Bool = false) { toggleWithLShift = useLShift toggleWithRShift = useRShift @@ -24,7 +25,7 @@ public struct ShiftKeyUpChecker { public var enabled: Bool { toggleWithLShift || toggleWithRShift } - private var checkModifier: NSEvent.ModifierFlags { NSEvent.ModifierFlags.shift } + private var checkModifier: NSEvent.ModifierFlags { .shift } private var checkKeyCode: [UInt16] { var result = [UInt16]() if toggleWithLShift { result.append(lShiftKeyCode) } @@ -32,43 +33,31 @@ public struct ShiftKeyUpChecker { return result } - private let delayInterval = 0.3 + // MARK: - 與業火五筆共用的內容 + /// 實現邏輯基本上是相同的,只是威注音這邊的行文風格習慣可能與業火五筆有不同。 + + private let delayInterval = 0.3 + private var previousKeyCode: UInt16? private var lastTime: Date = .init() - private var shiftIsBeingPressed = false - - private mutating func checkModifierKeyUp(event: NSEvent) -> Bool { - guard checkKeyCode.contains(event.keyCode) else { return false } - if event.type == .flagsChanged, - event.modifierFlags.intersection(.deviceIndependentFlagsMask) == .init(rawValue: 0), - Date() - lastTime <= delayInterval, shiftIsBeingPressed - { - // modifier keyup event - lastTime = Date(timeInterval: -3600 * 4, since: Date()) - return true - } - return false + private mutating func registerModifierKeyDown(event: NSEvent) { + var isKeyDown: Bool = event.type == .flagsChanged + // 注意:ModifierFlags 是 OptionSet,在使用 contains 時會在給定參數是「空集合」的時候返回 true(明明你可能想要 false)。 + isKeyDown = isKeyDown && event.modifierFlags.intersection(.deviceIndependentFlagsMask) == checkModifier + isKeyDown = isKeyDown && checkKeyCode.contains(event.keyCode) + lastTime = isKeyDown ? .init() : .init(timeInterval: .infinity * -1, since: Date()) + previousKeyCode = isKeyDown ? event.keyCode : nil } - private mutating func checkModifierKeyDown(event: NSEvent) -> Bool { - let isKeyDown = - event.type == .flagsChanged - && checkModifier.contains(event.modifierFlags.intersection(.deviceIndependentFlagsMask)) - && checkKeyCode.contains(event.keyCode) - if isKeyDown { - // modifier keydown event - lastTime = Date() - if event.modifierFlags.intersection(.deviceIndependentFlagsMask) == .shift { shiftIsBeingPressed = true } - } else { - lastTime = Date(timeInterval: -3600 * 4, since: Date()) - shiftIsBeingPressed = false - } - return false - } - - // To confirm that the shift key is "pressed-and-released". + // To confirm that only the shift key is "pressed-and-released". public mutating func check(_ event: NSEvent) -> Bool { - checkModifierKeyUp(event: event) || checkModifierKeyDown(event: event) + var met: Bool = event.type == .flagsChanged + met = met && checkKeyCode.contains(event.keyCode) + met = met && event.keyCode == previousKeyCode // 檢查 KeyCode 一致性。 + met = met && event.modifierFlags.intersection(.deviceIndependentFlagsMask).isEmpty + met = met && Date() - lastTime <= delayInterval + _ = met ? lastTime = Date(timeInterval: .infinity * -1, since: Date()) : registerModifierKeyDown(event: event) + return met } }