Module: wine Branch: master Commit: e8ce1085a92c46d9bdc4f69a0dc16d6378aa8413 URL: http://source.winehq.org/git/wine.git/?a=commit;h=e8ce1085a92c46d9bdc4f69a0d...
Author: Stefan Dösinger stefan@codeweavers.com Date: Thu Dec 4 21:51:44 2014 +0100
d3d8/tests: Test focus loss message filtering.
---
dlls/d3d8/tests/device.c | 79 +++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 64 insertions(+), 15 deletions(-)
diff --git a/dlls/d3d8/tests/device.c b/dlls/d3d8/tests/device.c index 33d3cd5..b6875d0 100644 --- a/dlls/d3d8/tests/device.c +++ b/dlls/d3d8/tests/device.c @@ -2181,8 +2181,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 { @@ -2230,12 +2231,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); } @@ -2344,13 +2345,19 @@ 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[] = { - /* 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_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[] = + { + {WM_ACTIVATEAPP, FOCUS_WINDOW, TRUE, TRUE}, {0, 0, FALSE, 0}, };
@@ -2568,12 +2575,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.\n", expect_messages->message, expect_messages->window); + 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"); @@ -2601,6 +2608,13 @@ static void test_wndproc(void) ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n", (LONG_PTR)test_proc, proc);
+ /* 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(d3d8, focus_window, &device_desc))) { @@ -2608,6 +2622,41 @@ static void test_wndproc(void) goto done; }
+ filter_messages = NULL; + + 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.\n", + expect_messages->message, expect_messages->window); + todo_wine ok(!windowposchanged_received, "Received WM_WINDOWPOSCHANGED but did not expect it.\n"); + expect_messages = NULL; + + /* The window is iconic even though no message was sent. */ + ok(IsIconic(focus_window), "The focus window is not iconic.\n"); + + hr = IDirect3DDevice8_TestCooperativeLevel(device); + ok(hr == D3DERR_DEVICELOST, "Got unexpected hr %#x.\n", hr); + + /* ShowWindow(SW_RESTORE); SetForegroundWindow(desktop); SetForegroundWindow(focus); + * results in the second SetForegroundWindow call failing and the device not being + * restored on native. Directly useing ShowWindow(SW_RESTORE) works, but it means + * we cannot test for the absence of WM_WINDOWPOSCHANGED messages. */ + expect_messages = reactivate_messages_filtered; + ShowWindow(focus_window, SW_RESTORE); + SetForegroundWindow(focus_window); + flush_events(); + ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it\n", + expect_messages->message, expect_messages->window); + expect_messages = NULL; + + filter_messages = focus_window; + hr = IDirect3DDevice8_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 = IDirect3DDevice8_Release(device); ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);