16#include "KWayland/Client/compositor.h"
17#include "KWayland/Client/connection_thread.h"
18#include "KWayland/Client/event_queue.h"
19#include "KWayland/Client/region.h"
20#include "KWayland/Client/registry.h"
21#include "KWayland/Client/surface.h"
22#include "KWayland/Client/xdgforeign.h"
34 void testDeleteImported();
35 void testDeleteChildSurface();
36 void testDeleteParentSurface();
37 void testDeleteExported();
38 void testExportTwoTimes();
39 void testImportTwoTimes();
40 void testImportInvalidToplevel();
46 QPointer<KWin::CompositorInterface> m_compositorInterface;
48 KWayland::Client::ConnectionThread *m_connection;
49 KWayland::Client::Compositor *m_compositor;
50 KWayland::Client::EventQueue *m_queue;
51 KWayland::Client::XdgExporter *m_exporter;
52 KWayland::Client::XdgImporter *m_importer;
54 QPointer<KWayland::Client::Surface> m_exportedSurface;
55 QPointer<KWin::SurfaceInterface> m_exportedSurfaceInterface;
57 QPointer<KWayland::Client::XdgExported> m_exported;
58 QPointer<KWayland::Client::XdgImported> m_imported;
60 QPointer<KWayland::Client::Surface> m_childSurface;
61 QPointer<KWin::SurfaceInterface> m_childSurfaceInterface;
66static const QString s_socketName = QStringLiteral(
"kwayland-test-xdg-foreign-0");
71 , m_compositorInterface(nullptr)
72 , m_connection(nullptr)
73 , m_compositor(nullptr)
81void TestForeign::init()
90 qRegisterMetaType<SurfaceInterface *>();
92 m_connection =
new KWayland::Client::ConnectionThread;
93 QSignalSpy connectedSpy(m_connection, &KWayland::Client::ConnectionThread::connected);
94 m_connection->setSocketName(s_socketName);
96 m_thread =
new QThread(
this);
97 m_connection->moveToThread(m_thread);
100 m_connection->initConnection();
101 QVERIFY(connectedSpy.wait());
103 m_queue =
new KWayland::Client::EventQueue(
this);
104 QVERIFY(!m_queue->isValid());
105 m_queue->setup(m_connection);
106 QVERIFY(m_queue->isValid());
108 KWayland::Client::Registry registry;
109 QSignalSpy compositorSpy(®istry, &KWayland::Client::Registry::compositorAnnounced);
111 QSignalSpy exporterSpy(®istry, &KWayland::Client::Registry::exporterUnstableV2Announced);
113 QSignalSpy importerSpy(®istry, &KWayland::Client::Registry::importerUnstableV2Announced);
115 QVERIFY(!registry.eventQueue());
116 registry.setEventQueue(m_queue);
117 QCOMPARE(registry.eventQueue(), m_queue);
118 registry.create(m_connection->display());
119 QVERIFY(registry.isValid());
123 QVERIFY(compositorSpy.wait());
124 m_compositor = registry.createCompositor(compositorSpy.first().first().value<quint32>(), compositorSpy.first().last().value<quint32>(),
this);
128 QVERIFY(exporterSpy.wait());
130 QCOMPARE(exporterSpy.count(), 1);
131 QCOMPARE(importerSpy.count(), 1);
133 m_exporter = registry.createXdgExporter(exporterSpy.first().first().value<quint32>(), exporterSpy.first().last().value<quint32>(),
this);
134 m_importer = registry.createXdgImporter(importerSpy.first().first().value<quint32>(), importerSpy.first().last().value<quint32>(),
this);
137void TestForeign::cleanup()
139#define CLEANUP(variable) \
142 variable = nullptr; \
150 m_connection->deleteLater();
151 m_connection =
nullptr;
164 m_foreignInterface =
nullptr;
167void TestForeign::doExport()
171 m_exportedSurface = m_compositor->createSurface();
172 QVERIFY(serverSurfaceCreated.wait());
177 m_exported = m_exporter->exportTopLevel(m_exportedSurface);
178 QVERIFY(m_exported->handle().isEmpty());
179 QSignalSpy doneSpy(m_exported.data(), &KWayland::Client::XdgExported::done);
180 QVERIFY(doneSpy.wait());
181 QVERIFY(!m_exported->handle().isEmpty());
186 m_imported = m_importer->importTopLevel(m_exported->handle());
187 QVERIFY(m_imported->isValid());
190 m_childSurface = m_compositor->createSurface();
191 QVERIFY(childSurfaceInterfaceCreated.wait());
193 m_childSurface->commit(KWayland::Client::Surface::CommitFlag::None);
195 m_imported->setParentOf(m_childSurface);
196 QVERIFY(transientSpy.wait());
199 QCOMPARE(transientSpy.first().at(1).value<
KWin::SurfaceInterface *>(), m_exportedSurfaceInterface.data());
202 QCOMPARE(m_foreignInterface->
transientFor(m_childSurfaceInterface), m_exportedSurfaceInterface.data());
205void TestForeign::testExport()
210void TestForeign::testDeleteImported()
216 m_imported->deleteLater();
217 m_imported =
nullptr;
219 QVERIFY(transientSpy.wait());
223 QVERIFY(!m_foreignInterface->
transientFor(m_childSurfaceInterface));
226void TestForeign::testDeleteChildSurface()
232 m_childSurface->deleteLater();
234 QVERIFY(transientSpy.wait());
237 QCOMPARE(transientSpy.first().at(1).value<
KWin::SurfaceInterface *>(), m_exportedSurfaceInterface.data());
240void TestForeign::testDeleteParentSurface()
245 m_exportedSurface->deleteLater();
246 QVERIFY(transientSpy.wait());
250 QVERIFY(!m_foreignInterface->
transientFor(m_childSurfaceInterface));
253void TestForeign::testDeleteExported()
258 QSignalSpy destroyedSpy(m_imported.data(), &KWayland::Client::XdgImported::importedDestroyed);
260 m_exported->deleteLater();
261 m_exported =
nullptr;
263 QVERIFY(transientSpy.wait());
264 QVERIFY(destroyedSpy.wait());
268 QVERIFY(!m_foreignInterface->
transientFor(m_childSurfaceInterface));
270 QVERIFY(!m_imported->isValid());
273void TestForeign::testExportTwoTimes()
278 KWayland::Client::XdgExported *exported2 = m_exporter->exportTopLevel(m_exportedSurface);
279 QVERIFY(exported2->handle().isEmpty());
280 QSignalSpy doneSpy(exported2, &KWayland::Client::XdgExported::done);
281 QVERIFY(doneSpy.wait());
282 QVERIFY(!exported2->handle().isEmpty());
287 KWayland::Client::XdgImported *imported2 = m_importer->importTopLevel(exported2->handle());
288 QVERIFY(imported2->isValid());
293 KWayland::Client::Surface *childSurface2 = m_compositor->createSurface();
294 QVERIFY(serverSurfaceCreated.wait());
298 imported2->setParentOf(childSurface2);
299 QVERIFY(transientSpy.wait());
302 QCOMPARE(transientSpy.first().at(1).value<
KWin::SurfaceInterface *>(), m_exportedSurfaceInterface.data());
306 QCOMPARE(m_foreignInterface->
transientFor(m_childSurfaceInterface), m_exportedSurfaceInterface.data());
308 QCOMPARE(m_foreignInterface->
transientFor(childSurface2Interface), m_exportedSurfaceInterface.data());
311void TestForeign::testImportTwoTimes()
318 KWayland::Client::XdgImported *imported2 = m_importer->importTopLevel(m_exported->handle());
319 QVERIFY(imported2->isValid());
324 KWayland::Client::Surface *childSurface2 = m_compositor->createSurface();
325 QVERIFY(serverSurfaceCreated.wait());
329 imported2->setParentOf(childSurface2);
330 QVERIFY(transientSpy.wait());
333 QCOMPARE(transientSpy.first().at(1).value<
KWin::SurfaceInterface *>(), m_exportedSurfaceInterface.data());
337 QCOMPARE(m_foreignInterface->
transientFor(m_childSurfaceInterface), m_exportedSurfaceInterface.data());
339 QCOMPARE(m_foreignInterface->
transientFor(childSurface2Interface), m_exportedSurfaceInterface.data());
342void TestForeign::testImportInvalidToplevel()
347 KWayland::Client::XdgImported *imported = m_importer->importTopLevel(QStringLiteral(
"foobar"));
348 QVERIFY(imported->isValid());
350 QSignalSpy importedDestroySpy(imported, &KWayland::Client::XdgImported::importedDestroyed);
351 QVERIFY(importedDestroySpy.wait());
355#include "test_xdg_foreign.moc"
void surfaceCreated(KWin::SurfaceInterface *surface)
Class holding the Wayland server display loop.
bool addSocketName(const QString &name=QString())
Resource representing a wl_surface.
void transientChanged(KWin::SurfaceInterface *child, KWin::SurfaceInterface *parent)
SurfaceInterface * transientFor(SurfaceInterface *surface)
TestForeign(QObject *parent=nullptr)
#define CLEANUP(variable)