[server] Don't destroy ShadowInterface when SurfaceInterface gets destroyed
Summary: Unlike the other cases this one is not as dangerous as the shadow protocol doesn't have a destructor request (yet). Once that is added the problem would be the same: destroying the ShadowInterface when the parent SurfaceInterface gets destroyed would result in a protocol error on client side. Reviewers: #plasma Subscribers: plasma-devel Tags: #plasma Differential Revision: https://phabricator.kde.org/D1711
This commit is contained in:
parent
33e802913f
commit
1f48daea1e
2 changed files with 47 additions and 8 deletions
|
@ -45,6 +45,7 @@ private Q_SLOTS:
|
|||
|
||||
void testCreateShadow();
|
||||
void testShadowElements();
|
||||
void testSurfaceDestroy();
|
||||
|
||||
private:
|
||||
Display *m_display = nullptr;
|
||||
|
@ -266,5 +267,51 @@ void ShadowTest::testShadowElements()
|
|||
QVERIFY(!serverShadow->left());
|
||||
}
|
||||
|
||||
void ShadowTest::testSurfaceDestroy()
|
||||
{
|
||||
using namespace KWayland::Client;
|
||||
using namespace KWayland::Server;
|
||||
QSignalSpy serverSurfaceCreated(m_compositorInterface, &CompositorInterface::surfaceCreated);
|
||||
QVERIFY(serverSurfaceCreated.isValid());
|
||||
|
||||
QScopedPointer<KWayland::Client::Surface> surface(m_compositor->createSurface());
|
||||
QVERIFY(serverSurfaceCreated.wait());
|
||||
auto serverSurface = serverSurfaceCreated.first().first().value<SurfaceInterface*>();
|
||||
QSignalSpy shadowChangedSpy(serverSurface, &SurfaceInterface::shadowChanged);
|
||||
QVERIFY(shadowChangedSpy.isValid());
|
||||
|
||||
QScopedPointer<Shadow> 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"
|
||||
|
|
|
@ -105,14 +105,6 @@ void ShadowManagerInterface::Private::createShadow(wl_client *client, wl_resourc
|
|||
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<ShadowInterface>(shadow));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue