Mouse Grab

Hey all,



Is there a way to disable mouse grab in JME?



Mark

If the native cursor is visible, the mouse is not grabbed. When the native cursor is hidden, it is grabbed. I tried inserting a call to org.lwjgl.input.Mouse.setFrabbed(false) when using a software cursor, but that lead to the the native cursor showing up again (on Windows). This showed that another problem is that the position of the RelativeMouse cursor is not always exactly the same of that of the native cursor (espc. after entering/leaving a window).



So you right now you could disable grabbing by using a native cursor with setCursorVisible(true) in MouseInput. If you want to use a RelativeAbsoluteMouse with a software cursor instead of a native cursor, then that’ll be hard with the current system.

This showed that another problem is that the position of the RelativeMouse cursor is not always exactly the same of that of the native cursor (espc. after entering/leaving a window).

I noticed that too, and have to say, that this is quite annoying, especially in menus.
Is there a work around or something to prevent that behavior?

Or should I make use of the native cursor until a fix is available?

Hopiu

In theory that problem shouldn’t happen when you use a software cursor, because then, the cursor should be grabbed. If you mean you have a problem with a software cursor being off target, when using it like you should (not “ungrabbing” the mouse like I did), then yes, that would be a bug, so please say if you do.



If you manage to fix relative mouse to work with an ungrabbed mouse, I suppose we could hide the native cursor by using a completly transparant bitmap for it (LWJGL provides a cross platform method for doing this, setNativeCursor or something like that), giving you in effect, an ungrabbed software cursor. If you come up with a fix that doesn’t affect RelativeAbsoluteMouse work in grabbed mode as it does now, I can commit it to CVS for you (feel free to call LWJGL methods directly, I’ll work them into the input system for you).

