File indexing completed on 2024-11-10 04:56:16

0001 /*
0002     SPDX-FileCopyrightText: 2016 Martin Gräßlin <mgraesslin@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0005 */
0006 // Qt
0007 #include <QSignalSpy>
0008 #include <QTest>
0009 // KWayland
0010 #include "wayland/compositor.h"
0011 #include "wayland/display.h"
0012 #include "wayland/plasmashell.h"
0013 
0014 #include "KWayland/Client/compositor.h"
0015 #include "KWayland/Client/connection_thread.h"
0016 #include "KWayland/Client/event_queue.h"
0017 #include "KWayland/Client/plasmashell.h"
0018 #include "KWayland/Client/registry.h"
0019 #include "KWayland/Client/surface.h"
0020 
0021 using namespace KWin;
0022 
0023 class TestPlasmaShell : public QObject
0024 {
0025     Q_OBJECT
0026 private Q_SLOTS:
0027     void init();
0028     void cleanup();
0029 
0030     void testRole_data();
0031     void testRole();
0032     void testPosition();
0033     void testSkipTaskbar();
0034     void testSkipSwitcher();
0035     void testPanelBehavior_data();
0036     void testPanelBehavior();
0037     void testAutoHidePanel();
0038     void testPanelTakesFocus();
0039     void testDisconnect();
0040     void testWhileDestroying();
0041 
0042 private:
0043     KWin::Display *m_display = nullptr;
0044     CompositorInterface *m_compositorInterface = nullptr;
0045     PlasmaShellInterface *m_plasmaShellInterface = nullptr;
0046 
0047     KWayland::Client::ConnectionThread *m_connection = nullptr;
0048     KWayland::Client::Compositor *m_compositor = nullptr;
0049     KWayland::Client::EventQueue *m_queue = nullptr;
0050     QThread *m_thread = nullptr;
0051     KWayland::Client::Registry *m_registry = nullptr;
0052     KWayland::Client::PlasmaShell *m_plasmaShell = nullptr;
0053 };
0054 
0055 static const QString s_socketName = QStringLiteral("kwayland-test-wayland-plasma-shell-0");
0056 
0057 void TestPlasmaShell::init()
0058 {
0059     delete m_display;
0060     m_display = new KWin::Display(this);
0061     m_display->addSocketName(s_socketName);
0062     m_display->start();
0063     QVERIFY(m_display->isRunning());
0064 
0065     m_compositorInterface = new CompositorInterface(m_display, m_display);
0066     m_display->createShm();
0067 
0068     m_plasmaShellInterface = new PlasmaShellInterface(m_display, m_display);
0069 
0070     // setup connection
0071     m_connection = new KWayland::Client::ConnectionThread;
0072     QSignalSpy connectedSpy(m_connection, &KWayland::Client::ConnectionThread::connected);
0073     m_connection->setSocketName(s_socketName);
0074 
0075     m_thread = new QThread(this);
0076     m_connection->moveToThread(m_thread);
0077     m_thread->start();
0078 
0079     m_connection->initConnection();
0080     QVERIFY(connectedSpy.wait());
0081 
0082     m_queue = new KWayland::Client::EventQueue(this);
0083     QVERIFY(!m_queue->isValid());
0084     m_queue->setup(m_connection);
0085     QVERIFY(m_queue->isValid());
0086 
0087     m_registry = new KWayland::Client::Registry();
0088     QSignalSpy interfacesAnnouncedSpy(m_registry, &KWayland::Client::Registry::interfaceAnnounced);
0089 
0090     QVERIFY(!m_registry->eventQueue());
0091     m_registry->setEventQueue(m_queue);
0092     QCOMPARE(m_registry->eventQueue(), m_queue);
0093     m_registry->create(m_connection);
0094     QVERIFY(m_registry->isValid());
0095     m_registry->setup();
0096 
0097     QVERIFY(interfacesAnnouncedSpy.wait());
0098 #define CREATE(variable, factory, iface)                                                                                                                      \
0099     variable =                                                                                                                                                \
0100         m_registry->create##factory(m_registry->interface(KWayland::Client::Registry::Interface::iface).name, m_registry->interface(KWayland::Client::Registry::Interface::iface).version, this); \
0101     QVERIFY(variable);
0102 
0103     CREATE(m_compositor, Compositor, Compositor)
0104     CREATE(m_plasmaShell, PlasmaShell, PlasmaShell)
0105 
0106 #undef CREATE
0107 }
0108 
0109 void TestPlasmaShell::cleanup()
0110 {
0111 #define DELETE(name)    \
0112     if (name) {         \
0113         delete name;    \
0114         name = nullptr; \
0115     }
0116     DELETE(m_plasmaShell)
0117     DELETE(m_compositor)
0118     DELETE(m_queue)
0119     DELETE(m_registry)
0120 #undef DELETE
0121     if (m_thread) {
0122         m_thread->quit();
0123         m_thread->wait();
0124         delete m_thread;
0125         m_thread = nullptr;
0126     }
0127     delete m_connection;
0128     m_connection = nullptr;
0129 
0130     delete m_display;
0131     m_display = nullptr;
0132 }
0133 
0134 void TestPlasmaShell::testRole_data()
0135 {
0136     QTest::addColumn<KWayland::Client::PlasmaShellSurface::Role>("clientRole");
0137     QTest::addColumn<KWin::PlasmaShellSurfaceInterface::Role>("serverRole");
0138 
0139     QTest::newRow("desktop") << KWayland::Client::PlasmaShellSurface::Role::Desktop << PlasmaShellSurfaceInterface::Role::Desktop;
0140     QTest::newRow("osd") << KWayland::Client::PlasmaShellSurface::Role::OnScreenDisplay << PlasmaShellSurfaceInterface::Role::OnScreenDisplay;
0141     QTest::newRow("panel") << KWayland::Client::PlasmaShellSurface::Role::Panel << PlasmaShellSurfaceInterface::Role::Panel;
0142     QTest::newRow("notification") << KWayland::Client::PlasmaShellSurface::Role::Notification << PlasmaShellSurfaceInterface::Role::Notification;
0143     QTest::newRow("tooltip") << KWayland::Client::PlasmaShellSurface::Role::ToolTip << PlasmaShellSurfaceInterface::Role::ToolTip;
0144     QTest::newRow("criticalnotification") << KWayland::Client::PlasmaShellSurface::Role::CriticalNotification << PlasmaShellSurfaceInterface::Role::CriticalNotification;
0145     QTest::newRow("appletPopup") << KWayland::Client::PlasmaShellSurface::Role::AppletPopup << PlasmaShellSurfaceInterface::Role::AppletPopup;
0146 }
0147 
0148 void TestPlasmaShell::testRole()
0149 {
0150     // this test verifies that setting the role on a plasma shell surface works
0151 
0152     // first create signal spies
0153     QSignalSpy surfaceCreatedSpy(m_compositorInterface, &CompositorInterface::surfaceCreated);
0154     QSignalSpy plasmaSurfaceCreatedSpy(m_plasmaShellInterface, &PlasmaShellInterface::surfaceCreated);
0155 
0156     // create the surface
0157     std::unique_ptr<KWayland::Client::Surface> s(m_compositor->createSurface());
0158     // no PlasmaShellSurface for the Surface yet yet
0159     QVERIFY(!KWayland::Client::PlasmaShellSurface::get(s.get()));
0160     std::unique_ptr<KWayland::Client::PlasmaShellSurface> ps(m_plasmaShell->createSurface(s.get()));
0161     QCOMPARE(ps->role(), KWayland::Client::PlasmaShellSurface::Role::Normal);
0162     // now we should have a PlasmaShellSurface for
0163     QCOMPARE(KWayland::Client::PlasmaShellSurface::get(s.get()), ps.get());
0164 
0165     // try to create another PlasmaShellSurface for the same Surface, should return from cache
0166     QCOMPARE(m_plasmaShell->createSurface(s.get()), ps.get());
0167 
0168     // and get them on the server
0169     QVERIFY(plasmaSurfaceCreatedSpy.wait());
0170     QCOMPARE(plasmaSurfaceCreatedSpy.count(), 1);
0171     QCOMPARE(surfaceCreatedSpy.count(), 1);
0172 
0173     // verify that we got a plasma shell surface
0174     auto sps = plasmaSurfaceCreatedSpy.first().first().value<PlasmaShellSurfaceInterface *>();
0175     QVERIFY(sps);
0176     QVERIFY(sps->surface());
0177     QCOMPARE(sps->surface(), surfaceCreatedSpy.first().first().value<SurfaceInterface *>());
0178 
0179     // default role should be normal
0180     QCOMPARE(sps->role(), PlasmaShellSurfaceInterface::Role::Normal);
0181 
0182     // now change it
0183     QSignalSpy roleChangedSpy(sps, &PlasmaShellSurfaceInterface::roleChanged);
0184     QFETCH(KWayland::Client::PlasmaShellSurface::Role, clientRole);
0185     ps->setRole(clientRole);
0186     QCOMPARE(ps->role(), clientRole);
0187     QVERIFY(roleChangedSpy.wait());
0188     QCOMPARE(roleChangedSpy.count(), 1);
0189     QTEST(sps->role(), "serverRole");
0190 
0191     // try changing again should not emit the signal
0192     ps->setRole(clientRole);
0193     QVERIFY(!roleChangedSpy.wait(100));
0194 
0195     // set role back to normal
0196     ps->setRole(KWayland::Client::PlasmaShellSurface::Role::Normal);
0197     QCOMPARE(ps->role(), KWayland::Client::PlasmaShellSurface::Role::Normal);
0198     QVERIFY(roleChangedSpy.wait());
0199     QCOMPARE(roleChangedSpy.count(), 2);
0200     QCOMPARE(sps->role(), PlasmaShellSurfaceInterface::Role::Normal);
0201 }
0202 
0203 void TestPlasmaShell::testPosition()
0204 {
0205     // this test verifies that updating the position of a PlasmaShellSurface is properly passed to the server
0206     QSignalSpy plasmaSurfaceCreatedSpy(m_plasmaShellInterface, &PlasmaShellInterface::surfaceCreated);
0207 
0208     std::unique_ptr<KWayland::Client::Surface> s(m_compositor->createSurface());
0209     std::unique_ptr<KWayland::Client::PlasmaShellSurface> ps(m_plasmaShell->createSurface(s.get()));
0210     QVERIFY(plasmaSurfaceCreatedSpy.wait());
0211     QCOMPARE(plasmaSurfaceCreatedSpy.count(), 1);
0212 
0213     // verify that we got a plasma shell surface
0214     auto sps = plasmaSurfaceCreatedSpy.first().first().value<PlasmaShellSurfaceInterface *>();
0215     QVERIFY(sps);
0216     QVERIFY(sps->surface());
0217 
0218     // default position should not be set
0219     QVERIFY(!sps->isPositionSet());
0220     QCOMPARE(sps->position(), QPoint());
0221 
0222     // now let's try to change the position
0223     QSignalSpy positionChangedSpy(sps, &PlasmaShellSurfaceInterface::positionChanged);
0224     ps->setPosition(QPoint(1, 2));
0225     QVERIFY(positionChangedSpy.wait());
0226     QCOMPARE(positionChangedSpy.count(), 1);
0227     QVERIFY(sps->isPositionSet());
0228     QCOMPARE(sps->position(), QPoint(1, 2));
0229 
0230     // let's try to set same position, should not trigger an update
0231     ps->setPosition(QPoint(1, 2));
0232     QVERIFY(!positionChangedSpy.wait(100));
0233     // different point should work, though
0234     ps->setPosition(QPoint(3, 4));
0235     QVERIFY(positionChangedSpy.wait());
0236     QCOMPARE(positionChangedSpy.count(), 2);
0237     QCOMPARE(sps->position(), QPoint(3, 4));
0238 }
0239 
0240 void TestPlasmaShell::testSkipTaskbar()
0241 {
0242     // this test verifies that sip taskbar is properly passed to server
0243     QSignalSpy plasmaSurfaceCreatedSpy(m_plasmaShellInterface, &PlasmaShellInterface::surfaceCreated);
0244 
0245     std::unique_ptr<KWayland::Client::Surface> s(m_compositor->createSurface());
0246     std::unique_ptr<KWayland::Client::PlasmaShellSurface> ps(m_plasmaShell->createSurface(s.get()));
0247     QVERIFY(plasmaSurfaceCreatedSpy.wait());
0248     QCOMPARE(plasmaSurfaceCreatedSpy.count(), 1);
0249 
0250     // verify that we got a plasma shell surface
0251     auto sps = plasmaSurfaceCreatedSpy.first().first().value<PlasmaShellSurfaceInterface *>();
0252     QVERIFY(sps);
0253     QVERIFY(sps->surface());
0254     QVERIFY(!sps->skipTaskbar());
0255 
0256     // now change
0257     QSignalSpy skipTaskbarChangedSpy(sps, &PlasmaShellSurfaceInterface::skipTaskbarChanged);
0258     ps->setSkipTaskbar(true);
0259     QVERIFY(skipTaskbarChangedSpy.wait());
0260     QVERIFY(sps->skipTaskbar());
0261     // setting to same again should not emit the signal
0262     ps->setSkipTaskbar(true);
0263     QEXPECT_FAIL("", "Should not be emitted if not changed", Continue);
0264     QVERIFY(!skipTaskbarChangedSpy.wait(100));
0265     QVERIFY(sps->skipTaskbar());
0266 
0267     // setting to false should change again
0268     ps->setSkipTaskbar(false);
0269     QVERIFY(skipTaskbarChangedSpy.wait());
0270     QVERIFY(!sps->skipTaskbar());
0271 }
0272 
0273 void TestPlasmaShell::testSkipSwitcher()
0274 {
0275     // this test verifies that Skip Switcher is properly passed to server
0276     QSignalSpy plasmaSurfaceCreatedSpy(m_plasmaShellInterface, &PlasmaShellInterface::surfaceCreated);
0277 
0278     std::unique_ptr<KWayland::Client::Surface> s(m_compositor->createSurface());
0279     std::unique_ptr<KWayland::Client::PlasmaShellSurface> ps(m_plasmaShell->createSurface(s.get()));
0280     QVERIFY(plasmaSurfaceCreatedSpy.wait());
0281     QCOMPARE(plasmaSurfaceCreatedSpy.count(), 1);
0282 
0283     // verify that we got a plasma shell surface
0284     auto sps = plasmaSurfaceCreatedSpy.first().first().value<PlasmaShellSurfaceInterface *>();
0285     QVERIFY(sps);
0286     QVERIFY(sps->surface());
0287     QVERIFY(!sps->skipSwitcher());
0288 
0289     // now change
0290     QSignalSpy skipSwitcherChangedSpy(sps, &PlasmaShellSurfaceInterface::skipSwitcherChanged);
0291     ps->setSkipSwitcher(true);
0292     QVERIFY(skipSwitcherChangedSpy.wait());
0293     QVERIFY(sps->skipSwitcher());
0294     // setting to same again should not emit the signal
0295     ps->setSkipSwitcher(true);
0296     QEXPECT_FAIL("", "Should not be emitted if not changed", Continue);
0297     QVERIFY(!skipSwitcherChangedSpy.wait(100));
0298     QVERIFY(sps->skipSwitcher());
0299 
0300     // setting to false should change again
0301     ps->setSkipSwitcher(false);
0302     QVERIFY(skipSwitcherChangedSpy.wait());
0303     QVERIFY(!sps->skipSwitcher());
0304 }
0305 
0306 void TestPlasmaShell::testPanelBehavior_data()
0307 {
0308     QTest::addColumn<KWayland::Client::PlasmaShellSurface::PanelBehavior>("client");
0309     QTest::addColumn<PlasmaShellSurfaceInterface::PanelBehavior>("server");
0310 
0311     QTest::newRow("autohide") << KWayland::Client::PlasmaShellSurface::PanelBehavior::AutoHide << PlasmaShellSurfaceInterface::PanelBehavior::AutoHide;
0312     QTest::newRow("can cover") << KWayland::Client::PlasmaShellSurface::PanelBehavior::WindowsCanCover << PlasmaShellSurfaceInterface::PanelBehavior::WindowsCanCover;
0313     QTest::newRow("go below") << KWayland::Client::PlasmaShellSurface::PanelBehavior::WindowsGoBelow << PlasmaShellSurfaceInterface::PanelBehavior::WindowsGoBelow;
0314 }
0315 
0316 void TestPlasmaShell::testPanelBehavior()
0317 {
0318     // this test verifies that the panel behavior is properly passed to the server
0319     QSignalSpy plasmaSurfaceCreatedSpy(m_plasmaShellInterface, &PlasmaShellInterface::surfaceCreated);
0320 
0321     std::unique_ptr<KWayland::Client::Surface> s(m_compositor->createSurface());
0322     std::unique_ptr<KWayland::Client::PlasmaShellSurface> ps(m_plasmaShell->createSurface(s.get()));
0323     ps->setRole(KWayland::Client::PlasmaShellSurface::Role::Panel);
0324     QVERIFY(plasmaSurfaceCreatedSpy.wait());
0325     QCOMPARE(plasmaSurfaceCreatedSpy.count(), 1);
0326 
0327     // verify that we got a plasma shell surface
0328     auto sps = plasmaSurfaceCreatedSpy.first().first().value<PlasmaShellSurfaceInterface *>();
0329     QVERIFY(sps);
0330     QVERIFY(sps->surface());
0331     QCOMPARE(sps->panelBehavior(), PlasmaShellSurfaceInterface::PanelBehavior::AlwaysVisible);
0332 
0333     // now change the behavior
0334     QSignalSpy behaviorChangedSpy(sps, &PlasmaShellSurfaceInterface::panelBehaviorChanged);
0335     QFETCH(KWayland::Client::PlasmaShellSurface::PanelBehavior, client);
0336     ps->setPanelBehavior(client);
0337     QVERIFY(behaviorChangedSpy.wait());
0338     QTEST(sps->panelBehavior(), "server");
0339 
0340     // changing to same should not trigger the signal
0341     ps->setPanelBehavior(client);
0342     QVERIFY(!behaviorChangedSpy.wait(100));
0343 
0344     // but changing back to Always Visible should work
0345     ps->setPanelBehavior(KWayland::Client::PlasmaShellSurface::PanelBehavior::AlwaysVisible);
0346     QVERIFY(behaviorChangedSpy.wait());
0347     QCOMPARE(sps->panelBehavior(), PlasmaShellSurfaceInterface::PanelBehavior::AlwaysVisible);
0348 }
0349 
0350 void TestPlasmaShell::testAutoHidePanel()
0351 {
0352     // this test verifies that auto-hiding panels work correctly
0353     QSignalSpy plasmaSurfaceCreatedSpy(m_plasmaShellInterface, &PlasmaShellInterface::surfaceCreated);
0354 
0355     std::unique_ptr<KWayland::Client::Surface> s(m_compositor->createSurface());
0356     std::unique_ptr<KWayland::Client::PlasmaShellSurface> ps(m_plasmaShell->createSurface(s.get()));
0357     ps->setRole(KWayland::Client::PlasmaShellSurface::Role::Panel);
0358     ps->setPanelBehavior(KWayland::Client::PlasmaShellSurface::PanelBehavior::AutoHide);
0359     QVERIFY(plasmaSurfaceCreatedSpy.wait());
0360     QCOMPARE(plasmaSurfaceCreatedSpy.count(), 1);
0361     auto sps = plasmaSurfaceCreatedSpy.first().first().value<PlasmaShellSurfaceInterface *>();
0362     QVERIFY(sps);
0363     QCOMPARE(sps->panelBehavior(), PlasmaShellSurfaceInterface::PanelBehavior::AutoHide);
0364 
0365     QSignalSpy autoHideRequestedSpy(sps, &PlasmaShellSurfaceInterface::panelAutoHideHideRequested);
0366     QSignalSpy autoHideShowRequestedSpy(sps, &PlasmaShellSurfaceInterface::panelAutoHideShowRequested);
0367     ps->requestHideAutoHidingPanel();
0368     QVERIFY(autoHideRequestedSpy.wait());
0369     QCOMPARE(autoHideRequestedSpy.count(), 1);
0370     QCOMPARE(autoHideShowRequestedSpy.count(), 0);
0371 
0372     QSignalSpy panelShownSpy(ps.get(), &KWayland::Client::PlasmaShellSurface::autoHidePanelShown);
0373     QSignalSpy panelHiddenSpy(ps.get(), &KWayland::Client::PlasmaShellSurface::autoHidePanelHidden);
0374 
0375     sps->hideAutoHidingPanel();
0376     QVERIFY(panelHiddenSpy.wait());
0377     QCOMPARE(panelHiddenSpy.count(), 1);
0378     QCOMPARE(panelShownSpy.count(), 0);
0379 
0380     ps->requestShowAutoHidingPanel();
0381     QVERIFY(autoHideShowRequestedSpy.wait());
0382     QCOMPARE(autoHideRequestedSpy.count(), 1);
0383     QCOMPARE(autoHideShowRequestedSpy.count(), 1);
0384 
0385     sps->showAutoHidingPanel();
0386     QVERIFY(panelShownSpy.wait());
0387     QCOMPARE(panelHiddenSpy.count(), 1);
0388     QCOMPARE(panelShownSpy.count(), 1);
0389 
0390     // change panel type
0391     ps->setPanelBehavior(KWayland::Client::PlasmaShellSurface::PanelBehavior::AlwaysVisible);
0392     // requesting auto hide should raise error
0393     QSignalSpy errorSpy(m_connection, &KWayland::Client::ConnectionThread::errorOccurred);
0394     ps->requestHideAutoHidingPanel();
0395     QVERIFY(errorSpy.wait());
0396 }
0397 
0398 void TestPlasmaShell::testPanelTakesFocus()
0399 {
0400     // this test verifies that whether a panel wants to take focus is passed through correctly
0401     QSignalSpy plasmaSurfaceCreatedSpy(m_plasmaShellInterface, &PlasmaShellInterface::surfaceCreated);
0402 
0403     std::unique_ptr<KWayland::Client::Surface> s(m_compositor->createSurface());
0404     std::unique_ptr<KWayland::Client::PlasmaShellSurface> ps(m_plasmaShell->createSurface(s.get()));
0405     ps->setRole(KWayland::Client::PlasmaShellSurface::Role::Panel);
0406     QVERIFY(plasmaSurfaceCreatedSpy.wait());
0407     QCOMPARE(plasmaSurfaceCreatedSpy.count(), 1);
0408     auto sps = plasmaSurfaceCreatedSpy.first().first().value<PlasmaShellSurfaceInterface *>();
0409     QSignalSpy plasmaSurfaceTakesFocusSpy(sps, &PlasmaShellSurfaceInterface::panelTakesFocusChanged);
0410 
0411     QVERIFY(sps);
0412     QCOMPARE(sps->role(), PlasmaShellSurfaceInterface::Role::Panel);
0413     QCOMPARE(sps->panelTakesFocus(), false);
0414 
0415     ps->setPanelTakesFocus(true);
0416     m_connection->flush();
0417     QVERIFY(plasmaSurfaceTakesFocusSpy.wait());
0418     QCOMPARE(plasmaSurfaceTakesFocusSpy.count(), 1);
0419     QCOMPARE(sps->panelTakesFocus(), true);
0420     ps->setPanelTakesFocus(false);
0421     m_connection->flush();
0422     QVERIFY(plasmaSurfaceTakesFocusSpy.wait());
0423     QCOMPARE(plasmaSurfaceTakesFocusSpy.count(), 2);
0424     QCOMPARE(sps->panelTakesFocus(), false);
0425 }
0426 
0427 void TestPlasmaShell::testDisconnect()
0428 {
0429     // this test verifies that a disconnect cleans up
0430     QSignalSpy plasmaSurfaceCreatedSpy(m_plasmaShellInterface, &PlasmaShellInterface::surfaceCreated);
0431     // create the surface
0432     std::unique_ptr<KWayland::Client::Surface> s(m_compositor->createSurface());
0433     std::unique_ptr<KWayland::Client::PlasmaShellSurface> ps(m_plasmaShell->createSurface(s.get()));
0434 
0435     // and get them on the server
0436     QVERIFY(plasmaSurfaceCreatedSpy.wait());
0437     QCOMPARE(plasmaSurfaceCreatedSpy.count(), 1);
0438     auto sps = plasmaSurfaceCreatedSpy.first().first().value<PlasmaShellSurfaceInterface *>();
0439     QVERIFY(sps);
0440 
0441     // disconnect
0442     QSignalSpy surfaceDestroyedSpy(sps, &QObject::destroyed);
0443     if (m_connection) {
0444         m_connection->deleteLater();
0445         m_connection = nullptr;
0446     }
0447     QCOMPARE(surfaceDestroyedSpy.count(), 0);
0448     QVERIFY(surfaceDestroyedSpy.wait());
0449     QCOMPARE(surfaceDestroyedSpy.count(), 1);
0450 
0451     s->destroy();
0452     ps->destroy();
0453     m_plasmaShell->destroy();
0454     m_compositor->destroy();
0455     m_registry->destroy();
0456     m_queue->destroy();
0457 }
0458 
0459 void TestPlasmaShell::testWhileDestroying()
0460 {
0461     // this test tries to hit a condition that a Surface gets created with an ID which was already
0462     // used for a previous Surface. For each Surface we try to create a PlasmaShellSurface.
0463     // Even if there was a Surface in the past with the same ID, it should create the PlasmaShellSurface
0464     QSignalSpy surfaceCreatedSpy(m_compositorInterface, &CompositorInterface::surfaceCreated);
0465     std::unique_ptr<KWayland::Client::Surface> s(m_compositor->createSurface());
0466     QVERIFY(surfaceCreatedSpy.wait());
0467     auto serverSurface = surfaceCreatedSpy.first().first().value<SurfaceInterface *>();
0468     QVERIFY(serverSurface);
0469 
0470     // create ShellSurface
0471     QSignalSpy shellSurfaceCreatedSpy(m_plasmaShellInterface, &PlasmaShellInterface::surfaceCreated);
0472     std::unique_ptr<KWayland::Client::PlasmaShellSurface> ps(m_plasmaShell->createSurface(s.get()));
0473     QVERIFY(shellSurfaceCreatedSpy.wait());
0474 
0475     // now try to create more surfaces
0476     QSignalSpy clientErrorSpy(m_connection, &KWayland::Client::ConnectionThread::errorOccurred);
0477     for (int i = 0; i < 100; i++) {
0478         s.reset();
0479         s.reset(m_compositor->createSurface());
0480         m_plasmaShell->createSurface(s.get(), this);
0481         QVERIFY(surfaceCreatedSpy.wait());
0482     }
0483     QVERIFY(clientErrorSpy.isEmpty());
0484     QVERIFY(!clientErrorSpy.wait(100));
0485     QVERIFY(clientErrorSpy.isEmpty());
0486 }
0487 
0488 QTEST_GUILESS_MAIN(TestPlasmaShell)
0489 #include "test_plasmashell.moc"