[PATCH 0/8] Fix SetForegroundWindow focus inversion.
Rémi Bernon
rbernon at codeweavers.com
Fri Aug 14 07:56:30 CDT 2020
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(-)
--
2.28.0
More information about the wine-devel
mailing list