ShiftKeyUpChecker // Enforce keyCode equality between contextual events.
This commit is contained in:
parent
098a10dff7
commit
ee97c5a5f1
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue