mirror of
https://github.com/moonlight-stream/moonlight-qt.git
synced 2025-07-01 15:26:09 +00:00
Fix keys being stuck after Moonlight loses focus or is quit via OS shortcut (Alt+Tab/Alt+F4)
This commit is contained in:
parent
1b4e75f49e
commit
6661ca17c2
@ -121,25 +121,11 @@ void SdlInputHandler::handleKeyEvent(SDL_KeyboardEvent* event)
|
|||||||
(event->keysym.mod & KMOD_CTRL) &&
|
(event->keysym.mod & KMOD_CTRL) &&
|
||||||
(event->keysym.mod & KMOD_ALT) &&
|
(event->keysym.mod & KMOD_ALT) &&
|
||||||
(event->keysym.mod & KMOD_SHIFT)) {
|
(event->keysym.mod & KMOD_SHIFT)) {
|
||||||
|
|
||||||
// Force raise all keys in the combo to avoid
|
|
||||||
// leaving them down after disconnecting
|
|
||||||
LiSendKeyboardEvent(0xA0, KEY_ACTION_UP, 0);
|
|
||||||
LiSendKeyboardEvent(0xA1, KEY_ACTION_UP, 0);
|
|
||||||
LiSendKeyboardEvent(0xA2, KEY_ACTION_UP, 0);
|
|
||||||
LiSendKeyboardEvent(0xA3, KEY_ACTION_UP, 0);
|
|
||||||
LiSendKeyboardEvent(0xA4, KEY_ACTION_UP, 0);
|
|
||||||
LiSendKeyboardEvent(0xA5, KEY_ACTION_UP, 0);
|
|
||||||
|
|
||||||
// Check for quit combo (Ctrl+Alt+Shift+Q)
|
// Check for quit combo (Ctrl+Alt+Shift+Q)
|
||||||
if (event->keysym.sym == SDLK_q) {
|
if (event->keysym.sym == SDLK_q) {
|
||||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
"Detected quit key combo");
|
"Detected quit key combo");
|
||||||
|
|
||||||
// Uncapture the mouse to avoid processing any
|
|
||||||
// further keyboard input
|
|
||||||
SDL_SetRelativeMouseMode(SDL_FALSE);
|
|
||||||
|
|
||||||
// Push a quit event to the main loop
|
// Push a quit event to the main loop
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
event.type = SDL_QUIT;
|
event.type = SDL_QUIT;
|
||||||
@ -151,7 +137,13 @@ void SdlInputHandler::handleKeyEvent(SDL_KeyboardEvent* event)
|
|||||||
else if (event->keysym.sym == SDLK_z) {
|
else if (event->keysym.sym == SDLK_z) {
|
||||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
"Detected mouse capture toggle combo");
|
"Detected mouse capture toggle combo");
|
||||||
|
|
||||||
|
// Stop handling future input
|
||||||
SDL_SetRelativeMouseMode((SDL_bool)!SDL_GetRelativeMouseMode());
|
SDL_SetRelativeMouseMode((SDL_bool)!SDL_GetRelativeMouseMode());
|
||||||
|
|
||||||
|
// Force raise all keys to ensure they aren't stuck,
|
||||||
|
// since we won't get their key up events.
|
||||||
|
raiseAllKeys();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Check for the full-screen combo (Ctrl+Alt+Shift+X)
|
// Check for the full-screen combo (Ctrl+Alt+Shift+X)
|
||||||
@ -159,6 +151,10 @@ void SdlInputHandler::handleKeyEvent(SDL_KeyboardEvent* event)
|
|||||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
"Detected full-screen toggle combo");
|
"Detected full-screen toggle combo");
|
||||||
Session::s_ActiveSession->toggleFullscreen();
|
Session::s_ActiveSession->toggleFullscreen();
|
||||||
|
|
||||||
|
// Force raise all keys just be safe across this full-screen/windowed
|
||||||
|
// transition just in case key events get lost.
|
||||||
|
raiseAllKeys();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -384,6 +380,14 @@ void SdlInputHandler::handleKeyEvent(SDL_KeyboardEvent* event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Track the key state so we always know which keys are down
|
||||||
|
if (event->state == SDL_PRESSED) {
|
||||||
|
m_KeysDown.insert(keyCode);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_KeysDown.remove(keyCode);
|
||||||
|
}
|
||||||
|
|
||||||
LiSendKeyboardEvent(keyCode,
|
LiSendKeyboardEvent(keyCode,
|
||||||
event->state == SDL_PRESSED ?
|
event->state == SDL_PRESSED ?
|
||||||
KEY_ACTION_DOWN : KEY_ACTION_UP,
|
KEY_ACTION_DOWN : KEY_ACTION_UP,
|
||||||
@ -914,6 +918,23 @@ int SdlInputHandler::getAttachedGamepadMask()
|
|||||||
return mask;
|
return mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SdlInputHandler::raiseAllKeys()
|
||||||
|
{
|
||||||
|
if (m_KeysDown.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
|
"Raising %d keys",
|
||||||
|
m_KeysDown.count());
|
||||||
|
|
||||||
|
for (auto keyDown : m_KeysDown) {
|
||||||
|
LiSendKeyboardEvent(keyDown, KEY_ACTION_UP, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_KeysDown.clear();
|
||||||
|
}
|
||||||
|
|
||||||
QString SdlInputHandler::getUnmappedGamepads()
|
QString SdlInputHandler::getUnmappedGamepads()
|
||||||
{
|
{
|
||||||
QString ret;
|
QString ret;
|
||||||
|
@ -47,6 +47,8 @@ public:
|
|||||||
|
|
||||||
int getAttachedGamepadMask();
|
int getAttachedGamepadMask();
|
||||||
|
|
||||||
|
void raiseAllKeys();
|
||||||
|
|
||||||
static
|
static
|
||||||
QString getUnmappedGamepads();
|
QString getUnmappedGamepads();
|
||||||
|
|
||||||
@ -70,6 +72,7 @@ private:
|
|||||||
bool m_NeedsInputDelay;
|
bool m_NeedsInputDelay;
|
||||||
int m_GamepadMask;
|
int m_GamepadMask;
|
||||||
GamepadState m_GamepadState[MAX_GAMEPADS];
|
GamepadState m_GamepadState[MAX_GAMEPADS];
|
||||||
|
QSet<short> m_KeysDown;
|
||||||
|
|
||||||
SDL_TouchFingerEvent m_TouchDownEvent[MAX_FINGERS];
|
SDL_TouchFingerEvent m_TouchDownEvent[MAX_FINGERS];
|
||||||
float m_CumulativeDelta[MAX_FINGERS];
|
float m_CumulativeDelta[MAX_FINGERS];
|
||||||
|
@ -992,13 +992,19 @@ void Session::exec(int displayOriginX, int displayOriginY)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// 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.
|
if (event.window.event == SDL_WINDOWEVENT_FOCUS_LOST) {
|
||||||
// Doing this while the window is full-screen breaks the transition out of FS
|
// Release mouse cursor when another window is activated (e.g. by using ALT+TAB).
|
||||||
// (desktop and exclusive), so we must check for that before releasing mouse capture.
|
// This lets user to interact with our window's title bar and with the buttons in it.
|
||||||
if (event.window.event == SDL_WINDOWEVENT_FOCUS_LOST &&
|
// Doing this while the window is full-screen breaks the transition out of FS
|
||||||
!(SDL_GetWindowFlags(m_Window) & SDL_WINDOW_FULLSCREEN)) {
|
// (desktop and exclusive), so we must check for that before releasing mouse capture.
|
||||||
SDL_SetRelativeMouseMode(SDL_FALSE);
|
if (!(SDL_GetWindowFlags(m_Window) & SDL_WINDOW_FULLSCREEN)) {
|
||||||
|
SDL_SetRelativeMouseMode(SDL_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.
|
||||||
|
inputHandler.raiseAllKeys();
|
||||||
}
|
}
|
||||||
|
|
||||||
// We want to recreate the decoder for resizes (full-screen toggles) and the initial shown event.
|
// We want to recreate the decoder for resizes (full-screen toggles) and the initial shown event.
|
||||||
@ -1139,6 +1145,9 @@ DispatchDeferredCleanup:
|
|||||||
SDL_EnableScreenSaver();
|
SDL_EnableScreenSaver();
|
||||||
SDL_SetHint(SDL_HINT_TIMER_RESOLUTION, "0");
|
SDL_SetHint(SDL_HINT_TIMER_RESOLUTION, "0");
|
||||||
|
|
||||||
|
// Raise any keys that are still down
|
||||||
|
inputHandler.raiseAllKeys();
|
||||||
|
|
||||||
// Destroy the decoder, since this must be done on the main thread
|
// Destroy the decoder, since this must be done on the main thread
|
||||||
SDL_AtomicLock(&m_DecoderLock);
|
SDL_AtomicLock(&m_DecoderLock);
|
||||||
delete m_VideoDecoder;
|
delete m_VideoDecoder;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user