From d4279a9cbe4efcb7622557a2f46a660d833556b9 Mon Sep 17 00:00:00 2001 From: Christoffer Winterkvist Date: Fri, 15 Mar 2024 08:51:54 +0100 Subject: [PATCH] Add unique ids for keyboard event pairs (keyUp, keyDown) --- Sources/MachPort/MachPortEvent.swift | 20 +++++++++-- .../MachPort/MachPortEventController.swift | 34 +++++++++++++++++-- 2 files changed, 48 insertions(+), 6 deletions(-) diff --git a/Sources/MachPort/MachPortEvent.swift b/Sources/MachPort/MachPortEvent.swift index a76c535..787a57b 100644 --- a/Sources/MachPort/MachPortEvent.swift +++ b/Sources/MachPort/MachPortEvent.swift @@ -2,16 +2,22 @@ import CoreGraphics import Foundation public final class MachPortEvent: @unchecked Sendable { + public let id: UUID public let keyCode: Int64 public let event: CGEvent public let eventSource: CGEventSource? + public let isRepeat: Bool public let type: CGEventType public let lhs: Bool public var result: Unmanaged? - internal init(event: CGEvent, eventSource: CGEventSource?, - lhs: Bool, type: CGEventType, result: Unmanaged?) { + internal init(id: UUID, + event: CGEvent, eventSource: CGEventSource?, + isRepeat: Bool, lhs: Bool, type: CGEventType, + result: Unmanaged?) { + self.id = id self.keyCode = event.getIntegerValueField(.keyboardEventKeycode) + self.isRepeat = isRepeat self.event = event self.eventSource = eventSource self.lhs = lhs @@ -21,6 +27,14 @@ public final class MachPortEvent: @unchecked Sendable { public static func empty() -> MachPortEvent? { guard let event = CGEvent(source: nil) else { return nil } - return MachPortEvent(event: event, eventSource: nil, lhs: false, type: .null, result: nil) + return MachPortEvent( + id: UUID(), + event: event, + eventSource: nil, + isRepeat: false, + lhs: false, + type: .null, + result: nil + ) } } diff --git a/Sources/MachPort/MachPortEventController.swift b/Sources/MachPort/MachPortEventController.swift index a19c2a8..05ecb9c 100644 --- a/Sources/MachPort/MachPortEventController.swift +++ b/Sources/MachPort/MachPortEventController.swift @@ -12,6 +12,7 @@ public class MachPortEventPublisher { public final class MachPortEventController: MachPortEventPublisher, @unchecked Sendable { private(set) public var eventSource: CGEventSource! + private var previousId: UUID? private var machPort: CFMachPort? private var runLoopSource: CFRunLoopSource? private static var lhs: Bool = true @@ -137,10 +138,37 @@ public final class MachPortEventController: MachPortEventPublisher, @unchecked S if cgEvent.getIntegerValueField(.eventSourceUserData) == signature { return Unmanaged.passUnretained(cgEvent) } + + let isRepeat = cgEvent.getIntegerValueField(.keyboardEventAutorepeat) == 1 + let id: UUID + + switch cgEvent.type { + case .keyUp: + if let previousId { + id = previousId + } else { + id = UUID() + } + previousId = nil + case .keyDown: + if isRepeat, let previousId { + id = previousId + } else { + id = UUID() + previousId = id + } + default: + previousId = nil + id = UUID() + } + let result = Unmanaged.passUnretained(cgEvent) - let newEvent = MachPortEvent(event: cgEvent, eventSource: eventSource, - lhs: Self.lhs, type: type, - result: result) + let newEvent = MachPortEvent( + id: id, + event: cgEvent, eventSource: eventSource, + isRepeat: isRepeat, + lhs: Self.lhs, type: type, + result: result) if let onAllEventChange { if type == .flagsChanged {