10#include "KWayland/Client/compositor.h"
11#include "KWayland/Client/connection_thread.h"
12#include "KWayland/Client/event_queue.h"
13#include "KWayland/Client/registry.h"
14#include "KWayland/Client/shadow.h"
15#include "KWayland/Client/shm_pool.h"
16#include "KWayland/Client/surface.h"
32 void testCreateShadow();
33 void testShadowElements();
34 void testSurfaceDestroy();
39 KWayland::Client::ConnectionThread *m_connection =
nullptr;
42 QThread *m_thread =
nullptr;
43 KWayland::Client::EventQueue *m_queue =
nullptr;
44 KWayland::Client::ShmPool *m_shm =
nullptr;
45 KWayland::Client::Compositor *m_compositor =
nullptr;
46 KWayland::Client::ShadowManager *m_shadow =
nullptr;
49static const QString s_socketName = QStringLiteral(
"kwayland-test-shadow-0");
51void ShadowTest::init()
63 m_connection =
new KWayland::Client::ConnectionThread;
64 QSignalSpy connectedSpy(m_connection, &KWayland::Client::ConnectionThread::connected);
65 m_connection->setSocketName(s_socketName);
67 m_thread =
new QThread(
this);
68 m_connection->moveToThread(m_thread);
71 m_connection->initConnection();
72 QVERIFY(connectedSpy.wait());
74 m_queue =
new KWayland::Client::EventQueue(
this);
75 m_queue->setup(m_connection);
77 KWayland::Client::Registry registry;
78 QSignalSpy interfacesAnnouncedSpy(®istry, &KWayland::Client::Registry::interfacesAnnounced);
79 registry.setEventQueue(m_queue);
80 registry.create(m_connection);
81 QVERIFY(registry.isValid());
83 QVERIFY(interfacesAnnouncedSpy.wait());
85 m_shm = registry.createShmPool(registry.interface(KWayland::Client::Registry::Interface::Shm).name, registry.interface(KWayland::Client::Registry::Interface::Shm).version,
this);
86 QVERIFY(m_shm->isValid());
88 registry.createCompositor(registry.interface(KWayland::Client::Registry::Interface::Compositor).name, registry.interface(KWayland::Client::Registry::Interface::Compositor).version,
this);
89 QVERIFY(m_compositor->isValid());
91 registry.createShadowManager(registry.interface(KWayland::Client::Registry::Interface::Shadow).name, registry.interface(KWayland::Client::Registry::Interface::Shadow).version,
this);
92 QVERIFY(m_shadow->isValid());
95void ShadowTest::cleanup()
97#define CLEANUP(variable) \
100 variable = nullptr; \
107 m_connection->deleteLater();
108 m_connection =
nullptr;
121 m_compositorInterface =
nullptr;
122 m_shadowInterface =
nullptr;
125void ShadowTest::testCreateShadow()
129 std::unique_ptr<KWayland::Client::Surface> surface(m_compositor->createSurface());
130 QVERIFY(surfaceCreatedSpy.wait());
131 auto serverSurface = surfaceCreatedSpy.first().first().value<
SurfaceInterface *>();
132 QVERIFY(serverSurface);
134 QVERIFY(!serverSurface->shadow());
138 std::unique_ptr<KWayland::Client::Shadow> shadow(m_shadow->createShadow(surface.get()));
140 QVERIFY(!shadowChangedSpy.wait(100));
143 surface->commit(KWayland::Client::Surface::CommitFlag::None);
144 QVERIFY(shadowChangedSpy.wait());
145 QCOMPARE(shadowChangedSpy.count(), 1);
148 auto serverShadow = serverSurface->shadow();
149 QVERIFY(serverShadow);
150 QCOMPARE(serverShadow->offset(), QMarginsF());
151 QVERIFY(!serverShadow->topLeft());
152 QVERIFY(!serverShadow->top());
153 QVERIFY(!serverShadow->topRight());
154 QVERIFY(!serverShadow->right());
155 QVERIFY(!serverShadow->bottomRight());
156 QVERIFY(!serverShadow->bottom());
157 QVERIFY(!serverShadow->bottomLeft());
158 QVERIFY(!serverShadow->left());
161 m_shadow->removeShadow(surface.get());
163 QVERIFY(!shadowChangedSpy.wait(100));
164 surface->commit(KWayland::Client::Surface::CommitFlag::None);
165 QVERIFY(shadowChangedSpy.wait());
166 QCOMPARE(shadowChangedSpy.count(), 2);
167 QVERIFY(!serverSurface->shadow());
174 if (QImage *image = view.image()) {
175 return image->copy();
181void ShadowTest::testShadowElements()
186 std::unique_ptr<KWayland::Client::Surface> surface(m_compositor->createSurface());
187 QVERIFY(surfaceCreatedSpy.wait());
188 auto serverSurface = surfaceCreatedSpy.first().first().value<
SurfaceInterface *>();
189 QVERIFY(serverSurface);
193 std::unique_ptr<KWayland::Client::Shadow> shadow(m_shadow->createShadow(surface.get()));
194 QImage topLeftImage(QSize(10, 10), QImage::Format_ARGB32_Premultiplied);
195 topLeftImage.fill(Qt::white);
196 shadow->attachTopLeft(m_shm->createBuffer(topLeftImage));
197 QImage topImage(QSize(11, 11), QImage::Format_ARGB32_Premultiplied);
198 topImage.fill(Qt::black);
199 shadow->attachTop(m_shm->createBuffer(topImage));
200 QImage topRightImage(QSize(12, 12), QImage::Format_ARGB32_Premultiplied);
201 topRightImage.fill(Qt::red);
202 shadow->attachTopRight(m_shm->createBuffer(topRightImage));
203 QImage rightImage(QSize(13, 13), QImage::Format_ARGB32_Premultiplied);
204 rightImage.fill(Qt::darkRed);
205 shadow->attachRight(m_shm->createBuffer(rightImage));
206 QImage bottomRightImage(QSize(14, 14), QImage::Format_ARGB32_Premultiplied);
207 bottomRightImage.fill(Qt::green);
208 shadow->attachBottomRight(m_shm->createBuffer(bottomRightImage));
209 QImage bottomImage(QSize(15, 15), QImage::Format_ARGB32_Premultiplied);
210 bottomImage.fill(Qt::darkGreen);
211 shadow->attachBottom(m_shm->createBuffer(bottomImage));
212 QImage bottomLeftImage(QSize(16, 16), QImage::Format_ARGB32_Premultiplied);
213 bottomLeftImage.fill(Qt::blue);
214 shadow->attachBottomLeft(m_shm->createBuffer(bottomLeftImage));
215 QImage leftImage(QSize(17, 17), QImage::Format_ARGB32_Premultiplied);
216 leftImage.fill(Qt::darkBlue);
217 shadow->attachLeft(m_shm->createBuffer(leftImage));
218 shadow->setOffsets(QMarginsF(1, 2, 3, 4));
220 surface->commit(KWayland::Client::Surface::CommitFlag::None);
222 QVERIFY(shadowChangedSpy.wait());
223 auto serverShadow = serverSurface->shadow();
224 QVERIFY(serverShadow);
225 QCOMPARE(serverShadow->offset(), QMarginsF(1, 2, 3, 4));
226 QCOMPARE(bufferToImage(serverShadow->topLeft()), topLeftImage);
227 QCOMPARE(bufferToImage(serverShadow->top()), topImage);
228 QCOMPARE(bufferToImage(serverShadow->topRight()), topRightImage);
229 QCOMPARE(bufferToImage(serverShadow->right()), rightImage);
230 QCOMPARE(bufferToImage(serverShadow->bottomRight()), bottomRightImage);
231 QCOMPARE(bufferToImage(serverShadow->bottom()), bottomImage);
232 QCOMPARE(bufferToImage(serverShadow->bottomLeft()), bottomLeftImage);
233 QCOMPARE(bufferToImage(serverShadow->left()), leftImage);
236void ShadowTest::testSurfaceDestroy()
238 using namespace KWin;
241 std::unique_ptr<KWayland::Client::Surface> surface(m_compositor->createSurface());
242 QVERIFY(serverSurfaceCreated.wait());
243 auto serverSurface = serverSurfaceCreated.first().first().value<
SurfaceInterface *>();
246 std::unique_ptr<KWayland::Client::Shadow> shadow(m_shadow->createShadow(surface.get()));
248 surface->commit(KWayland::Client::Surface::CommitFlag::None);
249 QVERIFY(shadowChangedSpy.wait());
250 auto serverShadow = serverSurface->shadow();
251 QVERIFY(serverShadow);
254 QSignalSpy surfaceDestroyedSpy(serverSurface, &QObject::destroyed);
255 QSignalSpy shadowDestroyedSpy(serverShadow, &QObject::destroyed);
257 QVERIFY(surfaceDestroyedSpy.wait());
258 QVERIFY(shadowDestroyedSpy.isEmpty());
261 QVERIFY(shadowDestroyedSpy.wait());
262 QCOMPARE(shadowDestroyedSpy.count(), 1);
266#include "test_shadow.moc"
void surfaceCreated(KWin::SurfaceInterface *surface)
Class holding the Wayland server display loop.
bool addSocketName(const QString &name=QString())
Resource representing a wl_surface.
#define CLEANUP(variable)