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