Отправка нажатий клавиш CGEvents фоновым приложениям

#objective-c #cocoa #macos #nsevent #cgeventtap

#objective-c #cocoa #macos #nsevent #cgeventtap

Вопрос:

Я пытаюсь отправить клавишу ввода в фоновое приложение, подобное этому:

 CGEventRef a = CGEventCreateKeyboardEvent(eventSource, 36, true);
CGEventRef b = CGEventCreateKeyboardEvent(eventSource, 36, false);
CGEventPostToPSN(amp;psn, a);
CGEventPostToPSN(amp;psn, b);
  

Это не работает, я думаю, это потому, что приложение должно быть самым передним приложением для получения нажатий клавиш? Я прав? Если да, могу ли я каким-либо образом отправить это событие, не делая приложение активным первым? Если нет, то что я делаю не так?
Спасибо.

Ответ №1:

Приложения, которые находятся в фоновом режиме, не реагируют на ключевые события. У вас есть два варианта заставить ваше приложение обрабатывать их, когда оно работает в фоновом режиме: Нажатия на событие и [NSEvent addLocalMonitorForEventsMatchingMask:] . NSEvent Вариант довольно прост:

 // A block callback to handle the events
NSEvent * (^monitorHandler)(NSEvent *);
monitorHandler = ^NSEvent * (NSEvent * theEvent){
    NSLog(@"Got a keyDown: %d", [theEvent keyCode]);
    // The block can return the same event, a different 
    // event, or nil, depending on how you want it to be 
    // handled later. In this case, being in the background, 
    // there won't be any handling regardless.
    return theEvent;
};

// Creates an object that we don't own but must keep track of to
// remove later (see docs). Here, it is placed in an ivar.
monitor = [NSEvent addLocalMonitorForEventsMatchingMask:NSKeyDownMask 
                                                handler:monitorHandler];
  

но вы уже возитесь с нажатиями событий, так что, возможно, вам просто захочется пойти этим путем.

 // Creates an object that must be CFRelease'd when we're done
CFMachPortRef tap = CGEventTapCreateForPSN(myOwnPSN, 
                                       kCGTailAppendEventTap,
                                       kCGEventTapOptionDefault, 
                                       kCGEventKeyDown,
                                       myEventTapCallback, 
                                       NULL);
  

Обратный вызов прост. Смотрите Обратные вызовы в справочнике служб событий для получения дополнительной информации.