1 /*
2 SPDX-FileCopyrightText: 2014 Martin Gräßlin <mgraesslin@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
5 */
6 // Qt
7 #include <QSignalSpy>
8 #include <QTest>
9 // KWin
10 #include "../../src/client/compositor.h"
11 #include "../../src/client/connection_thread.h"
12 #include "../../src/client/event_queue.h"
13 #include "../../src/client/region.h"
14 #include "../../src/client/registry.h"
15 #include "../../src/client/slide.h"
16 #include "../../src/client/surface.h"
17 #include "../../src/server/compositor_interface.h"
18 #include "../../src/server/display.h"
19 #include "../../src/server/region_interface.h"
20 #include "../../src/server/slide_interface.h"
21
22 using namespace KWayland::Client;
23
24 class TestSlide : public QObject
25 {
26 Q_OBJECT
27 public:
28 explicit TestSlide(QObject *parent = nullptr);
29 private Q_SLOTS:
30 void init();
31 void cleanup();
32
33 void testCreate();
34 void testSurfaceDestroy();
35
36 private:
37 KWayland::Server::Display *m_display;
38 KWayland::Server::CompositorInterface *m_compositorInterface;
39 KWayland::Server::SlideManagerInterface *m_slideManagerInterface;
40 KWayland::Client::ConnectionThread *m_connection;
41 KWayland::Client::Compositor *m_compositor;
42 KWayland::Client::SlideManager *m_slideManager;
43 KWayland::Client::EventQueue *m_queue;
44 QThread *m_thread;
45 };
46
47 static const QString s_socketName = QStringLiteral("kwayland-test-wayland-slide-0");
48
TestSlide(QObject * parent)49 TestSlide::TestSlide(QObject *parent)
50 : QObject(parent)
51 , m_display(nullptr)
52 , m_compositorInterface(nullptr)
53 , m_connection(nullptr)
54 , m_compositor(nullptr)
55 , m_queue(nullptr)
56 , m_thread(nullptr)
57 {
58 }
59
init()60 void TestSlide::init()
61 {
62 using namespace KWayland::Server;
63 delete m_display;
64 m_display = new Display(this);
65 m_display->setSocketName(s_socketName);
66 m_display->start();
67 QVERIFY(m_display->isRunning());
68
69 // setup connection
70 m_connection = new KWayland::Client::ConnectionThread;
71 QSignalSpy connectedSpy(m_connection, &KWayland::Client::ConnectionThread::connected);
72 m_connection->setSocketName(s_socketName);
73
74 m_thread = new QThread(this);
75 m_connection->moveToThread(m_thread);
76 m_thread->start();
77
78 m_connection->initConnection();
79 QVERIFY(connectedSpy.wait());
80
81 m_queue = new KWayland::Client::EventQueue(this);
82 QVERIFY(!m_queue->isValid());
83 m_queue->setup(m_connection);
84 QVERIFY(m_queue->isValid());
85
86 Registry registry;
87 QSignalSpy compositorSpy(®istry, &Registry::compositorAnnounced);
88 QVERIFY(compositorSpy.isValid());
89
90 QSignalSpy slideSpy(®istry, &Registry::slideAnnounced);
91 QVERIFY(slideSpy.isValid());
92
93 QVERIFY(!registry.eventQueue());
94 registry.setEventQueue(m_queue);
95 QCOMPARE(registry.eventQueue(), m_queue);
96 registry.create(m_connection->display());
97 QVERIFY(registry.isValid());
98 registry.setup();
99
100 m_compositorInterface = m_display->createCompositor(m_display);
101 m_compositorInterface->create();
102 QVERIFY(m_compositorInterface->isValid());
103
104 QVERIFY(compositorSpy.wait());
105 const auto name = compositorSpy.first().first().value<quint32>();
106 const auto version = compositorSpy.first().last().value<quint32>();
107 m_compositor = registry.createCompositor(name, version, this);
108
109 m_slideManagerInterface = m_display->createSlideManager(m_display);
110 m_slideManagerInterface->create();
111 QVERIFY(m_slideManagerInterface->isValid());
112
113 QVERIFY(slideSpy.wait());
114 m_slideManager = registry.createSlideManager(slideSpy.first().first().value<quint32>(), slideSpy.first().last().value<quint32>(), this);
115 }
116
cleanup()117 void TestSlide::cleanup()
118 {
119 #define CLEANUP(variable) \
120 if (variable) { \
121 delete variable; \
122 variable = nullptr; \
123 }
124 CLEANUP(m_compositor)
125 CLEANUP(m_slideManager)
126 CLEANUP(m_queue)
127 if (m_connection) {
128 m_connection->deleteLater();
129 m_connection = nullptr;
130 }
131 if (m_thread) {
132 m_thread->quit();
133 m_thread->wait();
134 delete m_thread;
135 m_thread = nullptr;
136 }
137 CLEANUP(m_compositorInterface)
138 CLEANUP(m_slideManagerInterface)
139 CLEANUP(m_display)
140 #undef CLEANUP
141 }
142
testCreate()143 void TestSlide::testCreate()
144 {
145 QSignalSpy serverSurfaceCreated(m_compositorInterface, &KWayland::Server::CompositorInterface::surfaceCreated);
146 QVERIFY(serverSurfaceCreated.isValid());
147
148 QScopedPointer<KWayland::Client::Surface> surface(m_compositor->createSurface());
149 QVERIFY(serverSurfaceCreated.wait());
150
151 auto serverSurface = serverSurfaceCreated.first().first().value<KWayland::Server::SurfaceInterface *>();
152 QSignalSpy slideChanged(serverSurface, &KWayland::Server::SurfaceInterface::slideOnShowHideChanged);
153
154 auto slide = m_slideManager->createSlide(surface.data(), surface.data());
155 slide->setLocation(KWayland::Client::Slide::Location::Top);
156 slide->setOffset(15);
157 slide->commit();
158 surface->commit(KWayland::Client::Surface::CommitFlag::None);
159
160 QVERIFY(slideChanged.wait());
161 QCOMPARE(serverSurface->slideOnShowHide()->location(), KWayland::Server::SlideInterface::Location::Top);
162 QCOMPARE(serverSurface->slideOnShowHide()->offset(), 15);
163
164 // and destroy
165 QSignalSpy destroyedSpy(serverSurface->slideOnShowHide().data(), &QObject::destroyed);
166 QVERIFY(destroyedSpy.isValid());
167 delete slide;
168 QVERIFY(destroyedSpy.wait());
169 }
170
testSurfaceDestroy()171 void TestSlide::testSurfaceDestroy()
172 {
173 using namespace KWayland::Server;
174 QSignalSpy serverSurfaceCreated(m_compositorInterface, &CompositorInterface::surfaceCreated);
175 QVERIFY(serverSurfaceCreated.isValid());
176
177 QScopedPointer<KWayland::Client::Surface> surface(m_compositor->createSurface());
178 QVERIFY(serverSurfaceCreated.wait());
179
180 auto serverSurface = serverSurfaceCreated.first().first().value<SurfaceInterface *>();
181 QSignalSpy slideChanged(serverSurface, &SurfaceInterface::slideOnShowHideChanged);
182 QVERIFY(slideChanged.isValid());
183
184 QScopedPointer<Slide> slide(m_slideManager->createSlide(surface.data()));
185 slide->commit();
186 surface->commit(KWayland::Client::Surface::CommitFlag::None);
187 QVERIFY(slideChanged.wait());
188 auto serverSlide = serverSurface->slideOnShowHide();
189 QVERIFY(!serverSlide.isNull());
190
191 // destroy the parent surface
192 QSignalSpy surfaceDestroyedSpy(serverSurface, &QObject::destroyed);
193 QVERIFY(surfaceDestroyedSpy.isValid());
194 QSignalSpy slideDestroyedSpy(serverSlide.data(), &QObject::destroyed);
195 QVERIFY(slideDestroyedSpy.isValid());
196 surface.reset();
197 QVERIFY(surfaceDestroyedSpy.wait());
198 QVERIFY(slideDestroyedSpy.isEmpty());
199 // destroy the slide
200 slide.reset();
201 QVERIFY(slideDestroyedSpy.wait());
202 }
203
204 QTEST_GUILESS_MAIN(TestSlide)
205 #include "test_wayland_slide.moc"
206