J'ai fini par écrire une application personnalisée pour filtrer les pressions sur les touches d'éjection. Elle utilise un événement tap pour le faire. Voici un exemple minimalement fonctionnel qui démontre comment faire :
#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);
}