在 macOS 上使用 Core Graphics 生成相对鼠标事件

3
我将使用核心图形框架来生成鼠标事件。我希望能够正常地移动鼠标,并在FPS游戏中移动鼠标。问题是这两种情况似乎需要不同的事件。
我可以使用以下代码来移动游戏外的鼠标:
// Event source was created with this:
// CGEventSourceCreate(kCGEventSourceStateCombinedSessionState)

CGPoint mouse_location(CGEventSourceRef source) {
    CGEventRef event = CGEventCreate(source);
    CGPoint loc = CGEventGetLocation(event);
    CFRelease(event);
}

void mouse_move_relative(CGEventSourceRef source, int x, int y) {
    CGPoint pos = mouse_location(source);
    pos.x += x;
    pos.y += y;
    CGEventRef event = CGEventCreateMouseEvent(source, kCGEventMouseMoved, loc, kCGMouseButtonLeft);
    CGEventSetIntegerValueField(event, kCGMouseEventDeltaX, x);
    CGEventSetIntegerValueField(event, kCGMouseEventDeltaY, y);
    CGEventPost(kCGHIDEventTap, event);
    CFRelease(event);
}

这段代码在游戏外运行正常,但在游戏中鼠标似乎会碰到屏幕边缘就停止移动。因此,我尝试使用增量值而不是设置位置。

void mouse_move_relative(CGEventSourceRef source, int x, int y) {
    CGEventRef event = CGEventCreate(source);
    CGEventSetType(event, kCGEventMouseMoved);
    CGEventSetIntegerValueField(event, kCGMouseEventButtonNumber, kCGMouseButtonLeft);
    CGEventSetIntegerValueField(event, kCGMouseEventDeltaX, x);
    CGEventSetIntegerValueField(event, kCGMouseEventDeltaY, y);
    CGEventPost(kCGHIDEventTap, event);
    CFRelease(event);
}

这段代码在游戏内部运行,鼠标不会碰到屏幕边缘,但当鼠标移到游戏外时就无法移动。如果我在游戏中打开菜单选项,就不能再移动鼠标了。我需要两种不同的代码路径或两种不同的模式来处理这两种情况。我想避免在这两种模式之间切换,想知道是否有可能实现。

我能生成一个可以在两种情况下都能工作的鼠标事件吗?

也许有一种方法可以告诉系统何时进入相对鼠标模式,并相应地更改发出的事件?我不确定核心图形是否能做到这一点(或者这是否合理)。此外,我不完全理解kCGHIDEventTapkCGEventSourceStateCombinedSessionState的含义。文档中谈论了点击和表格,我不是很懂。也许我只需要更改其中一个...?

请注意,以上片段可能不完全正确,因为我在Rust中使用了包装库,但这并不重要。

1个回答

2
原来很简单。我所需要做的就是限制鼠标坐标在显示范围内。
CGDirectDisplayID display = CGMainDisplayID();
size_t width = CGDisplayPixelsWide(display);
size_t height = CGDisplayPixelsHigh(display);
pos.x = min(max(pos.x, 0), width - 1);
pos.y = min(max(pos.y, 0), height - 1);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接