How to set the mouse cursor position?

Hello all!

I found a few things dating back to 7 years ago which don’t work, and couldn’t find anything similar/current, so I wanted to ask how I can set the mouse cursor to a certain position of my cam’s viewport. I say this because I have 2 viewports, and I want it move it to a point on it.

Thanks for the help,

~Jason

i know you can use org.lwjgl.input.Mouse.setCursorPosition(x, y), i do not think there is a proper wrapper for this. id be careful using this as its generally not advised to use lwjgl directly. (as it defeats the purpose of using a high level library like jmonkey). If jmonkey ever moves from lwjgl your code would become incompatible.

also from a user experience, be careful because moving your user’s mouse can cause anger and confusion in some.

2 Likes

There was apparently MouseInput.get.setCursorPoisiton froma topic from 2007, but that doesn’t work.

There is also this

http://hub.jmonkeyengine.org/forum/topic/set-the-cursor-location/

Which says to use Java.awt.Robot’s mouseMove(int x, int y), but only works on fullscreen(which I am using for now, but int he future might change).

In this topic http://hub.jmonkeyengine.org/forum/topic/set-mouse-location/

They talk abut “hardware” and “absolute mouse” which I’m not sure what eitehr of those are, and since iti s the 2007 topic, it probably is some old old code.

As for moving my mouse, I originally wasn’t going to do it, but with 1 of my commands I’m switching from no mouse to the mouse drag, and I need to use that to click on a mini map, otherwise there isn’t a cursor. I wanted to bring the mouse to my icon on the mini map, and only allow the mouse bounds to be within the mini-map…

If this is a bad idea then I wont do it, but I figure that it wont impact my users, so why not?

Thanks!

Well I was super tired last night and realized now that I could check out inputManager.getCursorPosition() further, and sure enough I found .set(x, y);

Trying it out now will update with results.

EDIT: Booo…? Didn’t work… I also tried to update the inputManager, but that just got weird.

I will check out the robotics, but I’m trying to see if there is a better way…

[java] public void onMouseMotionEvent(MouseMotionEvent evt) {
if (!eventsPermitted) {
throw new UnsupportedOperationException(“MouseInput has raised an event at an illegal time.”);
}

    cursorPos.set(evt.getX(), evt.getY());
    inputQueue.add(evt);
}[/java] 

This is from InputManager, cursorPos.set(evt.getX(), evt.getY()); is what we want from the looks of it.

using “getCursorPositon” returns “cursorPos” which is the Vector2f, and this is one of the only places it’s used otherwise.

goes deep…

EDIT: So after adding robot in I start up do what I normally do and nothign, except I couldn’t turn off my mouse anymore. After Trying to alt + tab and a bunch of other issues I came back in and it worked… Except when you move away “fasT” it snaps back the mouse to the original position. Slow cursor movement will alow you to move away, but once it’s move quickly again you’re sol…

Oh wells…

Hello, I’m very interested in this. I want to inject keyboard and joystick movements into the cursor.

I just tried to construct my own MouseMotionEvent and inject this directly, but the programm terminated with an exception.

I will post any successful workarounds here. I hope that I can replace the system cursor with my own cursor system, if nothing else works.

But I’m wondering why there isn’t any official solution to this - or is there any?

Because a) it’s not as straight forward as one might think, and b) it’s a little strange to indirectly call your own listeners through the InputManager.

…if you want to do the thing that happens when the mouse moves… then call your listener that does the thing. At least, most use-cases boil down to a design issue on the game side.

@pspeed said: Because a) it's not as straight forward as one might think, and b) it's a little strange to indirectly call your own listeners through the InputManager.

…if you want to do the thing that happens when the mouse moves… then call your listener that does the thing. At least, most use-cases boil down to a design issue on the game side.

I didn’t get this. But thanks for the swift response!

Here are my activities:

Recently I was using a java.util.Robot - but this failed (I was able to change the cursor position a little bit, but it jitters extremely and slides apart).

At the moment I’m on the way to write my own CustomInputManager and replace the standard one completely by my own implementation.
The Problem is, that many things, like Joystick work together with the original InputManager and that I will have to write my own “CustomApplication” class too.

Also, if this fails, I might write my own cursor-system that uses a GUI billboard and reacts to any input that I inject into it.

Since I did not understand what you wrote, pspeed, I might be missing a simple solution.
What would you do, if you would want the cursor to be moved by both joystick and key and normal mouse movement?

When you click on a mouse button or move the mouse, what happens? Your listener is called… or nothing happens.

