[PATCH 2/5] wined3d: Set the device window size on focus window activation.
Stefan Dösinger
stefan at codeweavers.com
Wed Nov 19 13:13:50 CST 2014
D3d9ex in principle has the same behavior, but it is unreliable.
Sometimes the WM_WINDOWPOSCHANGING message is missing, sometimes
WM_SIZE is not generated from the arriving WINDOWPOSCHANGED message,
and sometimes it works like in d3d8/9.
---
dlls/d3d8/tests/device.c | 14 +++++++++++++-
dlls/d3d9/tests/d3d9ex.c | 6 ++++++
dlls/d3d9/tests/device.c | 28 ++++++++++++++++++++++++----
dlls/wined3d/swapchain.c | 14 ++++++++++++++
4 files changed, 57 insertions(+), 5 deletions(-)
diff --git a/dlls/d3d8/tests/device.c b/dlls/d3d8/tests/device.c
index 6244254..6ee4f89 100644
--- a/dlls/d3d8/tests/device.c
+++ b/dlls/d3d8/tests/device.c
@@ -2282,6 +2282,14 @@ static void test_wndproc(void)
* or before. */
{0, 0, FALSE, 0},
};
+ static const struct message reactivate_messages[] =
+ {
+ {WM_WINDOWPOSCHANGING, DEVICE_WINDOW, FALSE, 0},
+ {WM_WINDOWPOSCHANGED, DEVICE_WINDOW, FALSE, 0},
+ {WM_MOVE, DEVICE_WINDOW, FALSE, 0},
+ {WM_ACTIVATEAPP, FOCUS_WINDOW, TRUE, TRUE},
+ {0, 0, FALSE, 0},
+ };
d3d8 = Direct3DCreate8(D3D_SDK_VERSION);
ok(!!d3d8, "Failed to create a D3D object.\n");
@@ -2469,13 +2477,17 @@ static void test_wndproc(void)
/* I have to minimize and restore the focus window, otherwise native d3d9 fails
* device::reset with D3DERR_DEVICELOST. This does not happen when the window
* restore is triggered by the user. */
+ expect_messages = reactivate_messages;
ShowWindow(focus_window, SW_MINIMIZE);
ShowWindow(focus_window, SW_RESTORE);
/* Set focus twice to make KDE and fvwm in focus-follows-mouse mode happy. */
SetForegroundWindow(focus_window);
flush_events();
SetForegroundWindow(focus_window);
- flush_events();
+ flush_events(); /* WM_WINDOWPOSCHANGING etc arrive after SetForegroundWindow returns. */
+ 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);
+ expect_messages = NULL;
hr = IDirect3DDevice8_TestCooperativeLevel(device);
ok(hr == D3DERR_DEVICENOTRESET, "Got unexpected hr %#x.\n", hr);
diff --git a/dlls/d3d9/tests/d3d9ex.c b/dlls/d3d9/tests/d3d9ex.c
index 5f54d5b..9f8c163 100644
--- a/dlls/d3d9/tests/d3d9ex.c
+++ b/dlls/d3d9/tests/d3d9ex.c
@@ -2052,6 +2052,12 @@ static void test_wndproc(void)
* independent of D3DCREATE_NOWINDOWCHANGES. */
ShowWindow(device_window, SW_MINIMIZE);
ShowWindow(device_window, SW_RESTORE);
+
+ /* Reactivation messages like in d3d8/9 are random in native d3d9ex.
+ * Sometimes they are sent, sometimes they are not (tested on Vista
+ * and Windows 7). The minimizing and restoring of the device window
+ * may have something to do with this, but if the messages are sent,
+ * they are generated by the 3 calls below. */
ShowWindow(focus_window, SW_MINIMIZE);
ShowWindow(focus_window, SW_RESTORE);
/* Set focus twice to make KDE and fvwm in focus-follows-mouse mode happy. */
diff --git a/dlls/d3d9/tests/device.c b/dlls/d3d9/tests/device.c
index 3fd25d1..3e91267 100644
--- a/dlls/d3d9/tests/device.c
+++ b/dlls/d3d9/tests/device.c
@@ -3244,15 +3244,30 @@ static void test_wndproc(void)
{WM_ACTIVATEAPP, FOCUS_WINDOW, TRUE, FALSE},
{0, 0, FALSE, 0},
};
+ static const struct message reactivate_messages[] =
+ {
+ {WM_WINDOWPOSCHANGING, DEVICE_WINDOW, FALSE, 0},
+ {WM_WINDOWPOSCHANGED, DEVICE_WINDOW, FALSE, 0},
+ {WM_MOVE, DEVICE_WINDOW, FALSE, 0},
+ {WM_ACTIVATEAPP, FOCUS_WINDOW, TRUE, TRUE},
+ {0, 0, FALSE, 0},
+ };
+ static const struct message reactivate_messages_nowc[] =
+ {
+ /* We're activating the device window before activating the
+ * focus window, so no ACTIVATEAPP message is sent. */
+ {WM_ACTIVATE, FOCUS_WINDOW, TRUE, WA_ACTIVE},
+ {0, 0, FALSE, 0},
+ };
static const struct
{
DWORD create_flags;
- const struct message *focus_loss_messages;
+ const struct message *focus_loss_messages, *reactivate_messages;
}
tests[] =
{
- {0, focus_loss_messages},
- {CREATE_DEVICE_NOWINDOWCHANGES, focus_loss_messages_nowc},
+ {0, focus_loss_messages, reactivate_messages},
+ {CREATE_DEVICE_NOWINDOWCHANGES, focus_loss_messages_nowc, reactivate_messages_nowc},
};
d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
@@ -3441,17 +3456,22 @@ static void test_wndproc(void)
ShowWindow(device_window, SW_MINIMIZE);
ShowWindow(device_window, SW_RESTORE);
}
+ flush_events();
/* I have to minimize and restore the focus window, otherwise native d3d9 fails
* device::reset with D3DERR_DEVICELOST. This does not happen when the window
* restore is triggered by the user. */
+ expect_messages = tests[i].reactivate_messages;
ShowWindow(focus_window, SW_MINIMIZE);
ShowWindow(focus_window, SW_RESTORE);
/* Set focus twice to make KDE and fvwm in focus-follows-mouse mode happy. */
SetForegroundWindow(focus_window);
flush_events();
SetForegroundWindow(focus_window);
- flush_events();
+ flush_events(); /* WM_WINDOWPOSCHANGING etc arrive after SetForegroundWindow returns. */
+ 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);
+ expect_messages = NULL;
hr = IDirect3DDevice9_TestCooperativeLevel(device);
ok(hr == D3DERR_DEVICENOTRESET, "Got unexpected hr %#x.\n", hr);
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c
index 20731ef..d1b6d0b 100644
--- a/dlls/wined3d/swapchain.c
+++ b/dlls/wined3d/swapchain.c
@@ -1178,6 +1178,20 @@ void wined3d_swapchain_activate(struct wined3d_swapchain *swapchain, BOOL activa
{
if (activate)
{
+ if (!(swapchain->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
+ * invisible window, generates messages but doesn't change the window
+ * properties. The implementation follows d3d9.
+ *
+ * Guild Wars 1 wants a WINDOWPOSCHANGED message on the device window to
+ * resume drawing after a focus loss. */
+ SetWindowPos(swapchain->device_window, NULL, 0, 0,
+ swapchain->desc.backbuffer_width, swapchain->desc.backbuffer_height,
+ SWP_NOACTIVATE | SWP_NOZORDER);
+ }
+
if (swapchain->device->wined3d->flags & WINED3D_RESTORE_MODE_ON_ACTIVATE)
{
if (FAILED(wined3d_set_adapter_display_mode(swapchain->device->wined3d,
--
2.0.4
More information about the wine-patches
mailing list