File indexing completed on 2024-11-10 04:56:15
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 0010 // server 0011 #include "wayland/compositor.h" 0012 #include "wayland/display.h" 0013 #include "wayland/plasmashell.h" 0014 0015 // client 0016 #include "KWayland/Client/compositor.h" 0017 #include "KWayland/Client/connection_thread.h" 0018 #include "KWayland/Client/event_queue.h" 0019 #include "KWayland/Client/plasmashell.h" 0020 #include "KWayland/Client/registry.h" 0021 #include "KWayland/Client/surface.h" 0022 0023 #include <wayland-client-protocol.h> 0024 0025 #include <cerrno> // For EPROTO 0026 0027 using namespace KWin; 0028 0029 class ErrorTest : public QObject 0030 { 0031 Q_OBJECT 0032 private Q_SLOTS: 0033 void init(); 0034 void cleanup(); 0035 0036 void testMultiplePlasmaShellSurfacesForSurface(); 0037 0038 private: 0039 KWin::Display *m_display = nullptr; 0040 CompositorInterface *m_ci = nullptr; 0041 PlasmaShellInterface *m_psi = nullptr; 0042 KWayland::Client::ConnectionThread *m_connection = nullptr; 0043 QThread *m_thread = nullptr; 0044 KWayland::Client::EventQueue *m_queue = nullptr; 0045 KWayland::Client::Compositor *m_compositor = nullptr; 0046 KWayland::Client::PlasmaShell *m_plasmaShell = nullptr; 0047 }; 0048 0049 static const QString s_socketName = QStringLiteral("kwayland-test-error-0"); 0050 0051 void ErrorTest::init() 0052 { 0053 delete m_display; 0054 m_display = new KWin::Display(this); 0055 m_display->addSocketName(s_socketName); 0056 m_display->start(); 0057 QVERIFY(m_display->isRunning()); 0058 m_display->createShm(); 0059 m_ci = new CompositorInterface(m_display, m_display); 0060 m_psi = new PlasmaShellInterface(m_display, m_display); 0061 0062 // setup connection 0063 m_connection = new KWayland::Client::ConnectionThread; 0064 QSignalSpy connectedSpy(m_connection, &KWayland::Client::ConnectionThread::connected); 0065 m_connection->setSocketName(s_socketName); 0066 0067 m_thread = new QThread(this); 0068 m_connection->moveToThread(m_thread); 0069 m_thread->start(); 0070 0071 m_connection->initConnection(); 0072 QVERIFY(connectedSpy.wait()); 0073 0074 m_queue = new KWayland::Client::EventQueue(this); 0075 m_queue->setup(m_connection); 0076 0077 KWayland::Client::Registry registry; 0078 QSignalSpy interfacesAnnouncedSpy(®istry, &KWayland::Client::Registry::interfacesAnnounced); 0079 registry.setEventQueue(m_queue); 0080 registry.create(m_connection); 0081 QVERIFY(registry.isValid()); 0082 registry.setup(); 0083 QVERIFY(interfacesAnnouncedSpy.wait()); 0084 0085 m_compositor = 0086 registry.createCompositor(registry.interface(KWayland::Client::Registry::Interface::Compositor).name, registry.interface(KWayland::Client::Registry::Interface::Compositor).version, this); 0087 QVERIFY(m_compositor); 0088 m_plasmaShell = registry.createPlasmaShell(registry.interface(KWayland::Client::Registry::Interface::PlasmaShell).name, 0089 registry.interface(KWayland::Client::Registry::Interface::PlasmaShell).version, 0090 this); 0091 QVERIFY(m_plasmaShell); 0092 } 0093 0094 void ErrorTest::cleanup() 0095 { 0096 #define CLEANUP(variable) \ 0097 if (variable) { \ 0098 delete variable; \ 0099 variable = nullptr; \ 0100 } 0101 CLEANUP(m_plasmaShell) 0102 CLEANUP(m_compositor) 0103 CLEANUP(m_queue) 0104 if (m_connection) { 0105 m_connection->deleteLater(); 0106 m_connection = nullptr; 0107 } 0108 if (m_thread) { 0109 m_thread->quit(); 0110 m_thread->wait(); 0111 delete m_thread; 0112 m_thread = nullptr; 0113 } 0114 CLEANUP(m_display) 0115 #undef CLEANUP 0116 // these are the children of the display 0117 m_psi = nullptr; 0118 m_ci = nullptr; 0119 } 0120 0121 void ErrorTest::testMultiplePlasmaShellSurfacesForSurface() 0122 { 0123 // this test verifies that creating two ShellSurfaces for the same Surface triggers a protocol error 0124 QSignalSpy errorSpy(m_connection, &KWayland::Client::ConnectionThread::errorOccurred); 0125 // PlasmaShell is too smart and doesn't allow us to create a second PlasmaShellSurface 0126 // thus we need to cheat by creating a surface manually 0127 auto surface = wl_compositor_create_surface(*m_compositor); 0128 std::unique_ptr<KWayland::Client::PlasmaShellSurface> shellSurface1(m_plasmaShell->createSurface(surface)); 0129 std::unique_ptr<KWayland::Client::PlasmaShellSurface> shellSurface2(m_plasmaShell->createSurface(surface)); 0130 QVERIFY(!m_connection->hasError()); 0131 QVERIFY(errorSpy.wait()); 0132 QVERIFY(m_connection->hasError()); 0133 QCOMPARE(m_connection->errorCode(), EPROTO); 0134 wl_surface_destroy(surface); 0135 } 0136 0137 QTEST_GUILESS_MAIN(ErrorTest) 0138 #include "test_error.moc"