diff --git a/UI/qt-wrappers.cpp b/UI/qt-wrappers.cpp index 0ce9ba0bc..18bd34c88 100644 --- a/UI/qt-wrappers.cpp +++ b/UI/qt-wrappers.cpp @@ -19,6 +19,7 @@ #include "obs-app.hpp" #include +#include #include #include #include @@ -224,6 +225,8 @@ QThread *CreateQThread(std::function func) return new QuickThread(func); } +volatile long insideEventLoop = 0; + void ExecuteFuncSafeBlock(std::function func) { QEventLoop eventLoop; @@ -235,10 +238,12 @@ void ExecuteFuncSafeBlock(std::function func) Qt::QueuedConnection); }; + os_atomic_inc_long(&insideEventLoop); QScopedPointer 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 thread(CreateQThread(wait)); thread->start(); dlg.exec(); thread->wait(); + os_atomic_dec_long(&insideEventLoop); } static bool enable_message_boxes = false; diff --git a/UI/window-basic-main.cpp b/UI/window-basic-main.cpp index b72065c0d..15f025b71 100644 --- a/UI/window-basic-main.cpp +++ b/UI/window-basic-main.cpp @@ -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()