From efdc6e44ee8b4d356cd74384f394e269afe701cf Mon Sep 17 00:00:00 2001 From: Adrien Faveraux Date: Tue, 14 Jul 2020 16:25:55 +0200 Subject: [PATCH] Migrate Server Decoration to new approach --- src/wayland/CMakeLists.txt | 4 +- .../client/test_server_side_decoration.cpp | 2 - src/wayland/server_decoration_interface.cpp | 235 ++++++++---------- src/wayland/server_decoration_interface.h | 25 +- 4 files changed, 118 insertions(+), 148 deletions(-) diff --git a/src/wayland/CMakeLists.txt b/src/wayland/CMakeLists.txt index 4c0f6fc466..d17ee13bc0 100644 --- a/src/wayland/CMakeLists.txt +++ b/src/wayland/CMakeLists.txt @@ -148,9 +148,9 @@ ecm_add_wayland_server_protocol(SERVER_LIB_SRCS BASENAME slide ) -ecm_add_wayland_server_protocol(SERVER_LIB_SRCS +ecm_add_qtwayland_server_protocol(SERVER_LIB_SRCS PROTOCOL ${PLASMA_WAYLAND_PROTOCOLS_DIR}/server-decoration.xml - BASENAME server_decoration + BASENAME server-decoration ) ecm_add_wayland_server_protocol(SERVER_LIB_SRCS diff --git a/src/wayland/autotests/client/test_server_side_decoration.cpp b/src/wayland/autotests/client/test_server_side_decoration.cpp index aca4179e88..7355a36035 100644 --- a/src/wayland/autotests/client/test_server_side_decoration.cpp +++ b/src/wayland/autotests/client/test_server_side_decoration.cpp @@ -101,8 +101,6 @@ void TestServerSideDecoration::init() m_compositor = m_registry->createCompositor(compositorSpy.first().first().value(), compositorSpy.first().last().value(), this); m_serverSideDecorationManagerInterface = m_display->createServerSideDecorationManager(m_display); - m_serverSideDecorationManagerInterface->create(); - QVERIFY(m_serverSideDecorationManagerInterface->isValid()); QVERIFY(serverSideDecoManagerSpy.wait()); m_serverSideDecorationManager = m_registry->createServerSideDecorationManager(serverSideDecoManagerSpy.first().first().value(), diff --git a/src/wayland/server_decoration_interface.cpp b/src/wayland/server_decoration_interface.cpp index b1c150723d..3a22351e8a 100644 --- a/src/wayland/server_decoration_interface.cpp +++ b/src/wayland/server_decoration_interface.cpp @@ -5,85 +5,35 @@ */ #include "server_decoration_interface.h" #include "display.h" -#include "global_p.h" #include "logging.h" -#include "resource_p.h" #include "surface_interface.h" #include -#include +#include namespace KWaylandServer { -class ServerSideDecorationManagerInterface::Private : public Global::Private +class ServerSideDecorationManagerInterfacePrivate : public QtWaylandServer::org_kde_kwin_server_decoration_manager { public: - Private(ServerSideDecorationManagerInterface *q, Display *d); - - Mode defaultMode = Mode::None; - - QVector resources; + ServerSideDecorationManagerInterfacePrivate(ServerSideDecorationManagerInterface *_q, Display *display); + void setDefaultMode(ServerSideDecorationManagerInterface::Mode mode); + ServerSideDecorationManagerInterface::Mode defaultMode = ServerSideDecorationManagerInterface::Mode::None; + private: - void bind(wl_client *client, uint32_t version, uint32_t id) override; - - static void unbind(wl_resource *resource); - static Private *cast(wl_resource *r) { - return reinterpret_cast(wl_resource_get_user_data(r)); - } - - static void createCallback(wl_client *client, wl_resource *resource, uint32_t id, wl_resource * surface); - void create(wl_client *client, wl_resource *resource, uint32_t id, wl_resource * surface); - ServerSideDecorationManagerInterface *q; - static const struct org_kde_kwin_server_decoration_manager_interface s_interface; static const quint32 s_version; + +protected: + void org_kde_kwin_server_decoration_manager_bind_resource(Resource *resource) override; + void org_kde_kwin_server_decoration_manager_create(Resource *resource, uint32_t id, wl_resource *surface) override; + }; -const quint32 ServerSideDecorationManagerInterface::Private::s_version = 1; - -#ifndef K_DOXYGEN -const struct org_kde_kwin_server_decoration_manager_interface ServerSideDecorationManagerInterface::Private::s_interface = { - createCallback -}; -#endif - -void ServerSideDecorationManagerInterface::Private::createCallback(wl_client *client, wl_resource *resource, uint32_t id, wl_resource *surface) -{ - reinterpret_cast(wl_resource_get_user_data(resource))->create(client, resource, id, surface); -} - -void ServerSideDecorationManagerInterface::Private::create(wl_client *client, wl_resource *resource, uint32_t id, wl_resource *surface) -{ - SurfaceInterface *s = SurfaceInterface::get(surface); - if (!s) { - // TODO: send error? - qCWarning(KWAYLAND_SERVER) << "ServerSideDecorationInterface requested for non existing SurfaceInterface"; - return; - } - ServerSideDecorationInterface *decoration = new ServerSideDecorationInterface(q, s, resource); - decoration->create(display->getConnection(client), wl_resource_get_version(resource), id); - if (!decoration->resource()) { - wl_resource_post_no_memory(resource); - delete decoration; - return; - } - decoration->setMode(defaultMode); - emit q->decorationCreated(decoration); -} - -ServerSideDecorationManagerInterface::Mode ServerSideDecorationManagerInterface::defaultMode() const -{ - return d_func()->defaultMode; -} - -ServerSideDecorationManagerInterface::Private::Private(ServerSideDecorationManagerInterface *q, Display *d) - : Global::Private(d, &org_kde_kwin_server_decoration_manager_interface, s_version) - , q(q) -{ -} +const quint32 ServerSideDecorationManagerInterfacePrivate::s_version = 1; namespace { static uint32_t modeWayland(ServerSideDecorationManagerInterface::Mode mode) @@ -104,82 +54,93 @@ static uint32_t modeWayland(ServerSideDecorationManagerInterface::Mode mode) } } -void ServerSideDecorationManagerInterface::Private::bind(wl_client *client, uint32_t version, uint32_t id) +void ServerSideDecorationManagerInterfacePrivate::org_kde_kwin_server_decoration_manager_create(Resource *resource, uint32_t id, wl_resource *surface) { - auto c = display->getConnection(client); - wl_resource *resource = c->createResource(&org_kde_kwin_server_decoration_manager_interface, qMin(version, s_version), id); - if (!resource) { - wl_client_post_no_memory(client); + SurfaceInterface *s = SurfaceInterface::get(surface); + if (!s) { + wl_resource_post_error(resource->handle, 0, "Invalid surface"); return; } - wl_resource_set_implementation(resource, &s_interface, this, unbind); - resources << resource; - - org_kde_kwin_server_decoration_manager_send_default_mode(resource, modeWayland(defaultMode)); - c->flush(); + wl_resource *decorationResource = wl_resource_create(resource->client(), &org_kde_kwin_server_decoration_interface, resource->version(), id); + if (!decorationResource) { + wl_client_post_no_memory(resource->client()); + return; + } + auto decoration = new ServerSideDecorationInterface(s, decorationResource); + decoration->setMode(defaultMode); + emit q->decorationCreated(decoration); } -void ServerSideDecorationManagerInterface::Private::unbind(wl_resource *resource) +void ServerSideDecorationManagerInterfacePrivate::setDefaultMode(ServerSideDecorationManagerInterface::Mode mode) { - cast(resource)->resources.removeAll(resource); + defaultMode = mode; + const uint32_t wlMode = modeWayland(mode); + + const auto clientResources = resourceMap(); + for (Resource *resource : clientResources) { + send_default_mode(resource->handle, wlMode); + } } +ServerSideDecorationManagerInterfacePrivate::ServerSideDecorationManagerInterfacePrivate(ServerSideDecorationManagerInterface *_q, Display *display) + : QtWaylandServer::org_kde_kwin_server_decoration_manager(*display, s_version) + , q(_q) +{ +} + +void ServerSideDecorationManagerInterfacePrivate::org_kde_kwin_server_decoration_manager_bind_resource(Resource *resource) +{ + send_default_mode(resource->handle, modeWayland(defaultMode)); +} + + ServerSideDecorationManagerInterface::ServerSideDecorationManagerInterface(Display *display, QObject *parent) - : Global(new Private(this, display), parent) + : QObject(parent) + , d(new ServerSideDecorationManagerInterfacePrivate(this, display)) { } ServerSideDecorationManagerInterface::~ServerSideDecorationManagerInterface() = default; -ServerSideDecorationManagerInterface::Private *ServerSideDecorationManagerInterface::d_func() const -{ - return reinterpret_cast(d.data()); -} - void ServerSideDecorationManagerInterface::setDefaultMode(Mode mode) { - Q_D(); - d->defaultMode = mode; - const uint32_t wlMode = modeWayland(mode); - for (auto it = d->resources.constBegin(); it != d->resources.constEnd(); it++) { - org_kde_kwin_server_decoration_manager_send_default_mode(*it, wlMode); - } + d->setDefaultMode(mode); } -class ServerSideDecorationInterface::Private : public Resource::Private +ServerSideDecorationManagerInterface::Mode ServerSideDecorationManagerInterface::defaultMode() const +{ + return d->defaultMode; +} + +class ServerSideDecorationInterfacePrivate : public QtWaylandServer::org_kde_kwin_server_decoration { public: - Private(ServerSideDecorationInterface *q, ServerSideDecorationManagerInterface *c, SurfaceInterface *surface, wl_resource *parentResource); - ~Private(); + ServerSideDecorationInterfacePrivate(ServerSideDecorationInterface *_q, SurfaceInterface *surface, wl_resource *resource); + ~ServerSideDecorationInterfacePrivate(); + + static ServerSideDecorationInterface *get(SurfaceInterface *surface); + void setMode(ServerSideDecorationManagerInterface::Mode mode); ServerSideDecorationManagerInterface::Mode mode = ServerSideDecorationManagerInterface::Mode::None; SurfaceInterface *surface; - static ServerSideDecorationInterface *get(SurfaceInterface *s); - private: - static void requestModeCallback(wl_client *client, wl_resource *resource, uint32_t mode); + ServerSideDecorationInterface *q; + static QVector s_all; - ServerSideDecorationInterface *q_func() { - return reinterpret_cast(q); - } - - static const struct org_kde_kwin_server_decoration_interface s_interface; - static QVector s_all; +protected: + void org_kde_kwin_server_decoration_destroy_resource(Resource *resource) override; + void org_kde_kwin_server_decoration_release(Resource *resource) override; + void org_kde_kwin_server_decoration_request_mode(Resource *resource, uint32_t mode) override; }; -#ifndef K_DOXYGEN -const struct org_kde_kwin_server_decoration_interface ServerSideDecorationInterface::Private::s_interface = { - resourceDestroyedCallback, - requestModeCallback -}; -QVector ServerSideDecorationInterface::Private::s_all; -#endif +QVector ServerSideDecorationInterfacePrivate::s_all; -void ServerSideDecorationInterface::Private::requestModeCallback(wl_client *client, wl_resource *resource, uint32_t mode) + +void ServerSideDecorationInterfacePrivate::org_kde_kwin_server_decoration_request_mode(Resource *resource, uint32_t mode) { - Q_UNUSED(client) + Q_UNUSED(resource) ServerSideDecorationManagerInterface::Mode m = ServerSideDecorationManagerInterface::Mode::None; switch (mode) { case ORG_KDE_KWIN_SERVER_DECORATION_MODE_NONE: @@ -196,32 +157,52 @@ void ServerSideDecorationInterface::Private::requestModeCallback(wl_client *clie qCWarning(KWAYLAND_SERVER) << "Invalid mode:" << mode; return; } - emit cast(resource)->q_func()->modeRequested(m); + emit q->modeRequested(m); } -ServerSideDecorationInterface *ServerSideDecorationInterface::Private::get(SurfaceInterface *s) +void ServerSideDecorationInterfacePrivate::org_kde_kwin_server_decoration_release(Resource *resource) { - auto it = std::find_if(s_all.constBegin(), s_all.constEnd(), [s] (Private *p) { return p->surface == s; }); - if (it == s_all.constEnd()) { - return nullptr; - } - return (*it)->q_func(); + wl_resource_destroy(resource->handle); } -ServerSideDecorationInterface::Private::Private(ServerSideDecorationInterface *q, ServerSideDecorationManagerInterface *c, SurfaceInterface *surface, wl_resource *parentResource) - : Resource::Private(q, c, parentResource, &org_kde_kwin_server_decoration_interface, &s_interface) +void ServerSideDecorationInterfacePrivate::org_kde_kwin_server_decoration_destroy_resource(Resource *resource) +{ + Q_UNUSED(resource) + delete q; +} + +ServerSideDecorationInterface *ServerSideDecorationInterfacePrivate::get(SurfaceInterface *surface) +{ + for (ServerSideDecorationInterfacePrivate *decoration : qAsConst(s_all)) { + if (decoration->surface == surface) { + return decoration->q; + } + } + return nullptr; +} + +ServerSideDecorationInterfacePrivate::ServerSideDecorationInterfacePrivate(ServerSideDecorationInterface *_q, SurfaceInterface *surface, wl_resource *resource) + : QtWaylandServer::org_kde_kwin_server_decoration(resource) , surface(surface) + , q(_q) { s_all << this; } -ServerSideDecorationInterface::Private::~Private() +ServerSideDecorationInterfacePrivate::~ServerSideDecorationInterfacePrivate() { s_all.removeAll(this); } -ServerSideDecorationInterface::ServerSideDecorationInterface(ServerSideDecorationManagerInterface *parent, SurfaceInterface *surface, wl_resource *parentResource) - : Resource(new Private(this, parent, surface, parentResource)) +void ServerSideDecorationInterfacePrivate::setMode(ServerSideDecorationManagerInterface::Mode mode) +{ + mode = mode; + send_mode(modeWayland(mode)); +} + +ServerSideDecorationInterface::ServerSideDecorationInterface(SurfaceInterface *surface, wl_resource *resource) + : QObject() + , d(new ServerSideDecorationInterfacePrivate(this, surface, resource)) { } @@ -229,32 +210,22 @@ ServerSideDecorationInterface::~ServerSideDecorationInterface() = default; void ServerSideDecorationInterface::setMode(ServerSideDecorationManagerInterface::Mode mode) { - Q_D(); - d->mode = mode; - org_kde_kwin_server_decoration_send_mode(resource(), modeWayland(mode)); - client()->flush(); + d->setMode(mode); } ServerSideDecorationManagerInterface::Mode ServerSideDecorationInterface::mode() const { - Q_D(); return d->mode; } SurfaceInterface *ServerSideDecorationInterface::surface() const { - Q_D(); return d->surface; } -ServerSideDecorationInterface::Private *ServerSideDecorationInterface::d_func() const +ServerSideDecorationInterface *ServerSideDecorationInterface::get(SurfaceInterface *surface) { - return reinterpret_cast(d.data()); -} - -ServerSideDecorationInterface *ServerSideDecorationInterface::get(SurfaceInterface *s) -{ - return Private::get(s); + return ServerSideDecorationInterfacePrivate::get(surface); } } diff --git a/src/wayland/server_decoration_interface.h b/src/wayland/server_decoration_interface.h index d950674529..d4faba0f19 100644 --- a/src/wayland/server_decoration_interface.h +++ b/src/wayland/server_decoration_interface.h @@ -6,28 +6,31 @@ #ifndef KWAYLAND_SERVER_SERVER_DECORATION_INTERFACE_H #define KWAYLAND_SERVER_SERVER_DECORATION_INTERFACE_H -#include "global.h" -#include "resource.h" +#include #include +struct wl_resource; + namespace KWaylandServer { class Display; class ServerSideDecorationInterface; class SurfaceInterface; +class ServerSideDecorationManagerInterfacePrivate; +class ServerSideDecorationInterfacePrivate; /** * @brief Manager to create ServerSideDecorationInterface. * * @since 5.6 **/ -class KWAYLANDSERVER_EXPORT ServerSideDecorationManagerInterface : public Global +class KWAYLANDSERVER_EXPORT ServerSideDecorationManagerInterface : public QObject { Q_OBJECT public: - virtual ~ServerSideDecorationManagerInterface(); + ~ServerSideDecorationManagerInterface() override; /** * Decoration mode used for SurfaceInterfaces. @@ -68,8 +71,7 @@ Q_SIGNALS: private: explicit ServerSideDecorationManagerInterface(Display *display, QObject *parent = nullptr); friend class Display; - class Private; - Private *d_func() const; + QScopedPointer d; }; /** @@ -79,11 +81,11 @@ private: * * @since 5.6 **/ -class KWAYLANDSERVER_EXPORT ServerSideDecorationInterface : public Resource +class KWAYLANDSERVER_EXPORT ServerSideDecorationInterface : public QObject { Q_OBJECT public: - virtual ~ServerSideDecorationInterface(); + ~ServerSideDecorationInterface() override; /** * Sets the @p mode on the SurfaceInterface. A client might refuse the provided @p mode, @@ -119,11 +121,10 @@ Q_SIGNALS: void modeRequested(KWaylandServer::ServerSideDecorationManagerInterface::Mode); private: - explicit ServerSideDecorationInterface(ServerSideDecorationManagerInterface *parent, SurfaceInterface *surface, wl_resource *parentResource); - friend class ServerSideDecorationManagerInterface; + explicit ServerSideDecorationInterface(SurfaceInterface *surface, wl_resource *resource); + friend class ServerSideDecorationManagerInterfacePrivate; - class Private; - Private *d_func() const; + QScopedPointer d; }; }