OSX: обнаруживать общесистемные события keyDown?

Я работаю над приложением для набора текста для Mac OSX, которому нужно перенаправлять нажатия клавиш, даже когда приложение не в фокусе.

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

РЕДАКТИРОВАТЬ: Пример кода ниже .

Спасибо @NSGod за то, что указал мне в правильном направлении - в итоге я добавил монитор глобальных событий , используя метод addGlobalMonitorForEventsMatchingMask: handler: , который прекрасно работает. Для полноты моя реализация выглядит так:

// register for keys throughout the device...
[NSEvent addGlobalMonitorForEventsMatchingMask:NSKeyDownMask
                                       handler:^(NSEvent *event){

    NSString *chars = [[event characters] lowercaseString];
    unichar character = [chars characterAtIndex:0];

    NSLog(@"keydown globally! Which key? This key: %c", character);

}];

Для меня самой сложной частью было использование блоков, поэтому я дам небольшое описание на случай, если это кому-то поможет:

В приведенном выше коде нужно отметить то, что он все один вызов метода в NSEvent. Блок предоставляется как аргумент, непосредственно в функцию. Вы можете думать об этом как о встроенном методе делегата. Просто потому, что это заняло у меня время, я собираюсь проработать это шаг за шагом здесь:

[NSEvent addGlobalMonitorForEventsMatchingMask:NSKeyDownMask

Этот первый бит - не проблема. Вы вызываете метод класса в NSEvent, и сообщая ему, какое событие вы хотите отслеживать, в данном случае NSKeyDownMask. Список масок для поддерживаемых типов событий можно найти здесь .

Теперь мы подошли к сложной части: обработчик, который ожидает блок:

handler:^(NSEvent *event){

Мне потребовалось несколько ошибок компиляции, чтобы понять это правильно, но (спасибо Apple) они были очень конструктивными сообщениями об ошибках. Первое, на что стоит обратить внимание - это карат ^. Это сигнализирует о начале блока. После этого в круглых скобках

NSEvent *event

объявляется переменная, которую вы будете использовать в блоке для захвата события. Вы можете назвать это

NSEvent *someCustomNameForAnEvent

, неважно, вы просто будете использовать это имя внутри блока. Тогда это почти все, что нужно сделать. Не забудьте закрыть фигурную скобку и скобку, чтобы завершить вызов метода:

}];

И все готово! Это действительно своего рода «однострочник». Неважно, где вы выполняете этот вызов в своем приложении - я делаю это в методе applicationDidFinishLaunching AppDelegate. Затем внутри блока вы можете вызывать другие методы из своего приложения.

59
задан Cœur 24 March 2019 в 18:09
поделиться