diff --git a/UI/qt-display.cpp b/UI/qt-display.cpp index e74e162e0..3da4c7bc7 100644 --- a/UI/qt-display.cpp +++ b/UI/qt-display.cpp @@ -13,15 +13,11 @@ #include #endif -#ifdef ENABLE_WAYLAND -#include - class SurfaceEventFilter : public QObject { OBSQTDisplay *display; - int mTimerId; public: - SurfaceEventFilter(OBSQTDisplay *src) : display(src), mTimerId(0) {} + SurfaceEventFilter(OBSQTDisplay *src) : display(src) {} protected: bool eventFilter(QObject *obj, QEvent *event) override @@ -35,22 +31,12 @@ protected: static_cast(event); switch (surfaceEvent->surfaceEventType()) { - case QPlatformSurfaceEvent::SurfaceCreated: - if (display->windowHandle()->isExposed()) - createOBSDisplay(); - else - mTimerId = startTimer(67); // Arbitrary - break; case QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed: display->DestroyDisplay(); break; default: break; } - - break; - case QEvent::Expose: - createOBSDisplay(); break; default: break; @@ -58,25 +44,8 @@ protected: return result; } - - void timerEvent(QTimerEvent *) override - { - createOBSDisplay(display->isVisible()); - } - -private: - void createOBSDisplay(bool force = false) - { - display->CreateDisplay(force); - if (mTimerId > 0) { - killTimer(mTimerId); - mTimerId = 0; - } - } }; -#endif - static inline long long color_to_int(const QColor &color) { auto shift = [&](unsigned val, int shift) { @@ -130,11 +99,7 @@ OBSQTDisplay::OBSQTDisplay(QWidget *parent, Qt::WindowFlags flags) connect(windowHandle(), &QWindow::visibleChanged, windowVisible); connect(windowHandle(), &QWindow::screenChanged, screenChanged); -#ifdef ENABLE_WAYLAND - if (obs_get_nix_platform() == OBS_NIX_PLATFORM_WAYLAND) - windowHandle()->installEventFilter( - new SurfaceEventFilter(this)); -#endif + windowHandle()->installEventFilter(new SurfaceEventFilter(this)); } QColor OBSQTDisplay::GetDisplayBackgroundColor() const @@ -157,12 +122,15 @@ void OBSQTDisplay::UpdateDisplayBackgroundColor() obs_display_set_background_color(display, backgroundColor); } -void OBSQTDisplay::CreateDisplay(bool force) +void OBSQTDisplay::CreateDisplay() { if (display) return; - if (!windowHandle()->isExposed() && !force) + if (destroying) + return; + + if (!windowHandle()->isExposed()) return; QSize size = GetPixelSize(this); diff --git a/UI/qt-display.hpp b/UI/qt-display.hpp index 10fe735ed..7a90f10fb 100644 --- a/UI/qt-display.hpp +++ b/UI/qt-display.hpp @@ -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; @@ -37,8 +38,12 @@ public: QColor GetDisplayBackgroundColor() const; void SetDisplayBackgroundColor(const QColor &color); void UpdateDisplayBackgroundColor(); - void CreateDisplay(bool force = false); - void DestroyDisplay() { display = nullptr; }; + void CreateDisplay(); + void DestroyDisplay() + { + display = nullptr; + destroying = true; + }; void OnMove(); void OnDisplayChange(); diff --git a/UI/window-basic-main.cpp b/UI/window-basic-main.cpp index a9215c53f..ebd8f1903 100644 --- a/UI/window-basic-main.cpp +++ b/UI/window-basic-main.cpp @@ -5128,6 +5128,16 @@ void OBSBasic::closeEvent(QCloseEvent *event) closing = true; + /* While closing, a resize event to OBSQTDisplay could be triggered. + * The graphics thread on macOS dispatches a lambda function to be + * executed asynchronously in the main thread. However, the display is + * sometimes deleted before the lambda function is actually executed. + * To avoid such a case, destroy displays earlier than others such as + * deleting browser docks. */ + ui->preview->DestroyDisplay(); + if (program) + program->DestroyDisplay(); + if (outputHandler->VirtualCamActive()) outputHandler->StopVirtualCam(); @@ -5154,10 +5164,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());