Destroy window before showing popup if graphics initialized

Work around SDL bug that prevents message popup from being closed.
This commit is contained in:
Robert Müller 2023-05-07 19:23:03 +02:00
parent 817d96a73d
commit c841c7ad05
6 changed files with 36 additions and 13 deletions

View file

@ -161,7 +161,7 @@ void CGraphicsBackend_Threaded::ProcessError()
else else
VerboseStr.append(ErrStr.m_Err + "\n"); VerboseStr.append(ErrStr.m_Err + "\n");
} }
const auto CreatedMsgBox = TryCreateMsgBox(true, "Graphics Assertion", VerboseStr.c_str()); const bool CreatedMsgBox = ShowMessageBox(SDL_MESSAGEBOX_ERROR, "Graphics Assertion", VerboseStr.c_str());
// check if error msg can be shown, then assert // check if error msg can be shown, then assert
dbg_assert(!CreatedMsgBox, VerboseStr.c_str()); dbg_assert(!CreatedMsgBox, VerboseStr.c_str());
} }
@ -774,12 +774,19 @@ void CGraphicsBackend_SDL_GL::ClampDriverVersion(EBackendType BackendType)
} }
} }
bool CGraphicsBackend_SDL_GL::TryCreateMsgBox(bool AsError, const char *pTitle, const char *pMsg) bool CGraphicsBackend_SDL_GL::ShowMessageBox(unsigned Type, const char *pTitle, const char *pMsg)
{ {
m_pProcessor->ErroneousCleanup(); if(m_pProcessor != nullptr)
SDL_DestroyWindow(m_pWindow); m_pProcessor->ErroneousCleanup();
SDL_ShowSimpleMessageBox(AsError ? SDL_MESSAGEBOX_ERROR : SDL_MESSAGEBOX_WARNING, pTitle, pMsg, nullptr); // TODO: Remove this workaround when https://github.com/libsdl-org/SDL/issues/3750 is
return true; // fixed and pass the window to SDL_ShowSimpleMessageBox to make the popup modal instead
// of destroying the window before opening the popup.
if(m_pWindow != nullptr)
{
SDL_DestroyWindow(m_pWindow);
m_pWindow = nullptr;
}
return SDL_ShowSimpleMessageBox(Type, pTitle, pMsg, nullptr) == 0;
} }
bool CGraphicsBackend_SDL_GL::IsModernAPI(EBackendType BackendType) bool CGraphicsBackend_SDL_GL::IsModernAPI(EBackendType BackendType)
@ -1203,6 +1210,7 @@ int CGraphicsBackend_SDL_GL::Init(const char *pName, int *pScreen, int *pWidth,
if(m_GLContext == NULL) if(m_GLContext == NULL)
{ {
SDL_DestroyWindow(m_pWindow); SDL_DestroyWindow(m_pWindow);
m_pWindow = nullptr;
dbg_msg("gfx", "unable to create graphic context: %s", SDL_GetError()); dbg_msg("gfx", "unable to create graphic context: %s", SDL_GetError());
return EGraphicsBackendErrorCodes::GRAPHICS_BACKEND_ERROR_CODE_GL_CONTEXT_FAILED; return EGraphicsBackendErrorCodes::GRAPHICS_BACKEND_ERROR_CODE_GL_CONTEXT_FAILED;
} }
@ -1211,6 +1219,7 @@ int CGraphicsBackend_SDL_GL::Init(const char *pName, int *pScreen, int *pWidth,
{ {
SDL_GL_DeleteContext(m_GLContext); SDL_GL_DeleteContext(m_GLContext);
SDL_DestroyWindow(m_pWindow); SDL_DestroyWindow(m_pWindow);
m_pWindow = nullptr;
return EGraphicsBackendErrorCodes::GRAPHICS_BACKEND_ERROR_CODE_UNKNOWN; return EGraphicsBackendErrorCodes::GRAPHICS_BACKEND_ERROR_CODE_UNKNOWN;
} }
} }
@ -1237,6 +1246,7 @@ int CGraphicsBackend_SDL_GL::Init(const char *pName, int *pScreen, int *pWidth,
if(m_GLContext) if(m_GLContext)
SDL_GL_DeleteContext(m_GLContext); SDL_GL_DeleteContext(m_GLContext);
SDL_DestroyWindow(m_pWindow); SDL_DestroyWindow(m_pWindow);
m_pWindow = nullptr;
// try setting to glew supported version // try setting to glew supported version
g_Config.m_GfxGLMajor = GlewMajor; g_Config.m_GfxGLMajor = GlewMajor;
@ -1339,6 +1349,7 @@ int CGraphicsBackend_SDL_GL::Init(const char *pName, int *pScreen, int *pWidth,
if(m_GLContext) if(m_GLContext)
SDL_GL_DeleteContext(m_GLContext); SDL_GL_DeleteContext(m_GLContext);
SDL_DestroyWindow(m_pWindow); SDL_DestroyWindow(m_pWindow);
m_pWindow = nullptr;
// try setting to version string's supported version // try setting to version string's supported version
if(InitError == -2) if(InitError == -2)
@ -1403,6 +1414,7 @@ int CGraphicsBackend_SDL_GL::Shutdown()
if(m_GLContext != nullptr) if(m_GLContext != nullptr)
SDL_GL_DeleteContext(m_GLContext); SDL_GL_DeleteContext(m_GLContext);
SDL_DestroyWindow(m_pWindow); SDL_DestroyWindow(m_pWindow);
m_pWindow = nullptr;
SDL_QuitSubSystem(SDL_INIT_VIDEO); SDL_QuitSubSystem(SDL_INIT_VIDEO);
return 0; return 0;

View file

@ -92,9 +92,6 @@ protected:
return m_Warning.m_WarningType != GFX_WARNING_TYPE_NONE; return m_Warning.m_WarningType != GFX_WARNING_TYPE_NONE;
} }
// returns true if the error msg was shown
virtual bool TryCreateMsgBox(bool AsError, const char *pTitle, const char *pMsg) = 0;
private: private:
ICommandProcessor *m_pProcessor; ICommandProcessor *m_pProcessor;
std::mutex m_BufferSwapMutex; std::mutex m_BufferSwapMutex;
@ -243,9 +240,6 @@ class CGraphicsBackend_SDL_GL : public CGraphicsBackend_Threaded
static EBackendType DetectBackend(); static EBackendType DetectBackend();
static void ClampDriverVersion(EBackendType BackendType); static void ClampDriverVersion(EBackendType BackendType);
protected:
bool TryCreateMsgBox(bool AsError, const char *pTitle, const char *pMsg) override;
public: public:
CGraphicsBackend_SDL_GL(TTranslateFunc &&TranslateFunc); CGraphicsBackend_SDL_GL(TTranslateFunc &&TranslateFunc);
int Init(const char *pName, int *pScreen, int *pWidth, int *pHeight, int *pRefreshRate, int *pFsaaSamples, int Flags, int *pDesktopWidth, int *pDesktopHeight, int *pCurrentWidth, int *pCurrentHeight, class IStorage *pStorage) override; int Init(const char *pName, int *pScreen, int *pWidth, int *pHeight, int *pRefreshRate, int *pFsaaSamples, int Flags, int *pDesktopWidth, int *pDesktopHeight, int *pCurrentWidth, int *pCurrentHeight, class IStorage *pStorage) override;
@ -313,6 +307,8 @@ public:
TGLBackendReadPresentedImageData &GetReadPresentedImageDataFuncUnsafe() override; TGLBackendReadPresentedImageData &GetReadPresentedImageDataFuncUnsafe() override;
bool ShowMessageBox(unsigned Type, const char *pTitle, const char *pMsg) override;
static bool IsModernAPI(EBackendType BackendType); static bool IsModernAPI(EBackendType BackendType);
}; };

