`CGEventPost` creates different event characters on key up

Viewed 48

I simulate a key press on macOS 12 using CGEventKeyboardSetUnicodeString and CGEventPost. Despite creating the key up and down events with the same parameters, the resulting NSEvent for key up has a different character value. Why?

Here is how I generate the key press:

    CGEventRef keyDown, keyUp;
    UniChar unicode = 'P';

    keyDown = CGEventCreateKeyboardEvent(NULL, 0, true);
    CGEventKeyboardSetUnicodeString(keyDown, 1, &unicode);
    CGEventPost(kCGSessionEventTap, keyDown);
    CFRelease(keyDown);

    keyUp = CGEventCreateKeyboardEvent(NULL, 0, false);
    CGEventKeyboardSetUnicodeString(keyUp, 1, &unicode);
    CGEventPost(kCGSessionEventTap, keyUp);
    CFRelease(keyUp);

In my first responder, I have:

- (void)keyDown:(NSEvent *)event
{
    NSLog(@"%s", [event.characters UTF8String]);
}

- (void)keyUp:(NSEvent *)event
{
    NSLog(@"%s", [event.characters UTF8String]);
}

But this prints

2022-09-08 12:04:55.570063-0400 test[14010:5447113] P

2022-09-08 12:04:55.570252-0400 test[14010:5447113] a

Why does the key up event have the character value "a" instead of "P", despite being create with the same parameters?

2 Answers

Well, since I totally misunderstood your question, I rewrote the answer.

Why it shows lowercase 'a'?

Take a look at this line:

keyUp = CGEventCreateKeyboardEvent(NULL, 0, false);

The second parameter, it's a virtual key code. You pass a zero to it. which is kVK_ANSI_A(0x00) in events.h.

It's exactly the lowercase "a."

You can do an experiment by replacing 2 key codes in CGEventCreateKeyboardEvent with 1. you will find it works the same, except it prints "s" in keyup: method. As 0x01 is kVK_ANSI_S, which is the keycode for letter "s".

As for why it does not print "P" in keyup:?

Take a look at this answer form eskimo:

CGEventKeyboardSetUnicodeString has always been problematic. It seems that something changed in macOS 12 to make this happen more often, but this has always been a possibility.

If you look at the documentation of CGEventKeyboardSetUnicodeString

You will notice this statement:

Note that application frameworks may ignore the Unicode string in a keyboard event and do their own translation based on the virtual keycode and perceived event state.

So I think your unicode string is ignored in keyup: method.

Is it acceptable to you?

Cheers.

Could it be possible you are using the wrong event type.

kCGEventKeyDown

and

kCGEventKeyUp

are not the same as

kCGEventKeyPress

kCGEventKeyPress

is the event that is sent when a key is pressed and released.

kCGEventKeyDown

is sent when a key is pressed.

kCGEventKeyUp

is sent when a key is released.

I probably didn't understand all of your code so sorry if my answer isn't helpful

Related