无论如何,对于Mac应用程序,在Objective-C中是否有全局性地拦截和更改/忽略给定的快捷方式?

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

我想做的是在打开特定应用程序时防止使用“退出”快捷方式(即CMD + q)(因为在这种情况下,无意中按下了该快捷方式,对某些人来说是不希望地关闭了该应用程序)。

简而言之,我可以监听所有全局键事件,然后在将事件交付给其预期的应用程序之前对其进行更改吗?

最佳答案

这是设置事件监听器的方法

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所在的位置,再次执行上述事件监听器的设置。

关于objective-c - 拦截/禁用键盘快捷键(例如CMD + q),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19596907/

10-14 20:42