我这里有代码将鼠标限制在屏幕上的一个区域,它运行得相对较好,只有一个大问题。当沿着区域的边缘运行时,鼠标不会干净/平滑地移动,而是以非常波动的方式跳跃,我相信这可能是由于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);
}
答案 0 :(得分:5)
正如您所发现的那样,CGSetLocalEventsSuppressionInterval
可以解决您的问题。
但是,从10.6开始,它已被弃用。 Apple文档声明:
由于未记录的特殊情况和不良副作用,建议不要将此功能用于一般用途。建议替换此函数的是
CGEventSourceSetLocalEventsSuppressionInterval
,它允许针对特定事件源调整抑制间隔,仅影响使用该事件源发布的事件。
很遗憾,替换CGEventSourceSetLocalEventsSuppressionInterval
不适用于CGWarpMouseCursorPosition
次移动。
相反,在warp之后立即使用CGAssociateMouseAndMouseCursorPosition(true)
:
CGPoint warpPoint = CGPointMake(42, 42);
CGWarpMouseCursorPosition(warpPoint);
CGAssociateMouseAndMouseCursorPosition(true);
文档没有提及此行为,但它似乎取消了warp之后的抑制间隔。
答案 1 :(得分:1)
你可能正在寻找CGSetLocalEventsSuppressionInterval(),这是一种从10.6开始不推荐使用的方法......它仍然可以在10.7中使用。
答案 2 :(得分:0)
我可以通过以下方式让CGEventSourceSetLocalEventsSuppressionInterval
与CGWarpMouseCursorPosition
一起工作:
auto eventSourceRef = CGEventSourceCreate(kCGEventSourceStateCombinedSessionState);
CGEventSourceSetLocalEventsSuppressionInterval(eventSourceRef, 0);
这对CGWarpMouseCursorPosition
很好(并且不推荐使用),而CGAssociateMouseAndMouseCursorPosition(true)
对我没有帮助。