engine: platform: sdl2: fix stupid bug when window of the size of display gets interpreted as fullscreen window

This commit is contained in:
Alibek Omarov
2025-12-14 02:12:44 +03:00
parent 4a16ca8bc0
commit e973c42bfa

View File

@@ -462,6 +462,46 @@ static int VID_GetDisplayIndex( const char *caller, const SDL_Point *pt )
return display_index;
}
static qboolean VID_GetDisplayBounds( int display_index, SDL_Window *hWnd, SDL_Rect *rect )
{
if( SDL_GetDisplayUsableBounds( display_index, rect ) == 0 )
{
wrect_t wrc = { 0 };
if( hWnd )
{
SDL_GetWindowBordersSize( hWnd, &wrc.top, &wrc.left, &wrc.bottom, &wrc.right );
}
else
{
#if XASH_WIN32
wrc.left = GetSystemMetrics( SM_CYSIZEFRAME );
wrc.right = wrc.bottom = wrc.left;
wrc.top = GetSystemMetrics( SM_CYSMCAPTION ) + wrc.left;
#endif // XASH_WIN32
}
rect->x += wrc.left + wrc.right;
rect->y += wrc.top + wrc.bottom;
rect->w -= ( wrc.left + wrc.right ) * 2;
rect->h -= ( wrc.top + wrc.bottom ) * 2;
return true;
}
else if( SDL_GetDisplayBounds( display_index, rect ) == 0 )
{
rect->x += 100;
rect->y += 100;
rect->w -= 100;
rect->h -= 100;
return true;
}
memset( rect, 0, sizeof( *rect ));
return false;
}
static qboolean VID_SetScreenResolution( int width, int height, window_mode_t window_mode, window_mode_t prev_window_mode )
{
int out_width, out_height;
@@ -506,8 +546,7 @@ static qboolean VID_SetScreenResolution( int width, int height, window_mode_t wi
}
case WINDOW_MODE_WINDOWED:
{
if( prev_window_mode != WINDOW_MODE_WINDOWED )
SDL_SetWindowPosition( host.hWnd, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED );
qboolean overriden = false;
if( SDL_SetWindowFullscreen( host.hWnd, 0 ) < 0 )
{
@@ -518,8 +557,32 @@ static qboolean VID_SetScreenResolution( int width, int height, window_mode_t wi
SDL_SetWindowResizable( host.hWnd, SDL_TRUE );
SDL_SetWindowBordered( host.hWnd, SDL_TRUE );
qboolean maximized = FBitSet( SDL_GetWindowFlags( host.hWnd ), SDL_WINDOW_MAXIMIZED ) != 0;
if( !maximized )
if( FBitSet( SDL_GetWindowFlags( host.hWnd ), SDL_WINDOW_MAXIMIZED ))
{
// no-op
overriden = true;
}
else if( prev_window_mode != WINDOW_MODE_WINDOWED )
{
int display_index = VID_GetDisplayIndex( __func__, NULL );
SDL_Rect bounds;
int xpos, ypos;
if( VID_GetDisplayBounds( display_index, host.hWnd, &bounds ))
{
if( width > bounds.w || height > bounds.h )
{
SDL_SetWindowPosition( host.hWnd, bounds.x, bounds.y );
SDL_SetWindowSize( host.hWnd, bounds.w, bounds.h );
overriden = true;
}
}
if( !overriden )
SDL_SetWindowPosition( host.hWnd, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED );
}
if( !overriden )
SDL_SetWindowSize( host.hWnd, width, height );
break;
@@ -683,9 +746,14 @@ qboolean VID_CreateWindow( int input_width, int input_height, window_mode_t wind
SetBits( flags, SDL_WINDOW_RESIZABLE );
if( vid_maximized.value != 0.0f )
{
SetBits( flags, SDL_WINDOW_MAXIMIZED );
if( !position_undefined )
}
else if( position_undefined )
{
VID_GetDisplayBounds( 0, NULL, &rect );
}
else
{
const int num_displays = SDL_GetNumVideoDisplays();
qboolean window_fits = false;
@@ -694,7 +762,7 @@ qboolean VID_CreateWindow( int input_width, int input_height, window_mode_t wind
{
SDL_Rect display_bounds;
if( SDL_GetDisplayBounds( i, &display_bounds ) == 0 )
if( VID_GetDisplayBounds( i, NULL, &display_bounds ))
{
Con_Reportf( "Display %d: %d %d %d %d\n", i, display_bounds.x, display_bounds.y, display_bounds.w, display_bounds.h );
}
@@ -715,7 +783,7 @@ qboolean VID_CreateWindow( int input_width, int input_height, window_mode_t wind
if( !window_fits )
{
Con_Printf( S_ERROR "Window { %d, %d, %d, %d } does not fit on any display\n", rect.x, rect.y, rect.w, rect.h );
rect.x = rect.y = SDL_WINDOWPOS_UNDEFINED;
VID_GetDisplayBounds( 0, NULL, &rect );
}
}
break;
@@ -799,6 +867,10 @@ qboolean VID_CreateWindow( int input_width, int input_height, window_mode_t wind
SDL_GetWindowSize( host.hWnd, &rect.w, &rect.h );
VID_SaveWindowSize( rect.w, rect.h );
SDL_GetWindowPosition( host.hWnd, &rect.x, &rect.y );
Cvar_DirectSetValue( &window_xpos, rect.x );
Cvar_DirectSetValue( &window_ypos, rect.y );
return true;
}