vdi-cloud/terminal/moonlight/patches/0006-vdi-release-stuck-mouse-buttons.patch

83 lines
2.8 KiB
Diff

--- a/app/streaming/input/input.h
+++ b/app/streaming/input/input.h
@@ -139,10 +139,14 @@
void handleTouchFingerEvent(SDL_TouchFingerEvent* event);
int getAttachedGamepadMask();
void raiseAllKeys();
+
+ // Release any remote mouse buttons when focus/session teardown interrupts
+ // the normal SDL button-up sequence.
+ void raiseAllMouseButtons();
void notifyMouseLeave();
void notifyFocusLost();
--- a/app/streaming/input/input.cpp
+++ b/app/streaming/input/input.cpp
@@ -278,13 +278,15 @@
// (desktop and exclusive), so we must check for that before releasing mouse capture.
if (!(SDL_GetWindowFlags(m_Window) & SDL_WINDOW_FULLSCREEN) && !m_AbsoluteMouseMode) {
setCaptureActive(false);
}
- // Raise all keys that are currently pressed. If we don't do this, certain keys
- // used in shortcuts that cause focus loss (such as Alt+Tab) may get stuck down.
+ // Raise all keys and mouse buttons that are currently pressed. If we don't
+ // do this, shortcuts or focus loss can leave the remote desktop in a stuck
+ // drag/click state.
raiseAllKeys();
+ raiseAllMouseButtons();
}
void SdlInputHandler::notifyFocusGained()
{
}
--- a/app/streaming/input/mouse.cpp
+++ b/app/streaming/input/mouse.cpp
@@ -25,10 +25,23 @@
}
}
}
}
+void SdlInputHandler::raiseAllMouseButtons()
+{
+ // A disconnect, focus loss, or a queued SDL event can skip BUTTONUP.
+ // Sending idempotent releases for every supported mouse button clears the
+ // host-side state and prevents the next session from inheriting a stuck
+ // drag/click.
+ static const int buttons[] = {BUTTON_LEFT, BUTTON_MIDDLE, BUTTON_RIGHT,
+ BUTTON_X1, BUTTON_X2};
+ for (int button : buttons) {
+ LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, button);
+ }
+}
+
void SdlInputHandler::handleMouseButtonEvent(SDL_MouseButtonEvent* event)
{
int button;
if (event->which == SDL_TOUCH_MOUSEID) {
--- a/app/streaming/session.cpp
+++ b/app/streaming/session.cpp
@@ -2338,12 +2338,15 @@
SDL_SetHint(SDL_HINT_TIMER_RESOLUTION, "0");
if (QGuiApplication::platformName() == "eglfs") {
QGuiApplication::restoreOverrideCursor();
}
- // Raise any keys that are still down
+ // Raise any keys or mouse buttons that are still down. A stream can end
+ // without SDL delivering the matching BUTTONUP, so clear the remote state
+ // before destroying the handler and opening the next session.
m_InputHandler->raiseAllKeys();
+ m_InputHandler->raiseAllMouseButtons();
// Destroy the input handler now. This must be destroyed
// before allowwing the UI to continue execution or it could
// interfere with SDLGamepadKeyNavigation.
delete m_InputHandler;