15#include "KWayland/Client/compositor.h"
16#include "KWayland/Client/connection_thread.h"
17#include "KWayland/Client/event_queue.h"
18#include "KWayland/Client/region.h"
19#include "KWayland/Client/registry.h"
20#include "KWayland/Client/shm_pool.h"
21#include "KWayland/Client/subcompositor.h"
22#include "KWayland/Client/subsurface.h"
23#include "KWayland/Client/surface.h"
26#include <wayland-client.h>
41 void testPosition_data();
43 void testPlaceAbove();
44 void testPlaceBelow();
46 void testDeSyncMode();
47 void testMainSurfaceFromTree();
48 void testRemoveSurface();
49 void testMappingOfSurfaceTree();
51 void testDestroyAttachedBuffer();
52 void testDestroyParentSurface();
58 KWayland::Client::ConnectionThread *m_connection;
59 KWayland::Client::Compositor *m_compositor;
60 KWayland::Client::ShmPool *m_shm;
61 KWayland::Client::SubCompositor *m_subCompositor;
62 KWayland::Client::EventQueue *m_queue;
66static const QString s_socketName = QStringLiteral(
"kwayland-test-wayland-subsurface-0");
71 , m_compositorInterface(nullptr)
72 , m_subcompositorInterface(nullptr)
73 , m_connection(nullptr)
74 , m_compositor(nullptr)
76 , m_subCompositor(nullptr)
82void TestSubSurface::init()
93 m_connection =
new KWayland::Client::ConnectionThread;
94 QSignalSpy connectedSpy(m_connection, &KWayland::Client::ConnectionThread::connected);
95 m_connection->setSocketName(s_socketName);
97 m_thread =
new QThread(
this);
98 m_connection->moveToThread(m_thread);
101 m_connection->initConnection();
102 QVERIFY(connectedSpy.wait());
104 m_queue =
new KWayland::Client::EventQueue(
this);
105 QVERIFY(!m_queue->isValid());
106 m_queue->setup(m_connection);
107 QVERIFY(m_queue->isValid());
109 KWayland::Client::Registry registry;
110 QSignalSpy compositorSpy(®istry, &KWayland::Client::Registry::compositorAnnounced);
111 QSignalSpy subCompositorSpy(®istry, &KWayland::Client::Registry::subCompositorAnnounced);
112 QVERIFY(!registry.eventQueue());
113 registry.setEventQueue(m_queue);
114 QCOMPARE(registry.eventQueue(), m_queue);
115 registry.create(m_connection->display());
116 QVERIFY(registry.isValid());
121 QVERIFY(m_subcompositorInterface);
123 QVERIFY(subCompositorSpy.wait());
124 m_subCompositor = registry.createSubCompositor(subCompositorSpy.first().first().value<quint32>(), subCompositorSpy.first().last().value<quint32>(),
this);
126 if (compositorSpy.isEmpty()) {
127 QVERIFY(compositorSpy.wait());
129 m_compositor =
registry.createCompositor(compositorSpy.first().first().value<quint32>(), compositorSpy.first().last().value<quint32>(),
this);
131 m_shm =
registry.createShmPool(
registry.interface(KWayland::Client::Registry::Interface::Shm).name,
132 registry.interface(KWayland::Client::Registry::Interface::Shm).version,
134 QVERIFY(m_shm->isValid());
137void TestSubSurface::cleanup()
143 if (m_subCompositor) {
144 delete m_subCompositor;
145 m_subCompositor =
nullptr;
149 m_compositor =
nullptr;
162 m_connection =
nullptr;
168void TestSubSurface::testCreate()
170 using namespace KWin;
174 std::unique_ptr<KWayland::Client::Surface> surface(m_compositor->createSurface());
175 QVERIFY(surfaceCreatedSpy.wait());
177 QVERIFY(serverSurface);
179 surfaceCreatedSpy.clear();
180 std::unique_ptr<KWayland::Client::Surface> parent(m_compositor->createSurface());
181 QVERIFY(surfaceCreatedSpy.wait());
183 QVERIFY(serverParentSurface);
188 std::unique_ptr<KWayland::Client::SubSurface> subSurface(m_subCompositor->createSubSurface(surface.get(), parent.get()));
190 QVERIFY(subSurfaceCreatedSpy.wait());
192 QVERIFY(serverSubSurface);
194 QCOMPARE(serverSubSurface->
parentSurface(), serverParentSurface);
195 QCOMPARE(serverSubSurface->
surface(), serverSurface);
196 QCOMPARE(serverSurface->
subSurface(), serverSubSurface);
197 QCOMPARE(serverSubSurface->
mainSurface(), serverParentSurface);
199 QCOMPARE(serverParentSurface->
below().count(), 0);
200 QEXPECT_FAIL(
"",
"Incorrect adding of child windows to workaround QtWayland behavior", Continue);
201 QCOMPARE(serverParentSurface->
above().count(), 0);
203 parent->commit(KWayland::Client::Surface::CommitFlag::None);
204 wl_display_flush(m_connection->display());
205 QCoreApplication::processEvents();
206 QCOMPARE(serverParentSurface->
below().count(), 0);
207 QCOMPARE(serverParentSurface->
above().count(), 1);
208 QCOMPARE(serverParentSurface->
above().constFirst(), serverSubSurface);
211 QSignalSpy destroyedSpy(serverSubSurface, &QObject::destroyed);
213 QVERIFY(destroyedSpy.wait());
214 QCOMPARE(serverSurface->
subSurface(), QPointer<SubSurfaceInterface>());
216 QCOMPARE(serverParentSurface->
below().count(), 0);
217 QEXPECT_FAIL(
"",
"Incorrect removing of child windows to workaround QtWayland behavior", Continue);
218 QCOMPARE(serverParentSurface->
above().count(), 1);
220 if (!serverParentSurface->
above().isEmpty()) {
221 QVERIFY(!serverParentSurface->
above().constFirst());
224 parent->commit(KWayland::Client::Surface::CommitFlag::None);
225 wl_display_flush(m_connection->display());
226 QCoreApplication::processEvents();
227 QCOMPARE(serverParentSurface->
below().count(), 0);
228 QCOMPARE(serverParentSurface->
above().count(), 0);
231void TestSubSurface::testMode()
233 using namespace KWin;
235 std::unique_ptr<KWayland::Client::Surface> surface(m_compositor->createSurface());
236 std::unique_ptr<KWayland::Client::Surface> parent(m_compositor->createSurface());
241 std::unique_ptr<KWayland::Client::SubSurface> subSurface(m_subCompositor->createSubSurface(surface.get(), parent.get()));
242 QVERIFY(subSurfaceCreatedSpy.wait());
244 QVERIFY(serverSubSurface);
247 QCOMPARE(subSurface->mode(), KWayland::Client::SubSurface::Mode::Synchronized);
248 QCOMPARE(serverSubSurface->
mode(), SubSurfaceInterface::Mode::Synchronized);
253 subSurface->setMode(KWayland::Client::SubSurface::Mode::Desynchronized);
254 QCOMPARE(subSurface->mode(), KWayland::Client::SubSurface::Mode::Desynchronized);
256 QVERIFY(modeChangedSpy.wait());
258 QCOMPARE(serverSubSurface->
mode(), SubSurfaceInterface::Mode::Desynchronized);
261 subSurface->setMode(KWayland::Client::SubSurface::Mode::Desynchronized);
262 QCOMPARE(subSurface->mode(), KWayland::Client::SubSurface::Mode::Desynchronized);
266 subSurface->setMode(KWayland::Client::SubSurface::Mode::Synchronized);
267 QCOMPARE(subSurface->mode(), KWayland::Client::SubSurface::Mode::Synchronized);
269 QVERIFY(modeChangedSpy.wait());
270 QCOMPARE(modeChangedSpy.count(), 2);
273 QCOMPARE(serverSubSurface->
mode(), SubSurfaceInterface::Mode::Synchronized);
276void TestSubSurface::testPosition_data()
278 QTest::addColumn<KWayland::Client::SubSurface::Mode>(
"commitMode");
280 QTest::addRow(
"sync") << KWayland::Client::SubSurface::Mode::Synchronized;
281 QTest::addRow(
"desync") << KWayland::Client::SubSurface::Mode::Desynchronized;
284void TestSubSurface::testPosition()
286 using namespace KWin;
288 std::unique_ptr<KWayland::Client::Surface> surface(m_compositor->createSurface());
289 std::unique_ptr<KWayland::Client::Surface> parent(m_compositor->createSurface());
294 std::unique_ptr<KWayland::Client::SubSurface> subSurface(m_subCompositor->createSubSurface(surface.get(), parent.get()));
295 QVERIFY(subSurfaceCreatedSpy.wait());
297 QVERIFY(serverSubSurface);
300 QFETCH(KWayland::Client::SubSurface::Mode, commitMode);
301 subSurface->setMode(commitMode);
304 QCOMPARE(subSurface->position(), QPoint());
305 QCOMPARE(serverSubSurface->
position(), QPoint());
310 subSurface->setPosition(QPoint(10, 20));
311 QCOMPARE(subSurface->position(), QPoint(10, 20));
313 wl_display_flush(m_connection->display());
314 QCoreApplication::processEvents();
315 QCOMPARE(serverSubSurface->
position(), QPoint());
317 subSurface->setPosition(QPoint(20, 30));
318 QCOMPARE(subSurface->position(), QPoint(20, 30));
320 wl_display_flush(m_connection->display());
321 QCoreApplication::processEvents();
322 QCOMPARE(serverSubSurface->
position(), QPoint());
325 QSignalSpy parentCommittedSpy(serverSubSurface->
parentSurface(), &SurfaceInterface::committed);
326 parent->commit(KWayland::Client::Surface::CommitFlag::None);
327 QVERIFY(parentCommittedSpy.wait());
328 QCOMPARE(positionChangedSpy.count(), 1);
329 QCOMPARE(positionChangedSpy.first().first().toPoint(), QPoint(20, 30));
330 QCOMPARE(serverSubSurface->
position(), QPoint(20, 30));
333void TestSubSurface::testPlaceAbove()
335 using namespace KWin;
337 std::unique_ptr<KWayland::Client::Surface> surface1(m_compositor->createSurface());
338 std::unique_ptr<KWayland::Client::Surface> surface2(m_compositor->createSurface());
339 std::unique_ptr<KWayland::Client::Surface> surface3(m_compositor->createSurface());
340 std::unique_ptr<KWayland::Client::Surface> parent(m_compositor->createSurface());
345 std::unique_ptr<KWayland::Client::SubSurface> subSurface1(m_subCompositor->createSubSurface(surface1.get(), parent.get()));
346 QVERIFY(subSurfaceCreatedSpy.wait());
348 QVERIFY(serverSubSurface1);
349 subSurfaceCreatedSpy.clear();
350 std::unique_ptr<KWayland::Client::SubSurface> subSurface2(m_subCompositor->createSubSurface(surface2.get(), parent.get()));
351 QVERIFY(subSurfaceCreatedSpy.wait());
353 QVERIFY(serverSubSurface2);
354 subSurfaceCreatedSpy.clear();
355 std::unique_ptr<KWayland::Client::SubSurface> subSurface3(m_subCompositor->createSubSurface(surface3.get(), parent.get()));
356 QVERIFY(subSurfaceCreatedSpy.wait());
358 QVERIFY(serverSubSurface3);
359 subSurfaceCreatedSpy.clear();
363 QEXPECT_FAIL(
"",
"Incorrect adding of child windows to workaround QtWayland behavior", Continue);
367 parent->commit(KWayland::Client::Surface::CommitFlag::None);
369 wl_display_flush(m_connection->display());
370 QCoreApplication::processEvents();
378 subSurface1->placeAbove(subSurface3.get());
380 wl_display_flush(m_connection->display());
381 QCoreApplication::processEvents();
385 parent->commit(KWayland::Client::Surface::CommitFlag::None);
386 wl_display_flush(m_connection->display());
387 QCoreApplication::processEvents();
394 subSurface3->placeAbove(subSurface1.get());
395 parent->commit(KWayland::Client::Surface::CommitFlag::None);
396 wl_display_flush(m_connection->display());
397 QCoreApplication::processEvents();
404 subSurface3->placeAbove(subSurface2.get());
405 parent->commit(KWayland::Client::Surface::CommitFlag::None);
406 wl_display_flush(m_connection->display());
407 QCoreApplication::processEvents();
414 subSurface1->placeAbove(subSurface3.get());
415 parent->commit(KWayland::Client::Surface::CommitFlag::None);
416 wl_display_flush(m_connection->display());
417 QCoreApplication::processEvents();
424 subSurface2->placeAbove(subSurface3.get());
425 parent->commit(KWayland::Client::Surface::CommitFlag::None);
426 wl_display_flush(m_connection->display());
427 QCoreApplication::processEvents();
434void TestSubSurface::testPlaceBelow()
436 using namespace KWin;
438 std::unique_ptr<KWayland::Client::Surface> surface1(m_compositor->createSurface());
439 std::unique_ptr<KWayland::Client::Surface> surface2(m_compositor->createSurface());
440 std::unique_ptr<KWayland::Client::Surface> surface3(m_compositor->createSurface());
441 std::unique_ptr<KWayland::Client::Surface> parent(m_compositor->createSurface());
446 std::unique_ptr<KWayland::Client::SubSurface> subSurface1(m_subCompositor->createSubSurface(surface1.get(), parent.get()));
447 QVERIFY(subSurfaceCreatedSpy.wait());
449 QVERIFY(serverSubSurface1);
450 subSurfaceCreatedSpy.clear();
451 std::unique_ptr<KWayland::Client::SubSurface> subSurface2(m_subCompositor->createSubSurface(surface2.get(), parent.get()));
452 QVERIFY(subSurfaceCreatedSpy.wait());
454 QVERIFY(serverSubSurface2);
455 subSurfaceCreatedSpy.clear();
456 std::unique_ptr<KWayland::Client::SubSurface> subSurface3(m_subCompositor->createSubSurface(surface3.get(), parent.get()));
457 QVERIFY(subSurfaceCreatedSpy.wait());
459 QVERIFY(serverSubSurface3);
460 subSurfaceCreatedSpy.clear();
464 QEXPECT_FAIL(
"",
"Incorrect adding of child windows to workaround QtWayland behavior", Continue);
468 parent->commit(KWayland::Client::Surface::CommitFlag::None);
470 wl_display_flush(m_connection->display());
471 QCoreApplication::processEvents();
478 subSurface3->lower();
480 wl_display_flush(m_connection->display());
481 QCoreApplication::processEvents();
485 parent->commit(KWayland::Client::Surface::CommitFlag::None);
486 wl_display_flush(m_connection->display());
487 QCoreApplication::processEvents();
495 subSurface1->placeBelow(subSurface3.get());
496 parent->commit(KWayland::Client::Surface::CommitFlag::None);
497 wl_display_flush(m_connection->display());
498 QCoreApplication::processEvents();
506 subSurface2->placeBelow(subSurface3.get());
507 parent->commit(KWayland::Client::Surface::CommitFlag::None);
508 wl_display_flush(m_connection->display());
509 QCoreApplication::processEvents();
517 subSurface1->placeBelow(subSurface2.get());
518 parent->commit(KWayland::Client::Surface::CommitFlag::None);
519 wl_display_flush(m_connection->display());
520 QCoreApplication::processEvents();
528 subSurface3->placeBelow(subSurface1.get());
529 parent->commit(KWayland::Client::Surface::CommitFlag::None);
530 wl_display_flush(m_connection->display());
531 QCoreApplication::processEvents();
539void TestSubSurface::testSyncMode()
542 using namespace KWin;
544 QSignalSpy surfaceCreatedSpy(m_compositorInterface, &CompositorInterface::surfaceCreated);
546 std::unique_ptr<KWayland::Client::Surface> surface(m_compositor->createSurface());
547 QVERIFY(surfaceCreatedSpy.wait());
548 auto childSurface = surfaceCreatedSpy.first().first().value<
SurfaceInterface *>();
549 QVERIFY(childSurface);
551 std::unique_ptr<KWayland::Client::Surface> parent(m_compositor->createSurface());
552 QVERIFY(surfaceCreatedSpy.wait());
553 auto parentSurface = surfaceCreatedSpy.last().first().value<
SurfaceInterface *>();
554 QVERIFY(parentSurface);
556 std::unique_ptr<KWayland::Client::SubSurface> subSurface(m_subCompositor->createSubSurface(surface.get(), parent.get()));
559 QSignalSpy childDamagedSpy(childSurface, &SurfaceInterface::damaged);
561 QImage image(QSize(200, 200), QImage::Format_ARGB32_Premultiplied);
562 image.fill(Qt::black);
563 surface->attachBuffer(m_shm->createBuffer(image));
564 surface->damage(QRect(0, 0, 200, 200));
568 QVERIFY(!childDamagedSpy.wait(100));
569 QVERIFY(!childSurface->buffer());
571 QVERIFY(!childSurface->isMapped());
572 QVERIFY(!parentSurface->isMapped());
574 QImage image2(QSize(400, 400), QImage::Format_ARGB32_Premultiplied);
575 image2.fill(Qt::red);
576 parent->attachBuffer(m_shm->createBuffer(image2));
577 parent->damage(QRect(0, 0, 400, 400));
579 QVERIFY(childDamagedSpy.wait());
580 QCOMPARE(childDamagedSpy.count(), 1);
581 QVERIFY(childSurface->isMapped());
582 QVERIFY(parentSurface->isMapped());
585void TestSubSurface::testDeSyncMode()
588 using namespace KWin;
590 QSignalSpy surfaceCreatedSpy(m_compositorInterface, &CompositorInterface::surfaceCreated);
592 std::unique_ptr<KWayland::Client::Surface> surface(m_compositor->createSurface());
593 QVERIFY(surfaceCreatedSpy.wait());
594 auto childSurface = surfaceCreatedSpy.first().first().value<
SurfaceInterface *>();
595 QVERIFY(childSurface);
597 std::unique_ptr<KWayland::Client::Surface> parent(m_compositor->createSurface());
598 QVERIFY(surfaceCreatedSpy.wait());
599 auto parentSurface = surfaceCreatedSpy.last().first().value<
SurfaceInterface *>();
600 QVERIFY(parentSurface);
602 std::unique_ptr<KWayland::Client::SubSurface> subSurface(m_subCompositor->createSubSurface(surface.get(), parent.get()));
605 QSignalSpy childDamagedSpy(childSurface, &SurfaceInterface::damaged);
607 QImage image(QSize(200, 200), QImage::Format_ARGB32_Premultiplied);
608 image.fill(Qt::black);
609 surface->attachBuffer(m_shm->createBuffer(image));
610 surface->damage(QRect(0, 0, 200, 200));
611 surface->commit(KWayland::Client::Surface::CommitFlag::None);
614 QVERIFY(!childDamagedSpy.wait(100));
615 QVERIFY(!childSurface->isMapped());
616 QVERIFY(!parentSurface->isMapped());
619 subSurface->setMode(KWayland::Client::SubSurface::Mode::Desynchronized);
620 QVERIFY(childDamagedSpy.wait());
621 QVERIFY(!childSurface->isMapped());
622 QVERIFY(!parentSurface->isMapped());
626 surface->attachBuffer(m_shm->createBuffer(image));
627 surface->damage(QRect(0, 0, 200, 200));
628 surface->commit(KWayland::Client::Surface::CommitFlag::None);
629 QVERIFY(childDamagedSpy.wait());
632void TestSubSurface::testMainSurfaceFromTree()
635 using namespace KWin;
636 QSignalSpy surfaceCreatedSpy(m_compositorInterface, &CompositorInterface::surfaceCreated);
638 std::unique_ptr<KWayland::Client::Surface> parentSurface(m_compositor->createSurface());
639 QVERIFY(surfaceCreatedSpy.wait());
640 auto parentServerSurface = surfaceCreatedSpy.last().first().value<
SurfaceInterface *>();
641 QVERIFY(parentServerSurface);
642 std::unique_ptr<KWayland::Client::Surface> childLevel1Surface(m_compositor->createSurface());
643 QVERIFY(surfaceCreatedSpy.wait());
644 auto childLevel1ServerSurface = surfaceCreatedSpy.last().first().value<
SurfaceInterface *>();
645 QVERIFY(childLevel1ServerSurface);
646 std::unique_ptr<KWayland::Client::Surface> childLevel2Surface(m_compositor->createSurface());
647 QVERIFY(surfaceCreatedSpy.wait());
648 auto childLevel2ServerSurface = surfaceCreatedSpy.last().first().value<
SurfaceInterface *>();
649 QVERIFY(childLevel2ServerSurface);
650 std::unique_ptr<KWayland::Client::Surface> childLevel3Surface(m_compositor->createSurface());
651 QVERIFY(surfaceCreatedSpy.wait());
652 auto childLevel3ServerSurface = surfaceCreatedSpy.last().first().value<
SurfaceInterface *>();
653 QVERIFY(childLevel3ServerSurface);
655 m_subCompositor->createSubSurface(childLevel1Surface.get(), parentSurface.get());
656 m_subCompositor->createSubSurface(childLevel2Surface.get(), childLevel1Surface.get());
657 m_subCompositor->createSubSurface(childLevel3Surface.get(), childLevel2Surface.get());
659 QSignalSpy parentCommittedSpy(parentServerSurface, &SurfaceInterface::committed);
660 parentSurface->commit(KWayland::Client::Surface::CommitFlag::None);
661 QVERIFY(parentCommittedSpy.wait());
663 QCOMPARE(parentServerSurface->below().count(), 0);
664 QCOMPARE(parentServerSurface->above().count(), 1);
665 auto child = parentServerSurface->above().constFirst();
666 QCOMPARE(child->parentSurface(), parentServerSurface);
667 QCOMPARE(child->mainSurface(), parentServerSurface);
668 QCOMPARE(child->surface()->below().count(), 0);
669 QCOMPARE(child->surface()->above().count(), 1);
670 auto child2 = child->surface()->above().constFirst();
671 QCOMPARE(child2->parentSurface(), child->surface());
672 QCOMPARE(child2->mainSurface(), parentServerSurface);
673 QCOMPARE(child2->surface()->below().count(), 0);
674 QCOMPARE(child2->surface()->above().count(), 1);
675 auto child3 = child2->surface()->above().constFirst();
676 QCOMPARE(child3->parentSurface(), child2->surface());
677 QCOMPARE(child3->mainSurface(), parentServerSurface);
678 QCOMPARE(child3->surface()->below().count(), 0);
679 QCOMPARE(child3->surface()->above().count(), 0);
682void TestSubSurface::testRemoveSurface()
685 using namespace KWin;
687 QSignalSpy surfaceCreatedSpy(m_compositorInterface, &CompositorInterface::surfaceCreated);
689 std::unique_ptr<KWayland::Client::Surface> parentSurface(m_compositor->createSurface());
690 QVERIFY(surfaceCreatedSpy.wait());
691 auto parentServerSurface = surfaceCreatedSpy.last().first().value<
SurfaceInterface *>();
692 QVERIFY(parentServerSurface);
693 std::unique_ptr<KWayland::Client::Surface> childSurface(m_compositor->createSurface());
694 QVERIFY(surfaceCreatedSpy.wait());
695 auto childServerSurface = surfaceCreatedSpy.last().first().value<
SurfaceInterface *>();
696 QVERIFY(childServerSurface);
698 QSignalSpy childrenChangedSpy(parentServerSurface, &SurfaceInterface::childSubSurfacesChanged);
700 m_subCompositor->createSubSurface(childSurface.get(), parentSurface.get());
701 parentSurface->commit(KWayland::Client::Surface::CommitFlag::None);
702 QVERIFY(childrenChangedSpy.wait());
704 QCOMPARE(parentServerSurface->below().count(), 0);
705 QCOMPARE(parentServerSurface->above().count(), 1);
708 childSurface.reset();
709 QVERIFY(childrenChangedSpy.wait());
710 QCOMPARE(parentServerSurface->below().count(), 0);
711 QCOMPARE(parentServerSurface->above().count(), 0);
714void TestSubSurface::testMappingOfSurfaceTree()
717 using namespace KWin;
718 QSignalSpy surfaceCreatedSpy(m_compositorInterface, &CompositorInterface::surfaceCreated);
720 std::unique_ptr<KWayland::Client::Surface> parentSurface(m_compositor->createSurface());
721 QVERIFY(surfaceCreatedSpy.wait());
722 auto parentServerSurface = surfaceCreatedSpy.last().first().value<
SurfaceInterface *>();
723 QVERIFY(parentServerSurface);
724 std::unique_ptr<KWayland::Client::Surface> childLevel1Surface(m_compositor->createSurface());
725 QVERIFY(surfaceCreatedSpy.wait());
726 auto childLevel1ServerSurface = surfaceCreatedSpy.last().first().value<
SurfaceInterface *>();
727 QVERIFY(childLevel1ServerSurface);
728 std::unique_ptr<KWayland::Client::Surface> childLevel2Surface(m_compositor->createSurface());
729 QVERIFY(surfaceCreatedSpy.wait());
730 auto childLevel2ServerSurface = surfaceCreatedSpy.last().first().value<
SurfaceInterface *>();
731 QVERIFY(childLevel2ServerSurface);
732 std::unique_ptr<KWayland::Client::Surface> childLevel3Surface(m_compositor->createSurface());
733 QVERIFY(surfaceCreatedSpy.wait());
734 auto childLevel3ServerSurface = surfaceCreatedSpy.last().first().value<
SurfaceInterface *>();
735 QVERIFY(childLevel3ServerSurface);
737 auto subSurfaceLevel1 = m_subCompositor->createSubSurface(childLevel1Surface.get(), parentSurface.get());
738 auto subSurfaceLevel2 = m_subCompositor->createSubSurface(childLevel2Surface.get(), childLevel1Surface.get());
739 auto subSurfaceLevel3 = m_subCompositor->createSubSurface(childLevel3Surface.get(), childLevel2Surface.get());
741 QSignalSpy parentCommittedSpy(parentServerSurface, &SurfaceInterface::committed);
742 parentSurface->commit(KWayland::Client::Surface::CommitFlag::None);
743 QVERIFY(parentCommittedSpy.wait());
745 QCOMPARE(parentServerSurface->below().count(), 0);
746 QCOMPARE(parentServerSurface->above().count(), 1);
747 auto child = parentServerSurface->above().constFirst();
748 QCOMPARE(child->surface()->below().count(), 0);
749 QCOMPARE(child->surface()->above().count(), 1);
750 auto child2 = child->surface()->above().constFirst();
751 QCOMPARE(child2->surface()->below().count(), 0);
752 QCOMPARE(child2->surface()->above().count(), 1);
753 auto child3 = child2->surface()->above().constFirst();
754 QCOMPARE(child3->parentSurface(), child2->surface());
755 QCOMPARE(child3->mainSurface(), parentServerSurface);
756 QCOMPARE(child3->surface()->below().count(), 0);
757 QCOMPARE(child3->surface()->above().count(), 0);
760 QVERIFY(!parentServerSurface->isMapped());
761 QVERIFY(!child->surface()->isMapped());
762 QVERIFY(!child2->surface()->isMapped());
763 QVERIFY(!child3->surface()->isMapped());
766 subSurfaceLevel1->setMode(KWayland::Client::SubSurface::Mode::Desynchronized);
767 subSurfaceLevel2->setMode(KWayland::Client::SubSurface::Mode::Desynchronized);
768 subSurfaceLevel3->setMode(KWayland::Client::SubSurface::Mode::Desynchronized);
771 QSignalSpy child3DamageSpy(child3->surface(), &SurfaceInterface::damaged);
772 QImage image(QSize(200, 200), QImage::Format_ARGB32_Premultiplied);
773 image.fill(Qt::black);
774 childLevel3Surface->attachBuffer(m_shm->createBuffer(image));
775 childLevel3Surface->damage(QRect(0, 0, 200, 200));
776 childLevel3Surface->commit(KWayland::Client::Surface::CommitFlag::None);
777 QVERIFY(child3DamageSpy.wait());
778 QVERIFY(child3->surface()->buffer());
779 QVERIFY(!child3->surface()->isMapped());
782 QSignalSpy parentSpy(parentServerSurface, &SurfaceInterface::damaged);
783 parentSurface->attachBuffer(m_shm->createBuffer(image));
784 parentSurface->damage(QRect(0, 0, 200, 200));
785 parentSurface->commit(KWayland::Client::Surface::CommitFlag::None);
786 QVERIFY(parentSpy.wait());
787 QVERIFY(parentServerSurface->isMapped());
789 QVERIFY(!child->surface()->isMapped());
790 QVERIFY(!child2->surface()->isMapped());
791 QVERIFY(!child3->surface()->isMapped());
794 QSignalSpy child2DamageSpy(child2->surface(), &SurfaceInterface::damaged);
795 childLevel2Surface->attachBuffer(m_shm->createBuffer(image));
796 childLevel2Surface->damage(QRect(0, 0, 200, 200));
797 childLevel2Surface->commit(KWayland::Client::Surface::CommitFlag::None);
798 QVERIFY(child2DamageSpy.wait());
799 QVERIFY(parentServerSurface->isMapped());
801 QVERIFY(!child->surface()->isMapped());
802 QVERIFY(!child2->surface()->isMapped());
803 QVERIFY(!child3->surface()->isMapped());
806 QSignalSpy child1DamageSpy(child->surface(), &SurfaceInterface::damaged);
807 childLevel1Surface->attachBuffer(m_shm->createBuffer(image));
808 childLevel1Surface->damage(QRect(0, 0, 200, 200));
809 childLevel1Surface->commit(KWayland::Client::Surface::CommitFlag::None);
810 QVERIFY(child1DamageSpy.wait());
813 QVERIFY(parentServerSurface->isMapped());
814 QVERIFY(child->surface()->isMapped());
815 QVERIFY(child2->surface()->isMapped());
816 QVERIFY(child3->surface()->isMapped());
819 QSignalSpy unmappedSpy(child->surface(), &SurfaceInterface::unmapped);
820 childLevel1Surface->attachBuffer(KWayland::Client::Buffer::Ptr());
821 childLevel1Surface->damage(QRect(0, 0, 200, 200));
822 childLevel1Surface->commit(KWayland::Client::Surface::CommitFlag::None);
823 QVERIFY(unmappedSpy.wait());
825 QVERIFY(parentServerSurface->isMapped());
826 QVERIFY(!child->surface()->isMapped());
827 QVERIFY(!child2->surface()->isMapped());
828 QVERIFY(!child3->surface()->isMapped());
831void TestSubSurface::testSurfaceAt()
834 using namespace KWin;
836 QSignalSpy serverSurfaceCreated(m_compositorInterface, &CompositorInterface::surfaceCreated);
837 std::unique_ptr<KWayland::Client::Surface> parent(m_compositor->createSurface());
838 QImage image(QSize(100, 100), QImage::Format_ARGB32_Premultiplied);
840 parent->attachBuffer(m_shm->createBuffer(image));
841 parent->damage(QRect(0, 0, 100, 100));
842 parent->commit(KWayland::Client::Surface::CommitFlag::None);
843 QVERIFY(serverSurfaceCreated.wait());
847 QImage directImage(QSize(50, 50), QImage::Format_ARGB32_Premultiplied);
848 std::unique_ptr<KWayland::Client::Surface> directChild1(m_compositor->createSurface());
849 directChild1->attachBuffer(m_shm->createBuffer(directImage));
850 directChild1->damage(QRect(0, 0, 50, 50));
851 directChild1->commit(KWayland::Client::Surface::CommitFlag::None);
852 QVERIFY(serverSurfaceCreated.wait());
854 QVERIFY(directChild1ServerSurface);
857 std::unique_ptr<KWayland::Client::Surface> directChild2(m_compositor->createSurface());
858 directChild2->attachBuffer(m_shm->createBuffer(directImage));
859 directChild2->damage(QRect(0, 0, 50, 50));
860 directChild2->commit(KWayland::Client::Surface::CommitFlag::None);
861 QVERIFY(serverSurfaceCreated.wait());
863 QVERIFY(directChild2ServerSurface);
866 std::unique_ptr<KWayland::Client::SubSurface> directChild1SubSurface(m_subCompositor->createSubSurface(directChild1.get(), parent.get()));
867 directChild1SubSurface->setMode(KWayland::Client::SubSurface::Mode::Desynchronized);
868 std::unique_ptr<KWayland::Client::SubSurface> directChild2SubSurface(m_subCompositor->createSubSurface(directChild2.get(), parent.get()));
869 directChild2SubSurface->setMode(KWayland::Client::SubSurface::Mode::Desynchronized);
870 directChild2SubSurface->setPosition(QPoint(50, 50));
873 QSignalSpy directChild1CommittedSpy(directChild1ServerSurface, &SurfaceInterface::committed);
874 directChild1->setInputRegion(m_compositor->createRegion(QRegion()).get());
875 directChild1->commit(KWayland::Client::Surface::CommitFlag::None);
876 parent->commit(KWayland::Client::Surface::CommitFlag::None);
877 QVERIFY(directChild1CommittedSpy.wait());
879 QSignalSpy directChild2CommittedSpy(directChild2ServerSurface, &SurfaceInterface::committed);
880 directChild2->setInputRegion(m_compositor->createRegion(QRegion()).get());
881 directChild2->commit(KWayland::Client::Surface::CommitFlag::None);
882 parent->commit(KWayland::Client::Surface::CommitFlag::None);
883 QVERIFY(directChild2CommittedSpy.wait());
886 std::unique_ptr<KWayland::Client::Surface> childFor1(m_compositor->createSurface());
887 QVERIFY(serverSurfaceCreated.wait());
889 std::unique_ptr<KWayland::Client::Surface> childFor2(m_compositor->createSurface());
890 QVERIFY(serverSurfaceCreated.wait());
894 std::unique_ptr<KWayland::Client::SubSurface> childFor1SubSurface(m_subCompositor->createSubSurface(childFor1.get(), directChild1.get()));
895 childFor1SubSurface->setMode(KWayland::Client::SubSurface::Mode::Desynchronized);
896 std::unique_ptr<KWayland::Client::SubSurface> childFor2SubSurface(m_subCompositor->createSubSurface(childFor2.get(), directChild2.get()));
897 childFor2SubSurface->setMode(KWayland::Client::SubSurface::Mode::Desynchronized);
900 QImage partImage(QSize(50, 50), QImage::Format_ARGB32_Premultiplied);
901 partImage.fill(Qt::green);
902 childFor1->attachBuffer(m_shm->createBuffer(partImage));
903 childFor1->damage(QRect(0, 0, 50, 50));
904 childFor1->commit(KWayland::Client::Surface::CommitFlag::None);
905 partImage.fill(Qt::blue);
907 QSignalSpy childFor2CommittedSpy(childFor2ServerSurface, &SurfaceInterface::committed);
908 childFor2->attachBuffer(m_shm->createBuffer(partImage));
911 region += QRect(0, 0, 25, 25);
912 region += QRect(25, 25, 25, 25);
913 childFor2->setInputRegion(m_compositor->createRegion(region).get());
914 childFor2->damage(QRect(0, 0, 50, 50));
915 childFor2->commit(KWayland::Client::Surface::CommitFlag::None);
916 QVERIFY(childFor2CommittedSpy.wait());
924 QCOMPARE(parentServerSurface->
surfaceAt(QPointF(0, 0)), childFor1ServerSurface);
925 QCOMPARE(parentServerSurface->
surfaceAt(QPointF(49, 49)), childFor1ServerSurface);
926 QCOMPARE(parentServerSurface->
surfaceAt(QPointF(50, 50)), childFor2ServerSurface);
927 QCOMPARE(parentServerSurface->
surfaceAt(QPointF(99, 99)), childFor2ServerSurface);
928 QCOMPARE(parentServerSurface->
surfaceAt(QPointF(99, 50)), childFor2ServerSurface);
929 QCOMPARE(parentServerSurface->
surfaceAt(QPointF(50, 99)), childFor2ServerSurface);
930 QCOMPARE(parentServerSurface->
surfaceAt(QPointF(25, 75)), parentServerSurface);
931 QCOMPARE(parentServerSurface->
surfaceAt(QPointF(75, 25)), parentServerSurface);
933 QCOMPARE(parentServerSurface->
inputSurfaceAt(QPointF(0, 0)), childFor1ServerSurface);
934 QCOMPARE(parentServerSurface->
inputSurfaceAt(QPointF(49, 49)), childFor1ServerSurface);
935 QCOMPARE(parentServerSurface->
inputSurfaceAt(QPointF(50, 50)), childFor2ServerSurface);
936 QCOMPARE(parentServerSurface->
inputSurfaceAt(QPointF(99, 99)), childFor2ServerSurface);
937 QCOMPARE(parentServerSurface->
inputSurfaceAt(QPointF(99, 50)), parentServerSurface);
938 QCOMPARE(parentServerSurface->
inputSurfaceAt(QPointF(50, 99)), parentServerSurface);
939 QCOMPARE(parentServerSurface->
inputSurfaceAt(QPointF(25, 75)), parentServerSurface);
940 QCOMPARE(parentServerSurface->
inputSurfaceAt(QPointF(75, 25)), parentServerSurface);
943 QVERIFY(!parentServerSurface->
surfaceAt(QPointF(-1, -1)));
944 QVERIFY(!parentServerSurface->
surfaceAt(QPointF(101, 101)));
947 QCOMPARE(parentServerSurface->
surfaceAt(QPointF(50, 25)), parentServerSurface);
948 QCOMPARE(parentServerSurface->
surfaceAt(QPointF(25, 50)), parentServerSurface);
949 QCOMPARE(parentServerSurface->
inputSurfaceAt(QPointF(50, 25)), parentServerSurface);
950 QCOMPARE(parentServerSurface->
inputSurfaceAt(QPointF(25, 50)), parentServerSurface);
953void TestSubSurface::testDestroyAttachedBuffer()
956 using namespace KWin;
958 QSignalSpy serverSurfaceCreated(m_compositorInterface, &CompositorInterface::surfaceCreated);
959 std::unique_ptr<KWayland::Client::Surface> parent(m_compositor->createSurface());
960 QVERIFY(serverSurfaceCreated.wait());
961 std::unique_ptr<KWayland::Client::Surface> child(m_compositor->createSurface());
962 QVERIFY(serverSurfaceCreated.wait());
965 m_subCompositor->createSubSurface(child.get(), parent.get());
968 QImage image(QSize(100, 100), QImage::Format_ARGB32_Premultiplied);
970 child->attachBuffer(m_shm->createBuffer(image));
971 child->damage(QRect(0, 0, 100, 100));
972 child->commit(KWayland::Client::Surface::CommitFlag::None);
973 m_connection->flush();
976 QSignalSpy destroySpy(serverChildSurface, &QObject::destroyed);
980 QVERIFY(destroySpy.wait());
983void TestSubSurface::testDestroyParentSurface()
987 using namespace KWin;
989 QSignalSpy serverSurfaceCreated(m_compositorInterface, &CompositorInterface::surfaceCreated);
990 std::unique_ptr<KWayland::Client::Surface> parent(m_compositor->createSurface());
991 QVERIFY(serverSurfaceCreated.wait());
993 std::unique_ptr<KWayland::Client::Surface> child(m_compositor->createSurface());
994 QVERIFY(serverSurfaceCreated.wait());
996 std::unique_ptr<KWayland::Client::Surface> grandChild(m_compositor->createSurface());
997 QVERIFY(serverSurfaceCreated.wait());
1000 auto sub1 = m_subCompositor->createSubSurface(child.get(), parent.get());
1001 sub1->setMode(KWayland::Client::SubSurface::Mode::Desynchronized);
1002 auto sub2 = m_subCompositor->createSubSurface(grandChild.get(), child.get());
1003 sub2->setMode(KWayland::Client::SubSurface::Mode::Desynchronized);
1008 QSignalSpy parentDestroyedSpy(serverParentSurface, &QObject::destroyed);
1009 QVERIFY(parentDestroyedSpy.wait());
1010 QImage image(QSize(100, 100), QImage::Format_ARGB32_Premultiplied);
1011 image.fill(Qt::red);
1012 grandChild->attachBuffer(m_shm->createBuffer(image));
1013 grandChild->damage(QRect(0, 0, 100, 100));
1014 grandChild->commit(KWayland::Client::Surface::CommitFlag::None);
1015 QSignalSpy damagedSpy(serverGrandChildSurface, &SurfaceInterface::damaged);
1016 QVERIFY(damagedSpy.wait());
1019 QSignalSpy destroySpy(serverChildSurface, &QObject::destroyed);
1021 QVERIFY(destroySpy.wait());
1025#include "test_wayland_subsurface.moc"
void surfaceCreated(KWin::SurfaceInterface *surface)
Class holding the Wayland server display loop.
bool addSocketName(const QString &name=QString())
void subSurfaceCreated(KWin::SubSurfaceInterface *subsurface)
SurfaceInterface * parentSurface() const
SurfaceInterface * surface() const
void positionChanged(const QPoint &position)
void modeChanged(KWin::SubSurfaceInterface::Mode mode)
SurfaceInterface * mainSurface() const
Resource representing a wl_surface.
SurfaceInterface * surfaceAt(const QPointF &position)
SubSurfaceInterface * subSurface() const
QList< SubSurfaceInterface * > above() const
QList< SubSurfaceInterface * > below() const
SurfaceInterface * inputSurfaceAt(const QPointF &position)
TestSubSurface(QObject *parent=nullptr)
KWayland::Client::Registry * registry