View file

@ -5005,5 +5005,6 @@ static Uint32 GetSdlMessageBoxFlags(IClient::EMessageBoxType Type)
void CClient::ShowMessageBox(const char *pTitle, const char *pMessage, EMessageBoxType Type) void CClient::ShowMessageBox(const char *pTitle, const char *pMessage, EMessageBoxType Type)
{ {
SDL_ShowSimpleMessageBox(GetSdlMessageBoxFlags(Type), pTitle, pMessage, nullptr); if(m_pGraphics == nullptr || !m_pGraphics->ShowMessageBox(GetSdlMessageBoxFlags(Type), pTitle, pMessage))
SDL_ShowSimpleMessageBox(GetSdlMessageBoxFlags(Type), pTitle, pMessage, nullptr);
} }

View file

@ -3279,6 +3279,13 @@ SWarning *CGraphics_Threaded::GetCurWarning()
} }
} }
bool CGraphics_Threaded::ShowMessageBox(unsigned Type, const char *pTitle, const char *pMsg)
{
if(m_pBackend == nullptr)
return false;
return m_pBackend->ShowMessageBox(Type, pTitle, pMsg);
}
const char *CGraphics_Threaded::GetVendorString() const char *CGraphics_Threaded::GetVendorString()
{ {
return m_pBackend->GetVendorString(); return m_pBackend->GetVendorString();

View file

@ -773,6 +773,9 @@ public:
virtual TGLBackendReadPresentedImageData &GetReadPresentedImageDataFuncUnsafe() = 0; virtual TGLBackendReadPresentedImageData &GetReadPresentedImageDataFuncUnsafe() = 0;
virtual bool GetWarning(std::vector<std::string> &WarningStrings) = 0; virtual bool GetWarning(std::vector<std::string> &WarningStrings) = 0;
// returns true if the error msg was shown
virtual bool ShowMessageBox(unsigned Type, const char *pTitle, const char *pMsg) = 0;
}; };
class CGraphics_Threaded : public IEngineGraphics class CGraphics_Threaded : public IEngineGraphics
@ -1296,6 +1299,7 @@ public:
void WaitForIdle() override; void WaitForIdle() override;
SWarning *GetCurWarning() override; SWarning *GetCurWarning() override;
bool ShowMessageBox(unsigned Type, const char *pTitle, const char *pMsg) override;
bool GetDriverVersion(EGraphicsDriverAgeType DriverAgeType, int &Major, int &Minor, int &Patch, const char *&pName, EBackendType BackendType) override { return m_pBackend->GetDriverVersion(DriverAgeType, Major, Minor, Patch, pName, BackendType); } bool GetDriverVersion(EGraphicsDriverAgeType DriverAgeType, int &Major, int &Minor, int &Patch, const char *&pName, EBackendType BackendType) override { return m_pBackend->GetDriverVersion(DriverAgeType, Major, Minor, Patch, pName, BackendType); }
bool IsConfigModernAPI() override { return m_pBackend->IsConfigModernAPI(); } bool IsConfigModernAPI() override { return m_pBackend->IsConfigModernAPI(); }

View file

@ -521,6 +521,9 @@ public:
virtual SWarning *GetCurWarning() = 0; virtual SWarning *GetCurWarning() = 0;
// returns true if the error msg was shown
virtual bool ShowMessageBox(unsigned Type, const char *pTitle, const char *pMsg) = 0;
protected: protected:
inline CTextureHandle CreateTextureHandle(int Index) inline CTextureHandle CreateTextureHandle(int Index)
{ {