Objective c 将鼠标限制为Mac上的一个显示器(可能使用Cocoa)

Objective c 将鼠标限制为Mac上的一个显示器(可能使用Cocoa),objective-c,macos,cocoa,mouse,multiple-monitors,Objective C,Macos,Cocoa,Mouse,Multiple Monitors,我一直在狂热地寻找一种方法,在Mac上的多显示器设置中,将用户的鼠标限制在一个显示器上 我偶然发现了这个问题:,我保证我没有重复这个问题 然而,这个问题确实在我的脑海中引发了一个想法,那就是可以使用Cocoa编写一个简单的应用程序,将鼠标限制在一个屏幕上,在后台运行这个应用程序,并且仍然使用我在AS3/Adobe AIR/Flash中开发的游戏 该游戏是一款全屏游戏,在同一显示器上的分辨率始终相同。另一个监视器也将始终具有相同的分辨率,但只是一个非交互式的信息显示。我需要用户能够与游戏交互,但不

我一直在狂热地寻找一种方法,在Mac上的多显示器设置中,将用户的鼠标限制在一个显示器上

我偶然发现了这个问题:,我保证我没有重复这个问题

然而,这个问题确实在我的脑海中引发了一个想法,那就是可以使用Cocoa编写一个简单的应用程序,将鼠标限制在一个屏幕上,在后台运行这个应用程序,并且仍然使用我在AS3/Adobe AIR/Flash中开发的游戏

该游戏是一款全屏游戏,在同一显示器上的分辨率始终相同。另一个监视器也将始终具有相同的分辨率,但只是一个非交互式的信息显示。我需要用户能够与游戏交互,但不要意外地将鼠标从游戏屏幕上移开

问题摘要: 我是否可以使用Cocoa/Objective C为Mac OS X(Lion)创建一个基本应用程序,将鼠标限制在一个可以在后台运行的监视器上,并防止用户将鼠标移到监视器外,监视器上会运行全屏游戏


[编辑:] 我找到了为石英事件过滤器运行循环所需的基本代码,这得益于以下回答:

我将使用该代码进行测试,并对其进行了一些修改,以检测如下鼠标事件:

CGEventRef mouse_filter(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon) {

    NSPoint point = CGEventGetLocation(event);
    NSPoint target = NSMakePoint(100,100);
    if (point.x >= 500){
        CGEventSetLocation(event,target);

    }
    return event;
}

int main(int argc, char *argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    CFRunLoopSourceRef runLoopSource;

    CFMachPortRef eventTap = CGEventTapCreate(kCGHIDEventTap, kCGHeadInsertEventTap, kCGEventTapOptionDefault, kCGEventMouseMoved, 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);
}
然而,这似乎并不完全正确。它当然能够正确地检测鼠标事件,并且能够正确地移动事件。例如,如果我从屏幕左侧拖动窗口超过500像素,窗口拖动事件将移动到100100。但是,当鼠标在屏幕上移动时,它本身不会移动到新位置,不会执行其他操作。IE:你仍然可以在屏幕上移动鼠标,而不仅仅是在左边的500像素列上


有什么想法吗?

使用石英事件点击过滤鼠标移动和鼠标拖动的事件。在点击回调中,使用
CGEventSetLocation
修改鼠标事件的位置,否则这些鼠标事件将移出主屏幕

您可能需要以root用户身份运行该程序,或者在系统首选项中启用辅助设备访问


这听起来是一个很好的解决方案,我会尽可能快地尝试一下,然后再与您联系。谢谢,Rob。我能定义一个形状不规则的区域吗?在该区域之外,鼠标会移回区域上最近的点?你可以根据你想要的任何标准调整或拒绝鼠标移动事件。Rob,我终于开始测试了,我想出来的还不是很好。似乎在不执行其他事件的情况下移动鼠标不会触发我的事件点击回调。我已经发布了问题中的代码和更多信息。将
kCGEventMouseMoved
更改为
CGEventMaskBit(kCGEventMouseMoved)
。实际上,您需要使用
CGEventMaskBit(kcGeventMouseMouseMoved)| CGEventMaskBit(kcGeventleftMouseDraged)| CGEventMaskBit(kcGeventotherMouseDraged)