[PATCH 7/8] wined3d: Filter messages generated by focus handling.

Stefan Dösinger stefan at codeweavers.com
Thu Dec 4 03:36:33 CST 2014


This fixes tabbing out of World in Conflict and fixes the regression in
Endless Space (bug 37658).

We may want to consider moving mode changes, window setup and focus loss
handling into the client libs. With this patch and the next one we have
3 wined3d flags just for focus loss handling. Furthermore, dxgi yet
again has different behavior - it doesn't hook the window procedure and
instead polls the state in present. Otherwise the behavior of dxgi is
similar to that of d3d9ex, except that it continues in windowed mode
after refocus.
---
 dlls/d3d8/tests/device.c |  2 +-
 dlls/d3d9/tests/d3d9ex.c |  5 +----
 dlls/d3d9/tests/device.c | 13 +++----------
 dlls/ddraw/ddraw.c       |  3 ++-
 dlls/wined3d/device.c    |  2 +-
 dlls/wined3d/swapchain.c | 21 ++++++++++++++-------
 include/wine/wined3d.h   |  1 +
 7 files changed, 23 insertions(+), 24 deletions(-)

diff --git a/dlls/d3d8/tests/device.c b/dlls/d3d8/tests/device.c
index 0084272..73970c1 100644
--- a/dlls/d3d8/tests/device.c
+++ b/dlls/d3d8/tests/device.c
@@ -2688,7 +2688,7 @@ static void test_wndproc(void)
     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");
+    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. */
diff --git a/dlls/d3d9/tests/d3d9ex.c b/dlls/d3d9/tests/d3d9ex.c
index 49be31e..fef80f4 100644
--- a/dlls/d3d9/tests/d3d9ex.c
+++ b/dlls/d3d9/tests/d3d9ex.c
@@ -2236,10 +2236,7 @@ static void test_wndproc(void)
         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);
+        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. */
diff --git a/dlls/d3d9/tests/device.c b/dlls/d3d9/tests/device.c
index 72044a5..3206e57 100644
--- a/dlls/d3d9/tests/device.c
+++ b/dlls/d3d9/tests/device.c
@@ -3675,10 +3675,7 @@ static void test_wndproc(void)
         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);
+        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. */
@@ -3730,12 +3727,8 @@ static void test_wndproc(void)
         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);
+        ok(!windowposchanged_received || broken(1),
+                "Received WM_WINDOWPOSCHANGED but did not expect it, i=%u.\n", i);
         expect_messages = NULL;
 
         filter_messages = focus_window;
diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c
index fce1c22..f0ebc52 100644
--- a/dlls/ddraw/ddraw.c
+++ b/dlls/ddraw/ddraw.c
@@ -4850,7 +4850,8 @@ HRESULT ddraw_init(struct ddraw *ddraw, enum wined3d_device_type device_type)
     ddraw->numIfaces = 1;
     ddraw->ref7 = 1;
 
-    flags = WINED3D_LEGACY_DEPTH_BIAS | WINED3D_VIDMEM_ACCOUNTING | WINED3D_RESTORE_MODE_ON_ACTIVATE;
+    flags = WINED3D_LEGACY_DEPTH_BIAS | WINED3D_VIDMEM_ACCOUNTING
+            | WINED3D_RESTORE_MODE_ON_ACTIVATE | WINED3D_FOCUS_MESSAGES;
     if (!(ddraw->wined3d = wined3d_create(flags)))
     {
         if (!(ddraw->wined3d = wined3d_create(flags | WINED3D_NO3D)))
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index ae6600e..89ec00a 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -4961,7 +4961,7 @@ void device_invalidate_state(const struct wined3d_device *device, DWORD state)
 LRESULT device_process_message(struct wined3d_device *device, HWND window, BOOL unicode,
         UINT message, WPARAM wparam, LPARAM lparam, WNDPROC proc)
 {
-    if (device->filter_messages)
+    if (device->filter_messages && message != WM_DISPLAYCHANGE)
     {
         TRACE("Filtering message: window %p, message %#x, wparam %#lx, lparam %#lx.\n",
                 window, message, wparam, lparam);
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c
index 89f83ea..887143f 100644
--- a/dlls/wined3d/swapchain.c
+++ b/dlls/wined3d/swapchain.c
@@ -1176,14 +1176,19 @@ void swapchain_update_draw_bindings(struct wined3d_swapchain *swapchain)
 
 void wined3d_swapchain_activate(struct wined3d_swapchain *swapchain, BOOL activate)
 {
+    struct wined3d_device *device = swapchain->device;
+    BOOL filter_messages = device->filter_messages;
+
     /* This code is not protected by the wined3d mutex, so it may run while
      * wined3d_device_reset is active. Testing on Windows shows that changing
      * focus during resets and resetting during focus change events causes
      * the application to crash with an invalid memory access. */
 
+    device->filter_messages = !(device->wined3d->flags & WINED3D_FOCUS_MESSAGES);
+
     if (activate)
     {
-        if (!(swapchain->device->create_parms.flags & WINED3DCREATE_NOWINDOWCHANGES))
+        if (!(device->create_parms.flags & WINED3DCREATE_NOWINDOWCHANGES))
         {
             /* The d3d versions do not agree on the exact messages here. D3d8 restores
              * the window but leaves the size untouched, d3d9 sets the size on an
@@ -1197,23 +1202,25 @@ void wined3d_swapchain_activate(struct wined3d_swapchain *swapchain, BOOL activa
                     SWP_NOACTIVATE | SWP_NOZORDER);
         }
 
-        if (swapchain->device->wined3d->flags & WINED3D_RESTORE_MODE_ON_ACTIVATE)
+        if (device->wined3d->flags & WINED3D_RESTORE_MODE_ON_ACTIVATE)
         {
-            if (FAILED(wined3d_set_adapter_display_mode(swapchain->device->wined3d,
-                    swapchain->device->adapter->ordinal, &swapchain->d3d_mode)))
+            if (FAILED(wined3d_set_adapter_display_mode(device->wined3d,
+                    device->adapter->ordinal, &swapchain->d3d_mode)))
                 ERR("Failed to set display mode.\n");
         }
     }
     else
     {
-        if (FAILED(wined3d_set_adapter_display_mode(swapchain->device->wined3d,
-                swapchain->device->adapter->ordinal, NULL)))
+        if (FAILED(wined3d_set_adapter_display_mode(device->wined3d,
+                device->adapter->ordinal, NULL)))
             ERR("Failed to set display mode.\n");
 
         swapchain->reapply_mode = TRUE;
 
-        if (!(swapchain->device->create_parms.flags & WINED3DCREATE_NOWINDOWCHANGES)
+        if (!(device->create_parms.flags & WINED3DCREATE_NOWINDOWCHANGES)
                 && IsWindowVisible(swapchain->device_window))
             ShowWindow(swapchain->device_window, SW_MINIMIZE);
     }
+
+    device->filter_messages = filter_messages;
 }
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index 2362cbc..baa102a 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -1238,6 +1238,7 @@ enum wined3d_display_rotation
 #define WINED3D_VIDMEM_ACCOUNTING                               0x00000004
 #define WINED3D_PRESENT_CONVERSION                              0x00000008
 #define WINED3D_RESTORE_MODE_ON_ACTIVATE                        0x00000010
+#define WINED3D_FOCUS_MESSAGES                                  0x00000020
 
 #define WINED3D_RESZ_CODE                                       0x7fa05000
 
-- 
2.0.4




More information about the wine-patches mailing list