В некоторых приложениях имеет смысл напрямую обрабатывать сочетания клавиш, которые в противном случае привязаны к общесистемным комбинациям. Например, ⌘-Пробел (обычно Spotlight) или ⌘-Tab (обычно переключатель приложений). Это работает в различных приложениях для Mac, таких как VMWare Fusion, собственные клиенты Apple для совместного использования экрана и удаленного рабочего стола (пересылка событий на виртуальную машину или сервер, соответственно, вместо их локальной обработки), а также в некоторых аналогичных сторонних приложениях в приложении. Магазин.
Мы хотели бы реализовать такой режим в приложении, над которым работаем, но пока не можем понять, как это сделать. Я должен отметить, что рассматриваемое приложение является обычным приложением переднего плана, находится в песочнице, и любое решение должно соответствовать правилам App Store. Тот факт, что другие приложения в магазине могут это делать, подразумевает, что это должно быть возможно.
Чтобы было ясно, мы хотим:
- Обнаружение и обработка всех нажатий клавиш, в том числе связанных с глобальными сочетаниями клавиш.
- Не допускайте, чтобы глобальные ярлыки вызывали их глобально привязанный эффект.
Документ по архитектуре событий предполагает, что приложение переднего плана уже должно получать эти события. (Это говорит только о более ранних уровнях, обрабатывающих такие вещи, как кнопки питания и извлечения, что нормально.) /Cocoa/Conceptual/EventOverview/HandlingKeyEvents/HandlingKeyEvents.html#//apple_ref/doc/uid/10000060i-CH7-SW11" rel="noreferrer">документ о ключевых событиях также подразумевает, что метод NSApplication
sendEvent:
обнаруживает потенциальные ярлыки на основе флагов модификаторов, отправляя их в окна и, если это не удается, в строку меню. Не указано явно, что происходит с глобальными ярлыками.
Я попытался создать подкласс NSApplication
и переопределить sendEvent:
. Независимо от того, передаю ли я все события в реализацию суперкласса или говорю, фильтровать события клавиши-модификатора, когда я нажимаю ⌘-Пробел, я получаю события для нажатия и отпускания клавиши команды (⌘), но не пробела. Пользовательский интерфейс Spotlight всегда всплывает.
Я не нашел много информации о подклассе NSApplication и его ранней обработке событий от Apple или других источников. Я не могу понять, на каком уровне обнаруживаются и обрабатываются глобальные ярлыки.
Может кто-нибудь указать мне в правильном направлении?
Возможные решения, которые не работают:
Предложения, которые я видел в других сообщениях о переполнении стека, но которые не относятся к другим приложениям, которые я видел, которые делают это (и которые нарушают правила App Store):
- Доступные API (требуется специальное разрешение)
- Отводы/перехватчики событий (необходимо запускать от имени пользователя root)
И то, и другое в любом случае было бы излишним, поскольку они позволяют перехватывать все события в всегда раз, а не только тогда, когда ваше приложение находится на переднем плане.
Между тем, addGlobalMonitorForEventsMatchingMask:handler:
NSevent
не предотвращает срабатывание глобального обработчика ярлыков для этих событий, поэтому я даже не стал пытаться это делать.
RegisterEventHotKey
фреймворка Carbon правила AppStore? Он работает по крайней мере в 10.12 Sierra. - person vadian   schedule 12.06.2017