Предотвратить обратный вызов `mouseMovedEvent` от обработки движения? Или глобально скрыть курсор на мгновение?

У меня есть глобальное приложение, которое предотвращает перемещение мыши по областям экрана. Должен работать со всеми приложениями, пока мое приложение в фоновом режиме и т. Д.

Я создал CGEventTap крючок с обратным вызовом для движений мыши.

Движение мыши пользователя продолжает проходить через крючок, независимо от того, как я пытаюсь изменить / убить движение. Это отражает опыт других: /questions/35895562/ispolzovanie-sobyitij-myishi-i-trekpada-osx-s-pomoschyu-sobyitiya/35895576#35895576

- (CGEventRef) mouseMovedEvent:(CGEventRef) newUserMouseMovement
{ 
    //Attempt to modify the mouse movement
    CGEventSetDoubleValueField(newUserMouseMovement, kCGMouseEventDeltaX, 0);
    CGEventSetDoubleValueField(newUserMouseMovement, kCGMouseEventDeltaY, 0);
    CGEventSetDoubleValueField(newUserMouseMovement, kCGMouseEventDeltaX, 0.0);

    //Attempt to kill the event
    return NULL;
}
//Mouse movement still works normally.

Я могу использовать CGDisplayMoveCursorToPoint или же CGWarpMouseCursorPosition переместить курсор обратно в исходное положение.

Это прекрасно работает, хотя я бы предпочел просто убить событие в целом.

Проблема в том, что исходное пользовательское движение мыши показывает курсор визуально в этой точке в течение доли секунды, прежде чем я смогу переместить курсор.

Я использую:

CGSetLocalEventsSuppressionInterval(0.0);

увеличить частоту срабатывания движения мыши. Но это также заставляет "настоящий" курсор, прежде чем я переместлю его, вспыхнуть в "запрещенной области", если пользователь удерживает мышь напротив области, в которую я не хочу, чтобы мышь перемещалась.

Я буду потенциально использовать: глобально скрывающий курсор (из фонового приложения), но я сомневаюсь, что это будет законно для Mac App Store.

Есть идеи?

РЕДАКТИРОВАТЬ: Как я создаю событие нажмите:

eventTap = CGEventTapCreate(kCGHIDEventTap, kCGHeadInsertEventTap, kCGEventTapOptionDefault, kCGEventMaskForAllEvents, myCGEventCallback, NULL);

...

    CGEventRef myCGEventCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon)
{
    if (type == kCGEventMouseMoved) {
        event = [refToSelf mouseMovedEvent:event];
    }

    ...

    return event;
}

1 ответ

Решение

Вы пытаетесь изменить события на kCGHIDEventTap место, которое

Указывает, что касание события помещается в точку, где системные события HID поступают на сервер окна.

К сожалению, CGEventTapCreate() Док говорит:

Только процессы, работающие от имени пользователя root, могут обнаружить отвод событий в точке, где события HID попадают на сервер окон; для других пользователей эта функция возвращает NULL,

Я подозреваю, что это сильно связано с вашей трудностью, хотя документы, похоже, не соответствуют точно тому, что происходит (им более четырех лет).

Возможно, вы можете выделить эту функцию в отдельный процесс с правами суперпользователя, оставив остальную часть вашего приложения в обычном пользовательском режиме? Я полагаю, что есть также способ запрашивать полномочия root только для конкретного действия, выполняемого вашей программой.

Другие вопросы по тегам