From f826c35c2933b99474124a4dbc820dcee5e90c1f Mon Sep 17 00:00:00 2001 From: tintinhamans <5984296+tintinhamans@users.noreply.github.com> Date: Thu, 27 Aug 2026 01:04:59 +0200 Subject: [PATCH] bugfix(gui): Remove destroyed windows from the modal stack --- .../Include/GameClient/GameWindowManager.h | 1 + .../GameClient/GUI/GameWindowManager.cpp | 26 ++++++++++++---- .../Include/GameClient/GameWindowManager.h | 1 + .../GameClient/GUI/GameWindowManager.cpp | 30 +++++++++++++++---- 4 files changed, 47 insertions(+), 11 deletions(-) diff --git a/Generals/Code/GameEngine/Include/GameClient/GameWindowManager.h b/Generals/Code/GameEngine/Include/GameClient/GameWindowManager.h index 5d3fde1e35c..4ce12aa8964 100644 --- a/Generals/Code/GameEngine/Include/GameClient/GameWindowManager.h +++ b/Generals/Code/GameEngine/Include/GameClient/GameWindowManager.h @@ -331,6 +331,7 @@ friend class GameWindow; protected: void processDestroyList(); ///< process windows waiting to be killed + void removeWindowFromModalStack( GameWindow *window ); Int drawWindow( GameWindow *window ); ///< draw this window diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/GameWindowManager.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/GameWindowManager.cpp index 679efce32e4..9fbf531b166 100644 --- a/Generals/Code/GameEngine/Source/GameClient/GUI/GameWindowManager.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/GUI/GameWindowManager.cpp @@ -103,9 +103,6 @@ void GameWindowManager::processDestroyList() if( m_keyboardFocus == doDestroy ) winSetFocus( nullptr ); - if( (m_modalHead != nullptr) && (doDestroy == m_modalHead->window) ) - winUnsetModal( m_modalHead->window ); - if( m_currMouseRgn == doDestroy ) m_currMouseRgn = nullptr; @@ -1519,8 +1516,7 @@ Int GameWindowManager::winDestroy( GameWindow *window ) if( m_keyboardFocus == window ) winSetFocus( nullptr ); - if( (m_modalHead != nullptr) && (window == m_modalHead->window) ) - winUnsetModal( m_modalHead->window ); + removeWindowFromModalStack( window ); if( m_currMouseRgn == window ) m_currMouseRgn = nullptr; @@ -1652,6 +1648,26 @@ Int GameWindowManager::winUnsetModal( GameWindow *window ) } +// TheSuperHackers @bugfix arcticdolphin 27/08/2026 Remove destroyed windows from the entire modal stack. +void GameWindowManager::removeWindowFromModalStack( GameWindow *window ) +{ + ModalWindow **link = &m_modalHead; + + while( *link ) + { + ModalWindow *modal = *link; + + if( modal->window != window ) + { + link = &modal->next; + continue; + } + + *link = modal->next; + deleteInstance(modal); + } +} + //------------------------------------------------------------------------------------------------- /** Get the grabbed window */ //------------------------------------------------------------------------------------------------- diff --git a/GeneralsMD/Code/GameEngine/Include/GameClient/GameWindowManager.h b/GeneralsMD/Code/GameEngine/Include/GameClient/GameWindowManager.h index 1dffbd5c6ed..8d0bfb6686d 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameClient/GameWindowManager.h +++ b/GeneralsMD/Code/GameEngine/Include/GameClient/GameWindowManager.h @@ -335,6 +335,7 @@ class GameWindowManager : public SubsystemInterface protected: void processDestroyList(); ///< process windows waiting to be killed + void removeWindowFromModalStack( GameWindow *window ); Int drawWindow(GameWindow* window); ///< draw this window diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GameWindowManager.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GameWindowManager.cpp index e59f6bab748..a80e368fc86 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GameWindowManager.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GameWindowManager.cpp @@ -103,11 +103,10 @@ void GameWindowManager::processDestroyList() if (m_keyboardFocus == doDestroy) winSetFocus(NULL); - if ((m_modalHead != NULL) && (doDestroy == m_modalHead->window)) - winUnsetModal(m_modalHead->window); + removeWindowFromModalStack(doDestroy); - if (m_currMouseRgn == doDestroy) - m_currMouseRgn = NULL; + if( m_currMouseRgn == doDestroy ) + m_currMouseRgn = nullptr; if (m_grabWindow == doDestroy) m_grabWindow = NULL; @@ -1423,8 +1422,7 @@ Int GameWindowManager::winDestroy(GameWindow* window) if (m_keyboardFocus == window) winSetFocus(NULL); - if ((m_modalHead != NULL) && (window == m_modalHead->window)) - winUnsetModal(m_modalHead->window); + removeWindowFromModalStack( window ); if (m_currMouseRgn == window) m_currMouseRgn = NULL; @@ -1556,6 +1554,26 @@ Int GameWindowManager::winUnsetModal(GameWindow* window) } +// TheSuperHackers @bugfix arcticdolphin 27/08/2026 Remove destroyed windows from the entire modal stack. +void GameWindowManager::removeWindowFromModalStack( GameWindow *window ) +{ + ModalWindow **link = &m_modalHead; + + while( *link ) + { + ModalWindow *modal = *link; + + if( modal->window != window ) + { + link = &modal->next; + continue; + } + + *link = modal->next; + deleteInstance(modal); + } +} + //------------------------------------------------------------------------------------------------- /** Get the grabbed window */ //-------------------------------------------------------------------------------------------------