2011-11-21 110 views
6

我有代碼在這裏限制鼠標到屏幕上的一個區域,它工作得比較好,只有一個大問題。當沿着區域的邊緣運行時,鼠標不會乾淨/平滑地移動,而是以非常不連貫的方式跳轉,我相信這可能是由於CGWarpMouseCursorPosition導致每個「warp」延遲。爲什麼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

我不認爲它很慢;計時,最長的時間是0.006秒。儘管如此,它可能會更好一些:您應該在NS或CGRect中定義分隔區域,我認爲您可以切除循環。 –

+0

矩形只是一個臨時演示工具。實際上,我將針對黑色和白色位圖進行測試,黑色像素區域是鼠標友好區域,鼠標不能移動到白色區域。黑色區域的形狀將非常怪異,因此我認爲該循環可能是必要的。除非你有更好的解決方案? – BumbleShrimp

+0

這可能實際上更容易找到鼠標是否超出了可接受的範圍。訣竅在於找到最接近的可接受點將其移回,但是,我認爲您需要一個循環。無論如何,我很驚訝,只是修改事件的位置和增量(甚至修改和返回副本)不起作用。 –

回答

4

當你發現,CGSetLocalEventsSuppressionInterval解決您的問題。

但是,從10.6開始不推薦使用。 Apple文檔狀態:

此功能不建議用於一般用途,因爲無證的特殊情況和不良副作用。該功能的推薦替代品爲CGEventSourceSetLocalEventsSuppressionInterval,它允許針對特定事件源調整抑制間隔,僅影響使用該事件源發佈的事件。

不幸的是,替換CGEventSourceSetLocalEventsSuppressionInterval不適用於CGWarpMouseCursorPosition移動。

相反,使用CGAssociateMouseAndMouseCursorPosition(true)經後:

CGPoint warpPoint = CGPointMake(42, 42); 
CGWarpMouseCursorPosition(warpPoint); 
CGAssociateMouseAndMouseCursorPosition(true); 

的文件沒有提到的這種行爲,但它出現在經後取消抑制間隔。