Tôi đã kết thúc việc viết một ứng dụng tùy chỉnh để lọc ra các lần nhấn phím. Nó sử dụng một vòi sự kiện để làm như vậy. Đây là một ví dụ hoạt động tối thiểu minh họa cách thực hiện:
#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);
}