Let's look at the bit-patterns (and you'll note that I've changed the order from the order in which you listed them):
2 × ⌘:
1048576: 00000000000100000000000000000000
-1048577: 11111111111011111111111111111111
2 × left-⌘:
1048584: 00000000000100000000000000001000
-1048585: 11111111111011111111111111110111
2 × right-⌘:
1048592: 00000000000100000000000000010000
-1048593: 11111111111011111111111111101111
2 × Fn:
8388608: 00000000100000000000000000000000
-8388609: 11111111011111111111111111111111
There's not much I can tell from this except that:
- Assuming that the positive value is the “real” one (see my comment for my theory on why there are two and why all four pairs are complementary), the key identifier is at least 20 bits up (note that in the first pair in my order, the positive value is exactly
2**20
), and at least 4 bits long (2×Fn is2**23
). - At least two of the lowest five bits specify which key (left or right), if the setting is so restricted. Left appears to be the first ⌘, whereas right is the second. If this part is zero, any of the identified key will match—e.g., left or right ⌘.
But we may not actually need to parse the bits.
On my MacBook Air, running Key Codes gives me the following output:
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
Some of those numbers look mighty familiar, don't they?
- Any time I press a ⌘ key, the modifiers state changes to something in the 1048000 range.
- When I press Fn, the modifiers state changes to 8388864. Yours was 8388608.
Let's look at the modifier masks in NSEvent.h:
NSCommandKeyMask = 1 << 20, NSFunctionKeyMask = 1 << 23,
Oh, hey.
And both of these, and in fact all of the modifier key (as we know them) masks, are within NSDeviceIndependentModifierFlagsMask
:
NSDeviceIndependentModifierFlagsMask = 0xffff0000UL
Which implies that the lower 16 bits are device-dependent: they may differ from one machine or one keyboard to the next. In other words, your lower 16 bits may differ from my lower 16 bits.
But wait! There's more!
If we look in I/O Kit's IOLLEvent.h, we find masks similar to the ones in NSEvent, plus these:
/* 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
So, LCMDKEYMASK
is 0b1000
, and RCMDKEYMASK
is 0b10000
. This, too, matches up with the left-⌘ and right-⌘ values you found: left is NX_COMMANDMASK | NX_DEVICELCMDKEYMASK
, while right is NX_COMMANDMASK | NX_DEVICERCMDKEYMASK
.
From this, I can conclude that:
- These numbers are not entire CGEvents.
- Within each pair, the positive value is a modifier flags mask, and the negative value is simply its complement.
- The events you need to generate are modifier-change events (
kCGEventFlagsChanged
), the same as Key Codes looks for (when you turn that checkbox on), with the modifier flags of each event as shown above. (Whether you can actually trigger dictation by generating such events, I don't know—you'll have to see for yourself.) - The bit layout isn't terribly important, but if you really want to know, the upper half (“device-independent”) identifies which modifiers are turned on, and the lower half (“device-dependent” and presumably only present in a flags-changed event) identify which keys have just been pressed to change them.
- The number of modifier key presses is, presumably, hard-coded (or, if not, it's specified elsewhere).