Add the activity management protocol server implementation
This commit is contained in:
parent
b822c1e63a
commit
d92fa7f140
4 changed files with 296 additions and 1 deletions
|
@ -353,6 +353,17 @@ target_link_libraries( testPlasmaVirtualDesktop Qt::Test Qt::Gui KF5::WaylandCli
|
|||
add_test(NAME kwayland-testPlasmaVirtualDesktop COMMAND testPlasmaVirtualDesktop)
|
||||
ecm_mark_as_test(testPlasmaVirtualDesktop)
|
||||
|
||||
########################################################
|
||||
# Test Activities
|
||||
########################################################
|
||||
set( testPlasmaActivities_SRCS
|
||||
test_plasma_activities.cpp
|
||||
)
|
||||
add_executable(testPlasmaActivities ${testPlasmaActivities_SRCS})
|
||||
target_link_libraries( testPlasmaActivities Qt::Test Qt::Gui KF5::WaylandClient Plasma::KWaylandServer)
|
||||
add_test(NAME kwayland-testPlasmaActivities COMMAND testPlasmaActivities)
|
||||
ecm_mark_as_test(testPlasmaActivities)
|
||||
|
||||
########################################################
|
||||
# Test XDG Output
|
||||
########################################################
|
||||
|
|
199
src/wayland/autotests/client/test_plasma_activities.cpp
Normal file
199
src/wayland/autotests/client/test_plasma_activities.cpp
Normal file
|
@ -0,0 +1,199 @@
|
|||
/*
|
||||
SPDX-FileCopyrightText: 2021 Kevin Ottens <kevin.ottens@enioka.com>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
|
||||
*/
|
||||
// Qt
|
||||
#include <QtTest>
|
||||
// KWin
|
||||
#include "KWayland/Client/compositor.h"
|
||||
#include "KWayland/Client/connection_thread.h"
|
||||
#include "KWayland/Client/event_queue.h"
|
||||
#include "KWayland/Client/region.h"
|
||||
#include "KWayland/Client/registry.h"
|
||||
#include "KWayland/Client/surface.h"
|
||||
#include "../../src/server/display.h"
|
||||
#include "../../src/server/compositor_interface.h"
|
||||
#include "../../src/server/plasmawindowmanagement_interface.h"
|
||||
#include "KWayland/Client/plasmawindowmanagement.h"
|
||||
|
||||
using namespace KWayland::Client;
|
||||
|
||||
class TestActivities : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit TestActivities(QObject *parent = nullptr);
|
||||
private Q_SLOTS:
|
||||
void init();
|
||||
void cleanup();
|
||||
|
||||
void testEnterLeaveActivity();
|
||||
|
||||
private:
|
||||
KWaylandServer::Display *m_display;
|
||||
KWaylandServer::CompositorInterface *m_compositorInterface;
|
||||
KWaylandServer::PlasmaWindowManagementInterface *m_windowManagementInterface;
|
||||
KWaylandServer::PlasmaWindowInterface *m_windowInterface;
|
||||
|
||||
KWayland::Client::ConnectionThread *m_connection;
|
||||
KWayland::Client::Compositor *m_compositor;
|
||||
KWayland::Client::EventQueue *m_queue;
|
||||
KWayland::Client::PlasmaWindowManagement *m_windowManagement;
|
||||
KWayland::Client::PlasmaWindow *m_window;
|
||||
|
||||
QThread *m_thread;
|
||||
};
|
||||
|
||||
static const QString s_socketName = QStringLiteral("kwayland-test-wayland-activities-0");
|
||||
|
||||
TestActivities::TestActivities(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_display(nullptr)
|
||||
, m_compositorInterface(nullptr)
|
||||
, m_connection(nullptr)
|
||||
, m_compositor(nullptr)
|
||||
, m_queue(nullptr)
|
||||
, m_thread(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
void TestActivities::init()
|
||||
{
|
||||
using namespace KWaylandServer;
|
||||
delete m_display;
|
||||
m_display = new Display(this);
|
||||
m_display->addSocketName(s_socketName);
|
||||
m_display->start();
|
||||
QVERIFY(m_display->isRunning());
|
||||
|
||||
// setup connection
|
||||
m_connection = new KWayland::Client::ConnectionThread;
|
||||
QSignalSpy connectedSpy(m_connection, &ConnectionThread::connected);
|
||||
QVERIFY(connectedSpy.isValid());
|
||||
m_connection->setSocketName(s_socketName);
|
||||
|
||||
m_thread = new QThread(this);
|
||||
m_connection->moveToThread(m_thread);
|
||||
m_thread->start();
|
||||
|
||||
m_connection->initConnection();
|
||||
QVERIFY(connectedSpy.wait());
|
||||
|
||||
m_queue = new KWayland::Client::EventQueue(this);
|
||||
QVERIFY(!m_queue->isValid());
|
||||
m_queue->setup(m_connection);
|
||||
QVERIFY(m_queue->isValid());
|
||||
|
||||
Registry registry;
|
||||
QSignalSpy compositorSpy(®istry, &Registry::compositorAnnounced);
|
||||
QVERIFY(compositorSpy.isValid());
|
||||
|
||||
QSignalSpy windowManagementSpy(®istry, &Registry::plasmaWindowManagementAnnounced);
|
||||
QVERIFY(windowManagementSpy.isValid());
|
||||
|
||||
QVERIFY(!registry.eventQueue());
|
||||
registry.setEventQueue(m_queue);
|
||||
QCOMPARE(registry.eventQueue(), m_queue);
|
||||
registry.create(m_connection->display());
|
||||
QVERIFY(registry.isValid());
|
||||
registry.setup();
|
||||
|
||||
m_compositorInterface = new CompositorInterface(m_display, m_display);
|
||||
QVERIFY(compositorSpy.wait());
|
||||
m_compositor = registry.createCompositor(compositorSpy.first().first().value<quint32>(), compositorSpy.first().last().value<quint32>(), this);
|
||||
|
||||
m_windowManagementInterface = new PlasmaWindowManagementInterface(m_display, m_display);
|
||||
|
||||
QVERIFY(windowManagementSpy.wait());
|
||||
m_windowManagement = registry.createPlasmaWindowManagement(windowManagementSpy.first().first().value<quint32>(), windowManagementSpy.first().last().value<quint32>(), this);
|
||||
|
||||
QSignalSpy windowSpy(m_windowManagement, &PlasmaWindowManagement::windowCreated);
|
||||
QVERIFY(windowSpy.isValid());
|
||||
m_windowInterface = m_windowManagementInterface->createWindow(this, QUuid::createUuid());
|
||||
m_windowInterface->setPid(1337);
|
||||
|
||||
QVERIFY(windowSpy.wait());
|
||||
m_window = windowSpy.first().first().value<PlasmaWindow *>();
|
||||
}
|
||||
|
||||
void TestActivities::cleanup()
|
||||
{
|
||||
#define CLEANUP(variable) \
|
||||
if (variable) { \
|
||||
delete variable; \
|
||||
variable = nullptr; \
|
||||
}
|
||||
CLEANUP(m_compositor)
|
||||
CLEANUP(m_windowInterface)
|
||||
CLEANUP(m_windowManagement)
|
||||
CLEANUP(m_queue)
|
||||
if (m_connection) {
|
||||
m_connection->deleteLater();
|
||||
m_connection = nullptr;
|
||||
}
|
||||
if (m_thread) {
|
||||
m_thread->quit();
|
||||
m_thread->wait();
|
||||
delete m_thread;
|
||||
m_thread = nullptr;
|
||||
}
|
||||
CLEANUP(m_compositorInterface)
|
||||
CLEANUP(m_windowManagementInterface)
|
||||
CLEANUP(m_display)
|
||||
#undef CLEANUP
|
||||
}
|
||||
|
||||
void TestActivities::testEnterLeaveActivity()
|
||||
{
|
||||
QSignalSpy enterRequestedSpy(m_windowInterface, &KWaylandServer::PlasmaWindowInterface::enterPlasmaActivityRequested);
|
||||
m_window->requestEnterActivity(QStringLiteral("0-1"));
|
||||
enterRequestedSpy.wait();
|
||||
|
||||
QCOMPARE(enterRequestedSpy.takeFirst().at(0).toString(), QStringLiteral("0-1"));
|
||||
|
||||
QSignalSpy activityEnteredSpy(m_window, &KWayland::Client::PlasmaWindow::plasmaActivityEntered);
|
||||
|
||||
//agree to the request
|
||||
m_windowInterface->addPlasmaActivity(QStringLiteral("0-1"));
|
||||
QCOMPARE(m_windowInterface->plasmaActivities().length(), 1);
|
||||
QCOMPARE(m_windowInterface->plasmaActivities().first(), QStringLiteral("0-1"));
|
||||
|
||||
//check if the client received the enter
|
||||
activityEnteredSpy.wait();
|
||||
QCOMPARE(activityEnteredSpy.takeFirst().at(0).toString(), QStringLiteral("0-1"));
|
||||
QCOMPARE(m_window->plasmaActivities().length(), 1);
|
||||
QCOMPARE(m_window->plasmaActivities().first(), QStringLiteral("0-1"));
|
||||
|
||||
//add another activity, server side
|
||||
m_windowInterface->addPlasmaActivity(QStringLiteral("0-3"));
|
||||
activityEnteredSpy.wait();
|
||||
QCOMPARE(activityEnteredSpy.takeFirst().at(0).toString(), QStringLiteral("0-3"));
|
||||
QCOMPARE(m_windowInterface->plasmaActivities().length(), 2);
|
||||
QCOMPARE(m_window->plasmaActivities().length(), 2);
|
||||
QCOMPARE(m_window->plasmaActivities()[1], QStringLiteral("0-3"));
|
||||
|
||||
|
||||
//remove an activity
|
||||
QSignalSpy leaveRequestedSpy(m_windowInterface, &KWaylandServer::PlasmaWindowInterface::leavePlasmaActivityRequested);
|
||||
m_window->requestLeaveActivity(QStringLiteral("0-1"));
|
||||
leaveRequestedSpy.wait();
|
||||
|
||||
QCOMPARE(leaveRequestedSpy.takeFirst().at(0).toString(), QStringLiteral("0-1"));
|
||||
|
||||
QSignalSpy activityLeftSpy(m_window, &KWayland::Client::PlasmaWindow::plasmaActivityLeft);
|
||||
|
||||
//agree to the request
|
||||
m_windowInterface->removePlasmaActivity(QStringLiteral("0-1"));
|
||||
QCOMPARE(m_windowInterface->plasmaActivities().length(), 1);
|
||||
QCOMPARE(m_windowInterface->plasmaActivities().first(), QStringLiteral("0-3"));
|
||||
|
||||
//check if the client received the leave
|
||||
activityLeftSpy.wait();
|
||||
QCOMPARE(activityLeftSpy.takeFirst().at(0).toString(), QStringLiteral("0-1"));
|
||||
QCOMPARE(m_window->plasmaActivities().length(), 1);
|
||||
QCOMPARE(m_window->plasmaActivities().first(), QStringLiteral("0-3"));
|
||||
}
|
||||
|
||||
QTEST_GUILESS_MAIN(TestActivities)
|
||||
#include "test_plasma_activities.moc"
|
|
@ -23,7 +23,7 @@
|
|||
namespace KWaylandServer
|
||||
{
|
||||
|
||||
static const quint32 s_version = 13;
|
||||
static const quint32 s_version = 14;
|
||||
|
||||
class PlasmaWindowManagementInterfacePrivate : public QtWaylandServer::org_kde_plasma_window_management
|
||||
{
|
||||
|
@ -78,6 +78,7 @@ public:
|
|||
PlasmaWindowInterface *parentWindow = nullptr;
|
||||
QMetaObject::Connection parentWindowDestroyConnection;
|
||||
QStringList plasmaVirtualDesktops;
|
||||
QStringList plasmaActivities;
|
||||
QRect geometry;
|
||||
PlasmaWindowInterface *q;
|
||||
QString m_title;
|
||||
|
@ -105,6 +106,8 @@ protected:
|
|||
void org_kde_plasma_window_request_enter_virtual_desktop(Resource *resource, const QString &id) override;
|
||||
void org_kde_plasma_window_request_enter_new_virtual_desktop(Resource *resource) override;
|
||||
void org_kde_plasma_window_request_leave_virtual_desktop(Resource *resource, const QString &id) override;
|
||||
void org_kde_plasma_window_request_enter_activity(Resource *resource, const QString &id) override;
|
||||
void org_kde_plasma_window_request_leave_activity(Resource *resource, const QString &id) override;
|
||||
};
|
||||
|
||||
PlasmaWindowManagementInterfacePrivate::PlasmaWindowManagementInterfacePrivate(PlasmaWindowManagementInterface *_q, Display *display)
|
||||
|
@ -343,6 +346,11 @@ void PlasmaWindowInterfacePrivate::org_kde_plasma_window_bind_resource(Resource
|
|||
for (const auto &desk : plasmaVirtualDesktops) {
|
||||
send_virtual_desktop_entered(resource->handle, desk);
|
||||
}
|
||||
for (const auto &activity : plasmaActivities) {
|
||||
if (resource->version() >= ORG_KDE_PLASMA_WINDOW_ACTIVITY_ENTERED_SINCE_VERSION) {
|
||||
send_activity_entered(resource->handle, activity);
|
||||
}
|
||||
}
|
||||
if (!m_appId.isEmpty()) {
|
||||
send_app_id_changed(resource->handle, m_appId);
|
||||
}
|
||||
|
@ -461,6 +469,18 @@ void PlasmaWindowInterfacePrivate::org_kde_plasma_window_request_leave_virtual_d
|
|||
emit q->leavePlasmaVirtualDesktopRequested(id);
|
||||
}
|
||||
|
||||
void PlasmaWindowInterfacePrivate::org_kde_plasma_window_request_enter_activity(Resource *resource, const QString &id)
|
||||
{
|
||||
Q_UNUSED(resource)
|
||||
emit q->enterPlasmaActivityRequested(id);
|
||||
}
|
||||
|
||||
void PlasmaWindowInterfacePrivate::org_kde_plasma_window_request_leave_activity(Resource *resource, const QString &id)
|
||||
{
|
||||
Q_UNUSED(resource)
|
||||
emit q->leavePlasmaActivityRequested(id);
|
||||
}
|
||||
|
||||
void PlasmaWindowInterfacePrivate::setTitle(const QString &title)
|
||||
{
|
||||
if (m_title == title) {
|
||||
|
@ -915,6 +935,41 @@ QStringList PlasmaWindowInterface::plasmaVirtualDesktops() const
|
|||
return d->plasmaVirtualDesktops;
|
||||
}
|
||||
|
||||
void PlasmaWindowInterface::addPlasmaActivity(const QString &id)
|
||||
{
|
||||
if (d->plasmaActivities.contains(id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
d->plasmaActivities << id;
|
||||
|
||||
const auto clientResources = d->resourceMap();
|
||||
for (auto resource : clientResources) {
|
||||
if (resource->version() >= ORG_KDE_PLASMA_WINDOW_ACTIVITY_ENTERED_SINCE_VERSION) {
|
||||
d->send_activity_entered(resource->handle, id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PlasmaWindowInterface::removePlasmaActivity(const QString &id)
|
||||
{
|
||||
if (!d->plasmaActivities.removeOne(id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto clientResources = d->resourceMap();
|
||||
for (auto resource : clientResources) {
|
||||
if (resource->version() >= ORG_KDE_PLASMA_WINDOW_ACTIVITY_LEFT_SINCE_VERSION) {
|
||||
d->send_activity_left(resource->handle, id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QStringList PlasmaWindowInterface::plasmaActivities() const
|
||||
{
|
||||
return d->plasmaActivities;
|
||||
}
|
||||
|
||||
void PlasmaWindowInterface::setShadeable(bool set)
|
||||
{
|
||||
d->setState(ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_SHADEABLE, set);
|
||||
|
|
|
@ -174,6 +174,24 @@ public:
|
|||
*/
|
||||
QStringList plasmaVirtualDesktops() const;
|
||||
|
||||
/**
|
||||
* Adds an activity to this window: a window can be on
|
||||
* an arbitrary subset of activities.
|
||||
* If it's on none it will be considered on all activities.
|
||||
*/
|
||||
void addPlasmaActivity(const QString &id);
|
||||
|
||||
/**
|
||||
* Removes an activity from a window
|
||||
*/
|
||||
void removePlasmaActivity(const QString &id);
|
||||
|
||||
/**
|
||||
* The ids of all the activities currently associated with this window.
|
||||
* When an activity is deleted it will be automatically removed from this list
|
||||
*/
|
||||
QStringList plasmaActivities() const;
|
||||
|
||||
/**
|
||||
* Set the application menu D-BUS service name and object path for the window.
|
||||
*/
|
||||
|
@ -242,6 +260,18 @@ Q_SIGNALS:
|
|||
*/
|
||||
void leavePlasmaVirtualDesktopRequested(const QString &desktop);
|
||||
|
||||
/**
|
||||
* Emitted when the client wishes this window to enter an activity.
|
||||
* The server will decide whether to consent this request
|
||||
*/
|
||||
void enterPlasmaActivityRequested(const QString &activity);
|
||||
|
||||
/**
|
||||
* Emitted when the client wishes to remove this window from an activity.
|
||||
* The server will decide whether to consent this request
|
||||
*/
|
||||
void leavePlasmaActivityRequested(const QString &activity);
|
||||
|
||||
private:
|
||||
friend class PlasmaWindowManagementInterface;
|
||||
friend class PlasmaWindowInterfacePrivate;
|
||||
|
|
Loading…
Reference in a new issue