How to programmatically emulate Appple special keys such as media navigation & power keys

June 28, 2019

Media keys along with some other keys are not handled through the standard apple keyboard event subsystem. They are treated differently, and therefore emulating them from software requires special code (EventTap won't work!).

Here's a function that does this:

void HIDPostAuxKey(uint32_t key, bool down)
{
    @autoreleasepool {

        NSEvent* ev = [NSEvent otherEventWithType:NSEventTypeSystemDefined
                                location:NSZeroPoint
                           modifierFlags:(down ? 0xa00 : 0xb00)
                               timestamp:0
                            windowNumber:0
                                 context:nil
                                 subtype:8
                                   data1:(key << 16)| ((down ? 0xa : 0xb) << 8)
                                   data2:-1
                                   ];
        CGEventPost(kCGHIDEventTap, [ev CGEvent]);
    }
}

This Objective-C code is adapted from an SO post that shows how to do this from Python.

Values for the key parameter NX_* macros defined in IOKit/hidsystem/ev_keymap.h. Some of them look like this:

#define NX_KEYTYPE_SOUND_UP  0
#define NX_KEYTYPE_SOUND_DOWN  1
#define NX_KEYTYPE_BRIGHTNESS_UP 2
#define NX_KEYTYPE_BRIGHTNESS_DOWN 3
#define NX_KEYTYPE_CAPS_LOCK  4
#define NX_KEYTYPE_HELP   5
#define NX_POWER_KEY   6
#define NX_KEYTYPE_MUTE   7
#define NX_UP_ARROW_KEY   8
#define NX_DOWN_ARROW_KEY  9
#define NX_KEYTYPE_NUM_LOCK  10

#define NX_KEYTYPE_CONTRAST_UP  11
#define NX_KEYTYPE_CONTRAST_DOWN 12
#define NX_KEYTYPE_LAUNCH_PANEL  13
#define NX_KEYTYPE_EJECT  14
#define NX_KEYTYPE_VIDMIRROR  15

#define NX_KEYTYPE_PLAY   16
#define NX_KEYTYPE_NEXT   17
#define NX_KEYTYPE_PREVIOUS  18
#define NX_KEYTYPE_FAST   19
#define NX_KEYTYPE_REWIND  20

#define NX_KEYTYPE_ILLUMINATION_UP 21
#define NX_KEYTYPE_ILLUMINATION_DOWN 22
#define NX_KEYTYPE_ILLUMINATION_TOGGLE 23

#define NX_NUMSPECIALKEYS  24 /* Maximum number of special keys */