为什么 CGWarpMouseCursorPosition 会导致延迟?如果不是,那是什么?
我这里有代码将鼠标限制在屏幕上的某个区域,它工作得相对良好,只有一个大问题。当沿着区域边缘运行时,鼠标不会干净/平滑地移动,而是以一种非常不稳定的方式跳跃,我相信这可能是由于 CGWarpMouseCursorPosition 导致每次“扭曲”延迟。
谁能告诉我是否是我的代码中的某些内容导致了这种延迟,或者实际上是鼠标扭曲功能。如果是鼠标扭曲功能,有什么方法可以平滑地重新定位鼠标吗?我在Flash中做了同样的事情,它工作完美,我知道循环不只是采取执行时间太长,导致速度减慢,因为它可能只运行 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);
}
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);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
正如您所发现的,
CGSetLocalEventsSuppressionInterval
解决了您的问题。但是,从 10.6 开始它已被弃用。苹果文档指出:
不幸的是,替换
CGEventSourceSetLocalEventsSuppressionInterval
不适用于CGWarpMouseCursorPosition
移动。相反,在扭曲之后立即使用 CGAssociateMouseAndMouseCursorPosition(true):
文档没有提及此行为,但它似乎取消了扭曲之后的抑制间隔。
As you discovered,
CGSetLocalEventsSuppressionInterval
fixes your problem.However, it's deprecated as of 10.6. the Apple docs state:
Unfortunately, the replacement
CGEventSourceSetLocalEventsSuppressionInterval
does not work withCGWarpMouseCursorPosition
movements.Instead, use
CGAssociateMouseAndMouseCursorPosition(true)
immediately after the warp:The documentation makes no mention of this behavior, but it appears to cancel the suppression interval after the warp.
我可以通过以下方式让
CGEventSourceSetLocalEventsSuppressionInterval
与CGWarpMouseCursorPosition
一起使用:这可以很好地与
CGWarpMouseCursorPosition
配合使用(并且未弃用),而CGAssociateMouseAndMouseCursorPosition (true)
对我没有帮助。I could get
CGEventSourceSetLocalEventsSuppressionInterval
to work withCGWarpMouseCursorPosition
the following way:This works fine with
CGWarpMouseCursorPosition
(and is not deprecated), whereasCGAssociateMouseAndMouseCursorPosition(true)
was of no help for me.您可能正在寻找 CGSetLocalEventsSuppressionInterval(),该方法从 10.6 开始已弃用...但在 10.7 中仍然有效。
http://developer.apple.com/library/mac/#documentation/Carbon/Reference/QuartzEventServicesRef/DeprecationAppendix/AppendixADeprecatedAPI.html#//apple_ref/c/func/CGSetLocalEventsSuppressionInterval
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