ShiftKeyUpChecker // Enforce keyCode equality between contextual events.

This commit is contained in:
ShikiSuen 2023-09-15 00:37:11 +08:00
parent 098a10dff7
commit ee97c5a5f1
1 changed files with 23 additions and 34 deletions

View File

@ -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
} }
} }