More forceful SDL_RaiseWindow() under MS Windows?

I’m in the middle of porting a very large legacy code base from MS Windows to Linux.
After looking at the alternatives, I chose SDL as my cross-platform window manager.

As I go, I’ve noticed SDL handles a lot of MS Windows quirks the way we do. The most recent outpoint I found involves raising the current window, i.e. SDL_RaiseWindow(). MS Windows goes through a lot of trouble to make it nearly impossible to programmatically move a window to the foreground, for “security” reasons. I don’t know if there’s any interest in replacing SDL_windowswindow.c’s WIN_RaiseWindow() with this, or maybe have another function like SDL_ForceRaiseWindow(), but I at least wanted to start the discussion.

// 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.
HWND m_hWnd = m_pScreen->getWindowHandle();
HWND hCurWnd = ::GetForegroundWindow();
DWORD dwMyID = ::GetCurrentThreadId();
DWORD dwCurID = ::GetWindowThreadProcessId(hCurWnd, NULL);
::ShowWindow(m_hWnd, SW_RESTORE);
::AttachThreadInput(dwCurID, dwMyID, TRUE);
::SetWindowPos(m_hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
::SetWindowPos(m_hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
::SetForegroundWindow(m_hWnd);
::AttachThreadInput(dwCurID, dwMyID, FALSE);
::SetFocus(m_hWnd);
::SetActiveWindow(m_hWnd);

Just occurred to me…instead of a separate function, how about a new value for SDL_SetHint(), such as SDL_HINT_FORCE_RAISEWINDOW or something? It’ll be a no-op on most platforms.

That seems like a good idea. We should default the hint off though, to respect Windows’ default behavior.

1 Like

I wonder if Microsoft is gonna fix that oversight if they really want to prevent windows to move to the foreground?
Seems pointless to disallow anyone from just calling SetForegroundWindow() (unless it belongs to the same process as the current foreground window) if a few more calls make it work anyway…

UPDATE: OTOH, apparently this hack has been known for >10 years without MS doing anything about it: c++ - Win32 SetForegroundWindow unreliable - Stack Overflow

Apart from that, I agree with @slouken

1 Like

Yeah, I was going to have it default to off.
Shall I make a pull request for this?

Yes please, that would be great.

Pull request created here.

1 Like