diff --git a/app/streaming/input/input.cpp b/app/streaming/input/input.cpp index a5c63c40..28afd798 100644 --- a/app/streaming/input/input.cpp +++ b/app/streaming/input/input.cpp @@ -30,7 +30,6 @@ SdlInputHandler::SdlInputHandler(StreamingPreferences& prefs, NvComputer*, int s m_StreamHeight(streamHeight), m_AbsoluteMouseMode(prefs.absoluteMouseMode), m_AbsoluteTouchMode(prefs.absoluteTouchMode), - m_PendingMouseLeaveButtonUp(0), m_LeftButtonReleaseTimer(0), m_RightButtonReleaseTimer(0), m_DragTimer(0), @@ -270,13 +269,14 @@ void SdlInputHandler::notifyMouseLeave() { #ifdef Q_OS_WIN32 // SDL on Windows doesn't send the mouse button up until the mouse re-enters the window - // after leaving it. This breaks some of the Aero snap gestures, so we'll fake it here. + // after leaving it. This breaks some of the Aero snap gestures, so we'll capture it to + // allow us to receive the mouse button up events later. if (m_AbsoluteMouseMode && isCaptureActive()) { // NB: Not using SDL_GetGlobalMouseState() because we want our state not the system's Uint32 mouseState = SDL_GetMouseState(nullptr, nullptr); for (Uint32 button = SDL_BUTTON_LEFT; button <= SDL_BUTTON_X2; button++) { if (mouseState & SDL_BUTTON(button)) { - m_PendingMouseLeaveButtonUp = button; + SDL_CaptureMouse(SDL_TRUE); break; } } diff --git a/app/streaming/input/input.h b/app/streaming/input/input.h index bc6df543..6ca660cb 100644 --- a/app/streaming/input/input.h +++ b/app/streaming/input/input.h @@ -7,6 +7,7 @@ #define SDL_CODE_HIDE_CURSOR 1 #define SDL_CODE_SHOW_CURSOR 2 +#define SDL_CODE_UNCAPTURE_MOUSE 3 struct GamepadState { SDL_GameController* controller; @@ -175,7 +176,6 @@ private: int m_StreamHeight; bool m_AbsoluteMouseMode; bool m_AbsoluteTouchMode; - Uint32 m_PendingMouseLeaveButtonUp; SDL_TouchFingerEvent m_TouchDownEvent[MAX_FINGERS]; SDL_TimerID m_LeftButtonReleaseTimer; diff --git a/app/streaming/input/mouse.cpp b/app/streaming/input/mouse.cpp index 8b67987c..a3b156db 100644 --- a/app/streaming/input/mouse.cpp +++ b/app/streaming/input/mouse.cpp @@ -133,7 +133,15 @@ void SdlInputHandler::flushMousePositionUpdate() // c) a mouse button is still down from before the cursor left the video region (to allow smooth dragging) Uint32 buttonState = SDL_GetMouseState(nullptr, nullptr); if (buttonState == 0) { - m_PendingMouseButtonsAllUpOnVideoRegionLeave = false; + if (m_PendingMouseButtonsAllUpOnVideoRegionLeave) { + // Tell the main thread to stop capturing the mouse now + SDL_Event event; + event.type = SDL_USEREVENT; + event.user.code = SDL_CODE_UNCAPTURE_MOUSE; + SDL_PushEvent(&event); + + m_PendingMouseButtonsAllUpOnVideoRegionLeave = false; + } } if (mouseInVideoRegion || m_MouseWasInVideoRegion || m_PendingMouseButtonsAllUpOnVideoRegionLeave) { LiSendMousePositionEvent(x, y, dst.w, dst.h); @@ -251,33 +259,5 @@ Uint32 SdlInputHandler::mouseMoveTimerCallback(Uint32 interval, void *param) // Send mouse position updates if applicable me->flushMousePositionUpdate(); -#ifdef Q_OS_WIN32 - // See comment in SdlInputHandler::notifyMouseLeave() - if (me->m_AbsoluteMouseMode && me->m_PendingMouseLeaveButtonUp != 0 && me->isCaptureActive()) { - int mouseX, mouseY; - int windowX, windowY; - Uint32 mouseState = SDL_GetGlobalMouseState(&mouseX, &mouseY); - SDL_GetWindowPosition(me->m_Window, &windowX, &windowY); - - // If the button is now up, send the synthetic mouse up event - if ((mouseState & SDL_BUTTON(me->m_PendingMouseLeaveButtonUp)) == 0) { - SDL_Event event; - - event.button.type = SDL_MOUSEBUTTONUP; - event.button.timestamp = SDL_GetTicks(); - event.button.windowID = SDL_GetWindowID(me->m_Window); - event.button.which = 0; - event.button.button = me->m_PendingMouseLeaveButtonUp; - event.button.state = SDL_RELEASED; - event.button.clicks = 1; - event.button.x = mouseX - windowX; - event.button.y = mouseY - windowY; - SDL_PushEvent(&event); - - me->m_PendingMouseLeaveButtonUp = 0; - } - } -#endif - return interval; } diff --git a/app/streaming/session.cpp b/app/streaming/session.cpp index ff1121dd..67ee0c0d 100644 --- a/app/streaming/session.cpp +++ b/app/streaming/session.cpp @@ -1321,6 +1321,9 @@ void Session::exec(int displayOriginX, int displayOriginY) case SDL_CODE_SHOW_CURSOR: SDL_ShowCursor(SDL_ENABLE); break; + case SDL_CODE_UNCAPTURE_MOUSE: + SDL_CaptureMouse(SDL_FALSE); + break; case SDL_CODE_FLUSH_WINDOW_EVENT_BARRIER: m_FlushingWindowEventsRef--; break;