Locking cursor in fullscreen when you are using dual monitors

P

ph101

Guest
Hi guys,

I have a problem. This is the code I use to find my mouse x,y:

x = global.xwidth * (device_mouse_raw_x(0) / max(1, window_get_width()));
y = global.yheight * (device_mouse_raw_y(0) / max(1, window_get_height()));

And I draw the cursor on GUI layer. Game is in fullscreen. No problem

What I find is that on my duel monitor setup if I move the cursor off the side into the next mointor it comes out of the game screen and into windows - that is to say on the side monitor I see my windows cursor, but the game doesn't lose focus (ie not alt tabbed unless I click), but my game cursor stays where it was edge of screen. In my game if you mouse to the edgeo fthe screen it pushines a boundry, but this wont happen in said scenario.

Is there a way to lock the cursor in game on a dual screen set up? Ideally if you went off the side, because I am in full screen mode, not see the windows cursor?

Thanks
 
Last edited by a moderator:

Freddy Jones

Your Main Detective
What have you tried to lock the mouse position? The code I see you've posted is just for reading the position.

Take a look at this function:
Code:
display_mouse_set(x, y);
How you would use that would be something like this:
  • set position of mouse in center of screen on end step
  • on step event check where the mouse has moved relative to the center of the screen
  • If the position of the mouse doesn't change then whatever values were dependent of it shouldn't either
  • Other wise you can use the mouse change values to do whatever you were intending. It's not an absolute position of the screen, but additive/relative.

If you're just trying to prevent the mouse from going into the other screen then I'm not sure exactly what you could do - but I guess you'd still use this function. Maybe if the mouse goes past a certain position fling it back to monitor one's coordinates, but if the game isn' in focus don't run the code?
 
P

ph101

Guest
Thanks for your thoughts. I am looking at this but still stumped. In my game you drag the view when your mouse is near the edge of the screen or window. But if you move it beyond that, the windows mouse cursor becomes visible, and it no longer scrolls. WIll have a look at your suggestion. It could be possible, although honestly I can't really figure out how.. Must be other people who have games where you use the mouse and boundaries to scroll view who have encountered this when using either a window or dual screen...?
 

Phil Strahl

Member
Hmm... to fully "capture" a mouse, I would have a "virtual" mouse pointer, an object that you position yourself each step depending on the mouse movement difference since the last frame, while having the actual mouse reset to the center of your game window. That way, the mouse can never leave the game (unless you set it free) while your "virtual" pointer also can't leave the game, obviously.
  • On creation, center the mouse on the screen and hide the system mouse cursor (window_set_cursor(cr_none) and window_mouse_set() )
  • Then, on each step, I would see how far the mouse has been moved from the center in X and Y
  • add this difference to the "virtual" mouse pointer
  • Re-position the mouse in the center of the screen again
So each time you would check mouse_x, and mouse_y, you need to check your virtual mouse pointer's position.

Here's some code
Code:
  mouse_center_x = round(window_width / 2);
  mouse_center_y = round(window_height / 2);

  var offset_x = window_mouse_get_x() - mouse_center_x;
  var offset_y = window_mouse_get_y() - mouse_center_y;

  virtualmouse.x = floor(virtualmouse.x + offset_x);
  virtualmouse.y = floor(virtualmouse.y + offset_y);

  // limit virtual mouse pointer
  if (virtualmouse.x >= screen_width)
  {
  virtualmouse.x  = screen_width-1;
  }
  if (virtualmouse.x <= 0)
  {
  virtualmouse.x = 1;
  }
  if (virtualmouse.y >= screen_height)
  {
  virtualmouse.y = screen_height-1;
  }
  if (virtualmouse.y <= 0)
  {
  virtualmouse.y = 1;
  }

window_mouse_set(round(mouse_center_x), round(mouse_center_y));
 
K

Khyrid

Guest
Hmm... to fully "capture" a mouse, I would have a "virtual" mouse pointer,..... snip
This is close to perfect. Thanks a ton, I have been searching for a fix to this problem for a while. With dual monitors, VR Headsets, Drawing tablets etc becoming the norm, YOYO needs to get with the times and offer support for this.

Your solution isn't perfect though. If you make the mouse visible you can see its behavior and I found that if you whip the mouse hard enough to the edge of the screen you can still click out of the game. This may still be an issue for any game where the player moves the mouse around erratically.

Because the mouse is set to return to the center of the screen each step, I don't see a better way of doing this. I did however change your code a bit for my test. Note that BCH is the name of my virtual cursor game object.

Code:
//BCH LOCK
if(instance_number(BCH) > 0)
{
//I added this because screen_width and height is not a built in var
var screen_width = view_xview + view_wview;
var screen_height = view_yview + view_hview;
   
  mouse_center_x = round(screen_width/2);
  mouse_center_y = round(screen_height/2);

  var offset_x = window_mouse_get_x() - mouse_center_x;
  var offset_y = window_mouse_get_y() - mouse_center_y;

  BCH.x = floor(BCH.x + offset_x);
  BCH.y = floor(BCH.y + offset_y);

  // limit virtual mouse pointer
  if (BCH.x >= screen_width)
  {
  BCH.x  = screen_width-1;
  }
  if (BCH.x <= 0)
  {
  BCH.x = 1;
  }
  if (BCH.y >= screen_height)
  {
  BCH.y = screen_height-1;
  }
  if (BCH.y <= 0)
  {
  BCH.y = 1;
  }

window_mouse_set(round(mouse_center_x), round(mouse_center_y));

}
I just wish there was a way to prevent game-out clicking 100%.
 

Phil Strahl

Member
Your solution isn't perfect though. If you make the mouse visible you can see its behavior and I found that if you whip the mouse hard enough to the edge of the screen you can still click out of the game. This may still be an issue for any game where the player moves the mouse around erratically
True... still haven't found a better way to do this, so at least make the necessary distance as far as possible by centering the mouse, I thought ;) EDIT: the higher your room_speed is, the better, since the virtual mouse pointer moves smoother plus with double the room-speed, you need to fling the mouse around twice as fast to leave the window. Still I doubt that you can go beyond the system fps in windowed mode, which usually is 59 ot 60 fps…

Code:
//I added this because screen_width and height is not a built in var
var screen_width = view_xview + view_wview;
var screen_height = view_yview + view_hview;
}
Thanks. Actually, there's at least a function where my screen_width and screen_height variables get their content from, forgot to substitute them. Here's my corrected first two lines:
Code:
  mouse_center_x = round(window_get_width() / 2);
  mouse_center_y = round(window_get_height() / 2);
 
P

ph101

Guest
Thanks guys for your response and the example Phil. It seems the best possible solution right now - hopefully in the future there could be a function to actually prevent the mouse cursor leaving the window/display even with "mouse whipping".

I could add you might not want to use window get height every step, only when you change the window size (if you are doing that through a menu system for example) and store it to save CPU. That way you can also save on having to use round every step - and also a division, both of which are kind of heavy on the cpu - although it's basically negligable in just the one object, is something to think about I guess.
 
Top