I'll have a closer look at this tomorrow. In particular, I want to see if the behavior is the same on my Windows machines.
One general musing (doesn't apply to a particular patch / line of code, hence the toppost) is how much of this behavior is d3d's / ddraw's doing and how much might be an external process like explorer.exe or whatever Windows equivalent of a window manager is. Prohibiting non-foreground applications from spawning a fullscreen window over your desktop sounds like a focus stealing prevention mechanism. I'd implement that in a component that is outside the badly behaved / malicious process and not inside like d3d*.dll are.
Musing 2: Is it the foreground thread that matters or that the foreground thread belongs to the current process?
And sorry that this is all so complicated. Window management and window flags are a pain :-(
Am 10.01.2022 um 17:47 schrieb Gabriel Ivăncescu gabrielopcode@gmail.com:
Fixes a regression introduced by f90d607c67768f19e36d9d74b498594252faa3fd.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50370 Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com
The current tests were testing a hidden window only, which ddraw treats as inactive (but not d3d8/d3d9ex). Tests were added to show that even visible windows, but inactive, are not set to topmost, while active ones are.
This is ddraw specific. d3d8 and d3d9ex treat hidden windows as "active" for the purposes of window changes (so only inactive visible windows prevent changes). We have existing tests for that.
Unfortunately, most of the tests are still todo_wine, even though the WS_EX_TOPMOST style matches (except when exiting, that's fixed on last patch). That's because we don't have WS_EX_WINDOWEDGE on fullscreen windows (long-standing issue), but the topmost bit is set correctly.
dlls/ddraw/ddraw.c | 6 ++-- dlls/ddraw/tests/ddraw1.c | 61 ++++++++++++++++++++++++++++++++++++++- dlls/ddraw/tests/ddraw2.c | 61 ++++++++++++++++++++++++++++++++++++++- dlls/ddraw/tests/ddraw4.c | 61 ++++++++++++++++++++++++++++++++++++++- dlls/ddraw/tests/ddraw7.c | 61 ++++++++++++++++++++++++++++++++++++++- 5 files changed, 244 insertions(+), 6 deletions(-)
diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c index 5b70bb4..77172d4 100644 --- a/dlls/ddraw/ddraw.c +++ b/dlls/ddraw/ddraw.c @@ -583,8 +583,10 @@ static HRESULT ddraw_attach_d3d_device(struct ddraw *ddraw, HWND window, swapchain_desc.swap_effect = WINED3D_SWAP_EFFECT_DISCARD; swapchain_desc.device_window = window; swapchain_desc.windowed = windowed;
- swapchain_desc.flags = WINED3D_SWAPCHAIN_ALLOW_MODE_SWITCH
| WINED3D_SWAPCHAIN_IMPLICIT | WINED3D_SWAPCHAIN_NO_WINDOW_CHANGES;
swapchain_desc.flags = WINED3D_SWAPCHAIN_ALLOW_MODE_SWITCH | WINED3D_SWAPCHAIN_IMPLICIT;
if (window != GetForegroundWindow())
swapchain_desc.flags |= WINED3D_SWAPCHAIN_NO_WINDOW_CHANGES;
if (ddraw->flags & DDRAW_NO3D) return wined3d_swapchain_create(ddraw->wined3d_device, &swapchain_desc,
diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c index 11c1477..80f04e7 100644 --- a/dlls/ddraw/tests/ddraw1.c +++ b/dlls/ddraw/tests/ddraw1.c @@ -2585,14 +2585,16 @@ static void test_window_style(void) { LONG style, exstyle, tmp, expected_style; RECT fullscreen_rect, r;
- HWND window, window2; IDirectDraw *ddraw;
HWND window; HRESULT hr; ULONG ref; BOOL ret;
window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW, 0, 0, 100, 100, 0, 0, 0, 0);
- window2 = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
ddraw = create_ddraw(); ok(!!ddraw, "Failed to create a ddraw object.\n");0, 0, 50, 50, 0, 0, 0, 0);
@@ -2636,6 +2638,63 @@ static void test_window_style(void) tmp = GetWindowLongA(window, GWL_EXSTYLE); ok(tmp == exstyle, "Expected window extended style %#x, got %#x.\n", exstyle, tmp);
- ShowWindow(window, SW_SHOW);
- ret = SetForegroundWindow(GetDesktopWindow());
- ok(ret, "Failed to set foreground window.\n");
- SetActiveWindow(window);
- ok(GetActiveWindow() == window, "Unexpected active window.\n");
- hr = IDirectDraw_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
- ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
- tmp = GetWindowLongA(window, GWL_STYLE);
- expected_style = style | WS_VISIBLE;
- todo_wine ok(tmp == expected_style, "Expected window style %#x, got %#x.\n", expected_style, tmp);
- tmp = GetWindowLongA(window, GWL_EXSTYLE);
- todo_wine ok(tmp == exstyle, "Expected window extended style %#x, got %#x.\n", exstyle, tmp);
- GetWindowRect(window, &r);
- ok(EqualRect(&r, &fullscreen_rect), "Expected %s, got %s.\n",
wine_dbgstr_rect(&fullscreen_rect), wine_dbgstr_rect(&r));
- hr = IDirectDraw_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
- ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
- ret = SetForegroundWindow(window2);
- ok(ret, "Failed to set foreground window.\n");
- hr = IDirectDraw_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
- ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
- tmp = GetWindowLongA(window, GWL_STYLE);
- expected_style = style | WS_VISIBLE;
- todo_wine ok(tmp == expected_style, "Expected window style %#x, got %#x.\n", expected_style, tmp);
- tmp = GetWindowLongA(window, GWL_EXSTYLE);
- todo_wine ok(tmp == exstyle, "Expected window extended style %#x, got %#x.\n", exstyle, tmp);
- GetWindowRect(window, &r);
- ok(EqualRect(&r, &fullscreen_rect), "Expected %s, got %s.\n",
wine_dbgstr_rect(&fullscreen_rect), wine_dbgstr_rect(&r));
- ret = SetForegroundWindow(window);
- ok(ret, "Failed to set foreground window.\n");
- hr = IDirectDraw_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
- ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
- tmp = GetWindowLongA(window, GWL_STYLE);
- expected_style = style | WS_VISIBLE;
- todo_wine ok(tmp == expected_style, "Expected window style %#x, got %#x.\n", expected_style, tmp);
- tmp = GetWindowLongA(window, GWL_EXSTYLE);
- expected_style = exstyle | WS_EX_TOPMOST;
- todo_wine ok(tmp == expected_style, "Expected window extended style %#x, got %#x.\n", expected_style, tmp);
- ShowWindow(window, SW_HIDE);
- hr = IDirectDraw_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
- ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
- tmp = GetWindowLongA(window, GWL_STYLE);
- ok(tmp == style, "Expected window style %#x, got %#x.\n", style, tmp);
- tmp = GetWindowLongA(window, GWL_EXSTYLE);
- todo_wine ok(tmp == exstyle, "Expected window extended style %#x, got %#x.\n", exstyle, tmp);
- ShowWindow(window, SW_SHOW); hr = IDirectDraw_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
diff --git a/dlls/ddraw/tests/ddraw2.c b/dlls/ddraw/tests/ddraw2.c index 33ad957..b7b6ba8 100644 --- a/dlls/ddraw/tests/ddraw2.c +++ b/dlls/ddraw/tests/ddraw2.c @@ -2663,14 +2663,16 @@ static void test_window_style(void) { LONG style, exstyle, tmp, expected_style; RECT fullscreen_rect, r;
- HWND window, window2; IDirectDraw2 *ddraw;
HWND window; HRESULT hr; ULONG ref; BOOL ret;
window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW, 0, 0, 100, 100, 0, 0, 0, 0);
- window2 = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
ddraw = create_ddraw(); ok(!!ddraw, "Failed to create a ddraw object.\n");0, 0, 50, 50, 0, 0, 0, 0);
@@ -2714,6 +2716,63 @@ static void test_window_style(void) tmp = GetWindowLongA(window, GWL_EXSTYLE); ok(tmp == exstyle, "Expected window extended style %#x, got %#x.\n", exstyle, tmp);
- ShowWindow(window, SW_SHOW);
- ret = SetForegroundWindow(GetDesktopWindow());
- ok(ret, "Failed to set foreground window.\n");
- SetActiveWindow(window);
- ok(GetActiveWindow() == window, "Unexpected active window.\n");
- hr = IDirectDraw2_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
- ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
- tmp = GetWindowLongA(window, GWL_STYLE);
- expected_style = style | WS_VISIBLE;
- todo_wine ok(tmp == expected_style, "Expected window style %#x, got %#x.\n", expected_style, tmp);
- tmp = GetWindowLongA(window, GWL_EXSTYLE);
- todo_wine ok(tmp == exstyle, "Expected window extended style %#x, got %#x.\n", exstyle, tmp);
- GetWindowRect(window, &r);
- ok(EqualRect(&r, &fullscreen_rect), "Expected %s, got %s.\n",
wine_dbgstr_rect(&fullscreen_rect), wine_dbgstr_rect(&r));
- hr = IDirectDraw2_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
- ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
- ret = SetForegroundWindow(window2);
- ok(ret, "Failed to set foreground window.\n");
- hr = IDirectDraw2_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
- ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
- tmp = GetWindowLongA(window, GWL_STYLE);
- expected_style = style | WS_VISIBLE;
- todo_wine ok(tmp == expected_style, "Expected window style %#x, got %#x.\n", expected_style, tmp);
- tmp = GetWindowLongA(window, GWL_EXSTYLE);
- todo_wine ok(tmp == exstyle, "Expected window extended style %#x, got %#x.\n", exstyle, tmp);
- GetWindowRect(window, &r);
- ok(EqualRect(&r, &fullscreen_rect), "Expected %s, got %s.\n",
wine_dbgstr_rect(&fullscreen_rect), wine_dbgstr_rect(&r));
- ret = SetForegroundWindow(window);
- ok(ret, "Failed to set foreground window.\n");
- hr = IDirectDraw2_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
- ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
- tmp = GetWindowLongA(window, GWL_STYLE);
- expected_style = style | WS_VISIBLE;
- todo_wine ok(tmp == expected_style, "Expected window style %#x, got %#x.\n", expected_style, tmp);
- tmp = GetWindowLongA(window, GWL_EXSTYLE);
- expected_style = exstyle | WS_EX_TOPMOST;
- todo_wine ok(tmp == expected_style, "Expected window extended style %#x, got %#x.\n", expected_style, tmp);
- ShowWindow(window, SW_HIDE);
- hr = IDirectDraw2_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
- ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
- tmp = GetWindowLongA(window, GWL_STYLE);
- ok(tmp == style, "Expected window style %#x, got %#x.\n", style, tmp);
- tmp = GetWindowLongA(window, GWL_EXSTYLE);
- todo_wine ok(tmp == exstyle, "Expected window extended style %#x, got %#x.\n", exstyle, tmp);
- ShowWindow(window, SW_SHOW); hr = IDirectDraw2_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
diff --git a/dlls/ddraw/tests/ddraw4.c b/dlls/ddraw/tests/ddraw4.c index 6182843..c7f5f64 100644 --- a/dlls/ddraw/tests/ddraw4.c +++ b/dlls/ddraw/tests/ddraw4.c @@ -2899,14 +2899,16 @@ static void test_window_style(void) { LONG style, exstyle, tmp, expected_style; RECT fullscreen_rect, r;
- HWND window, window2; IDirectDraw4 *ddraw;
HWND window; HRESULT hr; ULONG ref; BOOL ret;
window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW, 0, 0, 100, 100, 0, 0, 0, 0);
- window2 = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
ddraw = create_ddraw(); ok(!!ddraw, "Failed to create a ddraw object.\n");0, 0, 50, 50, 0, 0, 0, 0);
@@ -2950,6 +2952,63 @@ static void test_window_style(void) tmp = GetWindowLongA(window, GWL_EXSTYLE); ok(tmp == exstyle, "Expected window extended style %#x, got %#x.\n", exstyle, tmp);
- ShowWindow(window, SW_SHOW);
- ret = SetForegroundWindow(GetDesktopWindow());
- ok(ret, "Failed to set foreground window.\n");
- SetActiveWindow(window);
- ok(GetActiveWindow() == window, "Unexpected active window.\n");
- hr = IDirectDraw4_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
- ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
- tmp = GetWindowLongA(window, GWL_STYLE);
- expected_style = style | WS_VISIBLE;
- todo_wine ok(tmp == expected_style, "Expected window style %#x, got %#x.\n", expected_style, tmp);
- tmp = GetWindowLongA(window, GWL_EXSTYLE);
- todo_wine ok(tmp == exstyle, "Expected window extended style %#x, got %#x.\n", exstyle, tmp);
- GetWindowRect(window, &r);
- ok(EqualRect(&r, &fullscreen_rect), "Expected %s, got %s.\n",
wine_dbgstr_rect(&fullscreen_rect), wine_dbgstr_rect(&r));
- hr = IDirectDraw4_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
- ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
- ret = SetForegroundWindow(window2);
- ok(ret, "Failed to set foreground window.\n");
- hr = IDirectDraw4_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
- ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
- tmp = GetWindowLongA(window, GWL_STYLE);
- expected_style = style | WS_VISIBLE;
- todo_wine ok(tmp == expected_style, "Expected window style %#x, got %#x.\n", expected_style, tmp);
- tmp = GetWindowLongA(window, GWL_EXSTYLE);
- todo_wine ok(tmp == exstyle, "Expected window extended style %#x, got %#x.\n", exstyle, tmp);
- GetWindowRect(window, &r);
- ok(EqualRect(&r, &fullscreen_rect), "Expected %s, got %s.\n",
wine_dbgstr_rect(&fullscreen_rect), wine_dbgstr_rect(&r));
- ret = SetForegroundWindow(window);
- ok(ret, "Failed to set foreground window.\n");
- hr = IDirectDraw4_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
- ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
- tmp = GetWindowLongA(window, GWL_STYLE);
- expected_style = style | WS_VISIBLE;
- todo_wine ok(tmp == expected_style, "Expected window style %#x, got %#x.\n", expected_style, tmp);
- tmp = GetWindowLongA(window, GWL_EXSTYLE);
- expected_style = exstyle | WS_EX_TOPMOST;
- todo_wine ok(tmp == expected_style, "Expected window extended style %#x, got %#x.\n", expected_style, tmp);
- ShowWindow(window, SW_HIDE);
- hr = IDirectDraw4_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
- ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
- tmp = GetWindowLongA(window, GWL_STYLE);
- ok(tmp == style, "Expected window style %#x, got %#x.\n", style, tmp);
- tmp = GetWindowLongA(window, GWL_EXSTYLE);
- todo_wine ok(tmp == exstyle, "Expected window extended style %#x, got %#x.\n", exstyle, tmp);
- ShowWindow(window, SW_SHOW); hr = IDirectDraw4_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c index fc0f854..cbc10a3 100644 --- a/dlls/ddraw/tests/ddraw7.c +++ b/dlls/ddraw/tests/ddraw7.c @@ -2564,14 +2564,16 @@ static void test_window_style(void) { LONG style, exstyle, tmp, expected_style; RECT fullscreen_rect, r;
- HWND window, window2; IDirectDraw7 *ddraw;
HWND window; HRESULT hr; ULONG ref; BOOL ret;
window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW, 0, 0, 100, 100, 0, 0, 0, 0);
- window2 = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
ddraw = create_ddraw(); ok(!!ddraw, "Failed to create a ddraw object.\n");0, 0, 50, 50, 0, 0, 0, 0);
@@ -2615,6 +2617,63 @@ static void test_window_style(void) tmp = GetWindowLongA(window, GWL_EXSTYLE); ok(tmp == exstyle, "Expected window extended style %#x, got %#x.\n", exstyle, tmp);
- ShowWindow(window, SW_SHOW);
- ret = SetForegroundWindow(GetDesktopWindow());
- ok(ret, "Failed to set foreground window.\n");
- SetActiveWindow(window);
- ok(GetActiveWindow() == window, "Unexpected active window.\n");
- hr = IDirectDraw7_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
- ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
- tmp = GetWindowLongA(window, GWL_STYLE);
- expected_style = style | WS_VISIBLE;
- todo_wine ok(tmp == expected_style, "Expected window style %#x, got %#x.\n", expected_style, tmp);
- tmp = GetWindowLongA(window, GWL_EXSTYLE);
- todo_wine ok(tmp == exstyle, "Expected window extended style %#x, got %#x.\n", exstyle, tmp);
- GetWindowRect(window, &r);
- ok(EqualRect(&r, &fullscreen_rect), "Expected %s, got %s.\n",
wine_dbgstr_rect(&fullscreen_rect), wine_dbgstr_rect(&r));
- hr = IDirectDraw7_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
- ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
- ret = SetForegroundWindow(window2);
- ok(ret, "Failed to set foreground window.\n");
- hr = IDirectDraw7_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
- ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
- tmp = GetWindowLongA(window, GWL_STYLE);
- expected_style = style | WS_VISIBLE;
- todo_wine ok(tmp == expected_style, "Expected window style %#x, got %#x.\n", expected_style, tmp);
- tmp = GetWindowLongA(window, GWL_EXSTYLE);
- todo_wine ok(tmp == exstyle, "Expected window extended style %#x, got %#x.\n", exstyle, tmp);
- GetWindowRect(window, &r);
- ok(EqualRect(&r, &fullscreen_rect), "Expected %s, got %s.\n",
wine_dbgstr_rect(&fullscreen_rect), wine_dbgstr_rect(&r));
- ret = SetForegroundWindow(window);
- ok(ret, "Failed to set foreground window.\n");
- hr = IDirectDraw7_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
- ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
- tmp = GetWindowLongA(window, GWL_STYLE);
- expected_style = style | WS_VISIBLE;
- todo_wine ok(tmp == expected_style, "Expected window style %#x, got %#x.\n", expected_style, tmp);
- tmp = GetWindowLongA(window, GWL_EXSTYLE);
- expected_style = exstyle | WS_EX_TOPMOST;
- todo_wine ok(tmp == expected_style, "Expected window extended style %#x, got %#x.\n", expected_style, tmp);
- ShowWindow(window, SW_HIDE);
- hr = IDirectDraw7_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
- ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
- tmp = GetWindowLongA(window, GWL_STYLE);
- ok(tmp == style, "Expected window style %#x, got %#x.\n", style, tmp);
- tmp = GetWindowLongA(window, GWL_EXSTYLE);
- todo_wine ok(tmp == exstyle, "Expected window extended style %#x, got %#x.\n", exstyle, tmp);
- ShowWindow(window, SW_SHOW); hr = IDirectDraw7_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
-- 2.34.1