Search code examples
swiftmacoscocoaeventscore-graphics

How to simulate a continuous key press


I need to simulate a continuous key press. For example hold down the 'c' key for 5 seconds. To simulate a key press event I tried to use CGEventCreateKeyboardEvent:

let event:CGEventRef! = CGEventCreateKeyboardEvent(nil, 8, true)
CGEventPost(CGEventTapLocation.CGSessionEventTap, event)

But it acts like if the button is tapped and then released immediately. I need to create an event that keeps holding the button (key down) and then release it (key up).


Solution

  • I'm not sure what you are trying to achieve, but it appears that the system will continue to hold the button down. This simple experiment shows it.

    func applicationDidFinishLaunching(aNotification: NSNotification) {
        print("waiting 4 seconds, use this time to position your cursor in a text field")
        let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(4 * Double(NSEC_PER_SEC)))
        dispatch_after(delayTime, dispatch_get_main_queue(), {
            self.insertLetterZ()
        })
    }
    
    func insertLetterZ() {
        print("pressing shift")
        self.tapButton(56)
    
        print("holding button for 2 seconds")
        let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(2 * Double(NSEC_PER_SEC)))
        dispatch_after(delayTime, dispatch_get_main_queue(), {
            print("tapping z, but Z will be selected (since shift is still being pressed)")
            self.tapButton(6)
    
            print("untapping z and shift")
            self.untapButton(6)
            self.untapButton(56)
        })
    }
    
    func tapButton(button: CGKeyCode) {
        let event = CGEventCreateKeyboardEvent(nil, button, true)
        CGEventPost(CGEventTapLocation.CGSessionEventTap, event)
    }
    
    func untapButton(button: CGKeyCode) {
        let event = CGEventCreateKeyboardEvent(nil, button, false)
        CGEventPost(CGEventTapLocation.CGSessionEventTap, event)
    }
    

    This code however does not capitalize a letter if a user taps the keyboard when shift is programmatically pressed. I have also noticed that if the cursor location is changed between shift and z being tapped "z" will be inserted instead of "Z"