83 lines
2.8 KiB
Diff
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;
|