diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index 685ffeaa..3c5c334e 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -391,6 +391,7 @@ patch_enable_all () enable_user32_Dialog_Paint_Event="$1" enable_user32_DrawMenuItem="$1" enable_user32_DrawTextExW="$1" + enable_user32_FlashWindowEx="$1" enable_user32_GetAutoRotationState="$1" enable_user32_GetSystemMetrics="$1" enable_user32_Groupbox_Rectangle="$1" @@ -1452,6 +1453,9 @@ patch_enable () user32-DrawTextExW) enable_user32_DrawTextExW="$2" ;; + user32-FlashWindowEx) + enable_user32_FlashWindowEx="$2" + ;; user32-GetAutoRotationState) enable_user32_GetAutoRotationState="$2" ;; @@ -8611,6 +8615,18 @@ if test "$enable_user32_DrawTextExW" -eq 1; then ) >> "$patchlist" fi +# Patchset user32-FlashWindowEx +# | +# | Modified files: +# | * dlls/user32/tests/win.c, dlls/user32/win.c +# | +if test "$enable_user32_FlashWindowEx" -eq 1; then + patch_apply user32-FlashWindowEx/0001-user32-Fix-FlashWindowEx-return-value.patch + ( + printf '%s\n' '+ { "Sebastian Lackner", "user32: Fix FlashWindowEx return value.", 1 },'; + ) >> "$patchlist" +fi + # Patchset user32-GetAutoRotationState # | # | Modified files: diff --git a/patches/user32-FlashWindowEx/0001-user32-Fix-FlashWindowEx-return-value.patch b/patches/user32-FlashWindowEx/0001-user32-Fix-FlashWindowEx-return-value.patch new file mode 100644 index 00000000..43708f47 --- /dev/null +++ b/patches/user32-FlashWindowEx/0001-user32-Fix-FlashWindowEx-return-value.patch @@ -0,0 +1,169 @@ +From f352713c8c6c8a34c1f9a7d688f8618843ad60de Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Tue, 19 Sep 2017 00:28:34 +0200 +Subject: user32: Fix FlashWindowEx return value. + +Based on a patch by James Coonradt . +--- + dlls/user32/tests/win.c | 80 +++++++++++++++++++++++++++++++++++++++---------- + dlls/user32/win.c | 12 ++++---- + 2 files changed, 70 insertions(+), 22 deletions(-) + +diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c +index 9b8d16adc5f..a6bab29bd2b 100644 +--- a/dlls/user32/tests/win.c ++++ b/dlls/user32/tests/win.c +@@ -77,6 +77,7 @@ static HWND hwndMessage; + static HWND hwndMain, hwndMain2; + static HHOOK hhook; + static BOOL app_activated, app_deactivated; ++static BOOL nc_activated, nc_deactivated; + + static const char* szAWRClass = "Winsize"; + static HMENU hmenu; +@@ -863,6 +864,10 @@ static LRESULT WINAPI main_window_procA(HWND hwnd, UINT msg, WPARAM wparam, LPAR + if (wparam) app_activated = TRUE; + else app_deactivated = TRUE; + break; ++ case WM_NCACTIVATE: ++ if (wparam) nc_activated = TRUE; ++ else nc_deactivated = TRUE; ++ break; + } + + return DefWindowProcA(hwnd, msg, wparam, lparam); +@@ -8283,7 +8288,8 @@ static void test_FlashWindowEx(void) + { + HWND hwnd; + FLASHWINFO finfo; +- BOOL prev, ret; ++ BOOL expected, ret; ++ int i; + + if (!pFlashWindowEx) + { +@@ -8314,7 +8320,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); +@@ -8347,25 +8353,69 @@ static void test_FlashWindowEx(void) + 0, 0, 0, 0, 0, 0, 0, NULL ); + ok( hwnd != 0, "CreateWindowExA error %d\n", GetLastError() ); + finfo.hwnd = hwnd; ++ finfo.uCount = 1; ++ expected = SendMessageA(hwnd, WM_ISACTIVEICON, 0, 0); + + SetLastError(0xdeadbeef); + ret = pFlashWindowEx(NULL); + ok(!ret && GetLastError() == ERROR_NOACCESS, + "FlashWindowEx returned with %d\n", GetLastError()); + +- SetLastError(0xdeadbeef); +- prev = pFlashWindowEx(&finfo); +- +- ok(finfo.cbSize == sizeof(FLASHWINFO), "FlashWindowEx modified cdSize to %x\n", finfo.cbSize); +- ok(finfo.hwnd == hwnd, "FlashWindowEx modified hwnd to %p\n", finfo.hwnd); +- ok(finfo.dwFlags == FLASHW_TIMER, "FlashWindowEx modified dwFlags to %x\n", finfo.dwFlags); +- ok(finfo.uCount == 3, "FlashWindowEx modified uCount to %x\n", finfo.uCount); +- ok(finfo.dwTimeout == 200, "FlashWindowEx modified dwTimeout to %x\n", finfo.dwTimeout); +- +- finfo.dwFlags = FLASHW_STOP; +- SetLastError(0xdeadbeef); +- ret = pFlashWindowEx(&finfo); +- ok(prev != ret, "previous window state should be different\n"); ++ /* Test FLASHW_CAPTION */ ++ for (i = 0; i < 10; i++) ++ { ++ nc_activated = nc_deactivated = FALSE; ++ finfo.dwFlags = FLASHW_CAPTION; ++ ret = pFlashWindowEx(&finfo) != 0; ++ Sleep(50); ++ flush_events(TRUE); ++ ok(nc_activated ^ nc_deactivated, "didn't get expected WM_NCACTIVATE message\n"); ++ ok(ret == nc_deactivated, "expected FlashWindowEx to return %u, got %u\n", nc_deactivated, ret); ++ ok(ret == expected, "expected FlashWindowEx to return %u, got %u\n", expected, ret); ++ expected = !ret; ++ } ++ ++ /* Test FLASHW_TRAY */ ++ for (i = 0; i < 10; i++) ++ { ++ nc_activated = nc_deactivated = FALSE; ++ finfo.dwFlags = FLASHW_TRAY; ++ ret = pFlashWindowEx(&finfo) != 0; ++ Sleep(50); ++ flush_events(TRUE); ++ todo_wine_if(ret) ok(!nc_deactivated, "didn't expect WM_NCACTIVE message with wParam == FALSE\n"); ++ ok(ret == !nc_activated, "expected FlashWindowEx to return %u, got %u\n", !nc_activated, ret); ++ ok(ret == expected, "expected FlashWindowEx to return %u, got %u\n", expected, ret); ++ expected = !ret; ++ } ++ ++ /* Test FLASHW_ALL */ ++ for (i = 0; i < 10; i++) ++ { ++ nc_activated = nc_deactivated = FALSE; ++ finfo.dwFlags = FLASHW_ALL; ++ ret = pFlashWindowEx(&finfo) != 0; ++ Sleep(50); ++ flush_events(TRUE); ++ ok(nc_activated ^ nc_deactivated, "didn't get expected WM_NCACTIVATE message\n"); ++ ok(ret == nc_deactivated, "expected FlashWindowEx to return %u, got %u\n", nc_deactivated, ret); ++ ok(ret == expected, "expected FlashWindowEx to return %u, got %u\n", expected, ret); ++ expected = !ret; ++ } ++ ++ /* Test FLASHW_STOP */ ++ for (i = 0; i < 10; i++) ++ { ++ nc_activated = nc_deactivated = FALSE; ++ finfo.dwFlags = FLASHW_STOP; ++ ret = pFlashWindowEx(&finfo) != 0; ++ Sleep(50); ++ flush_events(TRUE); ++ todo_wine_if(ret) ok(!nc_deactivated, "didn't expect WM_NCACTIVE message with wParam == FALSE\n"); ++ ok(ret == !nc_activated, "expected FlashWindowEx to return %u, got %u\n", !nc_activated, ret); ++ ok(ret == expected, "expected FlashWindowEx to return %u, got %u\n", expected, ret); ++ expected = !ret; ++ } + + DestroyWindow( hwnd ); + } +diff --git a/dlls/user32/win.c b/dlls/user32/win.c +index 3042a560ce9..23cb638ba28 100644 +--- a/dlls/user32/win.c ++++ b/dlls/user32/win.c +@@ -3538,20 +3538,18 @@ BOOL WINAPI FlashWindowEx( PFLASHWINFO pfinfo ) + } + else + { +- WPARAM wparam; + HWND hwnd = pfinfo->hwnd; ++ BOOL ret; + + wndPtr = WIN_GetPtr( hwnd ); + 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); +- else wparam = (hwnd == GetForegroundWindow()); +- ++ ret = (wndPtr->flags & WIN_NCACTIVATED) != 0; + WIN_ReleasePtr( wndPtr ); +- SendMessageW( hwnd, WM_NCACTIVATE, wparam, 0 ); ++ ++ SendMessageW( hwnd, WM_NCACTIVATE, !ret, 0 ); + USER_Driver->pFlashWindowEx( pfinfo ); +- return wparam; ++ return ret; + } + } + +-- +2.14.1 + diff --git a/patches/user32-FlashWindowEx/definition b/patches/user32-FlashWindowEx/definition new file mode 100644 index 00000000..1c576125 --- /dev/null +++ b/patches/user32-FlashWindowEx/definition @@ -0,0 +1 @@ +Fixes: Fix return value of FlashWindowEx