From db7ed40e1e0c566d4c6bed53c283327c9d55ce4c Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Thu, 20 Aug 2020 11:58:45 -0300 Subject: [PATCH 20/20] UI: Check for Expose and PlatformSurface events to create display This is a workaround for QWaylandWindow never becoming exposed, or receiving the QEvent::Expose [1]. [1] https://bugreports.qt.io/browse/QTBUG-86176 --- UI/qt-display.cpp | 58 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/UI/qt-display.cpp b/UI/qt-display.cpp index b230ab4e..4487d460 100644 --- a/UI/qt-display.cpp +++ b/UI/qt-display.cpp @@ -10,6 +10,58 @@ #ifdef ENABLE_WAYLAND #include + +class SurfaceEventFilter : public QObject { + OBSQTDisplay *display; + int mTimerId; + +public: + SurfaceEventFilter(OBSQTDisplay *src) : display(src), mTimerId(0) {} + +protected: + bool eventFilter(QObject *obj, QEvent *event) override + { + bool result = QObject::eventFilter(obj, event); + QPlatformSurfaceEvent *surfaceEvent; + + switch (event->type()) { +#if QT_VERSION < QT_VERSION_CHECK(5, 15, 1) + case QEvent::PlatformSurface: + surfaceEvent = + static_cast(event); + if (surfaceEvent->surfaceEventType() != + QPlatformSurfaceEvent::SurfaceCreated) + return result; + + if (display->windowHandle()->isExposed()) + createOBSDisplay(); + else + mTimerId = startTimer(67); // Arbitrary + break; +#endif + case QEvent::Expose: + createOBSDisplay(); + break; + default: + break; + } + + return result; + } + + void timerEvent(QTimerEvent *) { createOBSDisplay(true); } + +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) @@ -65,6 +117,12 @@ 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 } QColor OBSQTDisplay::GetDisplayBackgroundColor() const -- 2.28.0