Terminé escribiendo una aplicación personalizada para filtrar las pulsaciones de expulsión. Utiliza un toque de evento para hacerlo. Aquí hay un ejemplo que funciona mínimamente que demuestra cómo hacerlo:
#include <stdio.h>
#include <ApplicationServices/ApplicationServices.h>
static CFMachPortRef machPortRef = NULL;
CGEventRef specialKeyEventTapCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon)
{
if (type == kCGEventTapDisabledByTimeout) {
CGEventTapEnable(machPortRef, true);
return event;
}
uint64_t subtype = CGEventGetIntegerValueField(event, 99);
if (subtype == 8) {
static CGEventFlags allModifiers = (kCGEventFlagMaskShift | kCGEventFlagMaskControl | kCGEventFlagMaskAlternate | kCGEventFlagMaskCommand);
int keycode = ((CGEventGetIntegerValueField(event, 149) & 0xFFFF0000) >> 16);
CGEventFlags flags = CGEventGetFlags(event);
if (keycode == NX_KEYTYPE_EJECT && (flags & allModifiers) == 0) {
// filter eject key when no modifiers are pressed
return NULL;
}
}
return event;
}
int main()
{
CFRunLoopSourceRef eventSrc = NULL;
machPortRef = CGEventTapCreate(kCGHIDEventTap, kCGHeadInsertEventTap, kCGEventTapOptionDefault, CGEventMaskBit(NX_SYSDEFINED), (CGEventTapCallBack)specialKeyEventTapCallback, NULL);
if (machPortRef == NULL) {
fprintf(stderr, "CGEventTapCreate failed!\n");
return 1;
}
eventSrc = CFMachPortCreateRunLoopSource(NULL, machPortRef, 0);
CFRunLoopAddSource(CFRunLoopGetCurrent(), eventSrc, kCFRunLoopDefaultMode);
CFRunLoopRun();
CFRelease(machPortRef);
CFRelease(eventSrc);
}