2014-09-24 4 views
0

Кто-нибудь знает, как определить, когда пользователь меняет текущий источник входного сигнала в OSX?OSX Изменение источника входного сигнала какао

Switching my keyboard settings to German

Я могу назвать TISCopyCurrentKeyboardInputSource(), чтобы узнать, какой источник входного ID используется так:

TISInputSourceRef isource = TISCopyCurrentKeyboardInputSource(); 
    if (isource == NULL) 
    { 
     cerr << "Couldn't get the current input source\n."; 
     return -1; 
    } 

    CFStringRef id = (CFStringRef)TISGetInputSourceProperty(
     isource, 
     kTISPropertyInputSourceID); 
    CFRelease(isource); 

Если мой входной источник «немецкий», то идентификатор заканчивает тем, что «ком. apple.keylayout.German ", который в основном я хочу. За исключением:

  1. Результаты TISCopyCurrentKeyboardInputSource() не изменяются после моего запуска процесса? В частности, я могу вызвать TISCopyCurrentKeyboardInputSource() в цикле и переключить свой входной источник, но TISCopyCurrentKeyboardInputSource() продолжает возвращать исходный источник, с которого начался мой процесс.
  2. Я бы очень хотел, чтобы вас уведомили, когда изменяется исходный источник. Есть ли способ сделать это? Чтобы получить уведомление или какое-либо событие, сообщившее мне, что источник ввода был изменен?

ответ

2

Уведомление об NSTextInputContextKeyboardSelectionDidChangeNotification отправлено NSTextInputContext в центр уведомлений по какао по умолчанию. В качестве альтернативы вы можете получить уведомление kTISNotifySelectedKeyboardInputSourceChanged, отправленное через центр распределенных уведомлений Core Foundation.

Однако любое такое изменение начинается с системного процесса, внешнего по отношению к вашему приложению. Затем система уведомляет структуры в каждом процессе приложения. Эти фреймворки могут получать только такие уведомления, когда разрешено запускать цикл событий. Аналогично, если вы сами наблюдаете за распределенным уведомлением, это может произойти только тогда, когда цикл выполнения (или, по крайней мере, цикл запуска основного потока) разрешен.

Итак, это объясняет, почему запуск цикла, который многократно проверяет результат TISCopyCurrentKeyboardInputSource(), не работает. Вы не позволяете фреймворкам контролировать канал, по которому он будет проинформирован об изменении. Если вместо петли вы должны использовать повторяющийся таймер с достаточно низкой частотой, чтобы другие вещи могли запускаться, и вы вернули управление циклу событий приложения, вы увидите результат изменения TISCopyCurrentKeyboardInputSource().

+0

Спасибо! Прекрасно работает. –

Смежные вопросы