mirror of
https://github.com/aseprite/aseprite.git
synced 2025-02-20 18:40:57 +00:00
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:
parent
69c1bb1d99
commit
588a6dc63c
@ -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);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user