diff --git a/kdevplatform/shell/ktexteditorpluginintegration.h b/kdevplatform/shell/ktexteditorpluginintegration.h --- a/kdevplatform/shell/ktexteditorpluginintegration.h +++ b/kdevplatform/shell/ktexteditorpluginintegration.h @@ -95,16 +95,6 @@ void addPluginView(const QString &id, QObject *pluginView); void removePluginView(const QString &id); - /** - * To be called when the actual mainwindow is destroyed. - * Some KTextEditor::View objects relying on this wrapper object at that point in time - * only have got called deleteLater() on them, so will still get their destruction - * done only in the next handling of QEvent::DeferredDelete. - * To outlive them, this method triggers deleteLater for this wrapper object as well, - * but already prepares for the actual mainwindow no longer being available. - */ - void startDestroy(); - private: KDevelop::MainWindow *m_mainWindow; KTextEditor::MainWindow *m_interface; diff --git a/kdevplatform/shell/ktexteditorpluginintegration.cpp b/kdevplatform/shell/ktexteditorpluginintegration.cpp --- a/kdevplatform/shell/ktexteditorpluginintegration.cpp +++ b/kdevplatform/shell/ktexteditorpluginintegration.cpp @@ -231,7 +231,8 @@ } MainWindow::MainWindow(KDevelop::MainWindow *mainWindow) - : m_mainWindow(mainWindow) + : QObject(mainWindow) + , m_mainWindow(mainWindow) , m_interface(new KTextEditor::MainWindow(this)) { connect(mainWindow, &Sublime::MainWindow::viewAdded, this, [this] (Sublime::View *view) { @@ -265,9 +266,6 @@ KXMLGUIFactory *MainWindow::guiFactory() const { - if (!m_mainWindow) { - return nullptr; - } return m_mainWindow->guiFactory(); } @@ -279,32 +277,23 @@ QList MainWindow::views() const { QList views; - if (m_mainWindow) { - foreach (auto area, m_mainWindow->areas()) { - foreach (auto view, area->views()) { - if (auto kteView = toKteView(view)) { - views << kteView; - } + foreach (auto area, m_mainWindow->areas()) { + foreach (auto view, area->views()) { + if (auto kteView = toKteView(view)) { + views << kteView; } } } return views; } KTextEditor::View *MainWindow::activeView() const { - if (!m_mainWindow) { - return nullptr; - } return toKteView(m_mainWindow->activeView()); } KTextEditor::View *MainWindow::activateView(KTextEditor::Document *doc) { - if (!m_mainWindow) { - return nullptr; - } - foreach (auto area, m_mainWindow->areas()) { foreach (auto view, area->views()) { if (auto kteView = toKteView(view)) { @@ -327,48 +316,39 @@ QWidget *MainWindow::createViewBar(KTextEditor::View *view) { Q_UNUSED(view); - if (!m_mainWindow) { - return nullptr; - } + // we reuse the central view bar for every view return m_mainWindow->viewBarContainer(); } void MainWindow::deleteViewBar(KTextEditor::View *view) { auto viewBar = m_viewBars.take(view); - if (m_mainWindow) { - m_mainWindow->viewBarContainer()->removeViewBar(viewBar); - } + m_mainWindow->viewBarContainer()->removeViewBar(viewBar); delete viewBar; } void MainWindow::showViewBar(KTextEditor::View *view) { auto viewBar = m_viewBars.value(view); Q_ASSERT(viewBar); - if (m_mainWindow) { - m_mainWindow->viewBarContainer()->showViewBar(viewBar); - } + + m_mainWindow->viewBarContainer()->showViewBar(viewBar); } void MainWindow::hideViewBar(KTextEditor::View *view) { auto viewBar = m_viewBars.value(view); Q_ASSERT(viewBar); - if (m_mainWindow) { - m_mainWindow->viewBarContainer()->hideViewBar(viewBar); - } + m_mainWindow->viewBarContainer()->hideViewBar(viewBar); } void MainWindow::addWidgetToViewBar(KTextEditor::View *view, QWidget *widget) { Q_ASSERT(widget); m_viewBars[view] = widget; - if (m_mainWindow) { - m_mainWindow->viewBarContainer()->addViewBar(widget); - } + m_mainWindow->viewBarContainer()->addViewBar(widget); } KTextEditor::MainWindow *MainWindow::interface() const @@ -389,12 +369,6 @@ emit m_interface->pluginViewDeleted(id, view); } -void MainWindow::startDestroy() -{ - m_mainWindow = nullptr; - deleteLater(); -} - Plugin::Plugin(KTextEditor::Plugin *plugin, QObject *parent) : IPlugin({}, parent) , m_plugin(plugin) @@ -449,9 +423,7 @@ void MainWindow::splitView(Qt::Orientation orientation) { - if (m_mainWindow) { - m_mainWindow->split(orientation); - } + m_mainWindow->split(orientation); } } diff --git a/kdevplatform/shell/mainwindow.cpp b/kdevplatform/shell/mainwindow.cpp --- a/kdevplatform/shell/mainwindow.cpp +++ b/kdevplatform/shell/mainwindow.cpp @@ -159,9 +159,6 @@ Core::self()->shutdown(); } - // The window wrapper has to stay alive until the last KTextEditor::Views are gone - // but needs to know this mainwindow is next an ex-mainwindow. - d->kateWrapper()->startDestroy(); delete d; } diff --git a/kdevplatform/shell/tests/test_ktexteditorpluginintegration.cpp b/kdevplatform/shell/tests/test_ktexteditorpluginintegration.cpp --- a/kdevplatform/shell/tests/test_ktexteditorpluginintegration.cpp +++ b/kdevplatform/shell/tests/test_ktexteditorpluginintegration.cpp @@ -95,21 +95,9 @@ TestCore::shutdown(); QVERIFY(!plugin); - // Test uncovers issue in shutdown behaviour when not triggered by last closed mainwindow, but directly: - // Core::shutdown() deletes itself via deleteLater, for which TestCore::shutdown() adds a QTest::qWait(1) - // so Core instance should be gone after the call returns. - // Core in its destructor deletes the Sublime::Controller instance. - // That one in the destructor deletes any still existing mainwindows, of which we have here in the test one. - // The KTE::MainWindow wrapper trying to outlive the KTE::View instances as needed now is only deleted with - // a deleteLater() from the mainwindow. Thus still living here. - QEXPECT_FAIL("", "Chain of deleteLater too long ATM", Continue); QVERIFY(!window); QVERIFY(!application); - // workaround for now, remove again if issue of too long deleteLater chain above is fixed - QTest::qWait(1); - QVERIFY(!window); - // editor lives by design until QCoreApplication terminates, then autodeletes } diff --git a/kdevplatform/sublime/view.cpp b/kdevplatform/sublime/view.cpp --- a/kdevplatform/sublime/view.cpp +++ b/kdevplatform/sublime/view.cpp @@ -59,7 +59,7 @@ if (d->widget && d->ws == View::TakeOwnership ) { d->widget->hide(); d->widget->setParent(nullptr); - d->widget->deleteLater(); + delete d->widget; } } @@ -73,6 +73,11 @@ if (!d->widget) { d->widget = createWidget(parent); + // if we own this widget, we will also delete it and ideally would disconnect + // the following connect before doing that. For that though we would need to store + // a reference to the connection. + // As the d object still exists in the destructor when we delete the widget + // this lambda method though can be still safely executed, so we spare ourselves such disconnect. connect(d->widget, &QWidget::destroyed, this, [&] { d->unsetWidget(); }); } return d->widget;