From e39a3a40f7d037f4eca73c2c37ac2e57ca792412 Mon Sep 17 00:00:00 2001 From: Armin Burgmeier Date: Sat, 1 Oct 2016 13:50:21 -1000 Subject: [PATCH] editor: delete viewport widgets immediately I don't know why the viewports are deleted with deleteLater(), but it leads to an OpenGL context getting deselected behind our back, and so we don't know when is a good time to re-select it. This leads to termination of the engine when selecting File->Close (Ctrl+W) in the editor, because the graphics re-initialization fails with no GL context active. Instead, just delete the viewport widget immediately, which works fine at least on Linux. This is also recommended by the Qt documentation at http://doc.qt.io/qt-5/qopenglwidget.html. --- src/editor/C4ConsoleQt.cpp | 2 +- src/editor/C4ConsoleQtState.cpp | 11 +++++++++-- src/editor/C4ConsoleQtViewport.cpp | 12 +++++++++--- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/editor/C4ConsoleQt.cpp b/src/editor/C4ConsoleQt.cpp index 7ec68d734..c65a8f009 100644 --- a/src/editor/C4ConsoleQt.cpp +++ b/src/editor/C4ConsoleQt.cpp @@ -94,8 +94,8 @@ void C4ConsoleGUI::DeleteConsoleWindow() { if (Active) { - state->DeleteConsoleWindow(); Active = false; + state->DeleteConsoleWindow(); } } diff --git a/src/editor/C4ConsoleQtState.cpp b/src/editor/C4ConsoleQtState.cpp index 8cdc10052..535513a29 100644 --- a/src/editor/C4ConsoleQtState.cpp +++ b/src/editor/C4ConsoleQtState.cpp @@ -755,8 +755,8 @@ void C4ConsoleGUIState::DeleteConsoleWindow() auto vp = viewports.front(); viewports.erase(viewports.begin()); - vp->deleteLater(); viewport_area->removeDockWidget(vp); + delete vp; } client_actions.clear(); @@ -922,8 +922,15 @@ void C4ConsoleGUIState::RemoveViewport(C4ViewportWindow *cvp) if (vp->GetViewportWindow() == cvp) { viewport_area->removeDockWidget(vp); - vp->deleteLater(); iter = viewports.erase(iter); + + // cannot use deleteLater here because Qt will then + // still select/deselect the viewport's GL context + // behind the scenes, leaving us with an unselected + // GL context. + // Documented at http://doc.qt.io/qt-5/qopenglwidget.html + // Instead, delete the viewport widget directly. + delete vp; } else { diff --git a/src/editor/C4ConsoleQtViewport.cpp b/src/editor/C4ConsoleQtViewport.cpp index 0ad868375..d71bc3f9e 100644 --- a/src/editor/C4ConsoleQtViewport.cpp +++ b/src/editor/C4ConsoleQtViewport.cpp @@ -524,9 +524,15 @@ void C4ConsoleQtViewportDockWidget::closeEvent(QCloseEvent * event) QDockWidget::closeEvent(event); if (event->isAccepted()) { - if (cvp) cvp->Close(); - cvp = NULL; - deleteLater(); + if (cvp) + { + // This causes "this" to be deleted: + cvp->Close(); + } + else + { + deleteLater(); + } } }