Browse Source

UI: Fix closing OBS before showing whats new dialog

The program can get stuck waiting for the browser within a event queue,
so instead mark that the program is closing, do it in a separate thread,
signal the window when it's finished, and then check whether it's in the
process of closing before actually showing the dialog.
jp9000 5 years ago
parent
commit
0fb34ed965
4 changed files with 70 additions and 3 deletions
  1. 17 0
      UI/win-update/win-update.cpp
  2. 14 0
      UI/win-update/win-update.hpp
  3. 36 3
      UI/window-basic-main.cpp
  4. 3 0
      UI/window-basic-main.hpp

+ 17 - 0
UI/win-update/win-update.cpp

@@ -20,8 +20,15 @@
 #include <winhttp.h>
 #include <shellapi.h>
 
+#ifdef BROWSER_AVAILABLE
+#include <browser-panel.hpp>
+#endif
+
 using namespace std;
 
+struct QCef;
+extern QCef *cef;
+
 /* ------------------------------------------------------------------------ */
 
 #ifndef WIN_MANIFEST_URL
@@ -799,3 +806,13 @@ try {
 } catch (string &text) {
 	blog(LOG_WARNING, "%s: %s", __FUNCTION__, text.c_str());
 }
+
+/* ------------------------------------------------------------------------ */
+
+void WhatsNewBrowserInitThread::run()
+{
+#ifdef BROWSER_AVAILABLE
+	cef->wait_for_browser_init();
+#endif
+	emit Result(url);
+}

+ 14 - 0
UI/win-update/win-update.hpp

@@ -33,3 +33,17 @@ signals:
 public:
 	inline WhatsNewInfoThread() {}
 };
+
+class WhatsNewBrowserInitThread : public QThread {
+	Q_OBJECT
+
+	QString url;
+
+	virtual void run() override;
+
+signals:
+	void Result(const QString &url);
+
+public:
+	inline WhatsNewBrowserInitThread(const QString &url_) : url(url_) {}
+};

+ 36 - 3
UI/window-basic-main.cpp

@@ -1896,6 +1896,9 @@ void OBSBasic::ReceivedIntroJson(const QString &text)
 {
 #ifdef BROWSER_AVAILABLE
 #ifdef _WIN32
+	if (closing)
+		return;
+
 	std::string err;
 	Json json = Json::parse(QT_TO_UTF8(text), err);
 	if (!err.empty())
@@ -1970,7 +1973,33 @@ void OBSBasic::ReceivedIntroJson(const QString &text)
 	}
 #endif
 	cef->init_browser();
-	ExecuteFuncSafeBlock([] { cef->wait_for_browser_init(); });
+
+	WhatsNewBrowserInitThread *wnbit =
+		new WhatsNewBrowserInitThread(QT_UTF8(info_url.c_str()));
+	if (wnbit) {
+		connect(wnbit, &WhatsNewBrowserInitThread::Result, this,
+			&OBSBasic::ShowWhatsNew);
+	}
+	if (wnbit) {
+		whatsNewInitThread.reset(wnbit);
+		whatsNewInitThread->start();
+	}
+#else
+	UNUSED_PARAMETER(text);
+#endif
+#else
+	UNUSED_PARAMETER(text);
+#endif
+}
+
+void OBSBasic::ShowWhatsNew(const QString &url)
+{
+#ifdef BROWSER_AVAILABLE
+#ifdef _WIN32
+	if (closing)
+		return;
+
+	std::string info_url = QT_TO_UTF8(url);
 
 	QDialog *dlg = new QDialog(this);
 	dlg->setAttribute(Qt::WA_DeleteOnClose, true);
@@ -2003,10 +2032,10 @@ void OBSBasic::ReceivedIntroJson(const QString &text)
 
 	dlg->show();
 #else
-	UNUSED_PARAMETER(text);
+	UNUSED_PARAMETER(url);
 #endif
 #else
-	UNUSED_PARAMETER(text);
+	UNUSED_PARAMETER(url);
 #endif
 }
 
@@ -3933,8 +3962,12 @@ void OBSBasic::closeEvent(QCloseEvent *event)
 
 	blog(LOG_INFO, SHUTDOWN_SEPARATOR);
 
+	closing = true;
+
 	if (introCheckThread)
 		introCheckThread->wait();
+	if (whatsNewInitThread)
+		whatsNewInitThread->wait();
 	if (updateCheckThread)
 		updateCheckThread->wait();
 	if (logUploadThread)

+ 3 - 0
UI/window-basic-main.hpp

@@ -193,6 +193,8 @@ private:
 	const char *copyFiltersString = nullptr;
 	bool copyVisible = true;
 
+	bool closing = false;
+	QScopedPointer<QThread> whatsNewInitThread;
 	QScopedPointer<QThread> updateCheckThread;
 	QScopedPointer<QThread> introCheckThread;
 	QScopedPointer<QThread> logUploadThread;
@@ -463,6 +465,7 @@ private:
 	void LoadSavedProjectors(obs_data_array_t *savedProjectors);
 
 	void ReceivedIntroJson(const QString &text);
+	void ShowWhatsNew(const QString &url);
 
 #ifdef BROWSER_AVAILABLE
 	QList<QSharedPointer<QDockWidget>> extraBrowserDocks;