2013-10-25 4 views
4

Есть ли способ перехватить и изменить/игнорировать глобально заданный ярлык в Objective-C для приложения Mac?Перехват/отключение сочетаний клавиш (например, CMD + q)

Примером является BetterTouchTool, он может переопределять любые ярлыки, которые вы предоставляете.

То, что я хочу сделать, это предотвратить «бросить курить» ярлык (т.е. CMD + д), когда конкретное приложение открыто (потому что в этом случае ярлык ненароком нажать и закрывает приложение нежелательному для некоторых людей).

Вкратце, могу ли я прослушивать любые события глобального ключа, а затем изменить событие до, он доставляется в его предполагаемое приложение?

+0

Как полностью не программируемое решение, вы можете просто изменить эквивалент ключа для этого приложения в Системные настройки> Клавиатура> Ярлыки клавиш> Ярлыки приложений> [конкретное приложение] (я думаю, что это переместилось в Mavericks, но это все равно должен быть в системных настройках где-то.) У меня есть пункт меню «Выход» моего браузера, установленный на^⌥⌘Q, например. Кодируя, вы ищете CGEventTaps. –

+0

Это не работает, так как приложение запускается с использованием сценария bash и не является приложением * .app. Я посмотрю на CGEventTaps, у вас есть какие-то непосредственные ресурсы для этого? – ehftwelve

+0

Gotcha. Служба [Quartz Event Services] (https://developer.apple.com/library/mac/documentation/Carbon/Reference/QuartzEventServicesRef/Reference/reference.html) является официальным документом. –

ответ

5

Вот как настроить слушателя событий

CFMachPortRef eventTap = CGEventTapCreate(kCGHIDEventTap, 
           kCGHeadInsertEventTap, 
           kCGEventTapOptionDefault, 
           CGEventMaskBit(kCGEventKeyDown), 
           &KeyDownCallback, 
           NULL); 

CFRunLoopSourceRef runLoopSource = CFMachPortCreateRunLoopSource(NULL, eventTap, 0); 
CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopCommonModes); 
CFRelease(runLoopSource); 
CGEventTapEnable(eventTap, true); 

А потом вот это "обратный вызов":

static CGEventRef KeyDownCallback(CGEventTapProxy proxy, 
           CGEventType type, 
           CGEventRef event, 
           void *refcon) 
{ 
    /* Do something with the event */ 
    NSEvent *e = [NSEvent eventWithCGEvent:event]; 
    return event; 
} 

на разобранной NSEvent, есть modifierFlags и keyCode свойства. keyCode - это код нажатого ключа, а modifierFlags - это различные модификаторы, которые были нажаты (Shift, Alt/Option, Command и т. Д.).

Просто return NULL; в методе KeyDownCallback, чтобы остановить мероприятие от распространения.

Примечание: похоже, проблема связана с выводом времени события, чтобы решить эту проблему, вы можете «сбросить» ответ на событие.

В методе KeyDownCallback, проверьте, если CGEventType type является kCGEventTapDisabledByTimeout так:

if (type == kCGEventTapDisabledByTimeout) 
{ 
    /* Reset eventTap */ 
    return NULL; 
} 

и где Reset eventTap есть, выполнить настройку приемника событий выше снова.

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