Changing from Fullscreen to Windowed loses mouse grab

Started by devonator, October 17, 2010, 14:47:10

Previous topic - Next topic

devonator

I have a method that toggles fullscreen mode:
boolean oldIsFullScreen = Display.isFullscreen();
Display.setFullscreen(!oldIsFullScreen);
if (oldIsFullScreen)
  Display.setLocation(-1, -1);

The mouse is grabbed right after Display.create().
When I switch from fullscreen back to windowed mode, the windows loses the mouse grab, and a naive
Mouse.setGrabbed(true);
does not re-grab the mouse.
Am I missing something or is this a bug?

EDIT: FYI, this is LWJGL-2.5 on Linux.

jediTofu

Does it work if you just start in Windowed (and not switch)?  Does it never work in Windowed mode, or is it just when switching?

It works for me on Windows.  What does your code look like?  This might be a bug on Linux.  Here's my code:

Display.setDisplayMode(new DisplayMode(800,600));
Display.setFullscreen(false);
Display.setInitialBackground(0.0f,0.0f,0.5f);
Display.setTitle("Test");
Display.create();
Keyboard.create();
Mouse.create();
Mouse.setGrabbed(true);



Alternatively, you could try to set the cursor to a transparent one.  This didn't seem to work for me though; I could see 1 small black pixel, even though my capabilities says that transparency is supported, perhaps I'm making the cursor incorrectly?  It's better than the big default cursor though.  Then just use Mouse.isInsideWindow().

  public void hideCursor() {
    try {
      java.nio.IntBuffer image = java.nio.IntBuffer.wrap(new int[]{0});
      org.lwjgl.input.Cursor cursor = new org.lwjgl.input.Cursor(1,1,0,0,1,image,null);
      System.out.println(org.lwjgl.input.Cursor.getCapabilities());
      Mouse.setNativeCursor(cursor);
    }
    catch(LWJGLException ex) {
    }
  }

  public void showCursor() {
    try {
      Mouse.setNativeCursor(null);
    }
    catch(LWJGLException ex) {
    }
  }
cool story, bro

devonator

It works when I initially start in windowed, but when I change from fullscreen back to windowed it doesn't work.
The mouse pointer sometimes warps outside the window, and sometimes inside.
When the mouse is inside the window, I get mouse movements, and there is no cursor.
When the mouse is outside the window, I don't get mouse movements, and there is a cursor.

jediTofu

Quote from: devonator on October 17, 2010, 20:08:08
It works when I initially start in windowed, but when I change from fullscreen back to windowed it doesn't work.
The mouse pointer sometimes warps outside the window, and sometimes inside.
When the mouse is inside the window, I get mouse movements, and there is no cursor.
When the mouse is outside the window, I don't get mouse movements, and there is a cursor.

I tried switching, and it worked fine for me; I didn't even have to call Mouse.setGrabbed(true); again.

Perhaps when you switch from fullscreen back to windowed, you could try destroying the window first and then recreating it.  If that doesn't work, hopefully someone here can fix it in a new build for Linux machines, and you could just use Mouse.isInsideWindow() until it's fixed.  It could be something with your code, but sounds unlikely.  This is the code that I tried and worked for me:

    Display.setDisplayModeAndFullscreen(Display.getDesktopDisplayMode());
    Display.setFullscreen(true);
    Display.setInitialBackground(0.0f,0.0f,0.5f);
    Display.setTitle("Testing");
    Display.create();

    Mouse.create();
    Mouse.setGrabbed(true);
    try{Thread.sleep(5000);}catch(Exception ex){};
    Display.setFullscreen(false);
    Display.setDisplayMode(new DisplayMode(800,600));
    //Mouse.setGrabbed(true);


You could also try the latest nightly build from http://lwjgl.org/download.php and also make sure that you have the latest Java (jre and jdk).  I doubt this will change anything, but worth a shot.
cool story, bro

devonator

I have a workaround, but it seems like I shouldn't have to do all of this.
This code is:
boolean oldIsFullScreen = Display.isFullscreen();
Display.setFullscreen(!oldIsFullScreen);
if (oldIsFullScreen) // changing to windowed mode
{
  Display.setLocation(-1, -1); // center the window

  try
  {
    Thread.sleep(500);
  } catch (InterruptedException e) {}

  Mouse.setGrabbed(false);
  Mouse.destroy();

  try
  {
    Mouse.create();
  } catch (LWJGLException e) {}

  Mouse.setGrabbed(true);
}


I need the sleep() call otherwise the mouse destroy/create/grab code only works 50% of the time.
Very weird.

jediTofu

 :o strange. Does Thread.yield(), Display.processMessages(), or Mouse.poll() (or all 3) work in place of sleeping?  Not sure why you would need to sleep.  I'll keep this in mind if I make a game that switches from full-screen.
cool story, bro

devonator

Quote from: jediTofu on October 17, 2010, 22:59:20
Does Thread.yield(), Display.processMessages(), or Mouse.poll() (or all 3) work in place of sleeping?
Nope. Still 50% of the time it doesn't re-grab the mouse.