提交 29a1a973 编写于 作者: J jp9000

UI: Don't open settings or close in event subloop

Fixes a crash that can happen if you try to use the settings window
while in an even subloop, or if you try to close OBS while in an event
subloop.  Continually retries (defers) the actions every one second
until the subloop has finished.
上级 11c0d6e9
......@@ -19,6 +19,7 @@
#include "obs-app.hpp"
#include <graphics/graphics.h>
#include <util/threading.h>
#include <QWidget>
#include <QLayout>
#include <QMessageBox>
......@@ -224,6 +225,8 @@ QThread *CreateQThread(std::function<void()> func)
return new QuickThread(func);
}
volatile long insideEventLoop = 0;
void ExecuteFuncSafeBlock(std::function<void()> func)
{
QEventLoop eventLoop;
......@@ -235,10 +238,12 @@ void ExecuteFuncSafeBlock(std::function<void()> func)
Qt::QueuedConnection);
};
os_atomic_inc_long(&insideEventLoop);
QScopedPointer<QThread> thread(CreateQThread(wait));
thread->start();
eventLoop.exec();
thread->wait();
os_atomic_dec_long(&insideEventLoop);
}
void ExecuteFuncSafeBlockMsgBox(
......@@ -258,10 +263,12 @@ void ExecuteFuncSafeBlockMsgBox(
QMetaObject::invokeMethod(&dlg, "accept", Qt::QueuedConnection);
};
os_atomic_inc_long(&insideEventLoop);
QScopedPointer<QThread> thread(CreateQThread(wait));
thread->start();
dlg.exec();
thread->wait();
os_atomic_dec_long(&insideEventLoop);
}
static bool enable_message_boxes = false;
......
......@@ -98,6 +98,8 @@ struct SignalContainer {
}
extern volatile long insideEventLoop;
Q_DECLARE_METATYPE(OBSScene);
Q_DECLARE_METATYPE(OBSSceneItem);
Q_DECLARE_METATYPE(OBSSource);
......@@ -3761,6 +3763,15 @@ void OBSBasic::ClearSceneData()
void OBSBasic::closeEvent(QCloseEvent *event)
{
/* Do not close window if inside of a temporary event loop because we
* could be inside of an Auth::LoadUI call. Keep trying once per
* second until we've exit any known sub-loops. */
if (os_atomic_load_long(&insideEventLoop) != 0) {
QTimer::singleShot(1000, this, SLOT(close()));
event->ignore();
return;
}
if (isVisible())
config_set_string(App()->GlobalConfig(),
"BasicWindow", "geometry",
......@@ -3860,9 +3871,28 @@ void OBSBasic::on_actionRemux_triggered()
void OBSBasic::on_action_Settings_triggered()
{
static bool settings_already_executing = false;
/* Do not load settings window if inside of a temporary event loop
* because we could be inside of an Auth::LoadUI call. Keep trying
* once per second until we've exit any known sub-loops. */
if (os_atomic_load_long(&insideEventLoop) != 0) {
QTimer::singleShot(1000, this,
SLOT(on_action_Settings_triggered()));
return;
}
if (settings_already_executing) {
return;
}
settings_already_executing = true;
OBSBasicSettings settings(this);
settings.exec();
SystemTray(false);
settings_already_executing = false;
}
void OBSBasic::on_actionAdvAudioProperties_triggered()
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册