Search code examples
windowswinapiwindows-10windows-11setforegroundwindow

SetForegroundWindow: relationship between the ForegroundLockTimeout registry value and the SPI_GETFOREGROUNDLOCKTIMEOUT WinAPI parameter


Context:

  • This question is about how to control, through configuration, whether programmatic cross-process window activation (making a window the foreground window with the input focus) is allowed, via the SetForegroundWindow WinAPI function.

It seems that the SPI_GETFOREGROUNDLOCKTIMEOUT / SPI_SETFOREGROUNDLOCKTIMEOUT values used with the SystemParametersInfo WinAPI function correspond to the ForegroundLockTimeout persistent, per-user registry value (in HKEY_CURRENT_USER\Control Panel\Desktop).
The foreground-lock timeout is the period of time following interactive user input during which cross-process window activation is not permitted.

My expectation is as follows:

  • The effective value in a session is the one reported by SPI_GETFOREGROUNDLOCKTIMEOUT, which may differ from the underlying ForegroundLockTimeout registry value if a non-persistent update was made via SPI_SETFOREGROUNDLOCKTIMEOUT (fWinIni parameter set to 0)

  • On next logon, the two values should be back in sync.

This expectation is not met in the following cases:

  • On Windows 11, the SPI_GETFOREGROUNDLOCKTIMEOUT always reports 2147483647 (the max. value of a signed 32-bit integer) on logon - even though the ForegroundLockTimeout registry default value is 200000

    • Update: The behavior was observed on an ARM W11 ISO image run via the VMWare Fusion Technology Preview for M1 Macs, current as of 16 Sep 2022.

    • While non-persistent SPI_SETFOREGROUNDLOCKTIMEOUT updates are possible, an attempt to persistently change the effective SPI_GETFOREGROUNDLOCKTIMEOUT value for future session is quietly ignored.

    • In effect, a new user session defaults to not allowing unconditional window activation.

  • On Windows 10, I observe similar behavior with one particular user account:

    • The behavior is as on Windows 11, except that 0 is the default SPI_GETFOREGROUNDLOCKTIMEOUT value, which cannot be changed persistently. In effect, a new session for this user default to allowing unconditional window activation.

    • Another user account on the same machine does not exhibit this behavior - there, the above expectations are met.

    • The machine is not in developer mode; the account with the divergent behavior is an administrator, while the other is not - but I wouldn't expect that to matter.

My questions:

  • Is the observed Windows 11 behavior to be expected? If so, is it documented somewhere?

  • On Windows 10, what is the explanation for the behavior of the wayward user account? Is there another persistent setting somewhere that overrides the expected behavior?


Solution

    • In Windows 10+, the registry-based setting (value ForegroundLockTimeout in HKEY_CURRENT_USER\Control Panel\Desktop) is no longer respected, and the invariable default value in a new session is [int]::MaxValue,[1] which in effect disables programmatic activation of windows by processes other than those that happen to run in the current foreground window.

    • In my case, it happened to be a third-party application configured to run on every logon (via registry key HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Run) that set the non-persistent SPI_GETFOREGROUNDLOCKTIMEOUT value to 0 on a per-session basis: AutoHotkey


    [1] This value in milliseconds amounts to a duration of 24+ days(!) of the system having to be idle (in terms of user input) before a non-foreground process is allowed to activate another window, which in effect amounts to disabling such activations.