Fix destruction order of native windows to avoid crashing

We've to send kCloseMessage first, and then destroy the native
window (so children native window are destroyed correctly when
kCloseMessage is received, e.g. ComboBox popup must destroy its native
window when it receives a kCloseMessage of the parent window).
This commit is contained in:
David Capello 2021-04-23 15:35:27 -03:00
parent 69c1bb1d99
commit 588a6dc63c

View File

@ -1384,38 +1384,6 @@ void Manager::_openWindow(Window* window, bool center)
void Manager::_closeWindow(Window* window, bool redraw_background)
{
Display* windowDisplay = window->display();
Display* parentDisplay;
if (// The display can be nullptr if the window was not opened or
// was closed before.
window->ownDisplay()) {
parentDisplay = windowDisplay->parentDisplay();
ASSERT(parentDisplay);
ASSERT(windowDisplay);
ASSERT(windowDisplay != this->display());
// Remove all messages for this display.
removeMessagesForDisplay(windowDisplay);
window->setDisplay(nullptr, false);
windowDisplay->nativeWindow()->setUserData<void*>(nullptr);
// Remove the mouse cursor from the display that we are going to
// delete.
_internal_set_mouse_display(parentDisplay);
// The ui::Display should destroy the os::Window
delete windowDisplay;
// Activate main windows
parentDisplay->nativeWindow()->activate();
}
else {
parentDisplay = windowDisplay;
window->setDisplay(nullptr, false);
}
if (!hasChild(window))
return;
@ -1460,6 +1428,38 @@ void Manager::_closeWindow(Window* window, bool redraw_background)
window->sendMessage(msg.get());
}
// Destroy native window associated with this window's display if needed
Display* windowDisplay = window->display();
Display* parentDisplay;
if (// The display can be nullptr if the window was not opened or
// was closed before.
window->ownDisplay()) {
parentDisplay = windowDisplay->parentDisplay();
ASSERT(parentDisplay);
ASSERT(windowDisplay);
ASSERT(windowDisplay != this->display());
// Remove all messages for this display.
removeMessagesForDisplay(windowDisplay);
// Remove the mouse cursor from the display that we are going to
// delete.
_internal_set_mouse_display(parentDisplay);
window->setDisplay(nullptr, false);
windowDisplay->nativeWindow()->setUserData<void*>(nullptr);
// The ui::Display should destroy the os::Window
delete windowDisplay;
// Activate main windows
parentDisplay->nativeWindow()->activate();
}
else {
parentDisplay = windowDisplay;
window->setDisplay(nullptr, false);
}
// Update manager list stuff.
removeChild(window);