Members of the KDE Community are recommended to subscribe to the kde-community mailing list at https://mail.kde.org/mailman/listinfo/kde-community to allow them to participate in important discussions and receive other important announcements

Commit 8f9f8d1c authored by Milian Wolff's avatar Milian Wolff

Fix crashes when document gets destroyed directly after load

This fixes the clang code completion unit test, which used to
crash on exit since the event loop wasn't run between loading
a document and destroying it again.

To guard against this, we need to jump through a QPointer hoop,
which requires some lambda boiler plate but otherwise isn't too bad.
parent 65c75e0c
......@@ -364,8 +364,24 @@ void MainWindow::initialize()
d->setupGui();
//Queued so we process it with some delay, to make sure the rest of the UI has already adapted
connect(Core::self()->documentController(), &IDocumentController::documentActivated, this, &MainWindow::updateCaption, Qt::QueuedConnection);
connect(Core::self()->documentController(), &IDocumentController::documentActivated, this, &MainWindow::updateActiveDocumentConnection, Qt::QueuedConnection);
connect(Core::self()->documentController(), &IDocumentController::documentActivated,
// Use a queued connection, because otherwise the view is not yet fully set up
// but wrap the document in a smart pointer to guard against crashes when it
// gets deleted in the meantime
this, [this](IDocument *doc) {
const auto textDocument = QPointer<KTextEditor::Document>(doc->textDocument());
QMetaObject::invokeMethod(this, [this, textDocument](){
updateCaption();
// update active document connection
disconnect(d->activeDocumentReadWriteConnection);
if (textDocument) {
d->activeDocumentReadWriteConnection = connect(textDocument, &KTextEditor::Document::readWriteChanged,
this, &MainWindow::updateCaption);
}
}, Qt::QueuedConnection);
});
connect(Core::self()->documentController(), &IDocumentController::documentClosed, this, &MainWindow::updateCaption, Qt::QueuedConnection);
connect(Core::self()->documentController(), &IDocumentController::documentUrlChanged, this, &MainWindow::updateCaption, Qt::QueuedConnection);
connect(Core::self()->sessionController()->activeSession(), &ISession::sessionUpdated, this, &MainWindow::updateCaption);
......@@ -396,15 +412,6 @@ bool MainWindow::queryClose()
return Sublime::MainWindow::queryClose();
}
void MainWindow::updateActiveDocumentConnection(IDocument* document)
{
disconnect(d->activeDocumentReadWriteConnection);
if (auto textDocument = document->textDocument()) {
d->activeDocumentReadWriteConnection = connect(textDocument, &KTextEditor::Document::readWriteChanged,
this, &MainWindow::updateCaption);
}
}
void MainWindow::updateCaption()
{
const auto activeSession = Core::self()->sessionController()->activeSession();
......
......@@ -98,7 +98,6 @@ protected Q_SLOTS:
private Q_SLOTS:
void updateCaption();
void updateActiveDocumentConnection(IDocument* document);
void updateTabColor(IDocument* doc);
void updateAllTabColors();
......
......@@ -58,6 +58,7 @@ Boston, MA 02110-1301, USA.
#include "debug.h"
#include "plugincontroller.h"
#include "sourceformatterjob.h"
#include "textdocument.h"
namespace {
......@@ -158,20 +159,27 @@ SourceFormatterController::SourceFormatterController(QObject *parent)
this, &SourceFormatterController::updateFormatTextAction);
connect(Core::self()->documentController(), &IDocumentController::documentClosed,
this, &SourceFormatterController::updateFormatTextAction);
// Use a queued connection, because otherwise the view is not yet fully set up
connect(Core::self()->documentController(), &IDocumentController::documentLoaded,
this, &SourceFormatterController::documentLoaded, Qt::QueuedConnection);
// Use a queued connection, because otherwise the view is not yet fully set up
// but wrap the document in a smart pointer to guard against crashes when it
// gets deleted in the meantime
this, [this](IDocument *doc) {
const auto textDoc = QPointer<TextDocument>(dynamic_cast<TextDocument*>(doc));
QMetaObject::invokeMethod(this, [this, textDoc](){
documentLoaded(textDoc);
}, Qt::QueuedConnection);
});
updateFormatTextAction();
}
void SourceFormatterController::documentLoaded( IDocument* doc )
void SourceFormatterController::documentLoaded(IDocument* doc)
{
// NOTE: explicitly check this here to prevent crashes on shutdown
// when this slot gets called (note: delayed connection)
// but the text document was already destroyed
// there have been unit tests that failed due to that...
if (!doc->textDocument()) {
if (!doc || !doc->textDocument()) {
return;
}
const auto url = doc->url();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment