diff --git a/src/wayland/autotests/client/test_xdg_output.cpp b/src/wayland/autotests/client/test_xdg_output.cpp index 0a4ada1b4e..d66100589d 100644 --- a/src/wayland/autotests/client/test_xdg_output.cpp +++ b/src/wayland/autotests/client/test_xdg_output.cpp @@ -33,7 +33,6 @@ private: std::unique_ptr m_outputHandle; KWaylandServer::OutputInterface *m_serverOutput; KWaylandServer::XdgOutputManagerV1Interface *m_serverXdgOutputManager; - KWaylandServer::XdgOutputV1Interface *m_serverXdgOutput; KWayland::Client::ConnectionThread *m_connection; KWayland::Client::EventQueue *m_queue; QThread *m_thread; @@ -70,7 +69,7 @@ void TestXdgOutput::init() m_serverOutput = new OutputInterface(m_display, m_outputHandle.get(), this); m_serverXdgOutputManager = new XdgOutputManagerV1Interface(m_display, this); - m_serverXdgOutput = m_serverXdgOutputManager->createXdgOutput(m_serverOutput, this); + m_serverXdgOutputManager->offer(m_serverOutput); // setup connection m_connection = new KWayland::Client::ConnectionThread; diff --git a/src/wayland/xdgoutput_v1_interface.cpp b/src/wayland/xdgoutput_v1_interface.cpp index 65ed5cc417..e4143659fa 100644 --- a/src/wayland/xdgoutput_v1_interface.cpp +++ b/src/wayland/xdgoutput_v1_interface.cpp @@ -22,6 +22,29 @@ namespace KWaylandServer { static const quint32 s_version = 3; +class XdgOutputV1Interface : public QObject, public QtWaylandServer::zxdg_output_v1 +{ +public: + explicit XdgOutputV1Interface(OutputInterface *wlOutput); + + void resend(); + void update(); + + QPointF pos; + QSizeF size; + QString name; + QString description; + QPointer output; + + void sendLogicalPosition(Resource *resource); + void sendLogicalSize(Resource *resource); + void sendDone(Resource *resource); + +protected: + void zxdg_output_v1_bind_resource(Resource *resource) override; + void zxdg_output_v1_destroy(Resource *resource) override; +}; + class XdgOutputManagerV1InterfacePrivate : public QtWaylandServer::zxdg_output_manager_v1 { public: @@ -35,31 +58,6 @@ protected: void zxdg_output_manager_v1_get_xdg_output(Resource *resource, uint32_t id, wl_resource *output) override; }; -class XdgOutputV1InterfacePrivate : public QtWaylandServer::zxdg_output_v1 -{ -public: - XdgOutputV1InterfacePrivate(XdgOutputV1Interface *q, OutputInterface *wlOutput) - : output(wlOutput) - , q(q) - { - } - - QPointF pos; - QSizeF size; - QString name; - QString description; - QPointer output; - XdgOutputV1Interface *const q; - - void sendLogicalPosition(Resource *resource); - void sendLogicalSize(Resource *resource); - void sendDone(Resource *resource); - -protected: - void zxdg_output_v1_bind_resource(Resource *resource) override; - void zxdg_output_v1_destroy(Resource *resource) override; -}; - XdgOutputManagerV1Interface::XdgOutputManagerV1Interface(Display *display, QObject *parent) : QObject(parent) , d(new XdgOutputManagerV1InterfacePrivate(this, display)) @@ -70,23 +68,15 @@ XdgOutputManagerV1Interface::~XdgOutputManagerV1Interface() { } -XdgOutputV1Interface *XdgOutputManagerV1Interface::createXdgOutput(OutputInterface *output, QObject *parent) +void XdgOutputManagerV1Interface::offer(OutputInterface *output) { - Q_ASSERT_X(!d->outputs.contains(output), "createXdgOutput", "An XdgOuputInterface already exists for this output"); + Q_ASSERT_X(!d->outputs.contains(output), "offer", "An XdgOuputInterface already exists for this output"); - auto xdgOutput = new XdgOutputV1Interface(output, parent); + auto xdgOutput = new XdgOutputV1Interface(output); d->outputs[output] = xdgOutput; - - // as XdgOutput lifespan is managed by user, delete our mapping when either - // it or the relevant Output gets deleted connect(output, &QObject::destroyed, this, [this, output]() { - d->outputs.remove(output); + delete d->outputs.take(output); }); - connect(xdgOutput, &QObject::destroyed, this, [this, output]() { - d->outputs.remove(output); - }); - - return xdgOutput; } XdgOutputManagerV1InterfacePrivate::XdgOutputManagerV1InterfacePrivate(XdgOutputManagerV1Interface *qptr, Display *d) @@ -105,7 +95,7 @@ void XdgOutputManagerV1InterfacePrivate::zxdg_output_manager_v1_get_xdg_output(R if (!xdgOutput) { return; // client is requesting XdgOutput for an Output that doesn't exist } - xdgOutput->d->add(resource->client(), id, resource->version()); + xdgOutput->add(resource->client(), id, resource->version()); } void XdgOutputManagerV1InterfacePrivate::zxdg_output_manager_v1_destroy(Resource *resource) @@ -113,62 +103,57 @@ void XdgOutputManagerV1InterfacePrivate::zxdg_output_manager_v1_destroy(Resource wl_resource_destroy(resource->handle); } -XdgOutputV1Interface::XdgOutputV1Interface(OutputInterface *output, QObject *parent) - : QObject(parent) - , d(new XdgOutputV1InterfacePrivate(this, output)) +XdgOutputV1Interface::XdgOutputV1Interface(OutputInterface *output) + : output(output) { const Output *handle = output->handle(); - d->name = handle->name(); - d->description = handle->description(); - d->pos = handle->geometry().topLeft(); - d->size = handle->geometry().size(); + name = handle->name(); + description = handle->description(); + pos = handle->geometry().topLeft(); + size = handle->geometry().size(); connect(handle, &Output::geometryChanged, this, &XdgOutputV1Interface::update); } -XdgOutputV1Interface::~XdgOutputV1Interface() -{ -} - void XdgOutputV1Interface::update() { - if (!d->output || d->output->isRemoved()) { + if (!output || output->isRemoved()) { return; } - const QRectF geometry = d->output->handle()->fractionalGeometry(); - const auto resources = d->resourceMap(); + const QRectF geometry = output->handle()->fractionalGeometry(); + const auto resources = resourceMap(); - if (d->pos != geometry.topLeft()) { - d->pos = geometry.topLeft(); + if (pos != geometry.topLeft()) { + pos = geometry.topLeft(); for (auto resource : resources) { - d->sendLogicalPosition(resource); + sendLogicalPosition(resource); } } - if (d->size != geometry.size()) { - d->size = geometry.size(); + if (size != geometry.size()) { + size = geometry.size(); for (auto resource : resources) { - d->sendLogicalSize(resource); + sendLogicalSize(resource); } } for (auto resource : resources) { if (wl_resource_get_version(resource->handle) < 3) { - d->send_done(resource->handle); + send_done(resource->handle); } } - d->output->scheduleDone(); + output->scheduleDone(); } -void XdgOutputV1InterfacePrivate::zxdg_output_v1_destroy(Resource *resource) +void XdgOutputV1Interface::zxdg_output_v1_destroy(Resource *resource) { wl_resource_destroy(resource->handle); } -void XdgOutputV1InterfacePrivate::zxdg_output_v1_bind_resource(Resource *resource) +void XdgOutputV1Interface::zxdg_output_v1_bind_resource(Resource *resource) { if (!output || output->isRemoved()) { return; @@ -186,10 +171,10 @@ void XdgOutputV1InterfacePrivate::zxdg_output_v1_bind_resource(Resource *resourc sendDone(resource); ClientConnection *connection = output->display()->getConnection(resource->client()); - QObject::connect(connection, &ClientConnection::scaleOverrideChanged, q, &XdgOutputV1Interface::resend, Qt::UniqueConnection); + connect(connection, &ClientConnection::scaleOverrideChanged, this, &XdgOutputV1Interface::resend, Qt::UniqueConnection); } -void XdgOutputV1InterfacePrivate::sendLogicalSize(Resource *resource) +void XdgOutputV1Interface::sendLogicalSize(Resource *resource) { ClientConnection *connection = output->display()->getConnection(resource->client()); qreal scaleOverride = connection->scaleOverride(); @@ -197,7 +182,7 @@ void XdgOutputV1InterfacePrivate::sendLogicalSize(Resource *resource) send_logical_size(resource->handle, std::round(size.width() * scaleOverride), std::round(size.height() * scaleOverride)); } -void XdgOutputV1InterfacePrivate::sendLogicalPosition(Resource *resource) +void XdgOutputV1Interface::sendLogicalPosition(Resource *resource) { ClientConnection *connection = output->display()->getConnection(resource->client()); qreal scaleOverride = connection->scaleOverride(); @@ -205,7 +190,7 @@ void XdgOutputV1InterfacePrivate::sendLogicalPosition(Resource *resource) send_logical_position(resource->handle, pos.x() * scaleOverride, pos.y() * scaleOverride); } -void XdgOutputV1InterfacePrivate::sendDone(Resource *resource) +void XdgOutputV1Interface::sendDone(Resource *resource) { if (wl_resource_get_version(resource->handle) >= 3) { output->done(resource->client()); @@ -216,18 +201,18 @@ void XdgOutputV1InterfacePrivate::sendDone(Resource *resource) void XdgOutputV1Interface::resend() { - if (!d->output || d->output->isRemoved()) { + if (!output || output->isRemoved()) { return; } auto changedConnection = qobject_cast(sender()); - const auto outputResources = d->resourceMap(); + const auto outputResources = resourceMap(); for (auto resource : outputResources) { - ClientConnection *connection = d->output->display()->getConnection(resource->client()); + ClientConnection *connection = output->display()->getConnection(resource->client()); if (connection == changedConnection) { - d->sendLogicalPosition(resource); - d->sendLogicalSize(resource); - d->sendDone(resource); + sendLogicalPosition(resource); + sendLogicalSize(resource); + sendDone(resource); } } } diff --git a/src/wayland/xdgoutput_v1_interface.h b/src/wayland/xdgoutput_v1_interface.h index f0c44920fe..f8e1e780b2 100644 --- a/src/wayland/xdgoutput_v1_interface.h +++ b/src/wayland/xdgoutput_v1_interface.h @@ -12,20 +12,11 @@ #include #include -/* - * In terms of protocol XdgOutputInterface are a resource - * but for the sake of sanity, we should treat XdgOutputs as globals like Output is - * Hence this doesn't match most of kwayland API paradigms. - */ - namespace KWaylandServer { class Display; class OutputInterface; -class XdgOutputV1Interface; - class XdgOutputManagerV1InterfacePrivate; -class XdgOutputV1InterfacePrivate; /** * Global manager for XdgOutputs @@ -37,42 +28,13 @@ class KWIN_EXPORT XdgOutputManagerV1Interface : public QObject public: explicit XdgOutputManagerV1Interface(Display *display, QObject *parent = nullptr); ~XdgOutputManagerV1Interface() override; - /** - * Creates an XdgOutputInterface object for an existing Output - * which exposes XDG specific properties of outputs - * - * @arg output the wl_output interface this XDG output is for - * @parent the parent of the newly created object - */ - XdgOutputV1Interface *createXdgOutput(OutputInterface *output, QObject *parent); + + void offer(OutputInterface *output); private: std::unique_ptr d; }; -/** - * Extension to Output - * Users should set all relevant values on creation and on future changes. - * done() should be explicitly called after change batches including initial setting. - */ -class KWIN_EXPORT XdgOutputV1Interface : public QObject -{ - Q_OBJECT -public: - ~XdgOutputV1Interface() override; - -private: - void resend(); - void update(); - - explicit XdgOutputV1Interface(OutputInterface *output, QObject *parent); - friend class XdgOutputV1InterfacePrivate; - friend class XdgOutputManagerV1Interface; - friend class XdgOutputManagerV1InterfacePrivate; - - std::unique_ptr d; -}; - } #endif diff --git a/src/wayland_server.cpp b/src/wayland_server.cpp index 3f65b37ecc..40969c470c 100644 --- a/src/wayland_server.cpp +++ b/src/wayland_server.cpp @@ -299,7 +299,7 @@ void WaylandServer::handleOutputEnabled(Output *output) { if (!output->isPlaceholder() && !output->isNonDesktop()) { auto waylandOutput = new KWaylandServer::OutputInterface(waylandServer()->display(), output); - m_xdgOutputManagerV1->createXdgOutput(waylandOutput, waylandOutput); + m_xdgOutputManagerV1->offer(waylandOutput); m_waylandOutputs.insert(output, waylandOutput); }