質問

Quartz CgeVentapを使用して、グローバルにCapslockプレスを傍受してブロックするために(代わりに何か便利なことをしてもらうために)。 Capslock Pressを成功させましたが、これまでブロックすることができませんでした。私のコード(から発信されます これ stackoverflowの回答)は次のようなものです:

eventTap = CGEventTapCreate(kCGHIDEventTap,
                            kCGTailAppendEventTap, 
                            kCGEventTapOptionDefault, 
                            eventMask,
                            myCGEventCallback,
                            &oldFlags);

runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0);

CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopCommonModes);
CGEventTapEnable(eventTap, true);

CGEventRef myCGEventCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef theEvent, void *refcon)
{
    CGEventFlags *oldFlags = (CGEventFlags *)refcon; 

    switch (type)
    {
        case kCGEventFlagsChanged:
        {
            CGEventFlags newFlags = CGEventGetFlags(theEvent);
            CGEventFlags changedFlags = *oldFlags ^ newFlags; 
            *oldFlags = newFlags;

            if (changedFlags == 65536)
            {
                NSLog(@"Capslock pressed. Let's not return the event");
                return NULL;
            }
            break;
        }
        default:
            break;
    }

    NSLog(@"Different modifier than capslock. Returning the event");
    return theEvent;
}

私が正しく戻ることを理解している場合、nullはキープレスが伝播するのを効果的にブロックするはずです。実際、それは「通常の」キーアップおよび - ダウンイベントに対しても行われます。ただし、CapsLockはそれに関係なく切り替えます。なぜそれがなぜですか?誤った仮定をしていますか?そして/または私は自分の目標を達成するために物事を違ったやり方で行うことができますか?

ありがとう、

ソー

役に立ちましたか?

解決

そのようなCapslockをブロックすることはできません。 CapsLockは、ウィンドウサーバーや個々のアプリケーションではなく、キーボードドライバーによって処理される条件です。キープレスイベントはそのようなOS Xで伝播します:

キーボードドライバー - >ウィンドウサーバー - >ユーザーセッション - >アクティブアプリケーション

各レベルの伝播(「 - >」で示されている)で、イベントをタップしてブロックしたり、キーイベントをブロックしたり、変更したりできます。キーボードドライバーとウィンドウサーバーはどちらも特権コンポーネントであり、他の2つは通常のユーザーレベルのコンポーネントです。

キーボードイベントをキャッチできるのは、イベントがドライバー(カーネルスペース)からウィンドウサーバー(ユーザースペースですが、まだ特権)に伝播するときです。ただし、上記のように、Capslock状態はドライバーで内部的に処理されるため、イベントをキャッチすると、すでに手遅れです。ドライバーは、キーボードのキャップロックライトを既に有効にしており(必要に応じて、ハードウェアで実行されていない)、Capslock状態がオンになっていることを思い出し、これはすべての将来のキープレスに影響を与えます。

HIDデバイスのためにプログラムでCapsLock光をオフにすることができます(Appleは均等です そのためのサンプルコード)、しかし、これはCapslockをターンオフすることはなく、ライトをオフにします。

イベントタップを使用して実装する唯一の方法は、CapsLockを使用してすべてのキープレスをCapsLockのないキープレスに手動で書き直すことです(CapsLockフラグが設定されておらず、付属の文字が添付されている場合は小文字です)。さらに、ユーザーを混同しないようにするために、Appleのサンプルコードで示されているように、Capslock光をオフにします。

その他の選択肢は次のとおりです。自分のキーボードドライバーを書いてください。これは、Appleの標準ドライバーではなくキーボードを制御します(考えているほど難しくはありませんが、それでも難しいです)、またはドライバーへの道をハッキングします(邪悪ですが、機能します)。たとえば、いくつかのキーボードリメッパーは、ドライバーの単一のメソッドのみをオーバーライドします(ドライバーはOS XのC ++です。したがって、それらはO-Objectsであり、実行時にC ++メソッドを動的にオーバーライドできます。実際にはオーバーライドするのではなく、メソッドテーブルを操作します)。これらの2つのソリューションの問題は次のとおりです。最初のソリューションは、ドライバーがAppleのものと同じくらい優れていない限り、一部のUSBキーボードがドライバーと動作しない場合がありますが、他のユーザーは、2つ目は間違いを犯した場合、システムは、カーネルパニックでこの間違いを罰します。

これまでのところ成功することなく、MacでCapslockをプログラム的に切り替える方法を探しています。しかし、私はあなたを保証することができます、イベントタップは行くべき道ではありません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top