From 7a7571f88a9ea1180f6c7cd9a46da8ee458aee48 Mon Sep 17 00:00:00 2001 From: Stephen Saunders Date: Fri, 11 Nov 2022 21:51:31 -0500 Subject: [PATCH] Fix window resize/fullscreen handling and make consistent between DX12 and Vulkan (Windows & SDL) --- neo/sys/DeviceManager_DX12.cpp | 22 +++++++++++++--------- neo/sys/sdl/sdl_events.cpp | 7 +++++-- neo/sys/sdl/sdl_vkimp.cpp | 2 -- neo/sys/win32/win_glimp.cpp | 34 ++++++++++++++++++++++++++++++++-- neo/sys/win32/win_wndproc.cpp | 7 ++++--- 5 files changed, 54 insertions(+), 18 deletions(-) diff --git a/neo/sys/DeviceManager_DX12.cpp b/neo/sys/DeviceManager_DX12.cpp index 581a7c46..fa4166b3 100644 --- a/neo/sys/DeviceManager_DX12.cpp +++ b/neo/sys/DeviceManager_DX12.cpp @@ -204,15 +204,6 @@ void DeviceManager_DX12::ReportLiveObjects() bool DeviceManager_DX12::CreateDeviceAndSwapChain() { - UINT windowStyle = deviceParms.startFullscreen - ? ( WS_POPUP | WS_SYSMENU | WS_VISIBLE ) - : deviceParms.startMaximized - ? ( WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_MAXIMIZE ) - : ( WS_OVERLAPPEDWINDOW | WS_VISIBLE ); - - RECT rect = { 0, 0, LONG( deviceParms.backBufferWidth ), LONG( deviceParms.backBufferHeight ) }; - AdjustWindowRect( &rect, windowStyle, FALSE ); - RefCountPtr targetAdapter; if( deviceParms.adapter ) @@ -248,12 +239,25 @@ bool DeviceManager_DX12::CreateDeviceAndSwapChain() isNvidia = IsNvDeviceID( aDesc.VendorId ); } +/* + // SRS - Don't center window here for DX12 only, instead use portable initialization in CreateWindowDeviceAndSwapChain() within win_glimp.cpp + // - Also, calling SetWindowPos() triggers a window mgr event that overwrites r_windowX / r_windowY, which may be undesirable to the user + + UINT windowStyle = deviceParms.startFullscreen + ? ( WS_POPUP | WS_SYSMENU | WS_VISIBLE ) + : deviceParms.startMaximized + ? ( WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_MAXIMIZE ) + : ( WS_OVERLAPPEDWINDOW | WS_VISIBLE ); + + RECT rect = { 0, 0, LONG( deviceParms.backBufferWidth ), LONG( deviceParms.backBufferHeight ) }; + AdjustWindowRect( &rect, windowStyle, FALSE ); if( MoveWindowOntoAdapter( targetAdapter, rect ) ) { SetWindowPos( ( HWND )windowHandle, deviceParms.startFullscreen ? HWND_TOPMOST : HWND_NOTOPMOST, rect.left, rect.top, 0, 0, SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE ); } +*/ HRESULT hr = E_FAIL; RECT clientRect; diff --git a/neo/sys/sdl/sdl_events.cpp b/neo/sys/sdl/sdl_events.cpp index 1a35e307..5451c7dd 100644 --- a/neo/sys/sdl/sdl_events.cpp +++ b/neo/sys/sdl/sdl_events.cpp @@ -1062,7 +1062,7 @@ sysEvent_t Sys_GetEvent() case SDL_KEYDOWN: if( ev.key.keysym.sym == SDLK_RETURN && ( ev.key.keysym.mod & KMOD_ALT ) > 0 ) { - // DG: go to fullscreen on current display, instead of always first display + /* DG: go to fullscreen on current display, instead of always first display int fullscreen = 0; if( ! renderSystem->IsFullScreen() ) { @@ -1071,7 +1071,10 @@ sysEvent_t Sys_GetEvent() fullscreen = -2; } cvarSystem->SetCVarInteger( "r_fullscreen", fullscreen ); - // DG end + // DG end */ + // SRS - Until Borderless Fullscreen is implemented properly, use same implementation as on Windows + cvarSystem->SetCVarBool( "r_fullscreen", !renderSystem->IsFullScreen() ); + // SRS end PushConsoleEvent( "vid_restart" ); continue; // handle next event } diff --git a/neo/sys/sdl/sdl_vkimp.cpp b/neo/sys/sdl/sdl_vkimp.cpp index 76d1a981..f4c5c40a 100644 --- a/neo/sys/sdl/sdl_vkimp.cpp +++ b/neo/sys/sdl/sdl_vkimp.cpp @@ -135,8 +135,6 @@ bool DeviceManager::CreateWindowDeviceAndSwapChain( const glimpParms_t& parms, c return false; } - glConfig.isFullscreen = parms.fullScreen; - return true; } diff --git a/neo/sys/win32/win_glimp.cpp b/neo/sys/win32/win_glimp.cpp index 181fdb68..abde471c 100644 --- a/neo/sys/win32/win_glimp.cpp +++ b/neo/sys/win32/win_glimp.cpp @@ -1065,6 +1065,29 @@ static bool GLW_GetWindowDimensions( const glimpParms_t parms, int& x, int& y, i return true; } +static bool GetCenteredWindowDimensions( int& x, int& y, int& w, int& h ) +{ + // get position and size of default display for windowed mode (parms.fullScreen = 0) + int displayX, displayY, displayW, displayH, displayHz = 0; + if( !GetDisplayCoordinates( 0, displayX, displayY, displayW, displayH, displayHz ) ) + { + return false; + } + + // find the centered position not exceeding display bounds + const int centreX = displayX + displayW / 2; + const int centreY = displayY + displayH / 2; + const int left = centreX - w / 2; + const int right = left + w; + const int top = centreY - h / 2; + const int bottom = top + h; + x = std::max( left, displayX ); + y = std::max( top, displayY ); + w = std::min( right - left, displayW ); + h = std::min( bottom - top, displayH ); + + return true; +} bool DeviceManager::CreateWindowDeviceAndSwapChain( const glimpParms_t& parms, const char* windowTitle ) { @@ -1074,6 +1097,15 @@ bool DeviceManager::CreateWindowDeviceAndSwapChain( const glimpParms_t& parms, c return false; } + // SRS - if in windowed mode, start with centered windowed on default display, afterwards use r_windowX / r_windowY + if( parms.fullScreen == 0 ) + { + if( !GetCenteredWindowDimensions( x, y, w, h ) ) + { + return false; + } + } + int stylebits; int exstyle; @@ -1136,8 +1168,6 @@ bool DeviceManager::CreateWindowDeviceAndSwapChain( const glimpParms_t& parms, c SetForegroundWindow( win32.hWnd ); SetFocus( win32.hWnd ); - glConfig.isFullscreen = parms.fullScreen; - return true; } diff --git a/neo/sys/win32/win_wndproc.cpp b/neo/sys/win32/win_wndproc.cpp index 2bf10304..e24abb9a 100644 --- a/neo/sys/win32/win_wndproc.cpp +++ b/neo/sys/win32/win_wndproc.cpp @@ -179,7 +179,6 @@ LONG WINAPI MainWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) switch( uMsg ) { case WM_WINDOWPOSCHANGED: - // RB: FIXME this messes with with the window size in a really bad way // SRS - Needed by ResizeImages() to resize before the start of a frame // SRS - Aspect ratio constraints are controlled by WIN_Sizing() above if( renderSystem->IsInitialized() && win32.hDC != NULL ) @@ -193,8 +192,9 @@ LONG WINAPI MainWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) glConfig.nativeScreenHeight = rect.bottom - rect.top; // save the window size in cvars if we aren't fullscreen + // SRS - also check renderSystem state to make sure WM doesn't fool us when exiting fullscreen int style = GetWindowLong( hWnd, GWL_STYLE ); - if( ( style & WS_POPUP ) == 0 ) + if( ( style & WS_POPUP ) == 0 && !renderSystem->IsFullScreen() ) { r_windowWidth.SetInteger( glConfig.nativeScreenWidth ); r_windowHeight.SetInteger( glConfig.nativeScreenHeight ); @@ -212,8 +212,9 @@ LONG WINAPI MainWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) RECT r; // save the window origin in cvars if we aren't fullscreen + // SRS - also check renderSystem state to make sure WM doesn't fool us when exiting fullscreen int style = GetWindowLong( hWnd, GWL_STYLE ); - if( ( style & WS_POPUP ) == 0 ) + if( ( style & WS_POPUP ) == 0 && !renderSystem->IsFullScreen() ) { xPos = ( short ) LOWORD( lParam ); // horizontal position yPos = ( short ) HIWORD( lParam ); // vertical position