From 57bc90403ed2bb8a26fe28e4ad3d3ae4f9bc470f Mon Sep 17 00:00:00 2001 From: ulatekh Date: Fri, 7 Jan 2022 08:54:08 -0700 Subject: [PATCH] Add hint to optionally forcibly raise the window under MS Windows. --- include/SDL_hints.h | 13 ++++++++++++ src/video/windows/SDL_windowswindow.c | 30 +++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/include/SDL_hints.h b/include/SDL_hints.h index 514580fa4..348c6d148 100644 --- a/include/SDL_hints.h +++ b/include/SDL_hints.h @@ -412,6 +412,19 @@ extern "C" { */ #define SDL_HINT_EVENT_LOGGING "SDL_EVENT_LOGGING" +/** + * \brief A variable controlling whether raising the window should be done more forcefully + * + * This variable can be set to the following values: + * "0" - No forcing (the default) + * "1" - Extra level of forcing + * + * At present, this is only an issue under MS Windows, which makes it nearly impossible to + * programmatically move a window to the foreground, for "security" reasons. See + * http://stackoverflow.com/a/34414846 for a discussion. + */ +#define SDL_HINT_FORCE_RAISEWINDOW "SDL_HINT_FORCE_RAISEWINDOW" + /** * \brief A variable controlling how 3D acceleration is used to accelerate the SDL screen surface. * diff --git a/src/video/windows/SDL_windowswindow.c b/src/video/windows/SDL_windowswindow.c index e392e5869..3776fb8c1 100644 --- a/src/video/windows/SDL_windowswindow.c +++ b/src/video/windows/SDL_windowswindow.c @@ -573,8 +573,38 @@ WIN_HideWindow(_THIS, SDL_Window * window) void WIN_RaiseWindow(_THIS, SDL_Window * window) { + /* If desired, raise the window more forcefully. + * Technique taken from http://stackoverflow.com/questions/916259/ . + * Specifically, http://stackoverflow.com/a/34414846 . + * + * The issue is that Microsoft has gone through a lot of trouble to make it + * nearly impossible to programmatically move a window to the foreground, + * for "security" reasons. Apparently, the following song-and-dance gets + * around their objections. */ + SDL_bool bForce = SDL_GetHintBoolean(SDL_HINT_FORCE_RAISEWINDOW, SDL_FALSE); + + HWND hCurWnd = NULL; + DWORD dwMyID = 0u; + DWORD dwCurID = 0u; + HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; + if(bForce) + { + hCurWnd = GetForegroundWindow(); + dwMyID = GetCurrentThreadId(); + dwCurID = GetWindowThreadProcessId(hCurWnd, NULL); + ShowWindow(hwnd, SW_RESTORE); + AttachThreadInput(dwCurID, dwMyID, TRUE); + SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); + SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); + } SetForegroundWindow(hwnd); + if (bForce) + { + AttachThreadInput(dwCurID, dwMyID, FALSE); + SetFocus(hwnd); + SetActiveWindow(hwnd); + } } void