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