Skip to content

Commit

Permalink
UI: Split out Whats New dialog, fix crash on shutdown
Browse files Browse the repository at this point in the history
CEF crashes on shutdown if any browser window remains open during the
shutdown flow. Reproducible 100% of the time on Linux with What's New.
The previous implementation of the What's New dialog correctly deleted
all the Qt widgets, but the CEF internal event flow would only call the
"preparing to close" function, and never the "window safely closed"
function. Moving the code (practically unchanged) to a custom QDialog
solves the problem entirely, and is more consistent with other uses.
  • Loading branch information
WizardCM authored and RytoEX committed Oct 24, 2024
1 parent 2e075f7 commit 0eef4e2
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 29 deletions.
2 changes: 2 additions & 0 deletions UI/cmake/ui-windows.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,6 @@ target_sources(
window-projector.hpp
window-remux.cpp
window-remux.hpp
window-whats-new.cpp
window-whats-new.hpp
)
35 changes: 6 additions & 29 deletions UI/window-basic-main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
#include "window-youtube-actions.hpp"
#include "youtube-api-wrappers.hpp"
#endif
#include "window-whats-new.hpp"
#include "context-bar-controls.hpp"
#include "obs-proxy-style.hpp"
#include "display-helpers.hpp"
Expand Down Expand Up @@ -128,6 +129,8 @@ void DestroyPanelCookieManager();

namespace {

QPointer<OBSWhatsNew> obsWhatsNew;

template<typename OBSRef> struct SignalContainer {
OBSRef ref;
vector<shared_ptr<OBSSignal>> handlers;
Expand Down Expand Up @@ -2544,37 +2547,11 @@ void OBSBasic::ShowWhatsNew(const QString &url)
if (closing)
return;

std::string info_url = QT_TO_UTF8(url);

QDialog *dlg = new QDialog(this);
dlg->setAttribute(Qt::WA_DeleteOnClose, true);
dlg->setWindowTitle("What's New");
dlg->resize(700, 600);

Qt::WindowFlags flags = dlg->windowFlags();
Qt::WindowFlags helpFlag = Qt::WindowContextHelpButtonHint;
dlg->setWindowFlags(flags & (~helpFlag));

QCefWidget *cefWidget = cef->create_widget(nullptr, info_url);
if (!cefWidget) {
return;
if (obsWhatsNew) {
obsWhatsNew->close();
}

connect(cefWidget, &QCefWidget::titleChanged, dlg, &QDialog::setWindowTitle);

QPushButton *close = new QPushButton(QTStr("Close"));
connect(close, &QAbstractButton::clicked, dlg, &QDialog::accept);

QHBoxLayout *bottomLayout = new QHBoxLayout();
bottomLayout->addStretch();
bottomLayout->addWidget(close);
bottomLayout->addStretch();

QVBoxLayout *topLayout = new QVBoxLayout(dlg);
topLayout->addWidget(cefWidget);
topLayout->addLayout(bottomLayout);

dlg->show();
obsWhatsNew = new OBSWhatsNew(this, QT_TO_UTF8(url));
#else
UNUSED_PARAMETER(url);
#endif
Expand Down
74 changes: 74 additions & 0 deletions UI/window-whats-new.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#include "moc_window-whats-new.cpp"

#include <QPushButton>
#include <QHBoxLayout>
#include <QVBoxLayout>

#include "window-basic-main.hpp"

#ifdef BROWSER_AVAILABLE
#include <browser-panel.hpp>
extern QCef *cef;
#endif

/* ------------------------------------------------------------------------- */

OBSWhatsNew::OBSWhatsNew(QWidget *parent, const std::string &url) : QDialog(parent)
{
#ifdef BROWSER_AVAILABLE
if (!cef) {
return;
}

setWindowTitle("What's New");
setAttribute(Qt::WA_DeleteOnClose, true);
resize(700, 600);

Qt::WindowFlags flags = windowFlags();
Qt::WindowFlags helpFlag = Qt::WindowContextHelpButtonHint;
setWindowFlags(flags & (~helpFlag));

OBSBasic::InitBrowserPanelSafeBlock();

cefWidget = cef->create_widget(nullptr, url);
if (!cefWidget) {
return;
}

connect(cefWidget, &QCefWidget::titleChanged, this, &OBSWhatsNew::setWindowTitle);

QPushButton *close = new QPushButton(QTStr("Close"));
connect(close, &QAbstractButton::clicked, this, &QDialog::accept);

QHBoxLayout *bottomLayout = new QHBoxLayout();
bottomLayout->addStretch();
bottomLayout->addWidget(close);
bottomLayout->addStretch();

QVBoxLayout *topLayout = new QVBoxLayout(this);
topLayout->addWidget(cefWidget);
topLayout->addLayout(bottomLayout);

show();
#else
UNUSED_PARAMETER(url);
#endif
}

OBSWhatsNew::~OBSWhatsNew() {}

void OBSWhatsNew::reject()
{
#ifdef BROWSER_AVAILABLE
delete cefWidget;
#endif
QDialog::reject();
}

void OBSWhatsNew::accept()
{
#ifdef BROWSER_AVAILABLE
delete cefWidget;
#endif
QDialog::accept();
}
20 changes: 20 additions & 0 deletions UI/window-whats-new.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#pragma once

#include <QPointer>
#include <QDialog>
#include <string>

class QCefWidget;

class OBSWhatsNew : public QDialog {
Q_OBJECT

QCefWidget *cefWidget = nullptr;

public:
OBSWhatsNew(QWidget *parent, const std::string &url);
~OBSWhatsNew();

virtual void reject() override;
virtual void accept() override;
};

0 comments on commit 0eef4e2

Please sign in to comment.