From 57bc90403ed2bb8a26fe28e4ad3d3ae4f9bc470f Mon Sep 17 00:00:00 2001
From: ulatekh <[EMAIL REDACTED]>
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 514580fa43b..348c6d1484c 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 e392e58694c..3776fb8c1a7 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