diff --git a/app/streaming/input/input.cpp b/app/streaming/input/input.cpp index d41d87f9..0628afd1 100644 --- a/app/streaming/input/input.cpp +++ b/app/streaming/input/input.cpp @@ -1,5 +1,6 @@ #include #include +#include #include "streaming/session.h" #include "settings/mappingmanager.h" #include "path.h" @@ -452,6 +453,31 @@ bool SdlInputHandler::isSystemKeyCaptureActive() void SdlInputHandler::setCaptureActive(bool active) { if (active) { +#if defined(Q_OS_WIN32) + // If our window is occluded when mouse is captured, the mouse may + // get stuck on top of the occluding window and not be properly + // captured. We can avoid this by raising our window before we + // capture the mouse. This can also cause problems when keyboard + // capture is enabled (modifiers will be eaten by our background window). + // We can't use SDL_RaiseWindow() because it doesn't let us know if + // SetForegroundWindow() failed. In the failure case, we must not + // enable capture to avoid trapping the mouse and/or keyboard. + { + SDL_SysWMinfo info; + + SDL_VERSION(&info.version); + SDL_GetWindowWMInfo(m_Window, &info); + + SDL_assert(info.subsystem == SDL_SYSWM_WINDOWS); + + if (!SetForegroundWindow(info.info.win.window)) { + SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, + "Not enabling input capture - window is not foreground"); + return; + } + } +#endif + // If we're in full-screen exclusive mode, grab the cursor so it can't accidentally leave our window. if ((SDL_GetWindowFlags(m_Window) & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN) { #if SDL_VERSION_ATLEAST(2, 0, 15) @@ -461,14 +487,6 @@ void SdlInputHandler::setCaptureActive(bool active) #endif } - if (!m_AbsoluteMouseMode) { - // If our window is occluded when mouse is captured, the mouse may - // get stuck on top of the occluding window and not be properly - // captured. We can avoid this by raising our window before we - // capture the mouse. - SDL_RaiseWindow(m_Window); - } - // If we're in relative mode, try to activate SDL's relative mouse mode if (m_AbsoluteMouseMode || SDL_SetRelativeMouseMode(SDL_TRUE) < 0) { // Relative mouse mode didn't work or was disabled, so we'll just hide the cursor