mirror of
https://github.com/obsproject/obs-studio.git
synced 2026-01-22 21:28:32 -05:00
UI: Fix crash at render_display while shutdown on macOS
The display context was sometimes created again by a resize event after destruction from `OBSBasic::closeEvent`. That resulted in the display context alive until reaching the destructor of the `OBSQTDisplay` class and caused a crash in `render_display` on macOS. To avoid this, destroy the display context at the event `SurfaceAboutToBeDestroyed` and let not create the display context again.
This commit is contained in:
@@ -13,6 +13,39 @@
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
class SurfaceEventFilter : public QObject {
|
||||
OBSQTDisplay *display;
|
||||
|
||||
public:
|
||||
SurfaceEventFilter(OBSQTDisplay *src) : display(src) {}
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *obj, QEvent *event) override
|
||||
{
|
||||
bool result = QObject::eventFilter(obj, event);
|
||||
QPlatformSurfaceEvent *surfaceEvent;
|
||||
|
||||
switch (event->type()) {
|
||||
case QEvent::PlatformSurface:
|
||||
surfaceEvent =
|
||||
static_cast<QPlatformSurfaceEvent *>(event);
|
||||
|
||||
switch (surfaceEvent->surfaceEventType()) {
|
||||
case QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed:
|
||||
display->DestroyDisplay();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
static inline long long color_to_int(const QColor &color)
|
||||
{
|
||||
auto shift = [&](unsigned val, int shift) {
|
||||
@@ -65,6 +98,8 @@ OBSQTDisplay::OBSQTDisplay(QWidget *parent, Qt::WindowFlags flags)
|
||||
|
||||
connect(windowHandle(), &QWindow::visibleChanged, windowVisible);
|
||||
connect(windowHandle(), &QWindow::screenChanged, screenChanged);
|
||||
|
||||
windowHandle()->installEventFilter(new SurfaceEventFilter(this));
|
||||
}
|
||||
|
||||
QColor OBSQTDisplay::GetDisplayBackgroundColor() const
|
||||
@@ -92,6 +127,9 @@ void OBSQTDisplay::CreateDisplay()
|
||||
if (display)
|
||||
return;
|
||||
|
||||
if (destroying)
|
||||
return;
|
||||
|
||||
if (!windowHandle()->isExposed())
|
||||
return;
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ class OBSQTDisplay : public QWidget {
|
||||
SetDisplayBackgroundColor)
|
||||
|
||||
OBSDisplay display;
|
||||
bool destroying = false;
|
||||
|
||||
virtual void paintEvent(QPaintEvent *event) override;
|
||||
virtual void moveEvent(QMoveEvent *event) override;
|
||||
@@ -38,7 +39,11 @@ public:
|
||||
void SetDisplayBackgroundColor(const QColor &color);
|
||||
void UpdateDisplayBackgroundColor();
|
||||
void CreateDisplay();
|
||||
void DestroyDisplay() { display = nullptr; };
|
||||
void DestroyDisplay()
|
||||
{
|
||||
display = nullptr;
|
||||
destroying = true;
|
||||
};
|
||||
|
||||
void OnMove();
|
||||
void OnDisplayChange();
|
||||
|
||||
@@ -5154,10 +5154,6 @@ void OBSBasic::closeEvent(QCloseEvent *event)
|
||||
|
||||
delete extraBrowsers;
|
||||
|
||||
ui->preview->DestroyDisplay();
|
||||
if (program)
|
||||
program->DestroyDisplay();
|
||||
|
||||
config_set_string(App()->GlobalConfig(), "BasicWindow", "DockState",
|
||||
saveState().toBase64().constData());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user