File indexing completed on 2024-11-10 04:56:22
0001 /* 0002 SPDX-FileCopyrightText: 2020 Vlad Zahorodnii <vlad.zahorodnii@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0005 */ 0006 0007 #include <QSignalSpy> 0008 #include <QTest> 0009 #include <QThread> 0010 0011 #include "wayland/compositor.h" 0012 #include "wayland/display.h" 0013 #include "wayland/layershell_v1.h" 0014 #include "wayland/surface.h" 0015 #include "wayland/xdgshell.h" 0016 0017 #include "KWayland/Client/compositor.h" 0018 #include "KWayland/Client/connection_thread.h" 0019 #include "KWayland/Client/event_queue.h" 0020 #include "KWayland/Client/registry.h" 0021 #include "KWayland/Client/surface.h" 0022 0023 #include "qwayland-wlr-layer-shell-unstable-v1.h" 0024 #include "qwayland-xdg-shell.h" 0025 0026 Q_DECLARE_METATYPE(KWin::LayerSurfaceV1Interface::Layer) 0027 Q_DECLARE_METATYPE(KWin::LayerSurfaceV1Interface *) 0028 0029 using namespace KWin; 0030 0031 class LayerShellV1 : public QtWayland::zwlr_layer_shell_v1 0032 { 0033 public: 0034 ~LayerShellV1() override 0035 { 0036 destroy(); 0037 } 0038 }; 0039 0040 class LayerSurfaceV1 : public QtWayland::zwlr_layer_surface_v1 0041 { 0042 public: 0043 ~LayerSurfaceV1() override 0044 { 0045 destroy(); 0046 } 0047 }; 0048 0049 class XdgShell : public QtWayland::xdg_wm_base 0050 { 0051 public: 0052 ~XdgShell() 0053 { 0054 destroy(); 0055 } 0056 }; 0057 0058 class XdgSurface : public QtWayland::xdg_surface 0059 { 0060 public: 0061 ~XdgSurface() 0062 { 0063 destroy(); 0064 } 0065 }; 0066 0067 class XdgPositioner : public QtWayland::xdg_positioner 0068 { 0069 public: 0070 ~XdgPositioner() 0071 { 0072 destroy(); 0073 } 0074 }; 0075 0076 class XdgPopup : public QtWayland::xdg_popup 0077 { 0078 public: 0079 ~XdgPopup() 0080 { 0081 destroy(); 0082 } 0083 }; 0084 0085 class TestLayerShellV1Interface : public QObject 0086 { 0087 Q_OBJECT 0088 0089 public: 0090 ~TestLayerShellV1Interface() override; 0091 0092 private Q_SLOTS: 0093 void initTestCase(); 0094 void testDesiredSize(); 0095 void testScope(); 0096 void testAnchor_data(); 0097 void testAnchor(); 0098 void testMargins(); 0099 void testExclusiveZone(); 0100 void testExclusiveEdge_data(); 0101 void testExclusiveEdge(); 0102 void testLayer_data(); 0103 void testLayer(); 0104 void testPopup(); 0105 0106 private: 0107 KWayland::Client::ConnectionThread *m_connection; 0108 KWayland::Client::EventQueue *m_queue; 0109 KWayland::Client::Compositor *m_clientCompositor; 0110 0111 QThread *m_thread; 0112 KWin::Display m_display; 0113 CompositorInterface *m_serverCompositor; 0114 LayerShellV1 *m_clientLayerShell = nullptr; 0115 LayerShellV1Interface *m_serverLayerShell = nullptr; 0116 XdgShell *m_clientXdgShell = nullptr; 0117 XdgShellInterface *m_serverXdgShell = nullptr; 0118 }; 0119 0120 static const QString s_socketName = QStringLiteral("kwin-wayland-server-layer-shell-v1-test-0"); 0121 0122 void TestLayerShellV1Interface::initTestCase() 0123 { 0124 m_display.addSocketName(s_socketName); 0125 m_display.start(); 0126 QVERIFY(m_display.isRunning()); 0127 0128 m_serverLayerShell = new LayerShellV1Interface(&m_display, this); 0129 m_serverXdgShell = new XdgShellInterface(&m_display, this); 0130 m_serverCompositor = new CompositorInterface(&m_display, this); 0131 0132 m_connection = new KWayland::Client::ConnectionThread; 0133 QSignalSpy connectedSpy(m_connection, &KWayland::Client::ConnectionThread::connected); 0134 m_connection->setSocketName(s_socketName); 0135 0136 m_thread = new QThread(this); 0137 m_connection->moveToThread(m_thread); 0138 m_thread->start(); 0139 0140 m_connection->initConnection(); 0141 QVERIFY(connectedSpy.wait()); 0142 QVERIFY(!m_connection->connections().isEmpty()); 0143 0144 m_queue = new KWayland::Client::EventQueue(this); 0145 QVERIFY(!m_queue->isValid()); 0146 m_queue->setup(m_connection); 0147 QVERIFY(m_queue->isValid()); 0148 0149 auto registry = new KWayland::Client::Registry(this); 0150 connect(registry, &KWayland::Client::Registry::interfaceAnnounced, this, [this, registry](const QByteArray &interface, quint32 id, quint32 version) { 0151 if (interface == QByteArrayLiteral("zwlr_layer_shell_v1")) { 0152 m_clientLayerShell = new LayerShellV1(); 0153 m_clientLayerShell->init(*registry, id, version); 0154 } 0155 if (interface == QByteArrayLiteral("xdg_wm_base")) { 0156 m_clientXdgShell = new XdgShell(); 0157 m_clientXdgShell->init(*registry, id, version); 0158 } 0159 }); 0160 QSignalSpy allAnnouncedSpy(registry, &KWayland::Client::Registry::interfaceAnnounced); 0161 QSignalSpy compositorSpy(registry, &KWayland::Client::Registry::compositorAnnounced); 0162 QSignalSpy shmSpy(registry, &KWayland::Client::Registry::shmAnnounced); 0163 registry->setEventQueue(m_queue); 0164 registry->create(m_connection->display()); 0165 QVERIFY(registry->isValid()); 0166 registry->setup(); 0167 QVERIFY(allAnnouncedSpy.wait()); 0168 0169 m_clientCompositor = registry->createCompositor(compositorSpy.first().first().value<quint32>(), compositorSpy.first().last().value<quint32>(), this); 0170 QVERIFY(m_clientCompositor->isValid()); 0171 } 0172 0173 TestLayerShellV1Interface::~TestLayerShellV1Interface() 0174 { 0175 if (m_clientXdgShell) { 0176 delete m_clientXdgShell; 0177 m_clientXdgShell = nullptr; 0178 } 0179 if (m_clientLayerShell) { 0180 delete m_clientLayerShell; 0181 m_clientLayerShell = nullptr; 0182 } 0183 if (m_queue) { 0184 delete m_queue; 0185 m_queue = nullptr; 0186 } 0187 if (m_thread) { 0188 m_thread->quit(); 0189 m_thread->wait(); 0190 delete m_thread; 0191 m_thread = nullptr; 0192 } 0193 m_connection->deleteLater(); 0194 m_connection = nullptr; 0195 } 0196 0197 void TestLayerShellV1Interface::testDesiredSize() 0198 { 0199 // Create a test wl_surface object. 0200 QSignalSpy serverSurfaceCreatedSpy(m_serverCompositor, &CompositorInterface::surfaceCreated); 0201 std::unique_ptr<KWayland::Client::Surface> clientSurface(m_clientCompositor->createSurface(this)); 0202 QVERIFY(serverSurfaceCreatedSpy.wait()); 0203 SurfaceInterface *serverSurface = serverSurfaceCreatedSpy.first().first().value<SurfaceInterface *>(); 0204 QVERIFY(serverSurface); 0205 0206 // Create a test wlr_layer_surface_v1 object. 0207 std::unique_ptr<LayerSurfaceV1> clientShellSurface(new LayerSurfaceV1); 0208 clientShellSurface->init(m_clientLayerShell->get_layer_surface(*clientSurface, nullptr, LayerShellV1::layer_top, QStringLiteral("test"))); 0209 QSignalSpy layerSurfaceCreatedSpy(m_serverLayerShell, &LayerShellV1Interface::surfaceCreated); 0210 QVERIFY(layerSurfaceCreatedSpy.wait()); 0211 auto serverShellSurface = layerSurfaceCreatedSpy.last().first().value<LayerSurfaceV1Interface *>(); 0212 QVERIFY(serverShellSurface); 0213 0214 clientShellSurface->set_size(10, 20); 0215 clientSurface->commit(KWayland::Client::Surface::CommitFlag::None); 0216 0217 QSignalSpy desiredSizeChangedSpy(serverShellSurface, &LayerSurfaceV1Interface::desiredSizeChanged); 0218 QVERIFY(desiredSizeChangedSpy.wait()); 0219 0220 QCOMPARE(serverShellSurface->desiredSize(), QSize(10, 20)); 0221 } 0222 0223 void TestLayerShellV1Interface::testScope() 0224 { 0225 // Create a test wl_surface object. 0226 QSignalSpy serverSurfaceCreatedSpy(m_serverCompositor, &CompositorInterface::surfaceCreated); 0227 std::unique_ptr<KWayland::Client::Surface> clientSurface(m_clientCompositor->createSurface(this)); 0228 QVERIFY(serverSurfaceCreatedSpy.wait()); 0229 SurfaceInterface *serverSurface = serverSurfaceCreatedSpy.first().first().value<SurfaceInterface *>(); 0230 QVERIFY(serverSurface); 0231 0232 // Create a test wlr_layer_surface_v1 object. 0233 std::unique_ptr<LayerSurfaceV1> clientShellSurface(new LayerSurfaceV1); 0234 clientShellSurface->init(m_clientLayerShell->get_layer_surface(*clientSurface, nullptr, LayerShellV1::layer_top, QStringLiteral("foobar"))); 0235 clientShellSurface->set_size(100, 50); 0236 QSignalSpy layerSurfaceCreatedSpy(m_serverLayerShell, &LayerShellV1Interface::surfaceCreated); 0237 QVERIFY(layerSurfaceCreatedSpy.wait()); 0238 auto serverShellSurface = layerSurfaceCreatedSpy.last().first().value<LayerSurfaceV1Interface *>(); 0239 QVERIFY(serverShellSurface); 0240 0241 QCOMPARE(serverShellSurface->scope(), QStringLiteral("foobar")); 0242 } 0243 0244 void TestLayerShellV1Interface::testAnchor_data() 0245 { 0246 QTest::addColumn<int>("anchor"); 0247 QTest::addColumn<Qt::Edge>("expected"); 0248 0249 QTest::addRow("left") << int(QtWayland::zwlr_layer_surface_v1::anchor_left) << Qt::LeftEdge; 0250 QTest::addRow("right") << int(QtWayland::zwlr_layer_surface_v1::anchor_right) << Qt::RightEdge; 0251 QTest::addRow("top") << int(QtWayland::zwlr_layer_surface_v1::anchor_top) << Qt::TopEdge; 0252 QTest::addRow("bottom") << int(QtWayland::zwlr_layer_surface_v1::anchor_bottom) << Qt::BottomEdge; 0253 } 0254 0255 void TestLayerShellV1Interface::testAnchor() 0256 { 0257 // Create a test wl_surface object. 0258 QSignalSpy serverSurfaceCreatedSpy(m_serverCompositor, &CompositorInterface::surfaceCreated); 0259 std::unique_ptr<KWayland::Client::Surface> clientSurface(m_clientCompositor->createSurface(this)); 0260 QVERIFY(serverSurfaceCreatedSpy.wait()); 0261 SurfaceInterface *serverSurface = serverSurfaceCreatedSpy.first().first().value<SurfaceInterface *>(); 0262 QVERIFY(serverSurface); 0263 0264 // Create a test wlr_layer_surface_v1 object. 0265 std::unique_ptr<LayerSurfaceV1> clientShellSurface(new LayerSurfaceV1); 0266 clientShellSurface->init(m_clientLayerShell->get_layer_surface(*clientSurface, nullptr, LayerShellV1::layer_top, QStringLiteral("test"))); 0267 QSignalSpy layerSurfaceCreatedSpy(m_serverLayerShell, &LayerShellV1Interface::surfaceCreated); 0268 QVERIFY(layerSurfaceCreatedSpy.wait()); 0269 auto serverShellSurface = layerSurfaceCreatedSpy.last().first().value<LayerSurfaceV1Interface *>(); 0270 QVERIFY(serverShellSurface); 0271 0272 QFETCH(int, anchor); 0273 QFETCH(Qt::Edge, expected); 0274 0275 clientShellSurface->set_anchor(anchor); 0276 clientShellSurface->set_size(100, 50); 0277 clientSurface->commit(KWayland::Client::Surface::CommitFlag::None); 0278 0279 QSignalSpy anchorChangedSpy(serverShellSurface, &LayerSurfaceV1Interface::anchorChanged); 0280 QVERIFY(anchorChangedSpy.wait()); 0281 0282 QCOMPARE(serverShellSurface->anchor(), expected); 0283 } 0284 0285 void TestLayerShellV1Interface::testMargins() 0286 { 0287 // Create a test wl_surface object. 0288 QSignalSpy serverSurfaceCreatedSpy(m_serverCompositor, &CompositorInterface::surfaceCreated); 0289 std::unique_ptr<KWayland::Client::Surface> clientSurface(m_clientCompositor->createSurface(this)); 0290 QVERIFY(serverSurfaceCreatedSpy.wait()); 0291 SurfaceInterface *serverSurface = serverSurfaceCreatedSpy.first().first().value<SurfaceInterface *>(); 0292 QVERIFY(serverSurface); 0293 0294 // Create a test wlr_layer_surface_v1 object. 0295 std::unique_ptr<LayerSurfaceV1> clientShellSurface(new LayerSurfaceV1); 0296 clientShellSurface->init(m_clientLayerShell->get_layer_surface(*clientSurface, nullptr, LayerShellV1::layer_top, QStringLiteral("test"))); 0297 QSignalSpy layerSurfaceCreatedSpy(m_serverLayerShell, &LayerShellV1Interface::surfaceCreated); 0298 QVERIFY(layerSurfaceCreatedSpy.wait()); 0299 auto serverShellSurface = layerSurfaceCreatedSpy.last().first().value<LayerSurfaceV1Interface *>(); 0300 QVERIFY(serverShellSurface); 0301 0302 clientShellSurface->set_margin(10, 20, 30, 40); 0303 clientShellSurface->set_size(100, 50); 0304 clientSurface->commit(KWayland::Client::Surface::CommitFlag::None); 0305 0306 QSignalSpy marginsChangedSpy(serverShellSurface, &LayerSurfaceV1Interface::marginsChanged); 0307 QVERIFY(marginsChangedSpy.wait()); 0308 0309 QCOMPARE(serverShellSurface->margins(), QMargins(40, 10, 20, 30)); 0310 } 0311 0312 void TestLayerShellV1Interface::testExclusiveZone() 0313 { 0314 // Create a test wl_surface object. 0315 QSignalSpy serverSurfaceCreatedSpy(m_serverCompositor, &CompositorInterface::surfaceCreated); 0316 std::unique_ptr<KWayland::Client::Surface> clientSurface(m_clientCompositor->createSurface(this)); 0317 QVERIFY(serverSurfaceCreatedSpy.wait()); 0318 SurfaceInterface *serverSurface = serverSurfaceCreatedSpy.first().first().value<SurfaceInterface *>(); 0319 QVERIFY(serverSurface); 0320 0321 // Create a test wlr_layer_surface_v1 object. 0322 std::unique_ptr<LayerSurfaceV1> clientShellSurface(new LayerSurfaceV1); 0323 clientShellSurface->init(m_clientLayerShell->get_layer_surface(*clientSurface, nullptr, LayerShellV1::layer_top, QStringLiteral("test"))); 0324 QSignalSpy layerSurfaceCreatedSpy(m_serverLayerShell, &LayerShellV1Interface::surfaceCreated); 0325 QVERIFY(layerSurfaceCreatedSpy.wait()); 0326 auto serverShellSurface = layerSurfaceCreatedSpy.last().first().value<LayerSurfaceV1Interface *>(); 0327 QVERIFY(serverShellSurface); 0328 0329 clientShellSurface->set_exclusive_zone(10); 0330 clientShellSurface->set_size(100, 50); 0331 clientSurface->commit(KWayland::Client::Surface::CommitFlag::None); 0332 0333 QSignalSpy exclusiveZoneChangedSpy(serverShellSurface, &LayerSurfaceV1Interface::exclusiveZoneChanged); 0334 QVERIFY(exclusiveZoneChangedSpy.wait()); 0335 0336 QCOMPARE(serverShellSurface->exclusiveZone(), 10); 0337 } 0338 0339 void TestLayerShellV1Interface::testExclusiveEdge_data() 0340 { 0341 QTest::addColumn<int>("anchor"); 0342 QTest::addColumn<Qt::Edge>("expected"); 0343 0344 QTest::addRow("left (singular)") << int(QtWayland::zwlr_layer_surface_v1::anchor_left) << Qt::LeftEdge; 0345 0346 QTest::addRow("left (triplet)") << (QtWayland::zwlr_layer_surface_v1::anchor_bottom | QtWayland::zwlr_layer_surface_v1::anchor_left 0347 | QtWayland::zwlr_layer_surface_v1::anchor_top) 0348 << Qt::LeftEdge; 0349 0350 QTest::addRow("right (singular)") << int(QtWayland::zwlr_layer_surface_v1::anchor_right) << Qt::RightEdge; 0351 0352 QTest::addRow("right (triplet)") << (QtWayland::zwlr_layer_surface_v1::anchor_top | QtWayland::zwlr_layer_surface_v1::anchor_right 0353 | QtWayland::zwlr_layer_surface_v1::anchor_bottom) 0354 << Qt::RightEdge; 0355 0356 QTest::addRow("top (singular)") << int(QtWayland::zwlr_layer_surface_v1::anchor_top) << Qt::TopEdge; 0357 0358 QTest::addRow("top (triplet)") << (QtWayland::zwlr_layer_surface_v1::anchor_left | QtWayland::zwlr_layer_surface_v1::anchor_top 0359 | QtWayland::zwlr_layer_surface_v1::anchor_right) 0360 << Qt::TopEdge; 0361 0362 QTest::addRow("bottom (singular)") << int(QtWayland::zwlr_layer_surface_v1::anchor_bottom) << Qt::BottomEdge; 0363 0364 QTest::addRow("bottom (triplet)") << (QtWayland::zwlr_layer_surface_v1::anchor_right | QtWayland::zwlr_layer_surface_v1::anchor_bottom 0365 | QtWayland::zwlr_layer_surface_v1::anchor_left) 0366 << Qt::BottomEdge; 0367 0368 QTest::addRow("all") << (QtWayland::zwlr_layer_surface_v1::anchor_left | QtWayland::zwlr_layer_surface_v1::anchor_right 0369 | QtWayland::zwlr_layer_surface_v1::anchor_top | QtWayland::zwlr_layer_surface_v1::anchor_bottom) 0370 << Qt::Edge(); 0371 } 0372 0373 void TestLayerShellV1Interface::testExclusiveEdge() 0374 { 0375 // Create a test wl_surface object. 0376 QSignalSpy serverSurfaceCreatedSpy(m_serverCompositor, &CompositorInterface::surfaceCreated); 0377 std::unique_ptr<KWayland::Client::Surface> clientSurface(m_clientCompositor->createSurface(this)); 0378 QVERIFY(serverSurfaceCreatedSpy.wait()); 0379 SurfaceInterface *serverSurface = serverSurfaceCreatedSpy.first().first().value<SurfaceInterface *>(); 0380 QVERIFY(serverSurface); 0381 0382 // Create a test wlr_layer_surface_v1 object. 0383 std::unique_ptr<LayerSurfaceV1> clientShellSurface(new LayerSurfaceV1); 0384 clientShellSurface->init(m_clientLayerShell->get_layer_surface(*clientSurface, nullptr, LayerShellV1::layer_top, QStringLiteral("test"))); 0385 QSignalSpy layerSurfaceCreatedSpy(m_serverLayerShell, &LayerShellV1Interface::surfaceCreated); 0386 QVERIFY(layerSurfaceCreatedSpy.wait()); 0387 auto serverShellSurface = layerSurfaceCreatedSpy.last().first().value<LayerSurfaceV1Interface *>(); 0388 QVERIFY(serverShellSurface); 0389 0390 QFETCH(int, anchor); 0391 QFETCH(Qt::Edge, expected); 0392 0393 clientShellSurface->set_exclusive_zone(10); 0394 clientShellSurface->set_size(100, 50); 0395 clientShellSurface->set_anchor(anchor); 0396 clientSurface->commit(KWayland::Client::Surface::CommitFlag::None); 0397 0398 QSignalSpy anchorChangedSpy(serverShellSurface, &LayerSurfaceV1Interface::anchorChanged); 0399 QVERIFY(anchorChangedSpy.wait()); 0400 0401 QCOMPARE(serverShellSurface->exclusiveEdge(), expected); 0402 } 0403 0404 void TestLayerShellV1Interface::testLayer_data() 0405 { 0406 QTest::addColumn<int>("layer"); 0407 QTest::addColumn<LayerSurfaceV1Interface::Layer>("expected"); 0408 0409 QTest::addRow("overlay") << int(QtWayland::zwlr_layer_shell_v1::layer_overlay) << LayerSurfaceV1Interface::OverlayLayer; 0410 QTest::addRow("top") << int(QtWayland::zwlr_layer_shell_v1::layer_top) << LayerSurfaceV1Interface::TopLayer; 0411 QTest::addRow("bottom") << int(QtWayland::zwlr_layer_shell_v1::layer_bottom) << LayerSurfaceV1Interface::BottomLayer; 0412 QTest::addRow("background") << int(QtWayland::zwlr_layer_shell_v1::layer_background) << LayerSurfaceV1Interface::BackgroundLayer; 0413 } 0414 0415 void TestLayerShellV1Interface::testLayer() 0416 { 0417 // Create a test wl_surface object. 0418 QSignalSpy serverSurfaceCreatedSpy(m_serverCompositor, &CompositorInterface::surfaceCreated); 0419 std::unique_ptr<KWayland::Client::Surface> clientSurface(m_clientCompositor->createSurface(this)); 0420 QVERIFY(serverSurfaceCreatedSpy.wait()); 0421 SurfaceInterface *serverSurface = serverSurfaceCreatedSpy.first().first().value<SurfaceInterface *>(); 0422 QVERIFY(serverSurface); 0423 0424 // Create a test wlr_layer_surface_v1 object. 0425 std::unique_ptr<LayerSurfaceV1> clientShellSurface(new LayerSurfaceV1); 0426 clientShellSurface->init(m_clientLayerShell->get_layer_surface(*clientSurface, nullptr, LayerShellV1::layer_top, QStringLiteral("test"))); 0427 QSignalSpy layerSurfaceCreatedSpy(m_serverLayerShell, &LayerShellV1Interface::surfaceCreated); 0428 QVERIFY(layerSurfaceCreatedSpy.wait()); 0429 auto serverShellSurface = layerSurfaceCreatedSpy.last().first().value<LayerSurfaceV1Interface *>(); 0430 QVERIFY(serverShellSurface); 0431 0432 QFETCH(int, layer); 0433 QFETCH(LayerSurfaceV1Interface::Layer, expected); 0434 0435 clientShellSurface->set_layer(layer); 0436 clientShellSurface->set_size(100, 50); 0437 clientSurface->commit(KWayland::Client::Surface::CommitFlag::None); 0438 0439 QSignalSpy committedSpy(serverSurface, &SurfaceInterface::committed); 0440 QVERIFY(committedSpy.wait()); 0441 0442 QCOMPARE(serverShellSurface->layer(), expected); 0443 } 0444 0445 void TestLayerShellV1Interface::testPopup() 0446 { 0447 // Create a test wl_surface object for the panel. 0448 QSignalSpy serverPanelSurfaceCreatedSpy(m_serverCompositor, &CompositorInterface::surfaceCreated); 0449 std::unique_ptr<KWayland::Client::Surface> clientPanelSurface(m_clientCompositor->createSurface(this)); 0450 QVERIFY(serverPanelSurfaceCreatedSpy.wait()); 0451 SurfaceInterface *serverPanelSurface = serverPanelSurfaceCreatedSpy.last().first().value<SurfaceInterface *>(); 0452 QVERIFY(serverPanelSurface); 0453 0454 // Create a test wlr_layer_surface_v1 object for the panel.. 0455 std::unique_ptr<LayerSurfaceV1> clientPanelShellSurface(new LayerSurfaceV1); 0456 clientPanelShellSurface->init(m_clientLayerShell->get_layer_surface(*clientPanelSurface, nullptr, LayerShellV1::layer_top, QStringLiteral("panel"))); 0457 clientPanelShellSurface->set_size(100, 50); 0458 QSignalSpy layerSurfaceCreatedSpy(m_serverLayerShell, &LayerShellV1Interface::surfaceCreated); 0459 QVERIFY(layerSurfaceCreatedSpy.wait()); 0460 auto serverPanelShellSurface = layerSurfaceCreatedSpy.last().first().value<LayerSurfaceV1Interface *>(); 0461 QVERIFY(serverPanelShellSurface); 0462 0463 // Create a wl_surface object for the popup. 0464 std::unique_ptr<KWayland::Client::Surface> clientPopupSurface(m_clientCompositor->createSurface(this)); 0465 QVERIFY(serverPanelSurfaceCreatedSpy.wait()); 0466 SurfaceInterface *serverPopupSurface = serverPanelSurfaceCreatedSpy.last().first().value<SurfaceInterface *>(); 0467 QVERIFY(serverPopupSurface); 0468 0469 // Create an xdg_surface object for the popup. 0470 std::unique_ptr<XdgSurface> clientXdgSurface(new XdgSurface); 0471 clientXdgSurface->init(m_clientXdgShell->get_xdg_surface(*clientPopupSurface)); 0472 0473 // Create an xdg_positioner object for the popup. 0474 std::unique_ptr<::XdgPositioner> positioner(new ::XdgPositioner); 0475 positioner->init(m_clientXdgShell->create_positioner()); 0476 positioner->set_size(100, 100); 0477 positioner->set_anchor_rect(0, 0, 10, 10); 0478 0479 // Create an xdg_popup surface. 0480 std::unique_ptr<XdgPopup> clientXdgPopup(new XdgPopup); 0481 clientXdgPopup->init(clientXdgSurface->get_popup(nullptr, positioner->object())); 0482 0483 // Wait for the server side to catch up. 0484 QSignalSpy popupCreatedSpy(m_serverXdgShell, &XdgShellInterface::popupCreated); 0485 QVERIFY(popupCreatedSpy.wait()); 0486 XdgPopupInterface *serverPopupShellSurface = popupCreatedSpy.last().first().value<XdgPopupInterface *>(); 0487 QVERIFY(serverPopupShellSurface); 0488 QCOMPARE(serverPopupShellSurface->parentSurface(), nullptr); 0489 0490 // Make the xdg_popup surface a child of the panel. 0491 clientPanelShellSurface->get_popup(clientXdgPopup->object()); 0492 0493 // Commit the initial state of the xdg_popup surface. 0494 clientPopupSurface->commit(KWayland::Client::Surface::CommitFlag::None); 0495 QSignalSpy initializeRequestedSpy(serverPopupShellSurface, &XdgPopupInterface::initializeRequested); 0496 QVERIFY(initializeRequestedSpy.wait()); 0497 0498 // The popup should be a transient for the panel. 0499 QCOMPARE(serverPopupShellSurface->parentSurface(), serverPanelSurface); 0500 } 0501 0502 QTEST_GUILESS_MAIN(TestLayerShellV1Interface) 0503 0504 #include "test_layershellv1_interface.moc"