wxTipWindow steals foreground from other processes (Issue #26740)

51 views
Skip to first unread message

Bill Su

unread,
Jul 26, 2026, 1:47:57 AMJul 26
to wx-...@googlegroups.com, Subscribed
wsu-cb created an issue (wxWidgets/wxWidgets#26740)

Description

Bug description:

If a process which is not the current foreground process displays a wxTipWindow, it steals the foreground status from the current foreground process.

Expected vs observed behaviour:

I expect displaying a wxTipWindow not to affect which process is the foreground process. However, if a process which is not the current foreground process displays a wxTipWindow, it becomes the foreground process. However, changing the foreground process only happens if the SPI_GETFOREGROUNDLOCKTIMEOUT has expired (see https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setforegroundwindow#remarks). I have tried two computers, on one the timeout is 0, so the process changes immediately, and on the other the timeout is 200 seconds, so it takes a few minutes. I have not tried to change the timeout on either computer.

Patch or snippet allowing to reproduce the problem:

tipwin-steal-activation.patch

To Reproduce:

  1. Apply the attached patch to the minimal sample
  2. Compile and run the minimal sample
  3. Arrange the minimal sample and another program, e.g., Task Manager so that both can be seen clearly
  4. Click on the minimal sample, and see that the status bar reports appactive is 1 (meaning that the minimal sample is the foreground process)
  5. Click on the Task Manager, and see that the minimal sample's status bar reports appactive is 0 (meaning that the minimal sample is NOT the foreground process)
  6. When the cntr in the minimal sample status bar reaches 5, it will display a wxTipWindow. The status bar displays the SPI_GETFOREGROUNDLOCKTIMEOUT. If the timeout has expired, notice that the Task Manager's display changes to the non-foreground state, and the minimal status bar appactive reports 1. (Strangely, the minimal sample display color does not change to the foreground state.)

Additional notes:

  • When the cntr, reaches 10, the minimal sample will dismiss the wxTipWindow
  • When the wxTipWindow is dismissed, the cntr resets to 0
  • If the Task Manager has the foreground state, and the minimal sample is clicked so it becomes the foreground process while wxTipWindow is displayed, a wxASSERT reports a double-destroy of the wxTipWindow. I have found a work-around for this problem, but I'm not sure if it's worth applying since the wxASSERT failure might be a side-effect of the focus changes.

Platform and version information

  • wxWidgets version you use: master fbbeb21
  • wxWidgets port you use: wxMSW
  • OS and its version: Windows 11 25H2


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!
You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/26740@github.com>

Bill Su

unread,
Jul 26, 2026, 2:02:46 AMJul 26
to wx-...@googlegroups.com, Subscribed
wsu-cb left a comment (wxWidgets/wxWidgets#26740)

The foreground change happens because wxPopupWindow::Show() calls SetForegroundWindow(). The call is commented as being required to support mouse capture, but I don't understand why a non-foreground process would need to capture the mouse. On the other hand, I think I only noticed this behavior because my main computer is the one that has the SPI_GETFOREGROUNDLOCKTIMEOUT 0, so my wxWidgets program would steal the foreground even when I was actively doing something else. I don't know what is responsible for setting SPI_GETFOREGROUNDLOCKTIMEOUT, so I am reluctant to try to override the value. I would much rather have my wxWidgets process not try to become the foreground process.


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/26740/5082290598@github.com>

wsu

unread,
Aug 22, 2026, 4:43:52 PM (5 days ago) Aug 22
to wx-dev
Does anyone have any insight here?
 

Vadim Zeitlin

unread,
Aug 22, 2026, 7:56:54 PM (5 days ago) Aug 22
to wx-...@googlegroups.com
On Sat, 22 Aug 2026 13:43:51 -0700 (PDT) 'wsu' via wx-dev wrote:

w> Does anyone have any insight here?

Sorry, no, otherwise I would have replied. I didn't have time to test this
myself yet, but what I don't understand is how does this manage to bypass
Windows blocking activation stealing, i.e. usually when a background
application tries to bring itself forward to the foreground, Windows
doesn't allow it to do it and just flashes its window in the taskbar. Is
your system specifically configured to allow this (I didn't even know that
this was possible)?

Regards,
VZ

wsu

unread,
Aug 22, 2026, 9:08:46 PM (5 days ago) Aug 22
to wx-dev
I too used to think Windows blocked activation stealing, but https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setforegroundwindow says a traditional desktop process can steal activation if SPI_GETFOREGROUNDLOCKTIMEOUT (https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-systemparametersinfoa#SPI_GETFOREGROUNDLOCKTIMEOUT) has expired.  As I noted in the github issue, I have checked two computers, one of which has a timeout of 200seconds, but the other has a timeout of 0, which appears to allow immediate activation stealing.  I have not intentionally set the timeout on either computer, but who knows what other installed software may do, since the timeout is system-wide.

Bill Su

unread,
Aug 25, 2026, 9:52:10 PM (2 days ago) Aug 25
to wx-...@googlegroups.com, Subscribed
wsu-cb left a comment (wxWidgets/wxWidgets#26740)

Can anyone (@New Pagodi) explain why wxPopupWindow::Show() calls SetForegroundWindow() (commit 07f64c3)?


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/26740/5419493284@github.com>

VZ

unread,
Aug 26, 2026, 11:36:50 AM (yesterday) Aug 26
to wx-...@googlegroups.com, Subscribed
vadz left a comment (wxWidgets/wxWidgets#26740)

The way I understand this is that SetForegroundWindow() only does something when the process is in the foreground and that Windows blocks it from doing anything otherwise and the documentation seems to confirm this. But it's obviously not the way it works for you, so maybe we should test if the process is actually foreground (i.e. any of its TLWs is) before doing it?

OTOH I don't know why does a popup window not containing controls need to capture the mouse, so maybe we indeed shouldn't do it at all... But I'd rather keep it as is as I'm not aware of any (other) problems with doing it.


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/26740/5427562989@github.com>

Bill Su

unread,
Aug 26, 2026, 10:31:39 PM (yesterday) Aug 26
to wx-...@googlegroups.com, Subscribed
wsu-cb left a comment (wxWidgets/wxWidgets#26740)

The way I understand this is that SetForegroundWindow() only does something when the process is in the foreground and that Windows blocks it from doing anything otherwise and the documentation seems to confirm this.

My interpretation of https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setforegroundwindow#remarks is that a traditional desktop application CAN move from background to foreground if SPI_GETFOREGROUNDLOCKTIMEOUT has expired. What documentation confirms that SetForegroundWindow() only acts if the process is in the foreground?

But it's obviously not the way it works for you, so maybe we should test if the process is actually foreground (i.e. any of its TLWs is) before doing it?

I tried this, and it does prevent the activation change. Would you accept a PR making this change?


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/26740/5433610500@github.com>

VZ

unread,
8:44 AM (15 hours ago) 8:44 AM
to wx-...@googlegroups.com, Subscribed
vadz left a comment (wxWidgets/wxWidgets#26740)

Let's add the foreground check, I don't see any harm in doing this.


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/26740/5439306236@github.com>

Reply all
Reply to author
Forward
0 new messages