Почему CGWarpMouseCursorPosition вызывает задержку? Если нет, то что? - PullRequest
7 голосов
/ 21 ноября 2011

У меня есть код, который ограничивает область мыши на экране, она работает относительно хорошо, с одной большой проблемой. Мышь не двигается чисто / плавно при беге по краям области, вместо этого она скачкообразно прыгает, я думаю, это может быть связано с тем, что CGWarpMouseCursorPosition вызывает задержку при каждом «перекосе».

Может кто-нибудь сказать, вызвало ли это что-то в моем коде, или это на самом деле функция деформации мыши. Если это функция деформации мыши, можно ли как-нибудь добиться плавного перемещения мыши? Я сделал то же самое во флэш-памяти, и она работает безупречно, я знаю, что цикл не просто много времени, чтобы выполнить, что это замедляет ход событий, потому что он работает только 4 или 5 раз.

CGEventRef 
mouse_filter(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon) {


    CGPoint point = CGEventGetLocation(event);

    float tX = point.x;
    float tY = point.y;

    if( tX <= 700 && tX >= 500 && tY <= 800 && tY >= 200){
        // target is inside O.K. area, do nothing
    }else{

    CGPoint target; 

    //point inside restricted region:
    float iX = 600; // inside x
    float iY = 500; // inside y

    // delta to midpoint between iX,iY and tX,tY
    float dX;
    float dY;

    float accuracy = .5; //accuracy to loop until reached

    do {
        dX = (tX-iX)/2;
        dY = (tY-iY)/2;

        if((tX-dX) <= 700 && (tX-dX) >= 500 && (tY-dY) <= 800 && (tY-dY) >= 200){
            iX += dX;
            iY += dY;
        } else {
            tX -= dX;
            tY -= dY;
        }

    } while (abs(dX)>accuracy || abs(dY)>accuracy);

        target = CGPointMake(roundf(tX), roundf(tY));
        CGWarpMouseCursorPosition(target);

    }



    return event;
}

int
main(int argc, char *argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    CFRunLoopSourceRef runLoopSource;
    CGEventMask event_mask;
    event_mask = CGEventMaskBit(kCGEventMouseMoved) | CGEventMaskBit(kCGEventLeftMouseDragged) | CGEventMaskBit(kCGEventRightMouseDragged) | CGEventMaskBit(kCGEventOtherMouseDragged);

    CFMachPortRef eventTap = CGEventTapCreate(kCGHIDEventTap, kCGHeadInsertEventTap, 0, event_mask, mouse_filter, NULL);

    if (!eventTap) {
        NSLog(@"Couldn't create event tap!");
        exit(1);
    }

    runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0);

    CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopCommonModes);

    CGEventTapEnable(eventTap, true);

    CFRunLoopRun();

    CFRelease(eventTap);
    CFRelease(runLoopSource);
    [pool release];

    exit(0);
}

Ответы [ 3 ]

5 голосов
/ 10 июля 2013

Как вы обнаружили, CGSetLocalEventsSuppressionInterval решает вашу проблему.

Однако по состоянию на 10.6 оно устарело.Состояние Apple Docs:

Эта функция не рекомендуется для общего пользования из-за недокументированных особых случаев и нежелательных побочных эффектов.Рекомендуемая замена для этой функции - CGEventSourceSetLocalEventsSuppressionInterval, которая позволяет настраивать интервал подавления для конкретного источника событий, затрагивая только события, публикуемые с использованием этого источника событий.

К сожалению, замена CGEventSourceSetLocalEventsSuppressionIntervalне работает с CGWarpMouseCursorPosition движениями.

Вместо этого используйте CGAssociateMouseAndMouseCursorPosition(true) сразу после деформации:

CGPoint warpPoint = CGPointMake(42, 42);
CGWarpMouseCursorPosition(warpPoint);
CGAssociateMouseAndMouseCursorPosition(true);

Документация не упоминает об этом поведении, но, похоже, отменяетинтервал подавления после варпа.

1 голос
/ 10 августа 2018

Я могу заставить CGEventSourceSetLocalEventsSuppressionInterval работать с CGWarpMouseCursorPosition следующим образом:

auto eventSourceRef = CGEventSourceCreate(kCGEventSourceStateCombinedSessionState);
CGEventSourceSetLocalEventsSuppressionInterval(eventSourceRef, 0);

Это прекрасно работает с CGWarpMouseCursorPosition (и не считается устаревшим), тогда как CGAssociateMouseAndMouseCursorPosition(true) мне не помогло.

1 голос
/ 24 ноября 2011

Возможно, вы ищете CGSetLocalEventsSuppressionInterval (), метод, который устарел с 10.6 ... он все еще работает, хотя в 10.7.

http://developer.apple.com/library/mac/#documentation/Carbon/Reference/QuartzEventServicesRef/DeprecationAppendix/AppendixADeprecatedAPI.html#//apple_ref/c/func/CGSetLocalEventsSuppressionInterval

...