Commit 603dfbaf authored by Adrien Faveraux's avatar Adrien Faveraux Committed by Vlad Zahorodnii
Browse files

migrate idle interface to the new approach

parent 3eb27e60
......@@ -57,7 +57,6 @@ void IdleTest::init()
m_seatInterface->setName(QStringLiteral("seat0"));
m_seatInterface->create();
m_idleInterface = m_display->createIdle();
m_idleInterface->create();
// setup connection
m_connection = new KWayland::Client::ConnectionThread;
......
......@@ -113,7 +113,7 @@ ecm_add_wayland_server_protocol(SERVER_LIB_SRCS
BASENAME qt-surface-extension
)
ecm_add_wayland_server_protocol(SERVER_LIB_SRCS
ecm_add_qtwayland_server_protocol(SERVER_LIB_SRCS
PROTOCOL ${PLASMA_WAYLAND_PROTOCOLS_DIR}/idle.xml
BASENAME idle
)
......
......@@ -3,115 +3,44 @@
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#include "idle_interface.h"
#include "idle_interface_p.h"
#include "display.h"
#include "global_p.h"
#include "resource_p.h"
#include "seat_interface.h"
#include <QTimer>
#include <functional>
#include <wayland-server.h>
#include <wayland-idle-server-protocol.h>
namespace KWaylandServer
{
class IdleInterface::Private : public Global::Private
{
public:
Private(IdleInterface *q, Display *d);
int inhibitCount = 0;
QVector<IdleTimeoutInterface*> idleTimeouts;
private:
void bind(wl_client *client, uint32_t version, uint32_t id) override;
static void getIdleTimeoutCallback(wl_client *client, wl_resource *resource, uint32_t id, wl_resource *seat, uint32_t timeout);
static void unbind(wl_resource *resource);
static Private *cast(wl_resource *r) {
return reinterpret_cast<Private*>(wl_resource_get_user_data(r));
}
IdleInterface *q;
static const struct org_kde_kwin_idle_interface s_interface;
static const quint32 s_version;
};
class IdleTimeoutInterface::Private : public Resource::Private
{
public:
Private(SeatInterface *seat, IdleTimeoutInterface *q, IdleInterface *manager, wl_resource *parentResource);
~Private();
void setup(quint32 timeout);
void simulateUserActivity();
SeatInterface *seat;
QTimer *timer = nullptr;
private:
static void simulateUserActivityCallback(wl_client *client, wl_resource *resource);
IdleTimeoutInterface *q_func() {
return reinterpret_cast<IdleTimeoutInterface*>(q);
}
static const struct org_kde_kwin_idle_timeout_interface s_interface;
};
const quint32 IdleInterfacePrivate::s_version = 1;
const quint32 IdleInterface::Private::s_version = 1;
#ifndef K_DOXYGEN
const struct org_kde_kwin_idle_interface IdleInterface::Private::s_interface = {
getIdleTimeoutCallback
};
#endif
IdleInterface::Private::Private(IdleInterface *q, Display *d)
: Global::Private(d, &org_kde_kwin_idle_interface, s_version)
, q(q)
IdleInterfacePrivate::IdleInterfacePrivate(IdleInterface *_q, Display *display)
: QtWaylandServer::org_kde_kwin_idle(*display, s_version)
, q(_q)
{
}
void IdleInterface::Private::getIdleTimeoutCallback(wl_client *client, wl_resource *resource, uint32_t id, wl_resource *seat, uint32_t timeout)
void IdleInterfacePrivate::org_kde_kwin_idle_get_idle_timeout(Resource *resource, uint32_t id, wl_resource *seat, uint32_t timeout)
{
Private *p = cast(resource);
SeatInterface *s = SeatInterface::get(seat);
Q_ASSERT(s);
IdleTimeoutInterface *idleTimeout = new IdleTimeoutInterface(s, p->q, resource);
idleTimeout->create(p->display->getConnection(client), wl_resource_get_version(resource), id);
if (!idleTimeout->resource()) {
wl_resource_post_no_memory(resource);
delete idleTimeout;
return;
}
p->idleTimeouts << idleTimeout;
QObject::connect(idleTimeout, &IdleTimeoutInterface::aboutToBeUnbound, p->q, [p, idleTimeout]() {
p->idleTimeouts.removeOne(idleTimeout);
});
idleTimeout->d_func()->setup(timeout);
}
void IdleInterface::Private::bind(wl_client *client, uint32_t version, uint32_t id)
{
auto c = display->getConnection(client);
wl_resource *resource = c->createResource(&org_kde_kwin_idle_interface, qMin(version, s_version), id);
if (!resource) {
wl_client_post_no_memory(client);
wl_resource *idleTimoutResource = wl_resource_create(resource->client(), &org_kde_kwin_idle_timeout_interface, resource->version(), id);
if (!idleTimoutResource) {
wl_client_post_no_memory(resource->client());
return;
}
wl_resource_set_implementation(resource, &s_interface, this, unbind);
// TODO: should we track?
}
void IdleInterface::Private::unbind(wl_resource *resource)
{
Q_UNUSED(resource)
IdleTimeoutInterface *idleTimeout = new IdleTimeoutInterface(s, q, idleTimoutResource);
idleTimeouts << idleTimeout;
QObject::connect(idleTimeout, &IdleTimeoutInterface::destroyed, q, [this, idleTimeout]() {
idleTimeouts.removeOne(idleTimeout);
});
idleTimeout->setup(timeout);
}
IdleInterface::IdleInterface(Display *display, QObject *parent)
: Global(new Private(this, display), parent)
: QObject(parent)
, d(new IdleInterfacePrivate(this, display))
{
}
......@@ -119,7 +48,6 @@ IdleInterface::~IdleInterface() = default;
void IdleInterface::inhibit()
{
Q_D();
d->inhibitCount++;
if (d->inhibitCount == 1) {
emit inhibitedChanged();
......@@ -128,7 +56,6 @@ void IdleInterface::inhibit()
void IdleInterface::uninhibit()
{
Q_D();
d->inhibitCount--;
if (d->inhibitCount == 0) {
emit inhibitedChanged();
......@@ -137,117 +64,97 @@ void IdleInterface::uninhibit()
bool IdleInterface::isInhibited() const
{
Q_D();
return d->inhibitCount > 0;
}
void IdleInterface::simulateUserActivity()
{
Q_D();
for (auto i : qAsConst(d->idleTimeouts)) {
i->d_func()->simulateUserActivity();
i->simulateUserActivity();
}
}
IdleInterface::Private *IdleInterface::d_func() const
IdleTimeoutInterface::IdleTimeoutInterface(SeatInterface *seat, IdleInterface *manager, wl_resource *resource)
: QObject()
, QtWaylandServer::org_kde_kwin_idle_timeout(resource)
, seat(seat)
, manager(manager)
{
return reinterpret_cast<Private*>(d.data());
connect(seat, &SeatInterface::timestampChanged, this,
[this] {
simulateUserActivity();
}
);
connect(manager, &IdleInterface::inhibitedChanged, this,
[this, manager] {
if (!timer) {
// not yet configured
return;
}
if (manager->isInhibited()) {
if (!timer->isActive()) {
send_resumed();
}
timer->stop();
} else {
timer->start();
}
}
);
}
#ifndef K_DOXYGEN
const struct org_kde_kwin_idle_timeout_interface IdleTimeoutInterface::Private::s_interface = {
resourceDestroyedCallback,
simulateUserActivityCallback
};
#endif
IdleTimeoutInterface::~IdleTimeoutInterface() = default;
IdleTimeoutInterface::Private::Private(SeatInterface *seat, IdleTimeoutInterface *q, IdleInterface *manager, wl_resource *parentResource)
: Resource::Private(q, manager, parentResource, &org_kde_kwin_idle_timeout_interface, &s_interface)
, seat(seat)
void IdleTimeoutInterface::org_kde_kwin_idle_timeout_release(Resource *resource)
{
wl_resource_destroy(resource->handle);
}
IdleTimeoutInterface::Private::~Private() = default;
void IdleTimeoutInterface::Private::simulateUserActivityCallback(wl_client *client, wl_resource *resource)
void IdleTimeoutInterface::org_kde_kwin_idle_timeout_destroy_resource(Resource *resource)
{
Q_UNUSED(client);
Private *p = reinterpret_cast<Private*>(wl_resource_get_user_data(resource));
p->simulateUserActivity();
Q_UNUSED(resource)
delete this;
}
void IdleTimeoutInterface::Private::simulateUserActivity()
void IdleTimeoutInterface::org_kde_kwin_idle_timeout_simulate_user_activity(Resource *resource)
{
Q_UNUSED(resource)
simulateUserActivity();
}
void IdleTimeoutInterface::simulateUserActivity()
{
if (!timer) {
// not yet configured
return;
}
if (qobject_cast<IdleInterface*>(global)->isInhibited()) {
if (manager->isInhibited()) {
// ignored while inhibited
return;
}
if (!timer->isActive() && resource) {
org_kde_kwin_idle_timeout_send_resumed(resource);
if (!timer->isActive()) {
send_resumed();
}
timer->start();
}
void IdleTimeoutInterface::Private::setup(quint32 timeout)
void IdleTimeoutInterface::setup(quint32 timeout)
{
if (timer) {
return;
}
timer = new QTimer(q);
timer = new QTimer(this);
timer->setSingleShot(true);
// less than 5 sec is not idle by definition
timer->setInterval(qMax(timeout, 5000u));
QObject::connect(timer, &QTimer::timeout, q,
QObject::connect(timer, &QTimer::timeout, this,
[this] {
if (resource) {
org_kde_kwin_idle_timeout_send_idle(resource);
}
send_idle();
}
);
if (qobject_cast<IdleInterface*>(global)->isInhibited()) {
if (manager->isInhibited()) {
// don't start if inhibited
return;
}
timer->start();
}
IdleTimeoutInterface::IdleTimeoutInterface(SeatInterface *seat, IdleInterface *parent, wl_resource *parentResource)
: Resource(new Private(seat, this, parent, parentResource))
{
connect(seat, &SeatInterface::timestampChanged, this,
[this] {
Q_D();
d->simulateUserActivity();
}
);
connect(parent, &IdleInterface::inhibitedChanged, this,
[this] {
Q_D();
if (!d->timer) {
// not yet configured
return;
}
if (qobject_cast<IdleInterface*>(d->global)->isInhibited()) {
if (!d->timer->isActive() && d->resource) {
org_kde_kwin_idle_timeout_send_resumed(d->resource);
}
d->timer->stop();
} else {
d->timer->start();
}
}
);
}
IdleTimeoutInterface::~IdleTimeoutInterface() = default;
IdleTimeoutInterface::Private *IdleTimeoutInterface::d_func() const
{
return reinterpret_cast<IdleTimeoutInterface::Private*>(d.data());
}
}
......@@ -6,15 +6,17 @@
#ifndef KWAYLAND_SERVER_IDLE_INTERFACE_H
#define KWAYLAND_SERVER_IDLE_INTERFACE_H
#include <QObject>
#include <KWaylandServer/kwaylandserver_export.h>
#include "global.h"
#include "resource.h"
struct wl_resource;
namespace KWaylandServer
{
class Display;
class SeatInterface;
class IdleInterfacePrivate;
/**
* @brief Global representing the org_kde_kwin_idle interface.
......@@ -36,11 +38,11 @@ class SeatInterface;
*
* @since 5.4
**/
class KWAYLANDSERVER_EXPORT IdleInterface : public Global
class KWAYLANDSERVER_EXPORT IdleInterface : public QObject
{
Q_OBJECT
public:
virtual ~IdleInterface();
~IdleInterface() override;
/**
* Inhibits the IdleInterface. While inhibited no IdleTimeoutInterface interface gets
......@@ -100,22 +102,7 @@ Q_SIGNALS:
private:
explicit IdleInterface(Display *display, QObject *parent = nullptr);
friend class Display;
class Private;
Private *d_func() const;
};
// TODO: KF6 make private class
class KWAYLANDSERVER_EXPORT IdleTimeoutInterface : public Resource
{
Q_OBJECT
public:
virtual ~IdleTimeoutInterface();
private:
explicit IdleTimeoutInterface(SeatInterface *seat, IdleInterface *parent, wl_resource *parentResource);
friend class IdleInterface;
class Private;
Private *d_func() const;
QScopedPointer<IdleInterfacePrivate> d;
};
}
......
/*
SPDX-FileCopyrightText: 2015 Martin Gräßlin <mgraesslin@kde.org>
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#ifndef KWAYLAND_SERVER_IDLE_INTERFACE_P_H
#define KWAYLAND_SERVER_IDLE_INTERFACE_P_H
#include "idle_interface.h"
#include <qwayland-server-idle.h>
#include <QTimer>
namespace KWaylandServer
{
class Display;
class SeatInterface;
class IdleTimeoutInterface;
class IdleTimeoutInterface;
class IdleInterfacePrivate : public QtWaylandServer::org_kde_kwin_idle
{
public:
IdleInterfacePrivate(IdleInterface *_q, Display *display);
int inhibitCount = 0;
QVector<IdleTimeoutInterface *> idleTimeouts;
IdleInterface *q;
static const quint32 s_version;
protected:
void org_kde_kwin_idle_get_idle_timeout(Resource *resource, uint32_t id, wl_resource *seat, uint32_t timeout) override;
};
class IdleTimeoutInterface : public QObject, QtWaylandServer::org_kde_kwin_idle_timeout
{
Q_OBJECT
public:
explicit IdleTimeoutInterface(SeatInterface *seat, IdleInterface *parent, wl_resource *resource);
~IdleTimeoutInterface() override;
void setup(quint32 timeout);
void simulateUserActivity();
private:
SeatInterface *seat;
IdleInterface *manager;
QTimer *timer = nullptr;
protected:
void org_kde_kwin_idle_timeout_destroy_resource(Resource *resource) override;
void org_kde_kwin_idle_timeout_release(Resource *resource) override;
void org_kde_kwin_idle_timeout_simulate_user_activity(Resource *resource) override;
};
}
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment