Tengo un código aquí que restringe el mouse a una región en la pantalla, funciona relativamente bien, con un solo gran problema. El mouse no se mueve limpiamente/sin problemas cuando se ejecuta a lo largo de los bordes del área, sino que salta de una manera muy entrecortada, creo que esto podría deberse a CGWarpMouseCursorPosition que causa un retraso en cada "deformación".¿Por qué CGWarpMouseCursorPosition causa un retraso? Si no es así, ¿qué es?
¿Alguien puede decir si es algo en mi código que está causando este retraso, o si de hecho es la función de deformación del mouse. Si se trata de la función de deformación del mouse, ¿hay alguna manera de que pueda obtener una reubicación sin problemas del mouse? He hecho lo mismo en flash y funciona sin problemas, sé que el ciclo no solo toma mucho tiempo en ejecutarse que está ralentizando las cosas porque solo funciona 4 o 5 veces.
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);
}
No creo que sea lento; cronometrando, el tiempo más largo que tardé fue de 0.006 segundos. Sin embargo, podría ser mejor en un par de formas: debe definir la región delimitada en un NS- o CGRect, y creo que puede cortar el bucle. –
El rectángulo es solo una herramienta de demostración temporal. De hecho, voy a probar esto con un mapa de bits en blanco y negro, donde las zonas de píxeles negros son aptas para ratón y zonas blancas en las que el mouse no se puede mover. La forma del área negra será bastante extraña y, por lo tanto, creo que el ciclo puede ser necesario. A menos que tengas una mejor solución? – BumbleShrimp
Eso en realidad podría hacer que sea más fácil encontrar si el mouse se ha salido del área aceptable. El truco sería encontrar el punto aceptable más cercano para moverlo de nuevo a, pero sí, creo que necesitarás un bucle para eso. De todos modos, me sorprende que simplemente modificar la ubicación y el delta del evento (o incluso modificar y devolver una copia) no funcione. –