Why is SPI_SETFOREGROUNDLOCKTIMEOUT set to zero on glfwInit (Win32)?

win32_init.c:
int _glfwPlatformInit(void)
{
    // To make SetForegroundWindow work as we want, we need to fiddle
    // with the FOREGROUNDLOCKTIMEOUT system setting (we do this as early
    // as possible in the hope of still being the foreground process)
    SystemParametersInfoW(SPI_GETFOREGROUNDLOCKTIMEOUT, 0,
                          &_glfw.win32.foregroundLockTimeout, 0);
    SystemParametersInfoW(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, UIntToPtr(0),
                          SPIF_SENDCHANGE);

It says to make setForegroundWindow work as you want, but what way is that?

Hi @bonimy,

welcome to the GLFW forum.

I think this was done in order to permit glfwFocusWindow to work. I did a git blame to check why it was committed, but this code goes back to GLFW 2.7 Lite.

Hi! That would be my code, dating back to the very early 2.x (possibly 1.x) versions.

The purpose is to enable us to call SetForegroundWindow(). Windows has a user input timeout thingy, meaning that if you are typing things on a keyboard while SetForegroundWindow() is called, the request to change window focus is ignored by the system. In general this is a good thing (e.g. imagine typing in a password in one window and then suddenly you’re switched to a new window and you accidentally continue typing in your password there instead).

This code is specifically there to circumvent that timeout mechanism by assuming that early on in the application lifecycle the application has focus etc which is a requirement for the SystemParametersInfo() call to have effect.

Check the documentation for SPI_GETFOREGROUNDLOCKTIMEOUT here: SystemParametersInfoW function (winuser.h) - Win32 apps | Microsoft Docs

It’s vague, but notice: “The calling thread must be able to change the foreground window, otherwise the call fails.”

IIRC the code was tested against Windows 98/ME/2000 (or thereabout). I’m not sure that it still works the same way in Windows 10.

OTOH - today (a few years wiser) I would strongly advice against using SetForegroundWindow() at all, so I’m not sure that this should be part of GLFW.

1 Like