Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/dxgi/tests/dxgi.c | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-)
diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c index 2d8826f..14cb555 100644 --- a/dlls/dxgi/tests/dxgi.c +++ b/dlls/dxgi/tests/dxgi.c @@ -2826,10 +2826,47 @@ static void test_set_fullscreen(IUnknown *device, BOOL is_d3d12) refcount = IDXGISwapChain_Release(swapchain); ok(!refcount, "IDXGISwapChain has %u references left.\n", refcount);
- swapchain_desc.OutputWindow = CreateWindowA("static", "dxgi_test", 0, 0, 0, 400, 200, 0, 0, 0, 0); + swapchain_desc.OutputWindow = CreateWindowA("static", "dxgi_test", WS_VISIBLE, 0, 0, 400, 200, 0, 0, 0, 0); check_window_fullscreen_state(swapchain_desc.OutputWindow, &initial_state.fullscreen_state); swapchain_desc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; hr = IDXGIFactory_CreateSwapChain(factory, device, &swapchain_desc, &swapchain); + ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + hr = IDXGISwapChain_SetFullscreenState(swapchain, TRUE, NULL); + ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + hr = IDXGISwapChain_GetFullscreenState(swapchain, &fullscreen, NULL); + ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + ok(!!fullscreen, "Got unexpected fullscreen %#x.\n", fullscreen); + + /* Removing topmost style makes the swapchain lose fullscreen state on next Present */ + SetWindowPos(swapchain_desc.OutputWindow, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE); + ok(!(GetWindowLongA(swapchain_desc.OutputWindow, GWL_EXSTYLE) & WS_EX_TOPMOST), "Got unexpected WS_EX_TOPMOST.\n"); + flush_events(); + + hr = IDXGISwapChain_GetFullscreenState(swapchain, &fullscreen, NULL); + ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + ok(!!fullscreen, "Got unexpected fullscreen %#x.\n", fullscreen); + hr = IDXGISwapChain_GetFullscreenState(swapchain, &fullscreen, NULL); + ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + ok(!!fullscreen, "Got unexpected fullscreen %#x.\n", fullscreen); + hr = IDXGISwapChain_Present(swapchain, 0, 0); + todo_wine ok(hr == DXGI_STATUS_OCCLUDED || broken(hr == DXGI_ERROR_INVALID_CALL) /* Win10 1809 */, "Got unexpected hr %#x.\n", hr); + if (hr != DXGI_ERROR_INVALID_CALL) + { + hr = IDXGISwapChain_GetFullscreenState(swapchain, &fullscreen, NULL); + ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + todo_wine ok(!fullscreen, "Got unexpected fullscreen %#x.\n", fullscreen); + hr = IDXGISwapChain_Present(swapchain, 0, 0); + ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + } + hr = IDXGISwapChain_SetFullscreenState(swapchain, FALSE, NULL); + ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + refcount = IDXGISwapChain_Release(swapchain); + ok(!refcount, "IDXGISwapChain has %u references left.\n", refcount); + + DestroyWindow(swapchain_desc.OutputWindow); + swapchain_desc.OutputWindow = CreateWindowA("static", "dxgi_test", 0, 0, 0, 400, 200, 0, 0, 0, 0); + check_window_fullscreen_state(swapchain_desc.OutputWindow, &initial_state.fullscreen_state); + hr = IDXGIFactory_CreateSwapChain(factory, device, &swapchain_desc, &swapchain); ok(SUCCEEDED(hr), "CreateSwapChain failed, hr %#x.\n", hr); check_swapchain_fullscreen_state(swapchain, &initial_state); test_swapchain_fullscreen_state(swapchain, adapter, &initial_state);
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/dxgi/swapchain.c | 16 +++++++++++++++- dlls/dxgi/tests/dxgi.c | 4 ++-- 2 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c index 82e5fbf..6e586cd 100644 --- a/dlls/dxgi/swapchain.c +++ b/dlls/dxgi/swapchain.c @@ -328,13 +328,27 @@ static HRESULT STDMETHODCALLTYPE d3d11_swapchain_GetDevice(IDXGISwapChain1 *ifac static HRESULT d3d11_swapchain_present(struct d3d11_swapchain *swapchain, unsigned int sync_interval, unsigned int flags) { + HWND hwnd = d3d11_swapchain_get_hwnd(swapchain); + BOOL fullscreen; + HRESULT hr; + if (sync_interval > 4) { WARN("Invalid sync interval %u.\n", sync_interval); return DXGI_ERROR_INVALID_CALL; }
- if (IsIconic(d3d11_swapchain_get_hwnd(swapchain))) + hr = IDXGISwapChain1_GetFullscreenState(&swapchain->IDXGISwapChain1_iface, &fullscreen, NULL); + if (FAILED(hr)) + return hr; + + if (fullscreen && !(GetWindowLongW(hwnd, GWL_EXSTYLE) & WS_EX_TOPMOST)) + { + IDXGISwapChain1_SetFullscreenState(&swapchain->IDXGISwapChain1_iface, FALSE, NULL); + return DXGI_STATUS_OCCLUDED; + } + + if (IsIconic(hwnd)) return DXGI_STATUS_OCCLUDED;
if (flags & ~DXGI_PRESENT_TEST) diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c index 14cb555..e859edc 100644 --- a/dlls/dxgi/tests/dxgi.c +++ b/dlls/dxgi/tests/dxgi.c @@ -2849,12 +2849,12 @@ static void test_set_fullscreen(IUnknown *device, BOOL is_d3d12) ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); ok(!!fullscreen, "Got unexpected fullscreen %#x.\n", fullscreen); hr = IDXGISwapChain_Present(swapchain, 0, 0); - todo_wine ok(hr == DXGI_STATUS_OCCLUDED || broken(hr == DXGI_ERROR_INVALID_CALL) /* Win10 1809 */, "Got unexpected hr %#x.\n", hr); + ok(hr == DXGI_STATUS_OCCLUDED || broken(hr == DXGI_ERROR_INVALID_CALL) /* Win10 1809 */, "Got unexpected hr %#x.\n", hr); if (hr != DXGI_ERROR_INVALID_CALL) { hr = IDXGISwapChain_GetFullscreenState(swapchain, &fullscreen, NULL); ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); - todo_wine ok(!fullscreen, "Got unexpected fullscreen %#x.\n", fullscreen); + ok(!fullscreen, "Got unexpected fullscreen %#x.\n", fullscreen); hr = IDXGISwapChain_Present(swapchain, 0, 0); ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); }
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=84672
Your paranoid android.
=== w10pro64 (64 bit report) ===
dxgi: dxgi.c:2804: Test failed: Got unexpected hr 0x887a0022. dxgi.c:2807: Test failed: Got unexpected fullscreen 0. dxgi.c:2810: Test failed: Got unexpected hr 0x887a0022. dxgi.c:2813: Test failed: Got unexpected fullscreen 0.
This is what Windows' DWM does to DXGI fullscreen windows when e.g. Alt-Tab is released.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com ---
Handling it in FocusOut seems like the closest option, although we have to workaround the Z-order by bringing the focused window to the top, because it should actually happen before the focus change, but that's out of our control.
dlls/dxgi/swapchain.c | 19 ++++++++++++-- dlls/winex11.drv/event.c | 48 ++++++++++++++++++++++++++++++++-- dlls/winex11.drv/x11drv.h | 1 + dlls/winex11.drv/x11drv_main.c | 1 + 4 files changed, 65 insertions(+), 4 deletions(-)
diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c index 6e586cd..6f14dbf 100644 --- a/dlls/dxgi/swapchain.c +++ b/dlls/dxgi/swapchain.c @@ -38,6 +38,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(dxgi); WINE_DECLARE_DEBUG_CHANNEL(winediag);
+static const WCHAR wine_dxgi_fs_propW[] = { '_','_','w','i','n','e','_','d','x','g','i','_','f','u','l','l','s','c','r','e','e','n',0 }; + static DXGI_SWAP_EFFECT dxgi_swap_effect_from_wined3d(enum wined3d_swap_effect swap_effect) { switch (swap_effect) @@ -242,6 +244,7 @@ static ULONG STDMETHODCALLTYPE d3d11_swapchain_Release(IDXGISwapChain1 *iface) if (!refcount) { IWineDXGIDevice *device = swapchain->device; + RemovePropW(d3d11_swapchain_get_hwnd(swapchain), wine_dxgi_fs_propW); if (swapchain->target) { WARN("Releasing fullscreen swapchain.\n"); @@ -439,8 +442,11 @@ static HRESULT STDMETHODCALLTYPE DECLSPEC_HOTPATCH d3d11_swapchain_SetFullscreen return DXGI_ERROR_NOT_CURRENTLY_AVAILABLE; }
- if (!fullscreen) + if (fullscreen) + SetPropW(d3d11_swapchain_get_hwnd(swapchain), wine_dxgi_fs_propW, (HANDLE)TRUE); + else { + RemovePropW(d3d11_swapchain_get_hwnd(swapchain), wine_dxgi_fs_propW); IDXGIOutput_Release(target); target = NULL; } @@ -922,6 +928,8 @@ HRESULT d3d11_swapchain_init(struct d3d11_swapchain *swapchain, struct dxgi_devi } wined3d_mutex_unlock();
+ if (fullscreen) + SetPropW(d3d11_swapchain_get_hwnd(swapchain), wine_dxgi_fs_propW, (HANDLE)TRUE); return S_OK;
cleanup: @@ -1954,6 +1962,7 @@ static ULONG STDMETHODCALLTYPE d3d12_swapchain_Release(IDXGISwapChain4 *iface)
if (!refcount) { + RemovePropW(swapchain->window, wine_dxgi_fs_propW); d3d12_swapchain_destroy(swapchain); heap_free(swapchain); } @@ -2290,8 +2299,12 @@ static HRESULT STDMETHODCALLTYPE DECLSPEC_HOTPATCH d3d12_swapchain_SetFullscreen goto fail;
fullscreen_desc->Windowed = wined3d_desc.windowed; - if (!fullscreen) + + if (fullscreen) + SetPropW(swapchain->window, wine_dxgi_fs_propW, (HANDLE)TRUE); + else { + RemovePropW(swapchain->window, wine_dxgi_fs_propW); IDXGIOutput_Release(target); target = NULL; } @@ -3199,6 +3212,8 @@ static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGI
IWineDXGIFactory_AddRef(swapchain->factory = factory);
+ if (!fullscreen_desc->Windowed) + SetPropW(swapchain->window, wine_dxgi_fs_propW, (HANDLE)TRUE); return S_OK; }
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c index d21d2a7..e37c0f4 100644 --- a/dlls/winex11.drv/event.c +++ b/dlls/winex11.drv/event.c @@ -817,6 +817,8 @@ static BOOL X11DRV_FocusIn( HWND hwnd, XEvent *xev ) */ static void focus_out( Display *display , HWND hwnd ) { + static const WCHAR wine_dxgi_fs_propW[] = { '_','_','w','i','n','e','_','d','x','g','i','_','f','u','l','l','s','c','r','e','e','n',0 }; + struct x11drv_win_data *data; HWND hwnd_tmp; Window focus_win; int revert; @@ -835,10 +837,52 @@ static void focus_out( Display *display , HWND hwnd ) if (hwnd != GetForegroundWindow()) return; SendMessageW( hwnd, WM_CANCELMODE, 0, 0 );
+ XGetInputFocus( display, &focus_win, &revert ); + + /* when focus is changed by the WM (e.g. alt-tab) while a + dxgi fullscreen window is active, remove its topmost */ + if ((GetWindowLongW( hwnd, GWL_EXSTYLE ) & WS_EX_TOPMOST) && + GetPropW( hwnd, wine_dxgi_fs_propW )) + { + SetWindowPos( hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOSENDCHANGING ); + + if ((data = get_win_data( hwnd ))) + { + int format, screen = data->vis.screen; + unsigned long count, remaining; + Window active_win = None; + XWindowAttributes attr; + XWindowChanges changes; + unsigned char *prop; + Atom type; + + /* reset the input focus in case the WM changed it */ + release_win_data( data ); + XSetInputFocus( display, focus_win, RevertToParent, CurrentTime ); + + /* move the active window to the top so it's not below the ex-topmost window */ + if (!XGetWindowProperty( display, DefaultRootWindow(display), x11drv_atom(_NET_ACTIVE_WINDOW), + 0, 1, False, XA_WINDOW, &type, &format, &count, &remaining, &prop )) + { + if (type == XA_WINDOW && format == 32 && count == 1) + active_win = *(long*)prop; + XFree(prop); + } + + if (XGetWindowAttributes( display, active_win != None ? active_win : focus_win, &attr ) && + XScreenNumberOfScreen( attr.screen ) == screen) + { + changes.stack_mode = Above; + if (active_win != None) + XReconfigureWMWindow( display, active_win, screen, CWStackMode, &changes ); + else if (focus_win) + XConfigureWindow( display, focus_win, CWStackMode, &changes ); + } + } + } + /* don't reset the foreground window, if the window which is getting the focus is a Wine window */ - - XGetInputFocus( display, &focus_win, &revert ); if (focus_win) { if (XFindContext( display, focus_win, winContext, (char **)&hwnd_tmp ) != 0) diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 4585597..be3a30b 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -437,6 +437,7 @@ enum x11drv_atoms XATOM_DndSelection, XATOM__ICC_PROFILE, XATOM__MOTIF_WM_HINTS, + XATOM__NET_ACTIVE_WINDOW, XATOM__NET_STARTUP_INFO_BEGIN, XATOM__NET_STARTUP_INFO, XATOM__NET_SUPPORTED, diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c index 9ec4c7a..3fcb117 100644 --- a/dlls/winex11.drv/x11drv_main.c +++ b/dlls/winex11.drv/x11drv_main.c @@ -150,6 +150,7 @@ static const char * const atom_names[NB_XATOMS - FIRST_XATOM] = "DndSelection", "_ICC_PROFILE", "_MOTIF_WM_HINTS", + "_NET_ACTIVE_WINDOW", "_NET_STARTUP_INFO_BEGIN", "_NET_STARTUP_INFO", "_NET_SUPPORTED",
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=84671
Your paranoid android.
=== w8adm (32 bit report) ===
dxgi: dxgi.c:2804: Test failed: Got unexpected hr 0x887a0022. dxgi.c:2807: Test failed: Got unexpected fullscreen 0. dxgi.c:2810: Test failed: Got unexpected hr 0x887a0022. dxgi.c:2813: Test failed: Got unexpected fullscreen 0.
=== w1064v1507 (64 bit report) ===
dxgi: dxgi.c:5704: Test failed: Got unexpected message 0x31f, hwnd 00000000000A0056, wparam 0x1, lparam 0.
On 1/28/21 9:51 PM, Gabriel Ivăncescu wrote:
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com
dlls/dxgi/tests/dxgi.c | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-)
diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c index 2d8826f..14cb555 100644 --- a/dlls/dxgi/tests/dxgi.c +++ b/dlls/dxgi/tests/dxgi.c @@ -2826,10 +2826,47 @@ static void test_set_fullscreen(IUnknown *device, BOOL is_d3d12) refcount = IDXGISwapChain_Release(swapchain); ok(!refcount, "IDXGISwapChain has %u references left.\n", refcount);
- swapchain_desc.OutputWindow = CreateWindowA("static", "dxgi_test", 0, 0, 0, 400, 200, 0, 0, 0, 0);
- swapchain_desc.OutputWindow = CreateWindowA("static", "dxgi_test", WS_VISIBLE, 0, 0, 400, 200, 0, 0, 0, 0);
test_swapchain_present() uses an invisible window to test Present() in fullscreen mode. So either this change is unnecessary or you need to handle the case of invisible windows. It would be helpful to test the existence of WS_EX_TOPMOST even for an invisible window for a fullscreen swapchain.
check_window_fullscreen_state(swapchain_desc.OutputWindow, &initial_state.fullscreen_state); swapchain_desc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; hr = IDXGIFactory_CreateSwapChain(factory, device, &swapchain_desc, &swapchain);
- ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
- hr = IDXGISwapChain_SetFullscreenState(swapchain, TRUE, NULL);
- ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
- hr = IDXGISwapChain_GetFullscreenState(swapchain, &fullscreen, NULL);
- ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
- ok(!!fullscreen, "Got unexpected fullscreen %#x.\n", fullscreen);
Please test the existence of WS_EX_TOPMOST first.
- /* Removing topmost style makes the swapchain lose fullscreen state on next Present */
- SetWindowPos(swapchain_desc.OutputWindow, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
- ok(!(GetWindowLongA(swapchain_desc.OutputWindow, GWL_EXSTYLE) & WS_EX_TOPMOST), "Got unexpected WS_EX_TOPMOST.\n");
- flush_events();
- hr = IDXGISwapChain_GetFullscreenState(swapchain, &fullscreen, NULL);
- ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
- ok(!!fullscreen, "Got unexpected fullscreen %#x.\n", fullscreen);
- hr = IDXGISwapChain_GetFullscreenState(swapchain, &fullscreen, NULL);
- ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
- ok(!!fullscreen, "Got unexpected fullscreen %#x.\n", fullscreen);
Do you need to call IDXGISwapChain_GetFullscreenState() twice?
- hr = IDXGISwapChain_Present(swapchain, 0, 0);
Please test if DXGI_PRESENT_TEST flag also make the swapchain exit fullscreen.
- todo_wine ok(hr == DXGI_STATUS_OCCLUDED || broken(hr == DXGI_ERROR_INVALID_CALL) /* Win10 1809 */, "Got unexpected hr %#x.\n", hr);
Does calling IDXGISwapChain_ResizeBuffers() before Present() help to remove this DXGI_ERROR_INVALID_CALL error?
- if (hr != DXGI_ERROR_INVALID_CALL)
- {
hr = IDXGISwapChain_GetFullscreenState(swapchain, &fullscreen, NULL);
ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
todo_wine ok(!fullscreen, "Got unexpected fullscreen %#x.\n", fullscreen);
hr = IDXGISwapChain_Present(swapchain, 0, 0);
ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
- }
- hr = IDXGISwapChain_SetFullscreenState(swapchain, FALSE, NULL);
- ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
- refcount = IDXGISwapChain_Release(swapchain);
- ok(!refcount, "IDXGISwapChain has %u references left.\n", refcount);
- DestroyWindow(swapchain_desc.OutputWindow);
- swapchain_desc.OutputWindow = CreateWindowA("static", "dxgi_test", 0, 0, 0, 400, 200, 0, 0, 0, 0);
- check_window_fullscreen_state(swapchain_desc.OutputWindow, &initial_state.fullscreen_state);
- hr = IDXGIFactory_CreateSwapChain(factory, device, &swapchain_desc, &swapchain); ok(SUCCEEDED(hr), "CreateSwapChain failed, hr %#x.\n", hr); check_swapchain_fullscreen_state(swapchain, &initial_state); test_swapchain_fullscreen_state(swapchain, adapter, &initial_state);
Hi Zhiyi,
Thanks for the review.
On 29/01/2021 04:34, Zhiyi Zhang wrote:
On 1/28/21 9:51 PM, Gabriel Ivăncescu wrote:
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com
dlls/dxgi/tests/dxgi.c | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-)
diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c index 2d8826f..14cb555 100644 --- a/dlls/dxgi/tests/dxgi.c +++ b/dlls/dxgi/tests/dxgi.c @@ -2826,10 +2826,47 @@ static void test_set_fullscreen(IUnknown *device, BOOL is_d3d12) refcount = IDXGISwapChain_Release(swapchain); ok(!refcount, "IDXGISwapChain has %u references left.\n", refcount);
- swapchain_desc.OutputWindow = CreateWindowA("static", "dxgi_test", 0, 0, 0, 400, 200, 0, 0, 0, 0);
- swapchain_desc.OutputWindow = CreateWindowA("static", "dxgi_test", WS_VISIBLE, 0, 0, 400, 200, 0, 0, 0, 0);
test_swapchain_present() uses an invisible window to test Present() in fullscreen mode. So either this change is unnecessary or you need to handle the case of invisible windows. It would be helpful to test the existence of WS_EX_TOPMOST even for an invisible window for a fullscreen swapchain.
When I tested on invisible windows the results were unreliable on Windows. Most of the time, it actually didn't exit fullscreen, but sometimes it did. I'm not sure what's the best way to handle that.
I don't think it matters that much in practice, but…
check_window_fullscreen_state(swapchain_desc.OutputWindow, &initial_state.fullscreen_state); swapchain_desc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; hr = IDXGIFactory_CreateSwapChain(factory, device, &swapchain_desc, &swapchain);
- ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
- hr = IDXGISwapChain_SetFullscreenState(swapchain, TRUE, NULL);
- ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
- hr = IDXGISwapChain_GetFullscreenState(swapchain, &fullscreen, NULL);
- ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
- ok(!!fullscreen, "Got unexpected fullscreen %#x.\n", fullscreen);
Please test the existence of WS_EX_TOPMOST first.
- /* Removing topmost style makes the swapchain lose fullscreen state on next Present */
- SetWindowPos(swapchain_desc.OutputWindow, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
- ok(!(GetWindowLongA(swapchain_desc.OutputWindow, GWL_EXSTYLE) & WS_EX_TOPMOST), "Got unexpected WS_EX_TOPMOST.\n");
- flush_events();
- hr = IDXGISwapChain_GetFullscreenState(swapchain, &fullscreen, NULL);
- ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
- ok(!!fullscreen, "Got unexpected fullscreen %#x.\n", fullscreen);
- hr = IDXGISwapChain_GetFullscreenState(swapchain, &fullscreen, NULL);
- ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
- ok(!!fullscreen, "Got unexpected fullscreen %#x.\n", fullscreen);
Do you need to call IDXGISwapChain_GetFullscreenState() twice?
I called it twice to test the fact that GetFullscreenState does not remove the fullscreen state itself. (iirc Stefan had a theory that it does, so I wanted to write a test for it)
- hr = IDXGISwapChain_Present(swapchain, 0, 0);
Please test if DXGI_PRESENT_TEST flag also make the swapchain exit fullscreen.
- todo_wine ok(hr == DXGI_STATUS_OCCLUDED || broken(hr == DXGI_ERROR_INVALID_CALL) /* Win10 1809 */, "Got unexpected hr %#x.\n", hr);
Does calling IDXGISwapChain_ResizeBuffers() before Present() help to remove this DXGI_ERROR_INVALID_CALL error?
- if (hr != DXGI_ERROR_INVALID_CALL)
- {
hr = IDXGISwapChain_GetFullscreenState(swapchain, &fullscreen, NULL);
ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
todo_wine ok(!fullscreen, "Got unexpected fullscreen %#x.\n", fullscreen);
hr = IDXGISwapChain_Present(swapchain, 0, 0);
ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
- }
- hr = IDXGISwapChain_SetFullscreenState(swapchain, FALSE, NULL);
- ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
- refcount = IDXGISwapChain_Release(swapchain);
- ok(!refcount, "IDXGISwapChain has %u references left.\n", refcount);
- DestroyWindow(swapchain_desc.OutputWindow);
- swapchain_desc.OutputWindow = CreateWindowA("static", "dxgi_test", 0, 0, 0, 400, 200, 0, 0, 0, 0);
- check_window_fullscreen_state(swapchain_desc.OutputWindow, &initial_state.fullscreen_state);
- hr = IDXGIFactory_CreateSwapChain(factory, device, &swapchain_desc, &swapchain); ok(SUCCEEDED(hr), "CreateSwapChain failed, hr %#x.\n", hr); check_swapchain_fullscreen_state(swapchain, &initial_state); test_swapchain_fullscreen_state(swapchain, adapter, &initial_state);
Right, I'll look into those.
Thanks, Gabriel