diff --git a/autotests/client/test_shadow.cpp b/autotests/client/test_shadow.cpp --- a/autotests/client/test_shadow.cpp +++ b/autotests/client/test_shadow.cpp @@ -45,6 +45,7 @@ void testCreateShadow(); void testShadowElements(); + void testSurfaceDestroy(); private: Display *m_display = nullptr; @@ -266,5 +267,51 @@ QVERIFY(!serverShadow->left()); } +void ShadowTest::testSurfaceDestroy() +{ + using namespace KWayland::Client; + using namespace KWayland::Server; + QSignalSpy serverSurfaceCreated(m_compositorInterface, &CompositorInterface::surfaceCreated); + QVERIFY(serverSurfaceCreated.isValid()); + + QScopedPointer surface(m_compositor->createSurface()); + QVERIFY(serverSurfaceCreated.wait()); + auto serverSurface = serverSurfaceCreated.first().first().value(); + QSignalSpy shadowChangedSpy(serverSurface, &SurfaceInterface::shadowChanged); + QVERIFY(shadowChangedSpy.isValid()); + + QScopedPointer shadow(m_shadow->createShadow(surface.data())); + shadow->commit(); + surface->commit(Surface::CommitFlag::None); + QVERIFY(shadowChangedSpy.wait()); + auto serverShadow = serverSurface->shadow(); + QVERIFY(serverShadow); + + // destroy the parent surface + QSignalSpy surfaceDestroyedSpy(serverSurface, &QObject::destroyed); + QVERIFY(surfaceDestroyedSpy.isValid()); + QSignalSpy shadowDestroyedSpy(serverShadow, &QObject::destroyed); + QVERIFY(shadowDestroyedSpy.isValid()); + QSignalSpy clientDisconnectedSpy(serverSurface->client(), &ClientConnection::disconnected); + QVERIFY(clientDisconnectedSpy.isValid()); + surface.reset(); + QVERIFY(surfaceDestroyedSpy.wait()); + QVERIFY(shadowDestroyedSpy.isEmpty()); + // destroy the shadow + shadow.reset(); + // shadow protocol doesn't have a destroy callback yet, so also disconnect + m_connection->deleteLater(); + m_connection = nullptr; + QVERIFY(clientDisconnectedSpy.wait()); + if (shadowDestroyedSpy.isEmpty()) { + QVERIFY(shadowDestroyedSpy.wait()); + } + QCOMPARE(shadowDestroyedSpy.count(), 1); + m_shm->destroy(); + m_compositor->destroy(); + m_shadow->destroy(); + m_queue->destroy(); +} + QTEST_GUILESS_MAIN(ShadowTest) #include "test_shadow.moc" diff --git a/src/server/shadow_interface.cpp b/src/server/shadow_interface.cpp --- a/src/server/shadow_interface.cpp +++ b/src/server/shadow_interface.cpp @@ -105,14 +105,6 @@ delete shadow; return; } - QObject::connect(s, &QObject::destroyed, shadow, - [shadow] { - if (shadow->resource()) { - wl_resource_destroy(shadow->resource()); - delete shadow; - } - } - ); s->d_func()->setShadow(QPointer(shadow)); }