KWin
Loading...
Searching...
No Matches
xdgoutput_v1.cpp
Go to the documentation of this file.
1/*
2 SPDX-FileCopyrightText: 2018 David Edmundson <kde@davidedmundson.co.uk>
3 SPDX-FileCopyrightText: 2020 David Edmundson <kde@davidedmundson.co.uk>
4
5 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
6*/
7#include "xdgoutput_v1.h"
8#include "clientconnection.h"
9#include "display.h"
10#include "output.h"
11
12#include "qwayland-server-xdg-output-unstable-v1.h"
13
14#include "core/output.h"
15
16#include <QDebug>
17#include <QHash>
18#include <QPointer>
19#include <cmath>
20
21namespace KWin
22{
23static const quint32 s_version = 3;
24
25class XdgOutputV1Interface : public QObject, public QtWaylandServer::zxdg_output_v1
26{
27public:
28 explicit XdgOutputV1Interface(OutputInterface *wlOutput);
29
30 void resend();
31 void update();
32
33 QPointF pos;
34 QSizeF size;
35 QString name;
36 QString description;
37 QPointer<OutputInterface> output;
38
39 void sendLogicalPosition(Resource *resource);
40 void sendLogicalSize(Resource *resource);
41 void sendDone(Resource *resource);
42
43protected:
44 void zxdg_output_v1_bind_resource(Resource *resource) override;
45 void zxdg_output_v1_destroy(Resource *resource) override;
46};
47
48class XdgOutputManagerV1InterfacePrivate : public QtWaylandServer::zxdg_output_manager_v1
49{
50public:
52
53 QHash<OutputInterface *, XdgOutputV1Interface *> outputs;
54
55protected:
56 void zxdg_output_manager_v1_destroy(Resource *resource) override;
57 void zxdg_output_manager_v1_get_xdg_output(Resource *resource, uint32_t id, wl_resource *output) override;
58};
59
61 : QObject(parent)
63{
64}
65
69
71{
72 Q_ASSERT_X(!d->outputs.contains(output), "offer", "An XdgOuputInterface already exists for this output");
73
74 auto xdgOutput = new XdgOutputV1Interface(output);
75 d->outputs[output] = xdgOutput;
76 connect(output, &QObject::destroyed, this, [this, output]() {
77 delete d->outputs.take(output);
78 });
79}
80
82 : QtWaylandServer::zxdg_output_manager_v1(*d, s_version)
83{
84}
85
86void XdgOutputManagerV1InterfacePrivate::zxdg_output_manager_v1_get_xdg_output(Resource *resource, uint32_t id, wl_resource *outputResource)
87{
88 auto output = OutputInterface::get(outputResource);
89 if (!output) { // output client is requesting XdgOutput for an Output that doesn't exist
90 return;
91 }
92 auto xdgOutput = outputs.value(output);
93 if (!xdgOutput) {
94 return; // client is requesting XdgOutput for an Output that doesn't exist
95 }
96 xdgOutput->add(resource->client(), id, resource->version());
97}
98
100{
101 wl_resource_destroy(resource->handle);
102}
103
105 : output(output)
106{
107 const Output *handle = output->handle();
108
109 name = handle->name();
110 description = handle->description();
111 pos = handle->geometryF().topLeft();
112 size = handle->geometryF().size();
113
115}
116
118{
119 if (!output || output->isRemoved()) {
120 return;
121 }
122
123 const QRectF geometry = output->handle()->geometryF();
124 const auto resources = resourceMap();
125
126 if (pos != geometry.topLeft()) {
127 pos = geometry.topLeft();
128 for (auto resource : resources) {
129 sendLogicalPosition(resource);
130 }
131 }
132
133 if (size != geometry.size()) {
134 size = geometry.size();
135 for (auto resource : resources) {
136 sendLogicalSize(resource);
137 }
138 }
139
140 for (auto resource : resources) {
141 if (wl_resource_get_version(resource->handle) < 3) {
142 send_done(resource->handle);
143 }
144 }
145
146 output->scheduleDone();
147}
148
150{
151 wl_resource_destroy(resource->handle);
152}
153
155{
156 if (!output || output->isRemoved()) {
157 return;
158 }
159
160 sendLogicalPosition(resource);
161 sendLogicalSize(resource);
162 if (resource->version() >= ZXDG_OUTPUT_V1_NAME_SINCE_VERSION) {
163 send_name(resource->handle, name);
164 }
165 if (resource->version() >= ZXDG_OUTPUT_V1_DESCRIPTION_SINCE_VERSION) {
166 send_description(resource->handle, description);
167 }
168
169 sendDone(resource);
170
171 ClientConnection *connection = output->display()->getConnection(resource->client());
173}
174
176{
177 ClientConnection *connection = output->display()->getConnection(resource->client());
178 qreal scaleOverride = connection->scaleOverride();
179
180 send_logical_size(resource->handle, std::round(size.width() * scaleOverride), std::round(size.height() * scaleOverride));
181}
182
184{
185 ClientConnection *connection = output->display()->getConnection(resource->client());
186 qreal scaleOverride = connection->scaleOverride();
187
188 send_logical_position(resource->handle, pos.x() * scaleOverride, pos.y() * scaleOverride);
189}
190
191void XdgOutputV1Interface::sendDone(Resource *resource)
192{
193 if (wl_resource_get_version(resource->handle) >= 3) {
194 output->done(resource->client());
195 } else {
196 send_done(resource->handle);
197 }
198}
199
201{
202 if (!output || output->isRemoved()) {
203 return;
204 }
205
206 auto changedConnection = qobject_cast<ClientConnection *>(sender());
207 const auto outputResources = resourceMap();
208 for (auto resource : outputResources) {
209 ClientConnection *connection = output->display()->getConnection(resource->client());
210 if (connection == changedConnection) {
211 sendLogicalPosition(resource);
212 sendLogicalSize(resource);
213 sendDone(resource);
214 }
215 }
216}
217}
218
219#include "moc_xdgoutput_v1.cpp"
Convenient Class which represents a wl_client.
Class holding the Wayland server display loop.
Definition display.h:34
ClientConnection * getConnection(wl_client *client)
Definition display.cpp:200
QString description() const
Definition output.cpp:541
QRectF geometryF() const
Definition output.cpp:465
void geometryChanged()
QString name
Definition output.h:136
static OutputInterface * get(wl_resource *native)
Definition output.cpp:320
void offer(OutputInterface *output)
XdgOutputManagerV1Interface(Display *display, QObject *parent=nullptr)
QHash< OutputInterface *, XdgOutputV1Interface * > outputs
void zxdg_output_manager_v1_get_xdg_output(Resource *resource, uint32_t id, wl_resource *output) override
void zxdg_output_manager_v1_destroy(Resource *resource) override
void sendLogicalSize(Resource *resource)
void sendDone(Resource *resource)
QPointer< OutputInterface > output
void sendLogicalPosition(Resource *resource)
void zxdg_output_v1_bind_resource(Resource *resource) override
void zxdg_output_v1_destroy(Resource *resource) override
XdgOutputV1Interface(OutputInterface *wlOutput)
KWIN_EXPORT xcb_connection_t * connection()
Definition xcb.h:19