diff --git a/src/frontend/qt_sdl/EmuInstance.cpp b/src/frontend/qt_sdl/EmuInstance.cpp index d619fd3e..13e026d6 100755 --- a/src/frontend/qt_sdl/EmuInstance.cpp +++ b/src/frontend/qt_sdl/EmuInstance.cpp @@ -204,7 +204,7 @@ void EmuInstance::createWindow(int id) if (windowList[id]) return; - MainWindow* win = new MainWindow(id, this, topWindow); + MainWindow* win = new MainWindow(id, this, mainWindow ? mainWindow : topWindow); if (!topWindow) topWindow = win; if (!mainWindow) mainWindow = win; windowList[id] = win; diff --git a/src/frontend/qt_sdl/Window.cpp b/src/frontend/qt_sdl/Window.cpp index 3ba8af1d..965dddcf 100755 --- a/src/frontend/qt_sdl/Window.cpp +++ b/src/frontend/qt_sdl/Window.cpp @@ -809,18 +809,6 @@ MainWindow::MainWindow(int id, EmuInstance* inst, QWidget* parent) : MainWindow::~MainWindow() { - if (windowID == 0) - emuInstance->saveEnabledWindows(); - else - saveEnabled(false); - - QByteArray geom = saveGeometry(); - QByteArray enc = geom.toBase64(QByteArray::Base64Encoding); - windowCfg.SetString("Geometry", enc.toStdString()); - Config::Save(); - - emuInstance->deleteWindow(windowID, false); - if (hasMenu) { delete[] actScreenAspectTop; @@ -841,6 +829,36 @@ void MainWindow::saveEnabled(bool enabled) enabledSaved = true; } +void MainWindow::closeEvent(QCloseEvent* event) +{ + if (emuInstance) + { + if (windowID == 0) + emuInstance->saveEnabledWindows(); + else + saveEnabled(false); + } + + // explicitly close children windows, so the OpenGL contexts get closed properly + auto childwins = findChildren(nullptr, Qt::FindDirectChildrenOnly); + for (auto child : childwins) + child->close(); + + if (!emuInstance) return; + + QByteArray geom = saveGeometry(); + QByteArray enc = geom.toBase64(QByteArray::Base64Encoding); + windowCfg.SetString("Geometry", enc.toStdString()); + Config::Save(); + + emuInstance->deleteWindow(windowID, false); + + // emuInstance may be deleted + // prevent use after free from us + emuInstance = nullptr; + QMainWindow::closeEvent(event); +} + void MainWindow::createScreenPanel() { if (panel) delete panel; diff --git a/src/frontend/qt_sdl/Window.h b/src/frontend/qt_sdl/Window.h index 5d02b4ee..678be7c9 100755 --- a/src/frontend/qt_sdl/Window.h +++ b/src/frontend/qt_sdl/Window.h @@ -242,6 +242,8 @@ private slots: void onScreenEmphasisToggled(); private: + virtual void closeEvent(QCloseEvent* event) override; + QStringList currentROM; QStringList currentGBAROM; QList recentFileList;