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

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

Я установил хук CGEventTap, который имеет функцию обратного вызова для движений мыши.

Движение мыши пользователя продолжаетпройти через крюк, независимо от того, как я пытаюсь изменить / убить движение.Это отражает опыт других: https://stackoverflow.com/a/5831573/106761

- (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.

I am , способный использовать 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 Ответ

2 голосов
/ 28 марта 2012

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

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

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

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

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

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

...