vChewing-macOS/Packages/Qwertyyb_ShiftKeyUpChecker/Sources/ShiftKeyUpChecker/ShiftKeyUpChecker.swift

64 lines
2.4 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// (c) 2022 and onwards Qwertyyb (MIT License).
// ====================
// This code is released under the MIT license (SPDX-License-Identifier: MIT)
import AppKit
private extension Date {
static func - (lhs: Date, rhs: Date) -> TimeInterval {
lhs.timeIntervalSinceReferenceDate - rhs.timeIntervalSinceReferenceDate
}
}
public struct ShiftKeyUpChecker {
// MARK: -
public init(useLShift: Bool = false, useRShift: Bool = false) {
toggleWithLShift = useLShift
toggleWithRShift = useRShift
}
public var toggleWithLShift = false
public var toggleWithRShift = false
public var lShiftKeyCode: UInt16 = 56
public var rShiftKeyCode: UInt16 = 60
public var enabled: Bool { toggleWithLShift || toggleWithRShift }
private var checkModifier: NSEvent.ModifierFlags { .shift }
private var checkKeyCode: [UInt16] {
var result = [UInt16]()
if toggleWithLShift { result.append(lShiftKeyCode) }
if toggleWithRShift { result.append(rShiftKeyCode) }
return result
}
// MARK: -
///
private let delayInterval = 0.3
private var previousKeyCode: UInt16?
private var lastTime: Date = .init()
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
}
// To confirm that only the shift key is "pressed-and-released".
public mutating func check(_ event: NSEvent) -> Bool {
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
}
}