2

続行する前に、これはおそらく最もハックで、実に邪悪で厄介なトピックであると言って、この投稿の前置きをしたいと思います。そのため、回答に「合法的な」コードが含まれているとはまったく期待していません。

OS X Mountain Lion がディクテーションを有効にするためのホット キーの組み合わせを格納するために使用する内部設定ファイルにアクセスしようとしているときに、System Preferences.app で定義されたキー コードを含む、美しく細工された署名付き整数に出くわしました。問題は、私が考えることができる唯一の方法はCGEvent、特定のキーコードのビットマスクを調べて基本的に解析することであり、これは潜在的に無益で迷惑な試みです. そして、CGEvent便利なように内部構造体 ( __CGEvent) に typedef されているため、それが内部構造であることを確認する方法はありません (つまり、ここmalloc()から抜け出すことはできません)。これまでに得たものは、以下のコードに示されています。

/***************************************UNSAFE*****************************************************/
//1048584, -1048585 - Two Left CMD presses; 1048576, -1048577 - Two CMD presses; 8388608, -8388609 - Two Fn presses; 1048592, -1048593 - Two Right CMD presses
- (void)forceDictation {

    NSString *path = [[NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) lastObject]stringByAppendingPathComponent:@"Preferences/com.apple.symbolichotkeys.plist"];
    NSDictionary *dictationPrefs = [NSDictionary dictionaryWithContentsOfFile:path];
    NSDictionary *dictationDict = dictationPrefs[@"AppleSymbolicHotKeys"];
    NSDictionary *keyvalueDict = dictationDict[@"164"];
    NSDictionary *valueDict = keyvalueDict[@"value"];
    NSArray *parameters = valueDict[@"parameters"];
    NSInteger firstCode = [[parameters objectAtIndex:0]longLongValue];
    NSInteger secondCode = [[parameters objectAtIndex:1]longLongValue];
}

HIToolbox のイベント ビットマスクに精通している人なら誰でも、これらのキー コード表現が、簡単にイベントに変換されてすぐに起動できれば、非常に役立つことがわかるでしょう。

4

1 に答える 1

7

ビットパターンを見てみましょう(そして、あなたがそれらをリストした順序から順序を変更したことに気付くでしょう):

2 × ⌘:
 1048576: 00000000000100000000000000000000
-1048577: 11111111111011111111111111111111

2 × left-⌘:
 1048584: 00000000000100000000000000001000
-1048585: 11111111111011111111111111110111

2 × right-⌘:
 1048592: 00000000000100000000000000010000
-1048593: 11111111111011111111111111101111

2 × Fn:
 8388608: 00000000100000000000000000000000
-8388609: 11111111011111111111111111111111

それ以外は、これからわか​​ることはあまりありません。

  • 正の値が「実際の」値であると仮定すると(2つある理由と、4つのペアすべてが相補的である理由についての私の理論については、私のコメントを参照してください)、キー識別子は少なくとも20ビット上にあります(私の最初のペアでは注意してください)次数の場合、正の値は正確に2**20)であり、少なくとも4ビット長です(2×Fnは2**23)。
  • 設定がそのように制限されている場合、下位5ビットのうち少なくとも2つがどのキー(左または右)を指定します。左が最初の⌘のように見えますが、右が2番目です。この部分がゼロの場合、識別されたキーのいずれかが一致します(たとえば、左または右⌘)。

ただし、実際にビットを解析する必要はない場合があります。

私のMacBookAirで、キーコードを実行すると、次の出力が得られます。

Modifier Change
  Keys:       ⌘
  Key Code:   65535 / 0xffff
  Modifiers:  1048848 / 0x100110

Modifier Change
  Keys:       
  Key Code:   65535 / 0xffff
  Modifiers:  256 / 0x100

Modifier Change
  Keys:       ⌘
  Key Code:   65535 / 0xffff
  Modifiers:  1048840 / 0x100108

Modifier Change
  Keys:       
  Key Code:   65535 / 0xffff
  Modifiers:  256 / 0x100

Modifier Change
  Keys:       
  Key Code:   65535 / 0xffff
  Modifiers:  8388864 / 0x800100

Modifier Change
  Keys:       
  Key Code:   65535 / 0xffff
  Modifiers:  256 / 0x100

それらの数字のいくつかは非常によく知られているように見えますね?

  • ⌘キーを押すたびに、修飾子の状態が1048000の範囲の値に変わります。
  • Fnを押すと、モディファイアの状態が8388864に変わります。あなたのモディファイアは8388608でした。

NSEvent.hのモディファイアマスクを見てみましょう。

NSCommandKeyMask            = 1 << 20,
NSFunctionKeyMask           = 1 << 23,

ああ、ねえ。

そして、これらの両方、そして実際にはすべての修飾キー(私たちが知っているように)マスクは、次の範囲内にありますNSDeviceIndependentModifierFlagsMask

NSDeviceIndependentModifierFlagsMask    = 0xffff0000UL

これは、下位16ビットがデバイスに依存していることを意味します。マシンごとまたはキーボードごとに異なる場合があります。つまり、下位16ビットは私の下位16ビットとは異なる場合があります。

ちょっと待って!もっとあります!

I / OキットのIOLLEvent.hを見ると、NSEventのものと同様のマスクに加えて、次のものが見つかります。

/* device-dependent (really?) */

#define   NX_DEVICELCTLKEYMASK    0x00000001
#define   NX_DEVICELSHIFTKEYMASK  0x00000002
#define   NX_DEVICERSHIFTKEYMASK  0x00000004
#define   NX_DEVICELCMDKEYMASK    0x00000008
#define   NX_DEVICERCMDKEYMASK    0x00000010
#define   NX_DEVICELALTKEYMASK    0x00000020
#define   NX_DEVICERALTKEYMASK    0x00000040
#define NX_DEVICERCTLKEYMASK  0x00002000

つまり、、、およびLCMDKEYMASKです。これも、見つけた左-⌘と右-⌘の値と一致します。左は、、右は。です。0b1000RCMDKEYMASK0b10000NX_COMMANDMASK | NX_DEVICELCMDKEYMASKNX_COMMANDMASK | NX_DEVICERCMDKEYMASK

このことから、私は次のように結論付けることができます。

  • これらの数値は、CGEvent全体ではありません。
  • 各ペア内で、正の値は修飾子フラグマスクであり、負の値は単にその補数です。
  • 生成する必要のあるイベントはkCGEventFlagsChanged、キーコードが検索するのと同じ(チェックボックスをオンにした場合)の修飾子変更イベント()であり、上記のように各イベントの修飾子フラグがあります。(そのようなイベントを生成することによって実際にディクテーションをトリガーできるかどうかはわかりません。自分で確認する必要があります。)
  • ビットレイアウトはそれほど重要ではありませんが、本当に知りたい場合は、上半分(「デバイスに依存しない」)でオンになっている修飾子を識別し、下半分(「デバイスに依存する」でおそらくflags-changed event)は、キーを変更するために押されたばかりのキーを識別します。
  • 修飾キーを押す回数は、おそらくハードコーディングされています(そうでない場合は、他の場所で指定されています)。
于 2013-03-10T10:12:50.927 に答える