diff --git a/app/streaming/input.cpp b/app/streaming/input.cpp index d93541db..f29e34e7 100644 --- a/app/streaming/input.cpp +++ b/app/streaming/input.cpp @@ -53,6 +53,7 @@ SdlInputHandler::SdlInputHandler(StreamingPreferences& prefs, NvComputer*, int s : m_MultiController(prefs.multiController), m_GamepadMouse(prefs.gamepadMouse), m_MouseMoveTimer(0), + m_FakeCaptureActive(false), m_LeftButtonReleaseTimer(0), m_RightButtonReleaseTimer(0), m_DragTimer(0), @@ -213,7 +214,7 @@ void SdlInputHandler::handleKeyEvent(SDL_KeyboardEvent* event) "Detected mouse capture toggle combo (SDLK)"); // Stop handling future input - SDL_SetRelativeMouseMode((SDL_bool)!SDL_GetRelativeMouseMode()); + setCaptureActive(!isCaptureActive()); // Force raise all keys to ensure they aren't stuck, // since we won't get their key up events. @@ -261,7 +262,7 @@ void SdlInputHandler::handleKeyEvent(SDL_KeyboardEvent* event) "Detected mouse capture toggle combo (scancode)"); // Stop handling future input - SDL_SetRelativeMouseMode((SDL_bool)!SDL_GetRelativeMouseMode()); + setCaptureActive(!isCaptureActive()); // Force raise all keys to ensure they aren't stuck, // since we won't get their key up events. @@ -294,7 +295,7 @@ void SdlInputHandler::handleKeyEvent(SDL_KeyboardEvent* event) } } - if (!SDL_GetRelativeMouseMode()) { + if (!isCaptureActive()) { // Not capturing return; } @@ -540,11 +541,11 @@ void SdlInputHandler::handleMouseButtonEvent(SDL_MouseButtonEvent* event) // the pressed event was consumed by this code). if (event->button == SDL_BUTTON_LEFT && event->state == SDL_RELEASED && - !SDL_GetRelativeMouseMode()) { - SDL_SetRelativeMouseMode(SDL_TRUE); + !isCaptureActive()) { + setCaptureActive(true); return; } - else if (!SDL_GetRelativeMouseMode()) { + else if (!isCaptureActive()) { // Not capturing return; } @@ -585,7 +586,7 @@ void SdlInputHandler::handleMouseButtonEvent(SDL_MouseButtonEvent* event) void SdlInputHandler::handleMouseMotionEvent(SDL_MouseMotionEvent* event) { - if (!SDL_GetRelativeMouseMode()) { + if (!isCaptureActive()) { // Not capturing return; } @@ -602,7 +603,7 @@ void SdlInputHandler::handleMouseMotionEvent(SDL_MouseMotionEvent* event) void SdlInputHandler::handleMouseWheelEvent(SDL_MouseWheelEvent* event) { - if (!SDL_GetRelativeMouseMode()) { + if (!isCaptureActive()) { // Not capturing return; } @@ -1299,6 +1300,35 @@ void SdlInputHandler::raiseAllKeys() m_KeysDown.clear(); } +bool SdlInputHandler::isCaptureActive() +{ + if (SDL_GetRelativeMouseMode()) { + return true; + } + + // Some platforms don't support SDL_SetRelativeMouseMode + return m_FakeCaptureActive; +} + +void SdlInputHandler::setCaptureActive(bool active) +{ + if (active) { + // Try to activate SDL's relative mouse mode + if (SDL_SetRelativeMouseMode(SDL_TRUE) < 0) { + // Relative mouse mode didn't work, so we'll use fake capture + SDL_ShowCursor(SDL_DISABLE); + m_FakeCaptureActive = true; + } + } + else if (m_FakeCaptureActive) { + SDL_ShowCursor(SDL_ENABLE); + m_FakeCaptureActive = false; + } + else { + SDL_SetRelativeMouseMode(SDL_FALSE); + } +} + QString SdlInputHandler::getUnmappedGamepads() { QString ret; diff --git a/app/streaming/input.h b/app/streaming/input.h index 79281738..06ed30ef 100644 --- a/app/streaming/input.h +++ b/app/streaming/input.h @@ -64,6 +64,10 @@ public: void raiseAllKeys(); + bool isCaptureActive(); + + void setCaptureActive(bool active); + static QString getUnmappedGamepads(); @@ -96,6 +100,7 @@ private: int m_GamepadMask; GamepadState m_GamepadState[MAX_GAMEPADS]; QSet m_KeysDown; + bool m_FakeCaptureActive; SDL_TouchFingerEvent m_TouchDownEvent[MAX_FINGERS]; float m_CumulativeDelta[MAX_FINGERS]; diff --git a/app/streaming/session.cpp b/app/streaming/session.cpp index 48da8f1e..f30945fb 100644 --- a/app/streaming/session.cpp +++ b/app/streaming/session.cpp @@ -1101,20 +1101,19 @@ void Session::exec(int displayOriginX, int displayOriginY) SDL_GetWindowPosition(m_Window, &x, &y); SDL_GetWindowSize(m_Window, &width, &height); if (mouseX > x && mouseX < x+width && mouseY > y && mouseY < y+height) { - SDL_SetRelativeMouseMode(SDL_TRUE); + m_InputHandler->setCaptureActive(true); } } } #endif - if (event.window.event == SDL_WINDOWEVENT_FOCUS_LOST) { // Release mouse cursor when another window is activated (e.g. by using ALT+TAB). // This lets user to interact with our window's title bar and with the buttons in it. // Doing this while the window is full-screen breaks the transition out of FS // (desktop and exclusive), so we must check for that before releasing mouse capture. if (!(SDL_GetWindowFlags(m_Window) & SDL_WINDOW_FULLSCREEN)) { - SDL_SetRelativeMouseMode(SDL_FALSE); + m_InputHandler->setCaptureActive(false); } // Raise all keys that are currently pressed. If we don't do this, certain keys @@ -1247,7 +1246,7 @@ void Session::exec(int displayOriginX, int displayOriginY) DispatchDeferredCleanup: // Uncapture the mouse and hide the window immediately, // so we can return to the Qt GUI ASAP. - SDL_SetRelativeMouseMode(SDL_FALSE); + m_InputHandler->setCaptureActive(false); SDL_EnableScreenSaver(); SDL_SetHint(SDL_HINT_TIMER_RESOLUTION, "0");