diff --git a/engine/platform/sdl2/vid_sdl2.c b/engine/platform/sdl2/vid_sdl2.c index fc425f38..3b025d6e 100644 --- a/engine/platform/sdl2/vid_sdl2.c +++ b/engine/platform/sdl2/vid_sdl2.c @@ -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; }