File indexing completed on 2024-06-02 05:36:39

0001 /*
0002     SPDX-FileCopyrightText: 2021 Kevin Ottens <kevin.ottens@enioka.com>
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 // KWin
0010 #include "wayland/compositor.h"
0011 #include "wayland/display.h"
0012 #include "wayland/plasmawindowmanagement.h"
0013 
0014 #include "KWayland/Client/compositor.h"
0015 #include "KWayland/Client/connection_thread.h"
0016 #include "KWayland/Client/event_queue.h"
0017 #include "KWayland/Client/plasmawindowmanagement.h"
0018 #include "KWayland/Client/region.h"
0019 #include "KWayland/Client/registry.h"
0020 #include "KWayland/Client/surface.h"
0021 
0022 class TestActivities : public QObject
0023 {
0024     Q_OBJECT
0025 public:
0026     explicit TestActivities(QObject *parent = nullptr);
0027 private Q_SLOTS:
0028     void init();
0029     void cleanup();
0030 
0031     void testEnterLeaveActivity();
0032 
0033 private:
0034     KWin::Display *m_display;
0035     KWin::CompositorInterface *m_compositorInterface;
0036     KWin::PlasmaWindowManagementInterface *m_windowManagementInterface;
0037     KWin::PlasmaWindowInterface *m_windowInterface;
0038 
0039     KWayland::Client::ConnectionThread *m_connection;
0040     KWayland::Client::Compositor *m_compositor;
0041     KWayland::Client::EventQueue *m_queue;
0042     KWayland::Client::PlasmaWindowManagement *m_windowManagement;
0043     KWayland::Client::PlasmaWindow *m_window;
0044 
0045     QThread *m_thread;
0046 };
0047 
0048 static const QString s_socketName = QStringLiteral("kwayland-test-wayland-activities-0");
0049 
0050 TestActivities::TestActivities(QObject *parent)
0051     : QObject(parent)
0052     , m_display(nullptr)
0053     , m_compositorInterface(nullptr)
0054     , m_connection(nullptr)
0055     , m_compositor(nullptr)
0056     , m_queue(nullptr)
0057     , m_thread(nullptr)
0058 {
0059 }
0060 
0061 void TestActivities::init()
0062 {
0063     using namespace KWin;
0064     delete m_display;
0065     m_display = new KWin::Display(this);
0066     m_display->addSocketName(s_socketName);
0067     m_display->start();
0068     QVERIFY(m_display->isRunning());
0069 
0070     // setup connection
0071     m_connection = new KWayland::Client::ConnectionThread;
0072     QSignalSpy connectedSpy(m_connection, &KWayland::Client::ConnectionThread::connected);
0073     m_connection->setSocketName(s_socketName);
0074 
0075     m_thread = new QThread(this);
0076     m_connection->moveToThread(m_thread);
0077     m_thread->start();
0078 
0079     m_connection->initConnection();
0080     QVERIFY(connectedSpy.wait());
0081 
0082     m_queue = new KWayland::Client::EventQueue(this);
0083     QVERIFY(!m_queue->isValid());
0084     m_queue->setup(m_connection);
0085     QVERIFY(m_queue->isValid());
0086 
0087     KWayland::Client::Registry registry;
0088     QSignalSpy compositorSpy(&registry, &KWayland::Client::Registry::compositorAnnounced);
0089 
0090     QSignalSpy windowManagementSpy(&registry, &KWayland::Client::Registry::plasmaWindowManagementAnnounced);
0091 
0092     QVERIFY(!registry.eventQueue());
0093     registry.setEventQueue(m_queue);
0094     QCOMPARE(registry.eventQueue(), m_queue);
0095     registry.create(m_connection->display());
0096     QVERIFY(registry.isValid());
0097     registry.setup();
0098 
0099     m_compositorInterface = new CompositorInterface(m_display, m_display);
0100     QVERIFY(compositorSpy.wait());
0101     m_compositor = registry.createCompositor(compositorSpy.first().first().value<quint32>(), compositorSpy.first().last().value<quint32>(), this);
0102 
0103     m_windowManagementInterface = new PlasmaWindowManagementInterface(m_display, m_display);
0104 
0105     QVERIFY(windowManagementSpy.wait());
0106     m_windowManagement =
0107         registry.createPlasmaWindowManagement(windowManagementSpy.first().first().value<quint32>(), windowManagementSpy.first().last().value<quint32>(), this);
0108 
0109     QSignalSpy windowSpy(m_windowManagement, &KWayland::Client::PlasmaWindowManagement::windowCreated);
0110     m_windowInterface = m_windowManagementInterface->createWindow(this, QUuid::createUuid());
0111     m_windowInterface->setPid(1337);
0112 
0113     QVERIFY(windowSpy.wait());
0114     m_window = windowSpy.first().first().value<KWayland::Client::PlasmaWindow *>();
0115 }
0116 
0117 void TestActivities::cleanup()
0118 {
0119 #define CLEANUP(variable)   \
0120     if (variable) {         \
0121         delete variable;    \
0122         variable = nullptr; \
0123     }
0124     CLEANUP(m_compositor)
0125     CLEANUP(m_windowInterface)
0126     CLEANUP(m_windowManagement)
0127     CLEANUP(m_queue)
0128     if (m_connection) {
0129         m_connection->deleteLater();
0130         m_connection = nullptr;
0131     }
0132     if (m_thread) {
0133         m_thread->quit();
0134         m_thread->wait();
0135         delete m_thread;
0136         m_thread = nullptr;
0137     }
0138     CLEANUP(m_compositorInterface)
0139     CLEANUP(m_windowManagementInterface)
0140     CLEANUP(m_display)
0141 #undef CLEANUP
0142 }
0143 
0144 void TestActivities::testEnterLeaveActivity()
0145 {
0146     QSignalSpy enterRequestedSpy(m_windowInterface, &KWin::PlasmaWindowInterface::enterPlasmaActivityRequested);
0147     m_window->requestEnterActivity(QStringLiteral("0-1"));
0148     enterRequestedSpy.wait();
0149 
0150     QCOMPARE(enterRequestedSpy.takeFirst().at(0).toString(), QStringLiteral("0-1"));
0151 
0152     QSignalSpy activityEnteredSpy(m_window, &KWayland::Client::PlasmaWindow::plasmaActivityEntered);
0153 
0154     // agree to the request
0155     m_windowInterface->addPlasmaActivity(QStringLiteral("0-1"));
0156     QCOMPARE(m_windowInterface->plasmaActivities().length(), 1);
0157     QCOMPARE(m_windowInterface->plasmaActivities().first(), QStringLiteral("0-1"));
0158 
0159     // check if the client received the enter
0160     activityEnteredSpy.wait();
0161     QCOMPARE(activityEnteredSpy.takeFirst().at(0).toString(), QStringLiteral("0-1"));
0162     QCOMPARE(m_window->plasmaActivities().length(), 1);
0163     QCOMPARE(m_window->plasmaActivities().first(), QStringLiteral("0-1"));
0164 
0165     // add another activity, server side
0166     m_windowInterface->addPlasmaActivity(QStringLiteral("0-3"));
0167     activityEnteredSpy.wait();
0168     QCOMPARE(activityEnteredSpy.takeFirst().at(0).toString(), QStringLiteral("0-3"));
0169     QCOMPARE(m_windowInterface->plasmaActivities().length(), 2);
0170     QCOMPARE(m_window->plasmaActivities().length(), 2);
0171     QCOMPARE(m_window->plasmaActivities()[1], QStringLiteral("0-3"));
0172 
0173     // remove an activity
0174     QSignalSpy leaveRequestedSpy(m_windowInterface, &KWin::PlasmaWindowInterface::leavePlasmaActivityRequested);
0175     m_window->requestLeaveActivity(QStringLiteral("0-1"));
0176     leaveRequestedSpy.wait();
0177 
0178     QCOMPARE(leaveRequestedSpy.takeFirst().at(0).toString(), QStringLiteral("0-1"));
0179 
0180     QSignalSpy activityLeftSpy(m_window, &KWayland::Client::PlasmaWindow::plasmaActivityLeft);
0181 
0182     // agree to the request
0183     m_windowInterface->removePlasmaActivity(QStringLiteral("0-1"));
0184     QCOMPARE(m_windowInterface->plasmaActivities().length(), 1);
0185     QCOMPARE(m_windowInterface->plasmaActivities().first(), QStringLiteral("0-3"));
0186 
0187     // check if the client received the leave
0188     activityLeftSpy.wait();
0189     QCOMPARE(activityLeftSpy.takeFirst().at(0).toString(), QStringLiteral("0-1"));
0190     QCOMPARE(m_window->plasmaActivities().length(), 1);
0191     QCOMPARE(m_window->plasmaActivities().first(), QStringLiteral("0-3"));
0192 }
0193 
0194 QTEST_GUILESS_MAIN(TestActivities)
0195 #include "test_plasma_activities.moc"