1

I want the user to be able to press and hold a key as hardware input without anything being typing on screen. For example, I want to be able to use a global listener to detect when the "a" key is pressed and held without "aaaaaaaaaa" being typed on the screen. So far I've looked at a few other threads like this, but I've been unable to effectively translate this to Swift to use with my Global Monitors. If anyone has idea of how to do this in Swift, it would be really helpful. This is what I have so far:

func setUpKeyInterception ( ) {

    keyDownPort = CGEvent . tapCreate( tap: . cghidEventTap, place: . headInsertEventTap, options: . defaultTap, eventsOfInterest: CGEventMask((1 << CGEventType.keyDown.rawValue)), callback: keyDownCallback , userInfo: UnsafeMutableRawPointer(Unmanaged.passUnretained(self).toOpaque()))! //keyDownPort is a CFMachPort

    keyDownRunLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, keyDownPort , 0) //keyDownRunLoopSource is a CFRunLoopSource

    CFRunLoopAddSource(CFRunLoopGetCurrent(), keyDownRunLoopSource, CFRunLoopMode . commonModes)


}

func keyDownCallback ( proxy: CGEventTapProxy, type: CGEventType, event: CGEvent, ptr: UnsafeMutableRawPointer ) -> Unmanaged<CGEvent>? {

    if ( event . getIntegerValueField ( CGEventField . keyboardEventKeycode ) == 0x2A ) || ( event . getIntegerValueField ( CGEventField . keyboardEventKeycode ) == 0x51 ){

        event . setIntegerValueField ( CGEventField . keyboardEventKeycode , value: 0x03)

    }

    return nil

}
J. Doe
  • 19
  • 2

1 Answers1

0

Firstly, is it necessary to use a global monitor?. Repeating key press can be intercepted by overriding the sendEvent method of NSWindow's Subclass containing the text field.

class MyWindow: NSWindow {

    override func sendEvent(_ event: NSEvent) {
        if event.type == .keyDown && event.isARepeat {
            return
        }
        super.sendEvent(event)
    }
}
Bharat Gadde
  • 173
  • 1
  • 10