diff --git a/src/wayland/autotests/client/test_wayland_subsurface.cpp b/src/wayland/autotests/client/test_wayland_subsurface.cpp index cd2c0c4311..40bbad59b4 100644 --- a/src/wayland/autotests/client/test_wayland_subsurface.cpp +++ b/src/wayland/autotests/client/test_wayland_subsurface.cpp @@ -869,8 +869,11 @@ void TestSubSurface::testMappingOfSurfaceTree() QVERIFY(parentSpy.wait()); QVERIFY(parentServerSurface->isMapped()); // children should not yet be mapped + QEXPECT_FAIL("", "Workaround for QtWayland bug https://bugreports.qt.io/browse/QTBUG-52192", Continue); QVERIFY(!child->surface()->isMapped()); + QEXPECT_FAIL("", "Workaround for QtWayland bug https://bugreports.qt.io/browse/QTBUG-52192", Continue); QVERIFY(!child2->surface()->isMapped()); + QEXPECT_FAIL("", "Workaround for QtWayland bug https://bugreports.qt.io/browse/QTBUG-52192", Continue); QVERIFY(!child3->surface()->isMapped()); // next level @@ -882,8 +885,11 @@ void TestSubSurface::testMappingOfSurfaceTree() QVERIFY(child2DamageSpy.wait()); QVERIFY(parentServerSurface->isMapped()); // children should not yet be mapped + QEXPECT_FAIL("", "Workaround for QtWayland bug https://bugreports.qt.io/browse/QTBUG-52192", Continue); QVERIFY(!child->surface()->isMapped()); + QEXPECT_FAIL("", "Workaround for QtWayland bug https://bugreports.qt.io/browse/QTBUG-52192", Continue); QVERIFY(!child2->surface()->isMapped()); + QEXPECT_FAIL("", "Workaround for QtWayland bug https://bugreports.qt.io/browse/QTBUG-52192", Continue); QVERIFY(!child3->surface()->isMapped()); // last but not least the first child level, which should map all our subsurfaces diff --git a/src/wayland/surface_interface.cpp b/src/wayland/surface_interface.cpp index 56fc18fe72..8791f6f5e7 100644 --- a/src/wayland/surface_interface.cpp +++ b/src/wayland/surface_interface.cpp @@ -343,6 +343,7 @@ void SurfaceInterface::Private::swapStates(State *source, State *target, bool em if (!windowRegion.isEmpty()) { target->damage = windowRegion.intersected(target->damage); if (emitChanged) { + subSurfaceIsMapped = true; emit q->damaged(target->damage); // workaround for https://bugreports.qt.io/browse/QTBUG-52092 // if the surface is a sub-surface, but the main surface is not yet mapped, fake frame rendered @@ -352,6 +353,7 @@ void SurfaceInterface::Private::swapStates(State *source, State *target, bool em } } } else if (!target->buffer && emitChanged) { + subSurfaceIsMapped = false; emit q->unmapped(); } } @@ -672,7 +674,7 @@ bool SurfaceInterface::isMapped() const if (d->subSurface) { // from spec: // "A sub-surface becomes mapped, when a non-NULL wl_buffer is applied and the parent surface is mapped." - return d->current.buffer && !d->subSurface->parentSurface().isNull() && d->subSurface->parentSurface()->isMapped(); + return d->subSurfaceIsMapped && !d->subSurface->parentSurface().isNull() && d->subSurface->parentSurface()->isMapped(); } return d->current.buffer != nullptr; } diff --git a/src/wayland/surface_interface_p.h b/src/wayland/surface_interface_p.h index 301248ab94..86e8186bf9 100644 --- a/src/wayland/surface_interface_p.h +++ b/src/wayland/surface_interface_p.h @@ -82,6 +82,12 @@ public: State subSurfacePending; QPointer subSurface; + // workaround for https://bugreports.qt.io/browse/QTBUG-52192 + // A subsurface needs to be considered mapped even if it doesn't have a buffer attached + // Otherwise Qt's sub-surfaces will never be visible and the client will freeze due to + // waiting on the frame callback of the never visible surface + bool subSurfaceIsMapped = true; + private: SurfaceInterface *q_func() { return reinterpret_cast(q);