我这里的代码将鼠标限制在屏幕上的一个区域,它工作得相对较好,只有一个大问题.当沿着区域的边缘运行时,鼠标没有干净/平滑地移动,而是以非常波动的方式跳跃,我相信这可能是由于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,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); }
解决方法
正如您所发现的,CGSetLocalEventsSuppressionInterval可以解决您的问题.
但是,从10.6开始,它已被弃用. Apple文档声明:
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.
不幸的是,replacementCGEventSourceSetLocalEventsSuppressionInterval不适用于CGWarpMouseCursorPosition移动.
相反,在warp之后立即使用CGAssociateMouseAndMouseCursorPosition(true):
CGPoint warpPoint = CGPointMake(42,42); CGWarpMouseCursorPosition(warpPoint); CGAssociateMouseAndMouseCursorPosition(true);
文档没有提到这种行为,但似乎取消了warp之后的抑制间隔.