mirror of
https://github.com/obsproject/obs-studio.git
synced 2026-09-24 23:31:36 +08: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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user