2016-12-01 64 views
4

我想限制鼠标移动到OS X 10.11屏幕上的特定矩形区域。我修改了一些来自MouseTools(下面)的代码来做到这一点,但是当你点击屏幕边缘时它很紧张。我怎样才能摆脱这种抖动?限制鼠标移动到OS X中没有抖动的区域

// gcc -Wall constrain.cpp -framework ApplicationServices -o constrain 

#include <ApplicationServices/ApplicationServices.h> 

int main (int argc, const char * argv[]) { 
    if(argc != 5) { 
     printf("Usage: constrain left top right bottom\n"); 
     return 0; 
    } 
    int leftBound = strtol(argv[1], NULL, 10); 
    int topBound = strtol(argv[2], NULL, 10); 
    int rightBound = strtol(argv[3], NULL, 10); 
    int bottomBound = strtol(argv[4], NULL, 10); 
    CGEventTapLocation tapLocation = kCGHIDEventTap; 
    CGEventSourceRef sourceRef = CGEventSourceCreate(kCGEventSourceStatePrivate); 
    while(true) { 
     CGEventRef mouseEvent = CGEventCreate(NULL); 
     CGPoint mouseLoc = CGEventGetLocation(mouseEvent); 
     int x = mouseLoc.x, y = mouseLoc.y; 
     if(x < leftBound || x > rightBound || y < topBound || y > bottomBound) { 
      if(x < leftBound) x = leftBound; 
      if(x > rightBound) x = rightBound; 
      if(y < topBound) y = topBound; 
      if(y > bottomBound) y = bottomBound; 
      CGEventRef moveMouse = CGEventCreateMouseEvent(sourceRef, kCGEventMouseMoved, CGPointMake(x, y), 0); 
      CGEventPost(tapLocation, moveMouse); 
      CFRelease(moveMouse); 
     } 
     CFRelease(mouseEvent); 
     usleep(8*1000); // 8ms, ~120fps 
    } 
    CFRelease(sourceRef); 
    return 0; 
} 

这里有一些其他的事情我想:Receiving, Filtering, and Modifying Mouse Events演示如何创建使用CGEventTapCreate鼠标移动回调。在代码中它说:“我们可以改变鼠标事件的各个方面,例如,我们可以使用CGEventSetLocation(event, newLocation)。”不幸的是,这实际上并没有改变鼠标位置(完整示例here)。我能够改变鼠标位置的唯一方法是做CGEventPostCGWarpMouseCursorPosition。我还尝试使用 kCGHIDEventTap而不是kCGSessionEventTap,并且检查了我为应用程序启用了超级用户权限和辅助功能。它似乎应该工作,因为有modifying key presses正常工作的另一个例子。而不是使用CGEventSetLocation我也尝试使用CGEventSetIntegerValueField(如在键盘示例中)将x和y偏移量设置为0,但这并没有改变任何东西。

最后,我也试过用和CGWarpMouseCursorPosition里面的CGEventCallback,“隐形边框”还是比上面的代码更加紧张。

+0

您的问题的描述是详细的。除非您遇到问题,否则没有人关心您使用AppleScript程序所做的工作。 –

+1

@ElTomato我通过删除解释我对AppleScript的第一次尝试的两个句子以及我对它的问题来减少了冗长的问题。假设你对这个话题有所了解,我很乐意在你提出的问题上提出反馈意见。谢谢! –

+0

谁的鼠标移动将被禁止?任何人使用您的计算机或您的应用程序的用户? –

回答

3

我已经在Mac驱动程序中为Wine实现了这个功能。它变得有点复杂。

该方法基本上通过调用CGAssociateMouseAndMouseCursorPosition(false)来禁用鼠标光标的移动。如果约束矩形是光标当前位置处的1x1矩形,则此处即可实现所需内容。

最重要的是,我使用事件点击来观察鼠标移动事件。这些不会改变立场,但有用户试图做的事情的增量。然后,我使用CGWarpMouseCursorPosition()根据这些增量移动光标,并在传递它们之前调整事件。

请注意,鼠标事件中的位置信息无意义。这将是陈旧的。有些事件会在你最后一次变形之前排队,因此有一个旧的位置。你需要跟踪光标所在的位置。无论它从鼠标中分离出来,它随时都会启动,无论何时都会发生变化。您将增量添加到该事件(而不是事件位置),将其限制在约束矩形中,并将其用作事件和变形的新位置。对于下一个活动,您将从这个新的位置开始。等

还有一个额外的不幸的皱纹。 CGWarpMouseCursorPosition()影响后续鼠标移动事件的增量值。基本上,您将光标扭曲的距离被添加到在扭曲之后排队的第一个鼠标移动事件。未经检查,这将有效地将用户的鼠标移动加倍,每个事件都会产生失控反馈循环,并且光标将射到一个极端或另一个极端。

所以,你必须记录你执行的经纱,当你执行它们时,以及它们改变了多少位置。然后,当事件通过水龙头进入时,您将他们的时间与扭曲时间进行比较。对于比当前事件早的任何经纱,您可以从事件的增量中减去它们的位置变化,并将它们从列表中删除。

+0

谢谢。你所描述的听起来像是最好的解决方案。并感谢您在Mac上Wine的工作! –