Jump to content

[SOLVED] Automatic Mouse Grab without requiring clicking on window


photo

Recommended Posts

Does anyone have any idea how I can properly have the mouse grabbed within the app without needing to click inside the window after changing the MouseHandle?

I've followed this guide and I've been able to get the mouse to grab and everything works properly. The caveat is that the mouse is only grabbed after clicking inside of the window after changing the MouseHandle.

I've tried to do it by directly setting App.MouseGrab to true and it has most of the behavior that I'm looking for. The mouse is grabbed immediately and works, but once I move the mouse to the edge of the screen, I'm no longer able to rotate the camera.

Link to comment

Hi Vadya_Rus,

The point is that the behavior described in the article you referred to (this guide) is considered normal.

 

 

Quote

 

The mouse behavior is defined by assigning any of the following modes:

  • Grab - the mouse is grabbed when clicked (the cursor disappears and camera movement is controlled by the mouse). This mode is set by default.
  • Soft - the mouse cursor disappears after being idle for a short time period.
  • User - the mouse is not handled by the system (allows input handling by some custom module).

 

So, you just don't want to click inside the window... Please correct me if I'm wrong. Well in this case the simplest way would be to emulate a click via code:

// checking for STATE_USE (ENTER key by default) and toggling mouse handling mode
if (controls->clearState(Controls::STATE_USE) == 1) {
	switch (ControlsApp::getMouseHandle())
	{
		case Input::MOUSE_HANDLE_GRAB:
			// if the mouse is currently grabbed, we disable grabbing and restore GUI interaction
			if (App::isMouseGrab())
			{
				App::setMouseGrab(false);
				Gui::get()->setMouseEnabled(true);
			}
			Input::setMouseHandle(Input::MOUSE_HANDLE_SOFT);
			break;
		case Input::MOUSE_HANDLE_SOFT:
			Input::setMouseHandle(Input::MOUSE_HANDLE_USER);
			break;
		case Input::MOUSE_HANDLE_USER:
			Input::setMouseHandle(Input::MOUSE_HANDLE_GRAB);
			App::setMouseButton(App::BUTTON_LEFT);// <--- Add this line
			break;
	}
}

Thanks! Hope this helps!

  • Like 1
Link to comment
  • 2 weeks later...

Okay. Got it. Yes. You are correct in your assumption.

At first this was not working since I was changing the mouse handling through an event. The event would call my function for changing the mouse state with the suggested code: App.SetMouseButton(App.BUTTON_LEFT); The problem was that I'd see the camera move for a single frame and then still be locked.

However I DID manage to get it working as long as I'm updating the mouse state on every single frame.

 

So my problem is partially solved. Do you have any idea on how make the mouse be grabbed by the app without needing to click inside the window but also not having to run this code on every single frame?

Link to comment

Hello,

You can try using the following function:

bool grabMouse()
{
	if (Gui::get()->isActive())
		return false;

	Gui::get()->setMouseCursor(Gui::CURSOR_NONE);
	Gui::get()->setMouseEnabled(false);

	App::setMouseCursorHide(true);
	// if mouse is outside window, then we get camera rotation
	App::setMouseGrab(true);

	ControlsApp::setMouseEnabled(true);

	return true;
}

It uses explicit mouse grab control for the application and GUI.

  • Thanks 1
Link to comment

Excellent! Thank you! That worked! For others coming for the solution, this is what I've come up with.

        private void SetMouseGrab(bool value) {
            if(value) {
                Gui.Get().MouseCursor = Gui.CURSOR_NONE;
                Gui.Get().MouseEnabled = false;

                App.MouseCursorHide = true;                
	            // if mouse is outside window, then we get camera rotation
                App.MouseGrab = true;

                ControlsApp.MouseEnabled = true;
            }
            else {
                // if the mouse is currently grabbed, we disable grabbing and restore GUI interaction
                if (App.MouseGrab) {
                    App.MouseGrab = false;
                    Gui.Get().MouseEnabled = true;
                }
                Input.MouseHandle = Input.MOUSE_HANDLE.USER;
            }
        }

 

Edited by Vadya_Rus
  • Like 3
  • Thanks 1
Link to comment
  • silent changed the title to [SOLVED] Automatic Mouse Grab without requiring clicking on window
×
×
  • Create New...