1 /*
2     SPDX-FileCopyrightText: 2017 David Edmundson <davidedmundson@kde.org>
3     SPDX-FileCopyrightText: 2014 Martin Gräßlin <mgraesslin@kde.org>
4 
5     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
6 */
7 // Qt
8 #include <QtTest>
9 // KWin
10 #include "../../src/server/compositor_interface.h"
11 #include "../../src/server/display.h"
12 #include "../../src/server/server_decoration_palette_interface.h"
13 #include "KWayland/Client/compositor.h"
14 #include "KWayland/Client/connection_thread.h"
15 #include "KWayland/Client/event_queue.h"
16 #include "KWayland/Client/region.h"
17 #include "KWayland/Client/registry.h"
18 #include "KWayland/Client/server_decoration_palette.h"
19 #include "KWayland/Client/surface.h"
20 
21 using namespace KWayland::Client;
22 
23 class TestServerSideDecorationPalette : public QObject
24 {
25     Q_OBJECT
26 public:
27     explicit TestServerSideDecorationPalette(QObject *parent = nullptr);
28 private Q_SLOTS:
29     void init();
30     void cleanup();
31 
32     void testCreateAndSet();
33 
34 private:
35     KWaylandServer::Display *m_display;
36     KWaylandServer::CompositorInterface *m_compositorInterface;
37     KWaylandServer::ServerSideDecorationPaletteManagerInterface *m_paletteManagerInterface;
38     KWayland::Client::ConnectionThread *m_connection;
39     KWayland::Client::Compositor *m_compositor;
40     KWayland::Client::ServerSideDecorationPaletteManager *m_paletteManager;
41     KWayland::Client::EventQueue *m_queue;
42     QThread *m_thread;
43 };
44 
45 static const QString s_socketName = QStringLiteral("kwayland-test-wayland-decopalette-0");
46 
TestServerSideDecorationPalette(QObject * parent)47 TestServerSideDecorationPalette::TestServerSideDecorationPalette(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 TestServerSideDecorationPalette::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     QVERIFY(connectedSpy.isValid());
71     m_connection->setSocketName(s_socketName);
72 
73     m_thread = new QThread(this);
74     m_connection->moveToThread(m_thread);
75     m_thread->start();
76 
77     m_connection->initConnection();
78     QVERIFY(connectedSpy.wait());
79 
80     m_queue = new KWayland::Client::EventQueue(this);
81     QVERIFY(!m_queue->isValid());
82     m_queue->setup(m_connection);
83     QVERIFY(m_queue->isValid());
84 
85     Registry registry;
86     QSignalSpy compositorSpy(&registry, &Registry::compositorAnnounced);
87     QVERIFY(compositorSpy.isValid());
88 
89     QSignalSpy registrySpy(&registry, &Registry::serverSideDecorationPaletteManagerAnnounced);
90     QVERIFY(registrySpy.isValid());
91 
92     QVERIFY(!registry.eventQueue());
93     registry.setEventQueue(m_queue);
94     QCOMPARE(registry.eventQueue(), m_queue);
95     registry.create(m_connection->display());
96     QVERIFY(registry.isValid());
97     registry.setup();
98 
99     m_compositorInterface = new CompositorInterface(m_display, m_display);
100     QVERIFY(compositorSpy.wait());
101     m_compositor = registry.createCompositor(compositorSpy.first().first().value<quint32>(), compositorSpy.first().last().value<quint32>(), this);
102 
103     m_paletteManagerInterface = new ServerSideDecorationPaletteManagerInterface(m_display, m_display);
104 
105     QVERIFY(registrySpy.wait());
106     m_paletteManager =
107         registry.createServerSideDecorationPaletteManager(registrySpy.first().first().value<quint32>(), registrySpy.first().last().value<quint32>(), this);
108 }
109 
cleanup()110 void TestServerSideDecorationPalette::cleanup()
111 {
112 #define CLEANUP(variable)                                                                                                                                      \
113     if (variable) {                                                                                                                                            \
114         delete variable;                                                                                                                                       \
115         variable = nullptr;                                                                                                                                    \
116     }
117     CLEANUP(m_compositor)
118     CLEANUP(m_paletteManager)
119     CLEANUP(m_queue)
120     if (m_connection) {
121         m_connection->deleteLater();
122         m_connection = nullptr;
123     }
124     if (m_thread) {
125         m_thread->quit();
126         m_thread->wait();
127         delete m_thread;
128         m_thread = nullptr;
129     }
130     CLEANUP(m_compositorInterface)
131     CLEANUP(m_paletteManagerInterface)
132     CLEANUP(m_display)
133 #undef CLEANUP
134 }
135 
testCreateAndSet()136 void TestServerSideDecorationPalette::testCreateAndSet()
137 {
138     QSignalSpy serverSurfaceCreated(m_compositorInterface, &KWaylandServer::CompositorInterface::surfaceCreated);
139     QVERIFY(serverSurfaceCreated.isValid());
140 
141     QScopedPointer<KWayland::Client::Surface> surface(m_compositor->createSurface());
142     QVERIFY(serverSurfaceCreated.wait());
143 
144     auto serverSurface = serverSurfaceCreated.first().first().value<KWaylandServer::SurfaceInterface *>();
145     QSignalSpy paletteCreatedSpy(m_paletteManagerInterface, &KWaylandServer::ServerSideDecorationPaletteManagerInterface::paletteCreated);
146 
147     QVERIFY(!m_paletteManagerInterface->paletteForSurface(serverSurface));
148 
149     auto palette = m_paletteManager->create(surface.data(), surface.data());
150     QVERIFY(paletteCreatedSpy.wait());
151     auto paletteInterface = paletteCreatedSpy.first().first().value<KWaylandServer::ServerSideDecorationPaletteInterface *>();
152     QCOMPARE(m_paletteManagerInterface->paletteForSurface(serverSurface), paletteInterface);
153 
154     QCOMPARE(paletteInterface->palette(), QString());
155 
156     QSignalSpy changedSpy(paletteInterface, &KWaylandServer::ServerSideDecorationPaletteInterface::paletteChanged);
157 
158     palette->setPalette("foobar");
159 
160     QVERIFY(changedSpy.wait());
161     QCOMPARE(paletteInterface->palette(), QString("foobar"));
162 
163     // and destroy
164     QSignalSpy destroyedSpy(paletteInterface, &QObject::destroyed);
165     QVERIFY(destroyedSpy.isValid());
166     delete palette;
167     QVERIFY(destroyedSpy.wait());
168     QVERIFY(!m_paletteManagerInterface->paletteForSurface(serverSurface));
169 }
170 
171 QTEST_GUILESS_MAIN(TestServerSideDecorationPalette)
172 #include "test_server_side_decoration_palette.moc"
173