Make fullscreen changes better (especially under windows)

This commit is contained in:
Jupeyy 2021-08-24 18:22:31 +02:00
parent 00ff285784
commit 7234c04c15
3 changed files with 67 additions and 46 deletions

View file

@ -1168,8 +1168,16 @@ void CGraphicsBackend_SDL_OpenGL::SetWindowGrab(bool Grab)
void CGraphicsBackend_SDL_OpenGL::ResizeWindow(int w, int h, int RefreshRate) void CGraphicsBackend_SDL_OpenGL::ResizeWindow(int w, int h, int RefreshRate)
{ {
// don't call resize events when the window is at fullscreen desktop
if((SDL_GetWindowFlags(m_pWindow) & SDL_WINDOW_FULLSCREEN_DESKTOP) != SDL_WINDOW_FULLSCREEN_DESKTOP)
{
// if the window is at fullscreen use SDL_SetWindowDisplayMode instead, suggested by SDL
if(SDL_GetWindowFlags(m_pWindow) & SDL_WINDOW_FULLSCREEN) if(SDL_GetWindowFlags(m_pWindow) & SDL_WINDOW_FULLSCREEN)
{ {
#ifdef CONF_PLATFORM_WINDOWS
// in windows make the window windowed mode first, this prevents strange window glitches (other games probably do something similar)
SetWindowParams(0, 1);
#endif
SDL_DisplayMode SetMode = {}; SDL_DisplayMode SetMode = {};
SDL_DisplayMode ClosestMode = {}; SDL_DisplayMode ClosestMode = {};
SetMode.format = 0; SetMode.format = 0;
@ -1177,6 +1185,11 @@ void CGraphicsBackend_SDL_OpenGL::ResizeWindow(int w, int h, int RefreshRate)
SetMode.h = h; SetMode.h = h;
SetMode.refresh_rate = RefreshRate; SetMode.refresh_rate = RefreshRate;
SDL_SetWindowDisplayMode(m_pWindow, SDL_GetClosestDisplayMode(g_Config.m_GfxScreen, &SetMode, &ClosestMode)); SDL_SetWindowDisplayMode(m_pWindow, SDL_GetClosestDisplayMode(g_Config.m_GfxScreen, &SetMode, &ClosestMode));
#ifdef CONF_PLATFORM_WINDOWS
// now change it back to fullscreen, this will restore the above set state, bcs SDL saves fullscreen modes appart from other video modes (as of SDL 2.0.16)
// see implementation of SDL_SetWindowDisplayMode
SetWindowParams(1, 0);
#endif
} }
else else
{ {
@ -1186,6 +1199,7 @@ void CGraphicsBackend_SDL_OpenGL::ResizeWindow(int w, int h, int RefreshRate)
SDL_RestoreWindow(m_pWindow); SDL_RestoreWindow(m_pWindow);
} }
} }
}
void CGraphicsBackend_SDL_OpenGL::GetViewportSize(int &w, int &h) void CGraphicsBackend_SDL_OpenGL::GetViewportSize(int &w, int &h)
{ {

View file

@ -2329,9 +2329,14 @@ void CGraphics_Threaded::Resize(int w, int h, int RefreshRate, bool SetWindowSiz
if(!ForceResizeEvent && WindowWidth() == w && WindowHeight() == h && (RefreshRate != -1 && RefreshRate == m_ScreenRefreshRate)) if(!ForceResizeEvent && WindowWidth() == w && WindowHeight() == h && (RefreshRate != -1 && RefreshRate == m_ScreenRefreshRate))
return; return;
// if the size is changed manually, only set the window resize, a window size changed event is triggered anyway
if(SetWindowSize) if(SetWindowSize)
{
m_pBackend->ResizeWindow(w, h, RefreshRate); m_pBackend->ResizeWindow(w, h, RefreshRate);
}
else
{
// if the size change event is triggered, set all parameters and change the viewport
m_pBackend->GetViewportSize(m_ScreenWidth, m_ScreenHeight); m_pBackend->GetViewportSize(m_ScreenWidth, m_ScreenHeight);
// adjust the viewport to only allow certain aspect ratios // adjust the viewport to only allow certain aspect ratios
@ -2365,6 +2370,7 @@ void CGraphics_Threaded::Resize(int w, int h, int RefreshRate, bool SetWindowSiz
for(auto &ResizeListener : m_ResizeListeners) for(auto &ResizeListener : m_ResizeListeners)
ResizeListener.m_pFunc(ResizeListener.m_pUser); ResizeListener.m_pFunc(ResizeListener.m_pUser);
} }
}
void CGraphics_Threaded::AddWindowResizeListener(WINDOW_RESIZE_FUNC pFunc, void *pUser) void CGraphics_Threaded::AddWindowResizeListener(WINDOW_RESIZE_FUNC pFunc, void *pUser)
{ {

View file

@ -344,7 +344,8 @@ int CInput::Update()
// shortcuts // shortcuts
switch(Event.window.event) switch(Event.window.event)
{ {
case SDL_WINDOWEVENT_RESIZED: // listen to size changes, this includes our manual changes and the ones by the window manager
case SDL_WINDOWEVENT_SIZE_CHANGED:
Graphics()->Resize(Event.window.data1, Event.window.data2, -1); Graphics()->Resize(Event.window.data1, Event.window.data2, -1);
break; break;
case SDL_WINDOWEVENT_FOCUS_GAINED: case SDL_WINDOWEVENT_FOCUS_GAINED: