开发者

Send NSEvent to background app

开发者 https://www.devze.com 2023-04-05 06:52 出处:网络
I need to send the key combo ^⌘C to a background app with the bundle identifier com.company.app. The key combo should then activate a menu item in that application.

I need to send the key combo ^⌘C to a background app with the bundle identifier com.company.app. The key combo should then activate a menu item in that application.

Unfortunately, I have no clue how to do that. Some research pointed me to the NSEvent and CGEvent API using CGEventPostToPSN(), but I was unable to get it work correctly, as I don't know how to set up the key combo. CGEventPost() didn't seem to work with the events I created, even if the desired app is the active one.

Here is the code I eventually came up with but that doesn't work:

CGWindowID windowNumber;
NSEvent *event = [NSEvent keyEventWithType:NSKeyUp
                                  location:NSZeroPoint
                             modifierFlags:(NSControlKeyMask | NSCommandKeyMask)
                                 timestamp:[[NSProcessInfo process开发者_开发知识库Info] systemUptime]
                              windowNumber:windowNumber
                                   context:[NSGraphicsContext currentContext]
                                characters:@"c"
               charactersIgnoringModifiers:@"c"
                                 isARepeat:NO
                                   keyCode:8];
CGEventRef eventRef = [event CGEvent];

What am I supposed to do with that event now? Why is there no NSEvent equivalent for CGEventPost()? Is there even an easier way to activate that menu item than posting an event? I can easily get an instance of NSRunningApplication, but there is no suitable API to accomplish my task.

Update: I got it working:

- (void) postFakedKeyboardEventForCopyScreenToPasteboardToPSN:(ProcessSerialNumber)psn {
    CGEventSourceRef source = CGEventSourceCreate(kCGEventSourceStatePrivate);
    CGEventRef keyDownEvent = CGEventCreateKeyboardEvent(source, (CGKeyCode)8, true);
    CGEventSetFlags(keyDownEvent, (kCGEventFlagMaskControl | kCGEventFlagMaskCommand));
    CGEventRef keyUpEvent = CGEventCreateKeyboardEvent(source, (CGKeyCode)8, false);
    CGEventSetFlags(keyUpEvent, (kCGEventFlagMaskControl | kCGEventFlagMaskCommand));
    CFRelease(source);

    CGEventPostToPSN(&psn, keyDownEvent);
    CFRelease(keyDownEvent);
    CGEventPostToPSN(&psn, keyUpEvent);
    CFRelease(keyUpEvent);
}

...

OSStatus err = noErr;
ProcessSerialNumber psn;
err = GetProcessForPID([simulator processIdentifier], &psn);
if (err == noErr)
    [self postFakedKeyboardEventForCopyScreenToPasteboardToPSN:psn];


A few notes:

  1. Send a keyDown event, too, not just keyUp. That way, it will be more like a real keypress.

  2. You need to call CGEventPostToPSN with that CGEvent, or at least SOME call that posts the event.

  3. Have you tried calling CGPostKeyboardEvent() instead?
0

精彩评论

暂无评论...
验证码 换一张
取 消