我想在OS X 10.11中将鼠标移动限制在屏幕的特定矩形区域。我修改了MouseTools(下面)中的一些代码来执行此操作,但是当您点击屏幕边缘时它会感到紧张。我怎样摆脱这种抖动?
// 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
为鼠标移动创建回调。在代码中它说&#34;我们可以改变鼠标事件的各个方面。例如,我们可以使用CGEventSetLocation(event, newLocation)
。&#34;不幸的是,这实际上并没有改变鼠标的位置(完整示例here)。我能够改变鼠标位置的唯一方法是CGEventPost
或CGWarpMouseCursorPosition
。我还尝试使用
kCGHIDEventTap
而不是kCGSessionEventTap
,我检查了我为该应用启用了超级用户权限和辅助功能。它似乎应该工作,因为有另一个modifying key presses的例子可以正常工作。我没有使用CGEventSetLocation
,而是尝试使用CGEventSetIntegerValueField
(如键盘示例中所示)将x和y增量设置为0,但这并没有改变任何内容。
最后,我还尝试在CGEventPost
内使用CGWarpMouseCursorPosition
和CGEventCallback
,&#34;隐形边框&#34;仍然比上面的代码更加紧张。
答案 0 :(得分:3)
我在Mac驱动程序中为Wine实现了这个功能。它有点复杂。
方法是通过调用CGAssociateMouseAndMouseCursorPosition(false)
来基本禁用鼠标光标的移动。如果约束矩形是光标当前位置的1x1矩形,这里就可以实现你想要的效果。
最重要的是,然后我使用事件点击来观察鼠标移动事件。这些不会改变位置,但具有用户尝试做的增量。然后我使用CGWarpMouseCursorPosition()
根据这些增量移动光标并在传递之前调整事件。
请注意,鼠标事件中的位置信息没有意义。这将是陈旧的。有些事件会在您最后一次扭曲之前排队,因此有一个旧位置。您需要跟踪光标本身的位置。它会从您将鼠标与鼠标取消关联的任何地方开始,并在您扭曲它时进行更改。您将增量添加到该(而不是事件位置),将其添加到约束矩形,并将其用作事件和扭曲的新位置。对于下一个活动,您将从这个新职位开始。等
还有一个令人遗憾的皱纹。 CGWarpMouseCursorPosition()
会影响后续鼠标移动事件的增量值。基本上,您扭曲光标的距离将添加到在扭曲后排队的第一个鼠标移动事件。未经检查,这将有效地使用户的鼠标移动加倍,每次事件都会出现失控的反馈循环,光标会射到一个极端或另一个极端。
因此,您必须记录您执行的经线,执行时的扭曲以及它们改变位置的程度。然后,当事件通过水龙头时,您将它们的时间与经线时间进行比较。对于比当前事件更早的任何扭曲,您从事件的增量中减去它们的位置变化并将其从列表中删除。