Avoid double deletion of HelpWidget when quitting application via Dock

HelpWidgets that are created to be shown in an external window, had
two different places where they were deleted:
1) When the widget was closed (due to Qt::WA_DeleteOnClose)
2) In HelpPlugin::aboutToShutdown via manual delete call

In certain circumstances (when the WebEngine backend was used)
this caused a double delete. Specifically, after opening an external
help window, and closing the MainWindow, the application did not quit
due to QTBUG-62596.

Now if the help window were left open, and the application was quit
via the macOS Dock, this caused a crash.

When the application quits, it calls the HelpPlugin::aboutToShutdown,
which deletes the HelpWidget. This in turn destroys the WebEngine
view, which destroys the underlying QQuickWidget, which destroys
a QQuickRenderControl, which calls
QQuickRenderControlPrivate::windowDestroyed, which handles all
posted QEvent::DeferredDelete events, which in turn triggers the
deletion of the same HelpWidget due to the
Qt::WA_DeleteOnClose attribute.

The solution is to remove the Qt::WA_DeleteOnClose attribute, and only
delete the external HelpWidget on shutdown, and not on CloseEvent.

Task-number: QTBUG-63945
Task-number: QTCREATORBUG-19582
Change-Id: I5b73ff7fe52e7e1259a8aa98c97c9dbedd5e3c20
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
Alexandru Croitor
2018-01-17 16:15:12 +01:00
parent 47ad489b97
commit b23dab3ba2
2 changed files with 3 additions and 1 deletions

View File

@@ -349,6 +349,7 @@ HelpViewer *HelpPlugin::externalHelpViewer()
if (m_externalWindow) if (m_externalWindow)
return m_externalWindow->currentViewer(); return m_externalWindow->currentViewer();
doSetupIfNeeded(); doSetupIfNeeded();
// Deletion for this widget is taken care of in HelpPlugin::aboutToShutdown().
m_externalWindow = createHelpWidget(Context(Constants::C_HELP_EXTERNAL), m_externalWindow = createHelpWidget(Context(Constants::C_HELP_EXTERNAL),
HelpWidget::ExternalWindow); HelpWidget::ExternalWindow);
if (m_externalWindowState.isNull()) { if (m_externalWindowState.isNull()) {
@@ -535,6 +536,8 @@ void HelpPlugin::showInHelpViewer(const QUrl &url, HelpViewer *viewer)
viewer->stop(); viewer->stop();
viewer->setSource(url); viewer->setSource(url);
ICore::raiseWindow(viewer); ICore::raiseWindow(viewer);
// Show the parent top-level-widget in case it was closed previously.
viewer->window()->show();
} }
HelpViewer *HelpPlugin::viewerForContextHelp() HelpViewer *HelpPlugin::viewerForContextHelp()

View File

@@ -127,7 +127,6 @@ HelpWidget::HelpWidget(const Core::Context &context, WidgetStyle style, QWidget
static int windowId = 0; static int windowId = 0;
Core::ICore::registerWindow(this, Core::ICore::registerWindow(this,
Core::Context(Core::Id("Help.Window.").withSuffix(++windowId))); Core::Context(Core::Id("Help.Window.").withSuffix(++windowId)));
setAttribute(Qt::WA_DeleteOnClose);
setAttribute(Qt::WA_QuitOnClose, false); // don't prevent Qt Creator from closing setAttribute(Qt::WA_QuitOnClose, false); // don't prevent Qt Creator from closing
} }
if (style != SideBarWidget) { if (style != SideBarWidget) {