So if you need to do this manually… just call your listener. There is no reason to write your own InputManager, really. It’s a lot of work just so you can call something else with is only going to be calling YOUR CODE again. Seems silly to me.

Edit: perhaps put another way: why do you want to simulate these events?

1 Like

The rabbit hole goes deep - I have an idea to improve the code written in jME:

Why not declare InputManager as an interface instead of a class?

Then I could simply swap in and out these components of the Application class.

This is one of the good principles of writing code always against an interface, not against classes.

:slight_smile:

EDIT: The rabbit hole is to deep - I would have to rewrite most of the engine code.
EDIT: So now I try to modify the SVN-checkout of jME3 and write a new “TestMouseCursorInjection” test case.

EDIT: I give up now - and will try the next thing: Write my own fancy cursor.
EDIT: This cursor will rely on the Picture or BillboardNode class and deactivate the NativeCursor that seems to be OS-controlled.

EDIT: There is already a jme3test.gui.TestSoftwareMouse :slight_smile:

EDIT: There is a one frame delay - which is bad when VSync is active. Tested this (VSync off is better for the cursor).
EDIT: This is not such a big problem though, as long as cursor-based ray-tests are always relative to the software cursor!

@pspeed said: When you click on a mouse button or move the mouse, what happens? Your listener is called... or nothing happens.

So if you need to do this manually… just call your listener. There is no reason to write your own InputManager, really. It’s a lot of work just so you can call something else with is only going to be calling YOUR CODE again. Seems silly to me.

Edit: perhaps put another way: why do you want to simulate these events?

This is why:
I want to have a game with a cursor, that I can control either by: mouse only / keyboard only / joystick only

@Ogli said: This is why: I want to have a game with a cursor, that I can control either by: mouse only / keyboard only / joystick only

Ah, then as you’ve already discovered… InputManager is not really the issue. You will have to make and control this cursor yourself… either using RawInputListener or analog listeners or whatever. (Though personally I’d use Lemur’s InputMapper so that I could write just one listener.)

Even if you’d been able to inject events there would have been no way to avoid a one frame delay. But I seriously doubt you are noticing the delay. If you are noticing it then it’s more than one frame. 16 ms lag is really hard to see. More likely there is some other phenomenon going on.

Well, it’s quite simple: If you have a system cursor (the native cursor) you don’t have a 1 frame delay.

My eyes are good enough, plus: When I activate the native cursor in addition to the software cursor, it is even easier to notice. :slight_smile:

Just as I said, if you turn off the vsync (I have some thousands of frames per second on my machine), it is of course different.
Then the software cursor is on par with the hardware cursor (you don’t notice the difference when it has been adjusted < 1ms after the native cursor).

I am now coding a nice software cursor system with animated mouse cursors, and my progress is quite nice.
Maybe you can take the best of my code after I’m finished with this and integrate that into Lemur. I would be proud.

Happy Coding!

EDIT: Ehm, I meant there is a 1 frame delay for native cursor and a 2 frame delay for software cursor. Stupid me! :slight_smile:

@pspeed said: Even if you'd been able to inject events there would have been no way to avoid a one frame delay. But I seriously doubt you are noticing the delay. If you are noticing it then it's more than one frame. 16 ms lag is really hard to see. More likely there is some other phenomenon going on.

Hm, there is another possible explanation that just came into my mind:
It might be that the native cursor is fed with the latest coords while the backbuffer is being rendered.
During this time a gap occurs: The software cursor is frozen to its last known value, but the native cursor still receives updates from the OS.

@Ogli said: Hm, there is another possible explanation that just came into my mind: It might be that the native cursor is fed with the latest coords while the backbuffer is being rendered. During this time a gap occurs: The software cursor is frozen to its last known value, but the native cursor still receives updates from the OS.

Yes, if you move really fast then you will see your cursor lag the native cursor… but you should be hiding the native cursor if you are managing your own.

For those reading this in the future, the JME inputManager cursorPosition is being inverted across the X axis and you can easily fix it within your onAction() method.

if (name.equals("leftClick")||name.equals("rightClick")) {
      if(keyPressed){
//Mouse is pressed, cursor position Recorded.
        cursorPosition = new Vector2f(app.getInputManager().getCursorPosition());
                     }
      else{
//Mouse is released, cursor is repositioned to original location 
//notice the flip across the X axis
          org.lwjgl.input.Mouse.setCursorPosition((int)cursorPosition.x,(int) (resolution.y-cursorPosition.y));
          }
  }

This should not be happening. For me, 0 is left and screenWidth is right as it should be.