Я пытаюсь добавить ловушку события, чтобы включить / отключить событие с моего волшебного трекпада. Я думал, что это будет просто, т.е. зарегистрируйте ловушку события и при необходимости отмените событие, вернув NULL
. Идея состоит в том, чтобы использовать панель для определенного, трудоемкого ввода данных, приложения для ввода данных являются сторонними, поэтому я не могу просто добавить код, чтобы я хотел там. Итак, я решил, что буду отслеживать системные события, а затем отправлять желаемый ввод через кучу CGEventCreateKeyboardEvent
s.
Проблема с возвратом null, похоже, не отбрасывает события, немного больше исследований предполагает что это касается не только трекпада, но и моей USB-мыши по умолчанию.
Мой код приведен ниже. С тем, что ниже, я бы ожидал, что не смогу перемещать мышь, если я изменю (A) на использование kCGEventScrollWheel
или kCGEventLeftMouseDragged
, тогда событие будет использовано, т.е. прокрутка или перетаскивание влево не происходит. Значит ли это, что не все события можно отбросить? Надеюсь, мне здесь не хватает чего-то очевидного.
#define case_print(a) case a: printf("%s - %d\n",#a,a); break;
CGEventRef eventOccurred(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void* refcon) {
int subType = CGEventGetIntegerValueField(event, kCGMouseEventSubtype);
if (type == NSEventTypeGesture || subType == NX_SUBTYPE_MOUSE_TOUCH) {
printf("touchpad\n");
switch(type) {
case_print(kCGEventNull)
case_print(kCGEventLeftMouseDown)
case_print(kCGEventLeftMouseUp)
case_print(kCGEventRightMouseDown)
case_print(kCGEventRightMouseUp)
case_print(kCGEventMouseMoved)
case_print(kCGEventLeftMouseDragged)
case_print(kCGEventRightMouseDragged)
case_print(kCGEventScrollWheel)
case_print(kCGEventOtherMouseDown)
case_print(kCGEventOtherMouseUp)
case_print(kCGEventOtherMouseDragged)
case_print(kCGEventTapDisabledByTimeout)
case_print(kCGEventTapDisabledByUserInput)
case_print(NSEventTypeGesture)
case_print(NSEventTypeMagnify)
case_print(NSEventTypeSwipe)
case_print(NSEventTypeRotate)
case_print(NSEventTypeBeginGesture)
case_print(NSEventTypeEndGesture)
default:
printf("default: %d\n",type);
break;
}
event = NULL;
} else {
if (type == kCGEventMouseMoved) { // (A)
printf("discarding mouse event");
event = NULL;
}
}
return event;
}
CFMachPortRef createEventTap() {
CGEventMask eventMask = NSAnyEventMask;
if (!AXAPIEnabled() && !AXIsProcessTrusted()) {
printf("axapi not enabled");
}
return CGEventTapCreate(kCGHIDEventTap,
kCGHeadInsertEventTap,
kCGEventTapOptionDefault,
eventMask,
eventOccurred,
NULL);
}
int main (int argc, const char * argv[]) {
CFMachPortRef tap = createEventTap();
if (tap) {
CFRunLoopSourceRef rl = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, tap, 0);
CFRunLoopAddSource(CFRunLoopGetMain(), rl, kCFRunLoopCommonModes);
CGEventTapEnable(tap, true);
CFRunLoopRun();
printf("Tap created.\n");
sleep(-1);
} else {
printf("failed!\n");
}
return 0;
}
Обратите внимание: «axapi not enabled» не выводится, хотя я не думаю, что опция доступности влияет на что-либо, кроме событий клавиатуры.
Кстати, я видел несколько похожих сообщения о том, как получить события с сенсорной панели, просто ничего не применимо к их отбрасыванию (кроме возврата null должно работать).