I'm resending these, with the tests also run in cross-process mode (in addition to the same-process/cross-thread calls). The results are the same in both cases, and it exposes an inversion in Wine which can then cause various focus inconsistencies.
PATCH 1/8 is not strictly necessary to make the test run well on testbot, and can possibly be dropped, but it helped me when running the test in a VM, especially when multiple processes are involved (the new process windows couldn't get foreground and were just flashing in the taskbar instead).
The remaining todo_wine after the series are caused by the same kind of behavior as is fixed by PATCH 8/8, where WM_KILLFOCUS/WM_SETFOCUS messages aren't sent because the window already has focus. As foreground was temporarily stolen by another thread they should still apparently be sent. The logic was a little bit more complicated so I left it aside.
The remaining focus issues with Wine are mostly caused by:
* asynchronous SetForegroundWindow consequences, with user actions interleaved, causing events coming late to steal foreground that was already lost,
* threads not checking their messages for a while, causing a delay between host focus changes, and wineserver focus state updates.
My plan, to fix those, would be to:
* use timestamps to order SetForegroundWindow requests and their corresponding host events, and then ignore out-of-order events,
* track the host focus state globally, for instance from explorer, so that threads that do not check their messages for a while will not make wine focus state inconsistent.
This inversion makes the whole thing useless, as threads can steal foreground from each other, as they process the internal WM_WINE_SETACTIVEWINDOW messages in the wrong order, so it has to be fixed first.
Cheers,
Rémi Bernon (8): user32/tests: Attach a debugger to help SetForegroundWindow suceed. user32/tests: Add concurrency tests for SetForegroundWindow. user32: Do not deactivate if thread is foreground. user32: Call set_active_window from internal handler. server: Allow filtering internal sent messages. user32: Add discard_internal parameter to peek_message. user32: Discard internal messages in set_active_window. user32: Send WM_NCACTIVATE on SetForegroundWindow call.
dlls/user32/focus.c | 17 +- dlls/user32/message.c | 34 +++- dlls/user32/tests/win.c | 388 +++++++++++++++++++++++++++++++------ dlls/user32/user_private.h | 2 + server/queue.c | 9 +- 5 files changed, 374 insertions(+), 76 deletions(-)