user32: Fix FlashWindowEx message and return value New

Old version!

This is an old revision. You are most probably looking for the newest revision.
Revisions: 

Revision 1

user image James Coonradt Author
10 Sep. 17

FlashWindowEx is fairly complicated with fake window active states and various timers, but wine currently doesn't simulate any of this.
This patchset makes the message value and return values more sensible and also closer to MSDN documentation:

The message value and return value now reflects the window's active state and not the inverted state or inactive state

This fixes games like Overwatch getting confused about the active window state after calling FlashWindowEx
Regarding the test change: while it's true that a test that used to work is now broken by this change, simply waiting (dwTimeout)ms would have also broken the test due to the behind the scenes timer.

user image James Coonradt Author
10 Sep. 17

An additional note, nearly all 16 flags combinations will finish their behavior by sending a message with the correct active state, where wine currently sends the inverted state. This change makes it more correct.

user image James Coonradt Author
5 days ago

I've noticed that a different patch made its way into staging, where the message still has the incorrect inverted value. This is wrong and games like Overwatch still think the window is inactive when it's focused and vice versa.

user image Sebastian Lackner
5 days ago

Please take a look at the newly added tests, they show that the inverted value in the window message is correct. Do you know which flags are exactly used by Overwatch?

user image James Coonradt Author
5 days ago

Overwatch uses 0xC + 0x2, and I believe 0 for count. My documentation on this function shows that if the window is active, TRUE is returned and NC_ACTIVATE is sent with a 1. Furthermore most of the documented behavior shows after doing whatever pulsing of titlebar/taskbar the last message sent is one of the active state.

user image James Coonradt Author
5 days ago

Your tests only wait 50ms while the timeout is set to 200ms, they are only acting on the first 0 of a set of 0 and 1 message pulses, hence the false idea that the proper value to send is the inverted one.

Single files Merged diff Tar archive
You have unsaved changes. Press CTRL + ENTER in a text field to submit your comments.

0001-user32-Fix-FlashWindowEx-message-and-return-value.patch

From 8e2f1124b7ca71e88d06fe25efcc37c3f6cf81e3 Mon Sep 17 00:00:00 2001
From: James Coonradt <gamax92@aol.com>
Date: Sat, 9 Sep 2017 18:12:26 -0600
Subject: [PATCH 1/2] user32: Fix FlashWindowEx message and return value
---
dlls/user32/win.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/user32/win.c b/dlls/user32/win.c
index 3042a560ce9..edfcbcded70 100644
--- a/dlls/user32/win.c
+++ b/dlls/user32/win.c
@@ -3545,7 +3545,7 @@ BOOL WINAPI FlashWindowEx( PFLASHWINFO pfinfo )
if (!wndPtr || wndPtr == WND_OTHER_PROCESS || wndPtr == WND_DESKTOP) return FALSE;
hwnd = wndPtr->obj.handle; /* make it a full handle */
- if (pfinfo->dwFlags) wparam = !(wndPtr->flags & WIN_NCACTIVATED);
+ if (pfinfo->dwFlags) wparam = (wndPtr->flags & WIN_NCACTIVATED) != 0;
else wparam = (hwnd == GetForegroundWindow());
WIN_ReleasePtr( wndPtr );
--
2.11.0

0002-user32-tests-Fix-tests-for-FlashWindowEx.patch

From e14054aff23e28d7cd8021a4959b054db5a9e23f Mon Sep 17 00:00:00 2001
From: James Coonradt <gamax92@aol.com>
Date: Sat, 9 Sep 2017 18:12:29 -0600
Subject: [PATCH 2/2] user32/tests: Fix tests for FlashWindowEx
---
dlls/user32/tests/win.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c
index 9b8d16adc5f..ee923668995 100644
--- a/dlls/user32/tests/win.c
+++ b/dlls/user32/tests/win.c
@@ -8314,7 +8314,7 @@ static void test_FlashWindowEx(void)
SetLastError(0xdeadbeef);
ret = pFlashWindowEx(&finfo);
- todo_wine ok(!ret, "previous window state should not be active\n");
+ ok(!ret, "previous window state should not be active\n");
finfo.cbSize = sizeof(FLASHWINFO) - 1;
SetLastError(0xdeadbeef);
@@ -8365,7 +8365,7 @@ static void test_FlashWindowEx(void)
finfo.dwFlags = FLASHW_STOP;
SetLastError(0xdeadbeef);
ret = pFlashWindowEx(&finfo);
- ok(prev != ret, "previous window state should be different\n");
+ todo_wine ok(prev != ret, "previous window state should be different\n");
DestroyWindow( hwnd );
}
--
2.11.0