I have code here that restricts the mouse to a region on the screen, it is working relatively well, with only one big problem. The mouse doesn't get moved cleanly/smoothly when running along the edges of the area, it instead jumps in a very choppy manner, I believe this might be due to CGWarpMouseCursorPosition causing a delay upon each "warp".
Can anyone tell if it's something in my code that is causing this delay, or if it is in fact the mouse warp function. If it is the mouse warp function, is there any way I can get a smooth relocation of the mouse? I've done the same thing in flash and it works flawlessly, I know that the loop isn't just taking so much time to execute that it's slowing things down because it only runs maybe 4 or 5 times.
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);
}
As you discovered, CGSetLocalEventsSuppressionInterval
fixes your problem.
However, it's deprecated as of 10.6. the Apple docs state:
This function is not recommended for general use because of undocumented special cases and undesirable side effects. The recommended replacement for this function is
CGEventSourceSetLocalEventsSuppressionInterval
, which allows the suppression interval to be adjusted for a specific event source, affecting only events posted using that event source.
Unfortunately, the replacementCGEventSourceSetLocalEventsSuppressionInterval
does not work with CGWarpMouseCursorPosition
movements.
Instead, use CGAssociateMouseAndMouseCursorPosition(true)
immediately after the warp:
CGPoint warpPoint = CGPointMake(42, 42);
CGWarpMouseCursorPosition(warpPoint);
CGAssociateMouseAndMouseCursorPosition(true);
The documentation makes no mention of this behavior, but it appears to cancel the suppression interval after the warp.
I could get CGEventSourceSetLocalEventsSuppressionInterval
to work with CGWarpMouseCursorPosition
the following way:
auto eventSourceRef = CGEventSourceCreate(kCGEventSourceStateCombinedSessionState);
CGEventSourceSetLocalEventsSuppressionInterval(eventSourceRef, 0);
This works fine with CGWarpMouseCursorPosition
(and is not deprecated), whereas CGAssociateMouseAndMouseCursorPosition(true)
was of no help for me.
You're probably looking for CGSetLocalEventsSuppressionInterval(), a method deprecated as of 10.6... it still works though in 10.7.
http://developer.apple.com/library/mac/#documentation/Carbon/Reference/QuartzEventServicesRef/DeprecationAppendix/AppendixADeprecatedAPI.html#//apple_ref/c/func/CGSetLocalEventsSuppressionInterval
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With