5

MacアプリケーションのObjective-Cで特定のショートカットをグローバルに傍受して変更/無視する方法はありますか?

例として BetterTouchTool があります。指定したショートカットをオーバーライドできます。

私がやりたいのは、特定のアプリケーションが開いているときに「終了」ショートカット(つまりCMD+ q)を防ぐことです(この場合、ショートカットが不注意に押され、一部の人にとって望ましくないアプリケーションを閉じるため)。

要するに、グローバルキーイベントをリッスンし、目的のアプリケーションに配信される前にイベントを変更できますか?

4

1 に答える 1

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で、上記のイベントリスナーのセットアップを再度実行します。

于 2013-10-26T19:48:01.870 に答える