21#include "KWayland/Client/compositor.h"
22#include "KWayland/Client/connection_thread.h"
23#include "KWayland/Client/event_queue.h"
24#include "KWayland/Client/idleinhibit.h"
25#include "KWayland/Client/output.h"
26#include "KWayland/Client/region.h"
27#include "KWayland/Client/registry.h"
28#include "KWayland/Client/shm_pool.h"
29#include "KWayland/Client/surface.h"
34#include <wayland-client-protocol.h>
45 void testStaticAccessor();
47 void testFrameCallback();
48 void testAttachBuffer();
52 void testUnmapOfNotMappedSurface();
54 void testDestroyAttachedBuffer();
55 void testDestroyWithPendingCallback();
57 void testDisconnect();
64 KWayland::Client::ConnectionThread *m_connection;
65 KWayland::Client::Compositor *m_compositor;
66 KWayland::Client::ShmPool *m_shm;
67 KWayland::Client::EventQueue *m_queue;
68 KWayland::Client::IdleInhibitManager *m_idleInhibitManager;
72static const QString s_socketName = QStringLiteral(
"kwin-test-wayland-surface-0");
77 , m_compositorInterface(nullptr)
78 , m_connection(nullptr)
79 , m_compositor(nullptr)
84void TestWaylandSurface::init()
95 QVERIFY(m_compositorInterface);
98 QVERIFY(m_idleInhibitInterface);
101 m_connection =
new KWayland::Client::ConnectionThread;
102 QSignalSpy connectedSpy(m_connection, &KWayland::Client::ConnectionThread::connected);
103 m_connection->setSocketName(s_socketName);
105 m_thread =
new QThread(
this);
106 m_connection->moveToThread(m_thread);
117 m_connection->initConnection();
118 QVERIFY(connectedSpy.wait());
120 m_queue =
new KWayland::Client::EventQueue(
this);
121 QVERIFY(!m_queue->isValid());
122 m_queue->setup(m_connection);
123 QVERIFY(m_queue->isValid());
125 KWayland::Client::Registry registry;
126 registry.setEventQueue(m_queue);
127 QSignalSpy compositorSpy(®istry, &KWayland::Client::Registry::compositorAnnounced);
128 QSignalSpy shmSpy(®istry, &KWayland::Client::Registry::shmAnnounced);
129 QSignalSpy allAnnounced(®istry, &KWayland::Client::Registry::interfacesAnnounced);
130 registry.create(m_connection->display());
131 QVERIFY(registry.isValid());
133 QVERIFY(allAnnounced.wait());
134 QVERIFY(!compositorSpy.isEmpty());
135 QVERIFY(!shmSpy.isEmpty());
137 m_compositor = registry.createCompositor(compositorSpy.first().first().value<quint32>(), compositorSpy.first().last().value<quint32>(),
this);
138 QVERIFY(m_compositor->isValid());
139 m_shm = registry.createShmPool(shmSpy.first().first().value<quint32>(), shmSpy.first().last().value<quint32>(),
this);
140 QVERIFY(m_shm->isValid());
142 m_idleInhibitManager = registry.createIdleInhibitManager(registry.interface(KWayland::Client::Registry::Interface::IdleInhibitManagerUnstableV1).name,
143 registry.interface(KWayland::Client::Registry::Interface::IdleInhibitManagerUnstableV1).version,
145 QVERIFY(m_idleInhibitManager->isValid());
148void TestWaylandSurface::cleanup()
152 m_compositor =
nullptr;
154 if (m_idleInhibitManager) {
155 delete m_idleInhibitManager;
156 m_idleInhibitManager =
nullptr;
173 m_connection =
nullptr;
179 m_compositorInterface =
nullptr;
180 m_idleInhibitInterface =
nullptr;
183void TestWaylandSurface::testStaticAccessor()
189 QVERIFY(KWayland::Client::Surface::all().isEmpty());
190 std::unique_ptr<KWayland::Client::Surface> s1(m_compositor->createSurface());
191 QVERIFY(s1->isValid());
192 QCOMPARE(KWayland::Client::Surface::all().count(), 1);
193 QCOMPARE(KWayland::Client::Surface::all().first(), s1.get());
194 QCOMPARE(KWayland::Client::Surface::get(*s1), s1.get());
195 QVERIFY(serverSurfaceCreated.wait());
197 QVERIFY(serverSurface1);
201 QVERIFY(!s1->size().isValid());
202 QSignalSpy sizeChangedSpy(s1.get(), &KWayland::Client::Surface::sizeChanged);
203 const QSize testSize(200, 300);
204 s1->setSize(testSize);
205 QCOMPARE(s1->size(), testSize);
206 QCOMPARE(sizeChangedSpy.count(), 1);
207 QCOMPARE(sizeChangedSpy.first().first().toSize(), testSize);
210 std::unique_ptr<KWayland::Client::Surface> s2(m_compositor->createSurface());
211 QVERIFY(s2->isValid());
212 QCOMPARE(KWayland::Client::Surface::all().count(), 2);
213 QCOMPARE(KWayland::Client::Surface::all().first(), s1.get());
214 QCOMPARE(KWayland::Client::Surface::all().last(), s2.get());
215 QCOMPARE(KWayland::Client::Surface::get(*s1), s1.get());
216 QCOMPARE(KWayland::Client::Surface::get(*s2), s2.get());
217 serverSurfaceCreated.clear();
218 QVERIFY(serverSurfaceCreated.wait());
220 QVERIFY(serverSurface2);
226 const quint32 surfaceId1 = serverSurface1->id();
227 const quint32 surfaceId2 = serverSurface2->id();
231 QCOMPARE(KWayland::Client::Surface::all().count(), 1);
232 QCOMPARE(KWayland::Client::Surface::all().first(), s1.get());
233 QCOMPARE(KWayland::Client::Surface::get(*s1), s1.get());
237 QVERIFY(KWayland::Client::Surface::all().isEmpty());
238 QVERIFY(!KWayland::Client::Surface::get(
nullptr));
239 QSignalSpy destroyedSpy(serverSurface1, &KWin::SurfaceInterface::destroyed);
240 QVERIFY(destroyedSpy.wait());
246void TestWaylandSurface::testDamage()
249 std::unique_ptr<KWayland::Client::Surface> s(m_compositor->createSurface());
251 QVERIFY(serverSurfaceCreated.wait());
253 QVERIFY(serverSurface);
255 QVERIFY(!serverSurface->
isMapped());
262 s->damage(QRect(0, 0, 100, 100));
263 s->commit(KWayland::Client::Surface::CommitFlag::None);
264 wl_display_flush(m_connection->display());
265 QCoreApplication::processEvents();
266 QCoreApplication::processEvents();
267 QVERIFY(damageSpy.isEmpty());
268 QVERIFY(!serverSurface->
isMapped());
269 QCOMPARE(committedSpy.count(), 1);
274 QImage img(QSize(10, 10), QImage::Format_ARGB32_Premultiplied);
276 auto b = m_shm->createBuffer(img);
277 s->attachBuffer(b, QPoint(55, 55));
278 s->damage(QRect(0, 0, 10, 10));
279 s->commit(KWayland::Client::Surface::CommitFlag::None);
280 QVERIFY(damageSpy.wait());
281 QCOMPARE(serverSurface->
offset(), QPoint(55, 55));
282 QCOMPARE(serverSurface->
bufferDamage(), QRegion(0, 0, 10, 10));
283 QCOMPARE(damageSpy.first().first().value<QRegion>(), QRegion(0, 0, 10, 10));
285 QCOMPARE(committedSpy.count(), 2);
290 const QRegion surfaceDamage = QRegion(5, 8, 3, 6).united(QRect(10, 11, 6, 1));
291 const QRegion expectedDamage = QRegion(10, 16, 6, 12).united(QRect(20, 22, 12, 2));
292 QImage img(QSize(80, 70), QImage::Format_ARGB32_Premultiplied);
294 auto b = m_shm->createBuffer(img);
296 s->damage(surfaceDamage);
298 s->commit(KWayland::Client::Surface::CommitFlag::None);
299 QVERIFY(damageSpy.wait());
300 QCOMPARE(serverSurface->
bufferDamage(), expectedDamage);
301 QCOMPARE(damageSpy.first().first().value<QRegion>(), expectedDamage);
303 QCOMPARE(committedSpy.count(), 3);
308 const QRegion damage(30, 40, 22, 4);
309 QImage img(QSize(80, 70), QImage::Format_ARGB32_Premultiplied);
311 auto b = m_shm->createBuffer(img);
313 s->damageBuffer(damage);
315 s->commit(KWayland::Client::Surface::CommitFlag::None);
316 QVERIFY(damageSpy.wait());
318 QCOMPARE(damageSpy.first().first().value<QRegion>(), damage);
324 const QRegion surfaceDamage(10, 20, 5, 5);
325 const QRegion bufferDamage(30, 50, 50, 20);
326 const QRegion expectedDamage = QRegion(20, 40, 10, 10).united(QRect(30, 50, 50, 20));
327 QImage img(QSize(80, 70), QImage::Format_ARGB32_Premultiplied);
329 auto b = m_shm->createBuffer(img);
331 s->damage(surfaceDamage);
332 s->damageBuffer(bufferDamage);
334 s->commit(KWayland::Client::Surface::CommitFlag::None);
335 QVERIFY(damageSpy.wait());
336 QCOMPARE(serverSurface->
bufferDamage(), expectedDamage);
337 QCOMPARE(damageSpy.first().first().value<QRegion>(), expectedDamage);
342void TestWaylandSurface::testFrameCallback()
345 std::unique_ptr<KWayland::Client::Surface> s(m_compositor->createSurface());
346 QVERIFY(serverSurfaceCreated.wait());
348 QVERIFY(serverSurface);
352 QSignalSpy frameRenderedSpy(s.get(), &KWayland::Client::Surface::frameRendered);
353 QImage img(QSize(10, 10), QImage::Format_ARGB32_Premultiplied);
355 auto b = m_shm->createBuffer(img);
357 s->damage(QRect(0, 0, 10, 10));
359 QVERIFY(damageSpy.wait());
361 QVERIFY(frameRenderedSpy.isEmpty());
362 QVERIFY(frameRenderedSpy.wait());
363 QVERIFY(!frameRenderedSpy.isEmpty());
366void TestWaylandSurface::testAttachBuffer()
370 std::unique_ptr<KWayland::Client::Surface> s(m_compositor->createSurface());
371 QVERIFY(serverSurfaceCreated.wait());
373 QVERIFY(serverSurface);
376 QImage black(24, 24, QImage::Format_RGB32);
377 black.fill(Qt::black);
378 QImage red(24, 24, QImage::Format_ARGB32);
379 red.fill(QColor(255, 0, 0, 128));
380 QImage blue(24, 24, QImage::Format_ARGB32_Premultiplied);
381 blue.fill(QColor(0, 0, 255, 128));
383 QSharedPointer<KWayland::Client::Buffer> blackBufferPtr = m_shm->createBuffer(black).toStrongRef();
384 QVERIFY(blackBufferPtr);
385 wl_buffer *blackBuffer = *(blackBufferPtr.data());
386 QSharedPointer<KWayland::Client::Buffer> redBuffer = m_shm->createBuffer(red).toStrongRef();
388 QSharedPointer<KWayland::Client::Buffer> blueBuffer = m_shm->createBuffer(blue).toStrongRef();
391 QCOMPARE(blueBuffer->format(), KWayland::Client::Buffer::Format::ARGB32);
392 QCOMPARE(blueBuffer->size(), blue.size());
393 QVERIFY(!blueBuffer->isReleased());
394 QVERIFY(!blueBuffer->isUsed());
395 QCOMPARE(blueBuffer->stride(), blue.bytesPerLine());
397 s->attachBuffer(redBuffer.data());
398 s->attachBuffer(blackBuffer);
399 s->damage(QRect(0, 0, 24, 24));
400 s->commit(KWayland::Client::Surface::CommitFlag::None);
404 QVERIFY(damageSpy.wait());
405 QCOMPARE(mappedSpy.count(), 1);
406 QVERIFY(unmappedSpy.isEmpty());
413 QVERIFY(view.image());
414 QCOMPARE(*view.image(), black);
415 QCOMPARE(view.image()->format(), QImage::Format_RGB32);
416 QCOMPARE(view.image()->size(), QSize(24, 24));
420 s->attachBuffer(redBuffer);
421 s->damage(QRect(0, 0, 24, 24));
422 s->commit(KWayland::Client::Surface::CommitFlag::None);
424 QVERIFY(damageSpy.wait());
425 QCOMPARE(mappedSpy.count(), 1);
426 QVERIFY(unmappedSpy.isEmpty());
431 QVERIFY(view.image());
432 QCOMPARE(view.image()->format(), QImage::Format_ARGB32_Premultiplied);
433 QCOMPARE(view.image()->size(), QSize(24, 24));
434 for (
int i = 0; i < 24; ++i) {
435 for (
int j = 0; j < 24; ++j) {
437 QCOMPARE(view.image()->pixel(i, j), qRgba(128, 0, 0, 128));
443 QVERIFY(!redBuffer.data()->isReleased());
446 blueBuffer->setUsed(
true);
447 QVERIFY(blueBuffer->isUsed());
448 s->attachBuffer(blueBuffer.data());
449 s->damage(QRect(0, 0, 24, 24));
450 QSignalSpy frameRenderedSpy(s.get(), &KWayland::Client::Surface::frameRendered);
453 QVERIFY(damageSpy.wait());
454 QCOMPARE(mappedSpy.count(), 1);
455 QVERIFY(unmappedSpy.isEmpty());
458 QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents);
459 if (!redBuffer.data()->isReleased()) {
460 QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents);
462 QVERIFY(redBuffer.data()->isReleased());
468 QVERIFY(view.image());
469 QCOMPARE(view.image()->format(), QImage::Format_ARGB32_Premultiplied);
470 QCOMPARE(view.image()->size(), QSize(24, 24));
471 for (
int i = 0; i < 24; ++i) {
472 for (
int j = 0; j < 24; ++j) {
474 QCOMPARE(view.image()->pixel(i, j), qRgba(0, 0, 128, 128));
482 QVERIFY(frameRenderedSpy.wait());
485 QCOMPARE(serverSurface->
buffer(), buffer3);
487 s->setInputRegion(m_compositor->createRegion(QRegion(0, 0, 24, 24)).get());
488 s->commit(KWayland::Client::Surface::CommitFlag::None);
489 wl_display_flush(m_connection->display());
490 QCoreApplication::processEvents();
491 QCoreApplication::processEvents();
492 QCOMPARE(serverSurface->
buffer(), buffer3);
493 QVERIFY(damageSpy.isEmpty());
494 QCOMPARE(mappedSpy.count(), 1);
495 QVERIFY(unmappedSpy.isEmpty());
499 s->attachBuffer(blackBuffer);
500 s->damage(QRect(0, 0, 1, 1));
502 s->attachBuffer((wl_buffer *)
nullptr);
503 s->damage(QRect(0, 0, 10, 10));
504 s->commit(KWayland::Client::Surface::CommitFlag::None);
505 QVERIFY(unmappedSpy.wait());
506 QCOMPARE(mappedSpy.count(), 1);
507 QCOMPARE(unmappedSpy.count(), 1);
508 QVERIFY(damageSpy.isEmpty());
509 QVERIFY(!serverSurface->
isMapped());
515void TestWaylandSurface::testOpaque()
517 using namespace KWin;
519 std::unique_ptr<KWayland::Client::Surface> s(m_compositor->createSurface());
520 QVERIFY(serverSurfaceCreated.wait());
522 QVERIFY(serverSurface);
526 QCOMPARE(serverSurface->
opaque(), QRegion());
529 s->setOpaqueRegion(m_compositor->createRegion(QRegion(0, 10, 20, 30)).get());
531 wl_display_flush(m_connection->display());
532 QCoreApplication::processEvents();
533 QCOMPARE(serverSurface->
opaque(), QRegion());
534 QCOMPARE(opaqueRegionChangedSpy.count(), 0);
537 QImage black(20, 40, QImage::Format_ARGB32_Premultiplied);
538 black.fill(Qt::black);
539 QSharedPointer<KWayland::Client::Buffer> buffer1 = m_shm->createBuffer(black).toStrongRef();
540 s->attachBuffer(buffer1);
541 s->commit(KWayland::Client::Surface::CommitFlag::None);
542 QVERIFY(opaqueRegionChangedSpy.wait());
543 QCOMPARE(opaqueRegionChangedSpy.count(), 1);
544 QCOMPARE(opaqueRegionChangedSpy.last().first().value<QRegion>(), QRegion(0, 10, 20, 30));
545 QCOMPARE(serverSurface->
opaque(), QRegion(0, 10, 20, 30));
548 s->commit(KWayland::Client::Surface::CommitFlag::None);
549 wl_display_flush(m_connection->display());
550 QCoreApplication::processEvents();
551 QCOMPARE(opaqueRegionChangedSpy.count(), 1);
552 QCOMPARE(serverSurface->
opaque(), QRegion(0, 10, 20, 30));
555 s->setOpaqueRegion(m_compositor->createRegion(QRegion(10, 20, 30, 40)).get());
556 s->commit(KWayland::Client::Surface::CommitFlag::None);
557 QVERIFY(opaqueRegionChangedSpy.wait());
558 QCOMPARE(opaqueRegionChangedSpy.count(), 2);
559 QCOMPARE(opaqueRegionChangedSpy.last().first().value<QRegion>(), QRegion(10, 20, 10, 20));
560 QCOMPARE(serverSurface->
opaque(), QRegion(10, 20, 10, 20));
563 s->setOpaqueRegion();
564 s->commit(KWayland::Client::Surface::CommitFlag::None);
565 QVERIFY(opaqueRegionChangedSpy.wait());
566 QCOMPARE(opaqueRegionChangedSpy.count(), 3);
567 QCOMPARE(opaqueRegionChangedSpy.last().first().value<QRegion>(), QRegion());
568 QCOMPARE(serverSurface->
opaque(), QRegion());
571void TestWaylandSurface::testInput()
573 using namespace KWin;
575 std::unique_ptr<KWayland::Client::Surface> s(m_compositor->createSurface());
576 QVERIFY(serverSurfaceCreated.wait());
578 QVERIFY(serverSurface);
580 QSignalSpy committedSpy(serverSurface, &SurfaceInterface::committed);
583 QVERIFY(!serverSurface->
isMapped());
584 QCOMPARE(serverSurface->
input(), QRegion());
587 QImage black(100, 50, QImage::Format_RGB32);
588 black.fill(Qt::black);
589 QSharedPointer<KWayland::Client::Buffer> buffer1 = m_shm->createBuffer(black).toStrongRef();
591 s->attachBuffer(buffer1);
592 s->commit(KWayland::Client::Surface::CommitFlag::None);
593 QVERIFY(committedSpy.wait());
595 QCOMPARE(inputRegionChangedSpy.count(), 1);
596 QCOMPARE(serverSurface->
input(), QRegion(0, 0, 100, 50));
599 s->setInputRegion(m_compositor->createRegion(QRegion(0, 10, 20, 30)).get());
601 wl_display_flush(m_connection->display());
602 QCoreApplication::processEvents();
603 QCOMPARE(inputRegionChangedSpy.count(), 1);
604 QCOMPARE(serverSurface->
input(), QRegion(0, 0, 100, 50));
607 s->commit(KWayland::Client::Surface::CommitFlag::None);
608 QVERIFY(committedSpy.wait());
609 QCOMPARE(inputRegionChangedSpy.count(), 2);
610 QCOMPARE(serverSurface->
input(), QRegion(0, 10, 20, 30));
613 s->commit(KWayland::Client::Surface::CommitFlag::None);
614 wl_display_flush(m_connection->display());
615 QCoreApplication::processEvents();
616 QCOMPARE(inputRegionChangedSpy.count(), 2);
617 QCOMPARE(serverSurface->
input(), QRegion(0, 10, 20, 30));
620 s->setInputRegion(m_compositor->createRegion(QRegion(10, 20, 30, 40)).get());
621 s->commit(KWayland::Client::Surface::CommitFlag::None);
622 QVERIFY(committedSpy.wait());
623 QCOMPARE(inputRegionChangedSpy.count(), 3);
624 QCOMPARE(serverSurface->
input(), QRegion(10, 20, 30, 30));
628 s->commit(KWayland::Client::Surface::CommitFlag::None);
629 QVERIFY(committedSpy.wait());
630 QCOMPARE(inputRegionChangedSpy.count(), 4);
631 QCOMPARE(serverSurface->
input(), QRegion(0, 0, 100, 50));
634void TestWaylandSurface::testScale()
637 using namespace KWin;
639 QSignalSpy serverSurfaceCreated(m_compositorInterface, &CompositorInterface::surfaceCreated);
640 std::unique_ptr<KWayland::Client::Surface> s(m_compositor->createSurface());
641 QCOMPARE(s->scale(), 1);
642 QVERIFY(serverSurfaceCreated.wait());
644 QVERIFY(serverSurface);
647 QSignalSpy sizeChangedSpy(serverSurface, &SurfaceInterface::sizeChanged);
650 QImage red(100, 100, QImage::Format_ARGB32_Premultiplied);
651 red.fill(QColor(255, 0, 0, 128));
652 QSharedPointer<KWayland::Client::Buffer> redBuffer = m_shm->createBuffer(red).toStrongRef();
654 s->attachBuffer(redBuffer.data());
655 s->damageBuffer(QRect(0, 0, 100, 100));
656 s->commit(KWayland::Client::Surface::CommitFlag::None);
657 QVERIFY(sizeChangedSpy.wait());
658 QCOMPARE(sizeChangedSpy.count(), 1);
659 QCOMPARE(serverSurface->
size(), QSize(100, 100));
663 s->commit(KWayland::Client::Surface::CommitFlag::None);
664 QVERIFY(sizeChangedSpy.wait());
665 QCOMPARE(sizeChangedSpy.count(), 2);
666 QCOMPARE(serverSurface->
size(), QSize(50, 50));
669 QImage blue(60, 60, QImage::Format_ARGB32_Premultiplied);
670 red.fill(QColor(255, 0, 0, 128));
671 QSharedPointer<KWayland::Client::Buffer> blueBuffer = m_shm->createBuffer(blue).toStrongRef();
673 s->attachBuffer(blueBuffer.data());
675 s->commit(KWayland::Client::Surface::CommitFlag::None);
676 QVERIFY(sizeChangedSpy.wait());
677 QCOMPARE(sizeChangedSpy.count(), 3);
678 QCOMPARE(serverSurface->
size(), QSize(20, 20));
681void TestWaylandSurface::testUnmapOfNotMappedSurface()
684 using namespace KWin;
686 QSignalSpy serverSurfaceCreated(m_compositorInterface, &CompositorInterface::surfaceCreated);
687 std::unique_ptr<KWayland::Client::Surface> s(m_compositor->createSurface());
688 QVERIFY(serverSurfaceCreated.wait());
691 QSignalSpy unmappedSpy(serverSurface, &SurfaceInterface::unmapped);
692 QSignalSpy committedSpy(serverSurface, &SurfaceInterface::committed);
695 s->attachBuffer(KWayland::Client::Buffer::Ptr());
696 s->commit(KWayland::Client::Surface::CommitFlag::None);
698 QVERIFY(committedSpy.wait());
699 QVERIFY(unmappedSpy.isEmpty());
702void TestWaylandSurface::testSurfaceAt()
705 using namespace KWin;
707 QSignalSpy serverSurfaceCreated(m_compositorInterface, &CompositorInterface::surfaceCreated);
708 std::unique_ptr<KWayland::Client::Surface> s(m_compositor->createSurface());
709 QVERIFY(serverSurfaceCreated.wait());
713 QVERIFY(!serverSurface->
isMapped());
714 QVERIFY(!serverSurface->
surfaceAt(QPointF(0, 0)));
717 QSignalSpy sizeChangedSpy(serverSurface, &SurfaceInterface::sizeChanged);
718 QImage image(QSize(100, 100), QImage::Format_ARGB32_Premultiplied);
720 s->attachBuffer(m_shm->createBuffer(image));
721 s->damage(QRect(0, 0, 100, 100));
722 s->commit(KWayland::Client::Surface::CommitFlag::None);
723 QVERIFY(sizeChangedSpy.wait());
727 QCOMPARE(serverSurface->
surfaceAt(QPointF(0, 0)), serverSurface);
728 QCOMPARE(serverSurface->
surfaceAt(QPointF(99, 99)), serverSurface);
730 QVERIFY(!serverSurface->
surfaceAt(QPointF(100, 100)));
731 QVERIFY(!serverSurface->
surfaceAt(QPointF(-1, -1)));
734void TestWaylandSurface::testDestroyAttachedBuffer()
737 using namespace KWin;
739 QSignalSpy serverSurfaceCreated(m_compositorInterface, &CompositorInterface::surfaceCreated);
740 std::unique_ptr<KWayland::Client::Surface> s(m_compositor->createSurface());
741 QVERIFY(serverSurfaceCreated.wait());
745 QSignalSpy damagedSpy(serverSurface, &SurfaceInterface::damaged);
746 QImage image(QSize(100, 100), QImage::Format_ARGB32_Premultiplied);
748 s->attachBuffer(m_shm->createBuffer(image));
749 s->damage(QRect(0, 0, 100, 100));
750 s->commit(KWayland::Client::Surface::CommitFlag::None);
751 QVERIFY(damagedSpy.wait());
752 QVERIFY(serverSurface->
buffer());
755 image.fill(Qt::blue);
756 s->attachBuffer(m_shm->createBuffer(image));
757 m_connection->flush();
765void TestWaylandSurface::testDestroyWithPendingCallback()
769 using namespace KWin;
770 std::unique_ptr<KWayland::Client::Surface> s(m_compositor->createSurface());
771 QVERIFY(s !=
nullptr);
772 QVERIFY(s->isValid());
773 QSignalSpy surfaceCreatedSpy(m_compositorInterface, &CompositorInterface::surfaceCreated);
774 QVERIFY(surfaceCreatedSpy.wait());
775 auto serverSurface = surfaceCreatedSpy.first().first().value<
SurfaceInterface *>();
776 QVERIFY(serverSurface);
779 QImage img(QSize(10, 10), QImage::Format_ARGB32_Premultiplied);
781 auto b = m_shm->createBuffer(img);
783 s->damage(QRect(0, 0, 10, 10));
785 for (
int i = 0; i < 1000; i++) {
786 wl_surface_frame(*s);
788 s->commit(KWayland::Client::Surface::CommitFlag::FrameCallback);
789 QSignalSpy damagedSpy(serverSurface, &SurfaceInterface::damaged);
790 QVERIFY(damagedSpy.wait());
793 QSignalSpy destroyedSpy(serverSurface, &QObject::destroyed);
795 QVERIFY(destroyedSpy.wait());
798void TestWaylandSurface::testDisconnect()
801 using namespace KWin;
802 std::unique_ptr<KWayland::Client::Surface> s(m_compositor->createSurface());
803 QVERIFY(s !=
nullptr);
804 QVERIFY(s->isValid());
805 QSignalSpy surfaceCreatedSpy(m_compositorInterface, &CompositorInterface::surfaceCreated);
806 QVERIFY(surfaceCreatedSpy.wait());
807 auto serverSurface = surfaceCreatedSpy.first().first().value<
SurfaceInterface *>();
808 QVERIFY(serverSurface);
811 QSignalSpy clientDisconnectedSpy(serverSurface->
client(), &ClientConnection::disconnected);
812 QSignalSpy surfaceDestroyedSpy(serverSurface, &QObject::destroyed);
814 m_connection->deleteLater();
815 m_connection =
nullptr;
817 QVERIFY(clientDisconnectedSpy.wait());
818 QCOMPARE(clientDisconnectedSpy.count(), 1);
819 if (surfaceDestroyedSpy.isEmpty()) {
820 QVERIFY(surfaceDestroyedSpy.wait());
822 QTRY_COMPARE(surfaceDestroyedSpy.count(), 1);
826 m_compositor->destroy();
828 m_idleInhibitManager->destroy();
831void TestWaylandSurface::testOutput()
834 using namespace KWin;
835 qRegisterMetaType<KWayland::Client::Output *>();
836 std::unique_ptr<KWayland::Client::Surface> s(m_compositor->createSurface());
837 QVERIFY(s !=
nullptr);
838 QVERIFY(s->isValid());
839 QVERIFY(s->outputs().isEmpty());
840 QSignalSpy enteredSpy(s.get(), &KWayland::Client::Surface::outputEntered);
841 QSignalSpy leftSpy(s.get(), &KWayland::Client::Surface::outputLeft);
843 QSignalSpy surfaceCreatedSpy(m_compositorInterface, &CompositorInterface::surfaceCreated);
844 QVERIFY(surfaceCreatedSpy.wait());
845 auto serverSurface = surfaceCreatedSpy.first().first().value<
SurfaceInterface *>();
846 QVERIFY(serverSurface);
847 QCOMPARE(serverSurface->
outputs(), QList<OutputInterface *>());
850 KWayland::Client::Registry
registry;
852 QSignalSpy allAnnounced(®istry, &KWayland::Client::Registry::interfacesAnnounced);
856 QVERIFY(allAnnounced.wait());
857 QSignalSpy outputAnnouncedSpy(®istry, &KWayland::Client::Registry::outputAnnounced);
859 auto outputHandle = std::make_unique<FakeOutput>();
860 auto serverOutput = std::make_unique<OutputInterface>(m_display, outputHandle.get());
861 QVERIFY(outputAnnouncedSpy.wait());
862 std::unique_ptr<KWayland::Client::Output> clientOutput(
863 registry.createOutput(outputAnnouncedSpy.first().first().value<quint32>(), outputAnnouncedSpy.first().last().value<quint32>()));
864 QVERIFY(clientOutput->isValid());
865 m_connection->flush();
869 serverSurface->
setOutputs(QList<OutputInterface *>{serverOutput.get()}, serverOutput.get());
870 QCOMPARE(serverSurface->
outputs(), QList<OutputInterface *>{serverOutput.get()});
871 QVERIFY(enteredSpy.wait());
872 QCOMPARE(enteredSpy.count(), 1);
873 QCOMPARE(enteredSpy.first().first().value<KWayland::Client::Output *>(), clientOutput.get());
874 QCOMPARE(s->outputs(), QList<KWayland::Client::Output *>{clientOutput.get()});
877 serverSurface->
setOutputs(QList<OutputInterface *>{serverOutput.get()}, serverOutput.get());
880 serverSurface->
setOutputs(QList<OutputInterface *>(),
nullptr);
881 QCOMPARE(serverSurface->
outputs(), QList<OutputInterface *>());
882 QVERIFY(leftSpy.wait());
883 QCOMPARE(enteredSpy.count(), 1);
884 QCOMPARE(leftSpy.count(), 1);
885 QCOMPARE(leftSpy.first().first().value<KWayland::Client::Output *>(), clientOutput.get());
886 QCOMPARE(s->outputs(), QList<KWayland::Client::Output *>());
889 serverSurface->
setOutputs(QList<OutputInterface *>(),
nullptr);
892 serverSurface->
setOutputs(QList<OutputInterface *>{serverOutput.get()}, serverOutput.get());
893 QCOMPARE(serverSurface->
outputs(), QList<OutputInterface *>{serverOutput.get()});
894 QVERIFY(enteredSpy.wait());
895 QCOMPARE(enteredSpy.count(), 2);
896 QCOMPARE(leftSpy.count(), 1);
900 serverOutput.reset();
901 outputHandle.reset();
902 QVERIFY(leftSpy.wait());
903 QCOMPARE(serverSurface->
outputs(), QList<OutputInterface *>());
906void TestWaylandSurface::testInhibit()
908 using namespace KWin;
909 std::unique_ptr<KWayland::Client::Surface> s(m_compositor->createSurface());
911 QSignalSpy surfaceCreatedSpy(m_compositorInterface, &CompositorInterface::surfaceCreated);
912 QVERIFY(surfaceCreatedSpy.wait());
913 auto serverSurface = surfaceCreatedSpy.first().first().value<
SurfaceInterface *>();
914 QVERIFY(serverSurface);
917 QSignalSpy inhibitsChangedSpy(serverSurface, &SurfaceInterface::inhibitsIdleChanged);
920 std::unique_ptr<KWayland::Client::IdleInhibitor> inhibitor1(m_idleInhibitManager->createInhibitor(s.get()));
921 QVERIFY(inhibitsChangedSpy.wait());
925 std::unique_ptr<KWayland::Client::IdleInhibitor> inhibitor2(m_idleInhibitManager->createInhibitor(s.get()));
926 QVERIFY(!inhibitsChangedSpy.wait(500));
931 QVERIFY(!inhibitsChangedSpy.wait(500));
936 QVERIFY(inhibitsChangedSpy.wait());
938 QCOMPARE(inhibitsChangedSpy.count(), 2);
941 inhibitor1.reset(m_idleInhibitManager->createInhibitor(s.get()));
942 QVERIFY(inhibitsChangedSpy.wait());
946 QVERIFY(inhibitsChangedSpy.wait());
948 QCOMPARE(inhibitsChangedSpy.count(), 4);
952#include "test_wayland_surface.moc"
void surfaceCreated(KWin::SurfaceInterface *surface)
Class holding the Wayland server display loop.
bool addSocketName(const QString &name=QString())
bool isReferenced() const
Resource representing a wl_surface.
SurfaceInterface * surfaceAt(const QPointF &position)
ClientConnection * client() const
void damaged(const QRegion &)
static SurfaceInterface * get(wl_resource *native)
QRegion bufferDamage() const
void inputChanged(const QRegion &)
GraphicsBuffer * buffer() const
QList< OutputInterface * > outputs() const
void opaqueChanged(const QRegion &)
void frameRendered(quint32 msec)
void setOutputs(const QList< OutputInterface * > &outputs, OutputInterface *primaryOutput)
bool inhibitsIdle() const
TestWaylandSurface(QObject *parent=nullptr)
KWayland::Client::Registry * registry