[PATCH 1/9] d3d9/tests: Test focus loss message filtering.

Stefan Dösinger stefan at codeweavers.com
Thu Dec 4 14:51:42 CST 2014


This supersedes 108033-108040. The individual patches are unchanged, but
an additional patch was added to address the test failure on the
testbot in an unrelated test in ddraw. Resending everything to make the
testbot run over them again.
---
 dlls/d3d9/tests/device.c | 103 +++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 86 insertions(+), 17 deletions(-)

diff --git a/dlls/d3d9/tests/device.c b/dlls/d3d9/tests/device.c
index a5cab96..fea68f1 100644
--- a/dlls/d3d9/tests/device.c
+++ b/dlls/d3d9/tests/device.c
@@ -3135,8 +3135,9 @@ struct message
     WPARAM expect_wparam;
 };
 
-static const struct message *expect_messages, *unexpected_messages;
+static const struct message *expect_messages;
 static HWND device_window, focus_window;
+static BOOL windowposchanged_received;
 
 struct wndproc_thread_param
 {
@@ -3184,12 +3185,12 @@ static LRESULT CALLBACK test_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM
         }
     }
 
-    if (unexpected_messages)
-    {
-        const struct message *i;
-        for (i = unexpected_messages; i->message; i++)
-            ok(i->message != message, "Got unexpected message %x on window %p.\n", message, hwnd);
-    }
+    /* KDE randomly does something with the hidden window during the
+     * mode change that sometimes generates a WM_WINDOWPOSCHANGING
+     * message. A WM_WINDOWPOSCHANGED message is not generated, so
+     * just flag WM_WINDOWPOSCHANGED as bad. */
+    if (message == WM_WINDOWPOSCHANGED)
+        windowposchanged_received = TRUE;
 
     return DefWindowProcA(hwnd, message, wparam, lparam);
 }
@@ -3312,24 +3313,31 @@ static void test_wndproc(void)
         {WM_ACTIVATEAPP,        FOCUS_WINDOW,   TRUE,   FALSE},
         {0,                     0,              FALSE,  0},
     };
-    static const struct message focus_loss_messages_hidden_unexpected[] =
+    static const struct message focus_loss_messages_filtered[] =
+    {
+        /* WM_ACTIVATE is delivered to the window proc because it is
+         * generated by SetForegroundWindow before the d3d routine
+         * starts it work. Don't check for it due to focus-follows-mouse
+         * WMs though. */
+        {WM_DISPLAYCHANGE,      FOCUS_WINDOW,   FALSE,  0},
+        {WM_ACTIVATEAPP,        FOCUS_WINDOW,   TRUE,   FALSE},
+        {0,                     0,              FALSE,  0},
+    };
+    static const struct message reactivate_messages_filtered[] =
     {
-        /* KDE randomly does something with the hidden window during the
-         * mode change that sometimes generates a WM_WINDOWPOSCHANGING
-         * message. A WM_WINDOWPOSCHANGED message is not generated, so
-         * just flag WM_WINDOWPOSCHANGED as bad. */
-        {WM_WINDOWPOSCHANGED,   0,              FALSE,  0},
+        {WM_ACTIVATEAPP,        FOCUS_WINDOW,   TRUE,   TRUE},
         {0,                     0,              FALSE,  0},
     };
     static const struct
     {
         DWORD create_flags;
         const struct message *focus_loss_messages, *reactivate_messages;
+        BOOL iconic;
     }
     tests[] =
     {
-        {0,                               focus_loss_messages,      reactivate_messages},
-        {CREATE_DEVICE_NOWINDOWCHANGES,   focus_loss_messages_nowc, reactivate_messages_nowc},
+        {0,                               focus_loss_messages,      reactivate_messages,        TRUE},
+        {CREATE_DEVICE_NOWINDOWCHANGES,   focus_loss_messages_nowc, reactivate_messages_nowc,   FALSE},
     };
 
     d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
@@ -3551,12 +3559,12 @@ static void test_wndproc(void)
         flush_events();
 
         expect_messages = focus_loss_messages_hidden;
-        unexpected_messages = focus_loss_messages_hidden_unexpected;
+        windowposchanged_received = FALSE;
         SetForegroundWindow(GetDesktopWindow());
         ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
                 expect_messages->message, expect_messages->window, i);
