Files
oak-editor/app/dialog/task/task.h
T
Mike-Solar 01f8be7267 Fix crash when closing export dialog while export is running
TaskDialog::closeEvent() was calling deleteLater() immediately when the
user closed the window. The ExportTask was a child QObject of the dialog,
so it got destroyed while its Run() method was still executing in the
worker thread, leading to a use-after-free on encoder_->Close().

Defer deletion until the QFutureWatcher reports that the task has actually
finished. A new task_finished_ flag tracks this so closeEvent only deletes
when it is safe, and TaskFinished() closes the dialog (which now deletes
instead of calling close() again while the task is still alive).
2026-07-13 10:19:30 +08:00

87 lines
1.9 KiB
C++

/***
Olive - Non-Linear Video Editor
Copyright (C) 2022 Olive Team
Modifications Copyright (C) 2025 mikesolar
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
***/
#ifndef TASKDIALOG_H
#define TASKDIALOG_H
#include "dialog/progress/progress.h"
#include "task/task.h"
namespace olive
{
class TaskDialog : public ProgressDialog {
Q_OBJECT
public:
/**
* @brief TaskDialog Constructor
*
* Creates a TaskDialog. The TaskDialog takes ownership of the Task and will destroy it on close.
* Connect to the Task::Succeeded() if you want to retrieve information from the task before it
* gets destroyed.
*/
TaskDialog(Task *task, const QString &title, QWidget *parent = nullptr);
/**
* @brief Set whether TaskDialog should destroy itself (and the task) when it's closed
*
* This is TRUE by default.
*/
void SetDestroyOnClose(bool e)
{
destroy_on_close_ = e;
}
/**
* @brief Returns this dialog's task
*/
Task *GetTask() const
{
return task_;
}
protected:
virtual void showEvent(QShowEvent *e) override;
virtual void closeEvent(QCloseEvent *e) override;
signals:
void TaskSucceeded(Task *task);
void TaskFailed(Task *task);
private:
Task *task_;
bool destroy_on_close_;
bool already_shown_;
bool task_finished_;
private slots:
void TaskFinished();
};
}
#endif // TASKDIALOG_H