Отправить NSEvent в фоновое приложение - PullRequest
7 голосов
/ 15 сентября 2011

Мне нужно отправить комбинацию клавиш ^ ⌘C в фоновое приложение с идентификатором пакета com.company.app.Затем комбинация клавиш должна активировать пункт меню в этом приложении.

К сожалению, я понятия не имею, как это сделать.Некоторые исследования показали, что NSEvent и CGEvent API используют CGEventPostToPSN(), но мне не удалось заставить его работать правильно, так как я не знаю, как настроить комбинацию клавиш.CGEventPost(), похоже, не работал с событиями, которые я создал, даже если нужное приложение является активным.

Вот код, который я в конце концов придумал, но он не работает:

CGWindowID windowNumber;
NSEvent *event = [NSEvent keyEventWithType:NSKeyUp
                                  location:NSZeroPoint
                             modifierFlags:(NSControlKeyMask | NSCommandKeyMask)
                                 timestamp:[[NSProcessInfo processInfo] systemUptime]
                              windowNumber:windowNumber
                                   context:[NSGraphicsContext currentContext]
                                characters:@"c"
               charactersIgnoringModifiers:@"c"
                                 isARepeat:NO
                                   keyCode:8];
CGEventRef eventRef = [event CGEvent];

Что мне теперь делать с этим событием?Почему NSEvent нет эквивалента для CGEventPost()?Есть ли более простой способ активировать этот пункт меню, чем публикация события?Я легко могу получить экземпляр NSRunningApplication, но нет подходящего API для выполнения моей задачи.

Обновление: У меня все работает:

- (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];

1 Ответ

1 голос
/ 15 сентября 2011

Несколько заметок:

  1. Отправка события keyDown тоже не просто keyUp. Таким образом, это будет больше похоже на настоящее нажатие клавиши.

  2. Вам необходимо вызвать CGEventPostToPSN с этим CGEvent или, по крайней мере, НЕКОТОРЫЙ вызов, который отправляет событие.

  3. Вы пытались вместо этого вызвать CGPostKeyboardEvent ()?
...