1

我有一些使用 LWJGL 的 Java 代码:

import org.lwjgl.input.Mouse; 
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
...
Display.setDisplayMode(new DisplayMode(200, 200));
Display.create();
Mouse.create();
Mouse.setGrabbed(true);
while (true) 
{
    Display.update();
    System.out.println("Data: d("+ Mouse.getDX() + "," + Mouse.getDY() + ") p(" + Mouse.getX() + "," + Mouse.getY() + ")");
    Thread.sleep(1000/20);
}

当我物理移动鼠标时它工作正常,但是当我使用 Cocoa 应用程序模拟移动鼠标时:

  • getDX()getDY()返回 0
  • getX()getY()返回之前的值(就好像鼠标没有移动一样)

我用来移动鼠标的代码是这样的:

PostMouseEvent(0, kCGEventMouseMoved, mouseLocation);
...
void PostMouseEvent(CGMouseButton button, CGEventType type, const CGPoint point)
{    
    CGWarpMouseCursorPosition(point);
    CGEventRef theEvent = CGEventCreateMouseEvent(NULL, type, point, button);
    CGEventSetType(theEvent, type);
    CGEventPost(kCGHIDEventTap, theEvent);
    CGAssociateMouseAndMouseCursorPosition(1);
    CFRelease(theEvent);
}

这在几乎所有其他应用程序(包括鼠标悬停事件)中都很有效。

如何修改我的 Objective-C 以便 LWJGL 正确响应鼠标事件?

干杯

附加信息:

物理移动鼠标并停止后,我在日志中得到这个(例如):

Data: d(0,0) p(379,-748)
Data: d(0,0) p(379,-748)
Data: d(0,0) p(379,-748)
Data: d(0,0) p(379,-748)
Data: d(0,0) p(379,-748)
Data: d(0,0) p(379,-748)

当我让我的 Cocoa 应用程序移动鼠标时,上面继续显示

然后,当我再次移动鼠标时,值会跳转到:

Data: d(163,123) p(542,-625)     //this seems like a huge change!
Data: d(8,7) p(550,-618)         //normal
Data: d(0,0) p(550,-618)         //normal
Data: d(48,36) p(598,-582)       //etc

好像鼠标被传送了?

编辑:当使用java.awt.Robot移动鼠标时,LWJGL 会按预期响应。

4

1 回答 1

1

我第一个假设没有 Cocoa 应用程序响应鼠标移动CGEventPost是错误的。真正的问题是:

如果使用CGEventPostand移动鼠标CGEventCreateMouseEvent,则事件没有 adeltaXdeltaY值。许多应用程序似乎都依赖于它们(就像我的目标应用程序(Minecraft)一样,它从 LWJGL 接收这些值)。

您必须手动计算这些值并在事件中设置它们。

我的项目中的示例代码:

CGEventRef pointGetEvent = CGEventCreate(NULL);
CGPoint point = CGEventGetLocation(pointGetEvent);
CFRelease(pointGetEvent);

if(test(SNES_Y)){
    CGPoint oldPoint = point;
    if(test(SNES_LEFT)){
        point = CGPointMake(point.x - MOUSE_STEP, point.y);
    }
    if(test(SNES_RIGHT)){
        point = CGPointMake(point.x + MOUSE_STEP, point.y);
    }
    if(test(SNES_DOWN)){
        point = CGPointMake(point.x, point.y + MOUSE_STEP);
    }
    if(test(SNES_UP)){
        point = CGPointMake(point.x, point.y - MOUSE_STEP);
    }

    if(oldPoint.x != point.x || oldPoint.y != point.y){
        CGEventRef move1 = CGEventCreateMouseEvent(NULL, kCGEventMouseMoved, point, kCGMouseButtonLeft);
        CGEventSetDoubleValueField(move1, kCGMouseEventDeltaX, point.x - oldPoint.x);
        CGEventSetDoubleValueField(move1, kCGMouseEventDeltaY, point.y - oldPoint.y);
        CGEventPost(kCGSessionEventTap, move1);
        CFRelease(move1);
    }
}
于 2015-01-26T17:54:54.520 回答