diff --git a/app/dialog/task/task.cpp b/app/dialog/task/task.cpp index 7aa1fdb44..0b8774f6c 100644 --- a/app/dialog/task/task.cpp +++ b/app/dialog/task/task.cpp @@ -34,6 +34,7 @@ TaskDialog::TaskDialog(Task *task, const QString &title, QWidget *parent) , task_(task) , destroy_on_close_(true) , already_shown_(false) + , task_finished_(false) { // Clear task when this dialog is destroyed task_->setParent(this); @@ -84,8 +85,11 @@ void TaskDialog::closeEvent(QCloseEvent *e) // Reset shown already_shown_ = false; - // Clean up this task and dialog - if (destroy_on_close_) { + // Clean up this task and dialog, but only if the task has actually finished. + // If the user closes the window while the task is still running, deleting now + // would destroy the Task object out from under the worker thread and crash + // when the task later touches its own members (e.g. ExportTask::encoder_). + if (destroy_on_close_ && task_finished_) { deleteLater(); } } @@ -95,6 +99,8 @@ void TaskDialog::TaskFinished() QFutureWatcher *task_watcher = static_cast *>(sender()); + task_finished_ = true; + if (task_watcher->result()) { emit TaskSucceeded(task_); } else { diff --git a/app/dialog/task/task.h b/app/dialog/task/task.h index ded311dbf..d01fddced 100644 --- a/app/dialog/task/task.h +++ b/app/dialog/task/task.h @@ -75,6 +75,8 @@ private: bool already_shown_; + bool task_finished_; + private slots: void TaskFinished(); };