@@ -144,6 +144,16 @@ CGUI_Impl::~CGUI_Impl()
144144 // DO NOT delete m_pRenderer - it's already deleted by System destructor
145145}
146146
147+ void CGUI_Impl::CreateRootWindow ()
148+ {
149+ if (!m_pWindowManager || !m_pSystem)
150+ return ;
151+
152+ // Create dummy GUI root
153+ m_pTop = reinterpret_cast <CEGUI::DefaultWindow*>(m_pWindowManager->createWindow (" DefaultWindow" , " guiroot" ));
154+ m_pSystem->setGUISheet (m_pTop);
155+ }
156+
147157void CGUI_Impl::SetSkin (const char * szName)
148158{
149159 if (m_HasSchemeLoaded)
@@ -162,12 +172,8 @@ void CGUI_Impl::SetSkin(const char* szName)
162172
163173 CEGUI::System::getSingleton ().setDefaultMouseCursor (" CGUI-Images" , " MouseArrow" );
164174
165- // Destroy any windows we already have
166- CEGUI::WindowManager::getSingleton ().destroyAllWindows ();
167-
168- // Create dummy GUI root
169- m_pTop = reinterpret_cast <CEGUI::DefaultWindow*>(m_pWindowManager->createWindow (" DefaultWindow" , " guiroot" ));
170- m_pSystem->setGUISheet (m_pTop);
175+ // Clean up CEGUI - this also re-creates the root window
176+ Cleanup ();
171177
172178 // Disable single click timeouts
173179 m_pSystem->setSingleClickTimeout (100000000 .0f );
@@ -327,28 +333,31 @@ bool CGUI_Impl::GetGUIInputEnabled()
327333 break ;
328334 case INPUTMODE_NO_BINDS_ON_EDIT:
329335 {
330- CEGUI::Window* pActiveWindow = m_pTop->getActiveChild ();
331- if (!pActiveWindow || pActiveWindow == m_pTop || !pActiveWindow->isVisible ())
332- {
333- return false ;
334- }
335- if (pActiveWindow->getType () == " CGUI/Editbox" )
336- {
337- CEGUI::Editbox* pEditBox = reinterpret_cast <CEGUI::Editbox*>(pActiveWindow);
338- return (!pEditBox->isReadOnly () && pEditBox->hasInputFocus ());
339- }
340- else if (pActiveWindow->getType () == " CGUI/MultiLineEditbox" )
341- {
342- CEGUI::MultiLineEditbox* pMultiLineEditBox = reinterpret_cast <CEGUI::MultiLineEditbox*>(pActiveWindow);
343- return (!pMultiLineEditBox->isReadOnly () && pMultiLineEditBox->hasInputFocus ());
344- }
345- else if (pActiveWindow->getType () == CGUIWEBBROWSER_NAME)
336+ if (m_pTop)
346337 {
347- auto pElement = reinterpret_cast <CGUIElement_Impl*>(pActiveWindow->getUserData ());
348- if (pElement->GetType () == CGUI_WEBBROWSER)
338+ CEGUI::Window* pActiveWindow = m_pTop->getActiveChild ();
339+ if (!pActiveWindow || pActiveWindow == m_pTop || !pActiveWindow->isVisible ())
340+ {
341+ return false ;
342+ }
343+ if (pActiveWindow->getType () == " CGUI/Editbox" )
344+ {
345+ CEGUI::Editbox* pEditBox = reinterpret_cast <CEGUI::Editbox*>(pActiveWindow);
346+ return (!pEditBox->isReadOnly () && pEditBox->hasInputFocus ());
347+ }
348+ else if (pActiveWindow->getType () == " CGUI/MultiLineEditbox" )
349+ {
350+ CEGUI::MultiLineEditbox* pMultiLineEditBox = reinterpret_cast <CEGUI::MultiLineEditbox*>(pActiveWindow);
351+ return (!pMultiLineEditBox->isReadOnly () && pMultiLineEditBox->hasInputFocus ());
352+ }
353+ else if (pActiveWindow->getType () == CGUIWEBBROWSER_NAME)
349354 {
350- auto pWebBrowser = reinterpret_cast <CGUIWebBrowser_Impl*>(pElement);
351- return pWebBrowser->HasInputFocus ();
355+ auto pElement = reinterpret_cast <CGUIElement_Impl*>(pActiveWindow->getUserData ());
356+ if (pElement->GetType () == CGUI_WEBBROWSER)
357+ {
358+ auto pWebBrowser = reinterpret_cast <CGUIWebBrowser_Impl*>(pElement);
359+ return pWebBrowser->HasInputFocus ();
360+ }
352361 }
353362 }
354363 return false ;
@@ -580,6 +589,9 @@ eCursorType CGUI_Impl::GetCursorType()
580589
581590void CGUI_Impl::AddChild (CGUIElement_Impl* pChild)
582591{
592+ if (!m_pTop)
593+ return ;
594+
583595 m_pTop->addChildWindow (pChild->GetWindow ());
584596}
585597
@@ -1153,12 +1165,15 @@ bool CGUI_Impl::Event_MouseButtonDown(const CEGUI::EventArgs& Args)
11531165 pElement->Event_OnMouseButtonDown ();
11541166 else
11551167 {
1156- // If there's no element, we're probably dealing with the root element
1157- CEGUI::Window* pActiveWindow = m_pTop->getActiveChild ();
1158- if (m_pTop == wnd && pActiveWindow)
1168+ if (m_pTop)
11591169 {
1160- // Deactivate active window to trigger onClientGUIBlur
1161- pActiveWindow->deactivate ();
1170+ // If there's no element, we're probably dealing with the root element
1171+ CEGUI::Window* pActiveWindow = m_pTop->getActiveChild ();
1172+ if (m_pTop == wnd && pActiveWindow)
1173+ {
1174+ // Deactivate active window to trigger onClientGUIBlur
1175+ pActiveWindow->deactivate ();
1176+ }
11621177 }
11631178 }
11641179
@@ -1797,3 +1812,33 @@ CEGUI::Window* CGUI_Impl::GetMasterWindow(CEGUI::Window* wnd)
17971812 }
17981813 return wnd;
17991814}
1815+
1816+ void CGUI_Impl::Cleanup ()
1817+ {
1818+ try
1819+ {
1820+ CleanDeadPool ();
1821+
1822+ m_pTop = nullptr ;
1823+
1824+ if (m_pWindowManager)
1825+ m_pWindowManager->destroyAllWindows ();
1826+
1827+ // Clear redraw structures that may reference old elements
1828+ m_RedrawQueue.clear ();
1829+ m_RedrawRegistry.clear ();
1830+
1831+ // Recreate the root window (destroyed above via destroyAllWindows)
1832+ CreateRootWindow ();
1833+ }
1834+ catch (const std::exception& e)
1835+ {
1836+ WriteDebugEvent (SString (" CGUI_Impl::Cleanup - Exception: %s" , e.what ()));
1837+ m_pTop = nullptr ;
1838+ }
1839+ catch (...)
1840+ {
1841+ WriteDebugEvent (" CGUI_Impl::Cleanup() failed with unknown exception" );
1842+ m_pTop = nullptr ;
1843+ }
1844+ }
0 commit comments