diff --git a/Core/GameEngine/Include/GameClient/GameWindowManager.h b/Core/GameEngine/Include/GameClient/GameWindowManager.h index e976c6f5735..39602701f1f 100644 --- a/Core/GameEngine/Include/GameClient/GameWindowManager.h +++ b/Core/GameEngine/Include/GameClient/GameWindowManager.h @@ -278,8 +278,7 @@ friend class GameWindow; virtual GameWindow *winGetCapture(); ///< current mouse capture settings virtual Int winSetModal( GameWindow *window ); ///< put at top of modal stack - virtual Int winUnsetModal( GameWindow *window ); /**< take window off modal stack, if window is - not at top of stack and error will occur */ + virtual Int winUnsetModal( GameWindow *window ); ///< take window off the modal stack from anywhere in the stack //--------------------------------------------------------------------------- ///////////////////////////////////////////////////////////////////////////// diff --git a/Core/GameEngine/Source/GameClient/GUI/GameWindowManager.cpp b/Core/GameEngine/Source/GameClient/GUI/GameWindowManager.cpp index 773c22dd94e..8af89b43ec3 100644 --- a/Core/GameEngine/Source/GameClient/GUI/GameWindowManager.cpp +++ b/Core/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; @@ -1422,8 +1419,8 @@ Int GameWindowManager::winDestroy( GameWindow *window ) if( m_keyboardFocus == window ) winSetFocus( nullptr ); - if( (m_modalHead != nullptr) && (window == m_modalHead->window) ) - winUnsetModal( m_modalHead->window ); + // TheSuperHackers @bugfix arcticdolphin 07/09/2026 Also remove it if it is buried in the modal stack. + winUnsetModal( window ); if( m_currMouseRgn == window ) m_currMouseRgn = nullptr; @@ -1525,33 +1522,41 @@ Int GameWindowManager::winSetModal( GameWindow *window ) } //------------------------------------------------------------------------------------------------- -/** pops window off of the modal stack. If this window is not the top - * of the modal stack an error will occur. */ +/** takes the window off the modal stack from anywhere in the stack */ //------------------------------------------------------------------------------------------------- Int GameWindowManager::winUnsetModal( GameWindow *window ) { - ModalWindow *next; - if( window == nullptr ) return WIN_ERR_INVALID_WINDOW; - // verify entry is at top of list - if( (m_modalHead == nullptr) || (m_modalHead->window != window) ) + // TheSuperHackers @bugfix arcticdolphin 07/09/2026 Remove it from anywhere in the stack, not just the top. + ModalWindow *previous = nullptr; + ModalWindow *modal = m_modalHead; + Bool found = FALSE; + + while( modal != nullptr ) { + ModalWindow *next = modal->next; - // return error if not - DEBUG_LOG(( "WinUnsetModal: Invalid window attempting to unset modal (%d)", - window->winGetWindowId() )); - return WIN_ERR_GENERAL_FAILURE; + if( modal->window == window ) + { + if( previous != nullptr ) + previous->next = next; + else + m_modalHead = next; - } + deleteInstance(modal); + found = TRUE; + } + else + { + previous = modal; + } - // remove from top of list - next = m_modalHead->next; - deleteInstance(m_modalHead); - m_modalHead = next; + modal = next; + } - return WIN_ERR_OK; + return found ? WIN_ERR_OK : WIN_ERR_GENERAL_FAILURE; }