拦截/禁用键盘快捷键(例如CMD + q)

时间:2013-10-25 18:21:57

标签: objective-c macos

无论如何在Mac-Application中为Objective-C中的给定快捷方式全局拦截和更改/忽略?

一个例子是BetterTouchTool,它可以覆盖你提供的任何快捷方式。

我想要做的是在特定应用程序打开时阻止'退出'快捷方式(即 CMD + q )(因为在这种情况下,快捷方式是无意中的某些人不应该按下并关闭应用程序。)

简而言之,我可以监听任何全局关键事件,然后在之前更改事件将其传递到预期的应用程序吗?

1 个答案:

答案 0 :(得分: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上,有modifierFlagskeyCode属性。 keyCode是按下的键的代码,modifierFlags是按下的不同修饰符(Shift,Alt / Option,Command等)。

return NULL;方法中的KeyDownCallback只是为了阻止事件传播。

注意:事件点击超时似乎存在问题,要解决此问题,您可以“重置”事件点击。

KeyDownCallback方法中,检查CGEventType type是否kCGEventTapDisabledByTimeout是这样的:

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

Reset eventTap的位置,再次执行上面事件监听器的设置。