+        ok(!windowposchanged_received, "Received WM_WINDOWPOSCHANGED but did not expect it.\n");
         expect_messages = NULL;
-        unexpected_messages = NULL;
 
         ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode);
         ok(ret, "Failed to get display mode.\n");
@@ -3586,12 +3594,73 @@ static void test_wndproc(void)
         ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx, i=%u.\n",
                 (LONG_PTR)test_proc, proc, i);
 
+        /* Hide the device window. It prevents WM_ACTIVATEAPP messages from being sent
+         * on native in the test below. It isn't needed anyways. Creating the third
+         * device will show it again. */
+        filter_messages = NULL;
+        ShowWindow(device_window, SW_HIDE);
+        filter_messages = focus_window;
+
         device_desc.device_window = focus_window;
         if (!(device = create_device(d3d9, focus_window, &device_desc)))
         {
             skip("Failed to create a D3D device, skipping tests.\n");
             goto done;
         }
+        filter_messages = NULL;
+        SetForegroundWindow(focus_window); /* For KDE. */
+        flush_events();
+
+        expect_messages = focus_loss_messages_filtered;
+        windowposchanged_received = FALSE;
+        SetForegroundWindow(GetDesktopWindow());
+        ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
+                expect_messages->message, expect_messages->window, i);
+        if (tests[i].create_flags & CREATE_DEVICE_NOWINDOWCHANGES)
+            ok(!windowposchanged_received, "Received WM_WINDOWPOSCHANGED but did not expect it, i=%u.\n", i);
+        else
+            todo_wine ok(!windowposchanged_received, "Received WM_WINDOWPOSCHANGED but did not expect it, i=%u.\n", i);
+        expect_messages = NULL;
+
+        /* The window is iconic even though no message was sent. */
+        ok(!IsIconic(focus_window) == !tests[i].iconic,
+                "Expected IsIconic %u, got %u, i=%u.\n", tests[i].iconic, IsIconic(focus_window), i);
+
+        hr = IDirect3DDevice9_TestCooperativeLevel(device);
+        ok(hr == D3DERR_DEVICELOST, "Got unexpected hr %#x.\n", hr);
+
+        if (tests[i].create_flags & CREATE_DEVICE_NOWINDOWCHANGES)
+            ShowWindow(focus_window, SW_MINIMIZE);
+
+        ShowWindow(focus_window, SW_RESTORE);
+        /* Make sure the SetWindowPos call done by d3d9 is not a no-op. */
+        SetWindowPos(focus_window, NULL, 10, 10, 100, 100, SWP_NOZORDER | SWP_NOACTIVATE);
+        SetForegroundWindow(GetDesktopWindow());
+        flush_events();
+        SetForegroundWindow(GetDesktopWindow()); /* For FVWM. */
+        flush_events();
+
+        expect_messages = reactivate_messages_filtered;
+        windowposchanged_received = FALSE;
+        SetForegroundWindow(focus_window);
+        flush_events();
+        ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
+                expect_messages->message, expect_messages->window, i);
+        /* About 1 in 8 test runs receives WM_WINDOWPOSCHANGED on Vista. */
+        if (tests[i].create_flags & CREATE_DEVICE_NOWINDOWCHANGES)
+            ok(!windowposchanged_received || broken(1),
+                    "Received WM_WINDOWPOSCHANGED but did not expect it, i=%u.\n", i);
+        else
+            todo_wine ok(!windowposchanged_received || broken(1),
+                    "Received WM_WINDOWPOSCHANGED but did not expect it, i=%u.\n", i);
+        expect_messages = NULL;
+
+        filter_messages = focus_window;
+        hr = IDirect3DDevice9_TestCooperativeLevel(device);
+        ok(hr == D3DERR_DEVICENOTRESET, "Got unexpected hr %#x.\n", hr);
+
+        hr = reset_device(device, &device_desc);
+        ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
 
         ref = IDirect3DDevice9_Release(device);
         ok(ref == 0, "The device was not properly freed: refcount %u, i=%u.\n", ref, i);
-- 
2.0.4




More information about the wine-patches mailing list