Is it possible to lock the cursor inside the game window?

Is there any way in MonoGame to lock the mouse cursor inside the game window, to prevent accidental clicks outside that cause the game to minimize? This happens pretty often with a second monitor.

It’s been a while, but I believe a way I’ve implemented this in the past is to simply check each frame if the mouse position is out of the window (either negative in the x/y or greater than window width/height) and if so, use Mouse.SetPosition to keep it in bounds.

i.e.

MouseState mouseState = Mouse.GetState();
Point relativeCursorPos = new Point(mouseState.X, mouseState.Y);
Point relativeCursorPosCache = relativeCursorPos;

if (relativeCursorPos.X < 0)
	relativeCursorPos.X = 0;
else if (relativeCursorPos.X > Window.ClientBounds.Width)
	relativeCursorPos.X = Window.ClientBounds.Width;

if (relativeCursorPos.Y < 0)
	relativeCursorPos.Y = 0;
else if (relativeCursorPos.Y > Window.ClientBounds.Height)
	relativeCursorPos.Y = Window.ClientBounds.Height;

if (relativeCursorPos != relativeCursorPosCache)
	Mouse.SetPosition(relativeCursorPos.X, relativeCursorPos.Y);

This wouldn’t be a “great” solution since the cursor and game run at different frequencies so the mouse still “jitters” out of the window when being moved, so to speak.

1 Like

Thinking about this a bit more: assuming you don’t need the system cursor, an easy way to avoid the “jittering outside the window” issue would be to do this instead:

  1. Hide the real cursor (IsMouseVisible = false;)
  2. Have a Point variable that stores a virtual cursor position
  3. Every frame add the cursors actual position to it, minus the offset explained in the next step. I.e. add the vector that the cursor has moved since the last time you checked.
  4. Right after that use Mouse.SetPosition to set it in the middle of the window. I.e. create this offset from half your window’s width/height.
  5. Use the above (previous post) method to limit the virtual cursor position to the window bounds
  6. Render a cursor sprite using your virtual cursor position instead of the real one

Since the real cursor is set to the center of the window every frame, the only way it’d actually leave the window is if it managed to move from the center to the outside of the window in a single frame. Therefore, no jitter due to mismatched frequencies and no need to dig into platform-level stuff to lock the window focus or anything like that, win-win.