Ok, to be clear I was saying RelativeMouse in my posts when I meant Absolute (edited that to make it clear for others) |:(



I've tried to recreate your problem, but no matter how violently I abuse the mouse in various display modes and tests (mostly TestJMEDesktop, switching back and forth between the native and software cursor), nothing…



I remember having a problem like this one time due to wrongly translated coordinates (due to a display resolution change or something like that) once.



So what exactly are you using? The JMEDesktop system or something else? What version of jME, and what OS? Are you running windowed or fullscreen?

O.k., thank you very much for your effort!



I'm using WinXP SP2 (all available updates installed), latest jME version from CVS and it doesn't matter whether I'm running fullscreen or windowed mode.



I more and more think that it's a failure in my program code as its going all well on your and anyone others machine…



Anyway, here's the sourcecode of my JMEDesktop test:



/*
 * Copyright (c) 2003-2006 jMonkeyEngine
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 * * Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 *
 * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
 *   may be used to endorse or promote products derived from this software
 *   without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package mygame.test2;

import java.awt.Color;

import com.jme.app.GameState;
import com.jme.app.StandardGameState;
import com.jme.image.Texture;
import com.jme.input.AbsoluteMouse;
import com.jme.input.InputHandler;
import com.jme.input.Mouse;
import com.jme.input.MouseInput;
import com.jme.math.Vector3f;
import com.jme.renderer.Renderer;
import com.jme.scene.Node;
import com.jme.scene.Spatial;
import com.jme.scene.Text;
import com.jme.scene.state.AlphaState;
import com.jme.scene.state.LightState;
import com.jme.scene.state.TextureState;
import com.jme.system.DisplaySystem;
import com.jme.util.TextureManager;
import com.jmex.awt.swingui.JMEDesktop;

/**
 * @author Per Thulin
 */
public class MenuState extends StandardGameState {
   
   /** The cursor node which holds the mouse gotten from input. */
   private Node cursor;
   /** The node that holds the swing elements. */
   private Node swingNode;
   
   protected JMEDesktop desktop;
   
   /** Our display system. */
   private DisplaySystem display;

    private Text text;

    private InputHandler input;
    private AbsoluteMouse mouse;

    public MenuState(String name) {
        super(name);

        display = DisplaySystem.getDisplaySystem();
        swingNode = new Node( "swingNode" );
        initInput();
        initCursor();
        initDesktopSystem();

        rootNode.setLightCombineMode(LightState.OFF);
        rootNode.setRenderQueueMode(Renderer.QUEUE_ORTHO);
        rootNode.updateRenderState();
        rootNode.updateGeometricState(0, true);
    }
   
   private void initDesktopSystem() {
//       create a node for ortho gui stuff
       
      swingNode.setRenderQueueMode( Renderer.QUEUE_ORTHO );

        // create the desktop Quad
        desktop = new JMEDesktop( "desktop", display.getWidth(), display.getHeight(), input );
        // make it transparent blue
        desktop.getJDesktop().setBackground( new Color( 0, 0, 1, 0.2f ) );
        // and attach it to the gui node
        swingNode.attachChild( desktop );
        // center it on screen
        desktop.getLocalTranslation().set( display.getWidth() / 2, display.getHeight() / 2, 0 );
        setDesktopComponents();
        // don't cull the gui away
        swingNode.setCullMode( Spatial.CULL_NEVER );
        // gui needs no lighting
        swingNode.setLightCombineMode( LightState.OFF );
        // update the render states (especially the texture state of the deskop!)
        swingNode.updateRenderState();
        // update the world vectors (needed as we have altered local translation of the desktop and it's
        //  not called in the update loop)
        swingNode.updateGeometricState( 0, true );

        // finally show the system mouse cursor to allow the user to click our button
       // MouseInput.get().setCursorVisible( true );
      
        //rootNode.attachChild(swingNode);
   }

   private void setDesktopComponents() {
      // TODO Auto-generated method stub
      // to implement in all sub classes
   }

   /**
    * @see com.jme.app.StandardGameState#onActivate()
    */
   public void onActivate() {
      display.setTitle("Test Game State System - Menu State");
      super.onActivate();
   }
   
   /**
    * Inits the input handler we will use for navigation of the menu.
    */
   protected void initInput() {
      //input = new InputHandler();
      
      input = new MenuHandler( this );
      display = DisplaySystem.getDisplaySystem();
        mouse = new AbsoluteMouse("Mouse Input", display.getWidth(),
                display.getHeight());
        mouse.registerWithInputHandler( input );
   }
   
   /**
    * Creates a pretty cursor.
    */
   private void initCursor() {      
      Texture texture =
           TextureManager.loadTexture(
                  MenuState.class.getClassLoader().getResource(
                  "mygame/data/cursor/Arrow.png"),
                  Texture.MM_LINEAR_LINEAR,
                  Texture.FM_LINEAR);
      
      TextureState ts = display.getRenderer().createTextureState();
      ts.setEnabled(true);
      ts.setTexture(texture);
      
      AlphaState alpha = display.getRenderer().createAlphaState();
      alpha.setBlendEnabled(true);
      alpha.setSrcFunction(AlphaState.SB_SRC_ALPHA);
      alpha.setDstFunction(AlphaState.DB_ONE);
      alpha.setTestEnabled(true);
      alpha.setTestFunction(AlphaState.TF_GREATER);
      alpha.setEnabled(true);
      
      mouse.setRenderState(ts);
        mouse.setRenderState(alpha);
        mouse.setLocalScale(new Vector3f(1, 1, 1));
      mouse.updateRenderState();
       
      //cursor = new Node("Cursor");
      //cursor.attachChild( mouse );
      //cursor.updateRenderState();
      
      swingNode.attachChild(mouse);
   }
   
   /**
    * Updates input and button.
    *
    * @param tpf The time since last frame.
    * @see GameState#update(float)
    */
   protected void stateUpdate(float tpf) {
      input.update(tpf);
      // Check if the button has been pressed.
      rootNode.updateGeometricState(tpf, true);
      display.getRenderer().draw(swingNode);
   }
}

Call mouse.setUsingDelta( false ) to make it work with JMEDesktop (as done in TestJMEDesktop btw :))

Ah, well that also solves the entry/re-entry problem, so Hopiu, it's possible to make an "ungrabbed" software cursor.



Is there any reason why usingDelta = true; by default?

llama said:

Is there any reason why usingDelta = true; by default?

I introduced that setDelta short time ago and when you set it to false it alters the behaviour of the former AbsoluteMouse - that's why I made true the default: to keep the old behaviour

I think we can change it to false to prevent this kind of problem. It doesn't effect the actual working of AbsoluteMouse itself, your new method is more reliable, and people relying on some kind of delta behaviour should be using RelativeMouse anyway… If you agree I'll make the change and post a warning in Dev General.

First of all, thank you for helping me out here!  :slight_smile:

Secondly, I agree with llama, I would change usingDelta's default value to false, or at least add "mouse.setUsingDelta( false );" to every jME Test class that makes use of an absolute software mouse. (e.g. jmetest.game.state.MenuState)



Thanks for your help!



Hopiu