1/*
2 SPDX-FileCopyrightText: 2018 Marco Martin <notmart@gmail.com>
3
4 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
5*/
6#include "plasmavirtualdesktop.h"
7#include "event_queue.h"
8#include "wayland_pointer_p.h"
9
10#include <QDebug>
11#include <QMap>
12
13#include <wayland-plasma-virtual-desktop-client-protocol.h>
14
15namespace KWayland
16{
17namespace Client
18{
19class Q_DECL_HIDDEN PlasmaVirtualDesktopManagement::Private
20{
21public:
22 Private(PlasmaVirtualDesktopManagement *q);
23
24 void setup(org_kde_plasma_virtual_desktop_management *arg);
25
26 WaylandPointer<org_kde_plasma_virtual_desktop_management, org_kde_plasma_virtual_desktop_management_destroy> plasmavirtualdesktopmanagement;
27 EventQueue *queue = nullptr;
28
29 quint32 rows = 1;
30 QList<PlasmaVirtualDesktop *> desktops;
31
32 inline QList<PlasmaVirtualDesktop *>::const_iterator constFindDesktop(const QString &id);
33 inline QList<PlasmaVirtualDesktop *>::iterator findDesktop(const QString &id);
34
35private:
36 static void
37 createdCallback(void *data, org_kde_plasma_virtual_desktop_management *org_kde_plasma_virtual_desktop_management, const char *id, uint32_t position);
38 static void removedCallback(void *data, org_kde_plasma_virtual_desktop_management *org_kde_plasma_virtual_desktop_management, const char *id);
39 static void rowsCallback(void *data, org_kde_plasma_virtual_desktop_management *org_kde_plasma_virtual_desktop_management, uint32_t rows);
40 static void doneCallback(void *data, org_kde_plasma_virtual_desktop_management *org_kde_plasma_virtual_desktop_management);
41
42 PlasmaVirtualDesktopManagement *q;
43
44 static const org_kde_plasma_virtual_desktop_management_listener s_listener;
45};
46
47class Q_DECL_HIDDEN PlasmaVirtualDesktop::Private
48{
49public:
50 Private(PlasmaVirtualDesktop *q);
51
52 void setup(org_kde_plasma_virtual_desktop *arg);
53
54 WaylandPointer<org_kde_plasma_virtual_desktop, org_kde_plasma_virtual_desktop_destroy> plasmavirtualdesktop;
55
56 QString id;
57 QString name;
58 bool active = false;
59
60private:
61 PlasmaVirtualDesktop *q;
62
63private:
64 static void idCallback(void *data, org_kde_plasma_virtual_desktop *org_kde_plasma_virtual_desktop, const char *id);
65 static void nameCallback(void *data, org_kde_plasma_virtual_desktop *org_kde_plasma_virtual_desktop, const char *name);
66
67 static void activatedCallback(void *data, org_kde_plasma_virtual_desktop *org_kde_plasma_virtual_desktop);
68 static void deactivatedCallback(void *data, org_kde_plasma_virtual_desktop *org_kde_plasma_virtual_desktop);
69 static void doneCallback(void *data, org_kde_plasma_virtual_desktop *org_kde_plasma_virtual_desktop);
70 static void removedCallback(void *data, org_kde_plasma_virtual_desktop *org_kde_plasma_virtual_desktop);
71
72 static const org_kde_plasma_virtual_desktop_listener s_listener;
73};
74
75inline QList<PlasmaVirtualDesktop *>::const_iterator PlasmaVirtualDesktopManagement::Private::constFindDesktop(const QString &id)
76{
77 return std::find_if(first: desktops.constBegin(), last: desktops.constEnd(), pred: [id](const PlasmaVirtualDesktop *desk) {
78 return desk->id() == id;
79 });
80}
81
82inline QList<PlasmaVirtualDesktop *>::iterator PlasmaVirtualDesktopManagement::Private::findDesktop(const QString &id)
83{
84 return std::find_if(first: desktops.begin(), last: desktops.end(), pred: [id](const PlasmaVirtualDesktop *desk) {
85 return desk->id() == id;
86 });
87}
88
89const org_kde_plasma_virtual_desktop_management_listener PlasmaVirtualDesktopManagement::Private::s_listener = {.desktop_created: createdCallback,
90 .desktop_removed: removedCallback,
91 .done: doneCallback,
92 .rows: rowsCallback};
93
94void PlasmaVirtualDesktopManagement::Private::createdCallback(void *data,
95 org_kde_plasma_virtual_desktop_management *org_kde_plasma_virtual_desktop_management,
96 const char *id,
97 uint32_t position)
98{
99 auto p = reinterpret_cast<PlasmaVirtualDesktopManagement::Private *>(data);
100 Q_ASSERT(p->plasmavirtualdesktopmanagement == org_kde_plasma_virtual_desktop_management);
101 const QString stringId = QString::fromUtf8(utf8: id);
102 PlasmaVirtualDesktop *vd = p->q->getVirtualDesktop(id: stringId);
103 Q_ASSERT(vd);
104
105 p->desktops.insert(i: position, t: vd);
106 // TODO: emit a lot of desktopMoved?
107
108 Q_EMIT p->q->desktopCreated(id: stringId, position);
109}
110
111void PlasmaVirtualDesktopManagement::Private::removedCallback(void *data,
112 org_kde_plasma_virtual_desktop_management *org_kde_plasma_virtual_desktop_management,
113 const char *id)
114{
115 auto p = reinterpret_cast<PlasmaVirtualDesktopManagement::Private *>(data);
116 Q_ASSERT(p->plasmavirtualdesktopmanagement == org_kde_plasma_virtual_desktop_management);
117 const QString stringId = QString::fromUtf8(utf8: id);
118 PlasmaVirtualDesktop *vd = p->q->getVirtualDesktop(id: stringId);
119 // TODO: emit a lot of desktopMoved?
120 Q_ASSERT(vd);
121 auto i = p->findDesktop(id: stringId);
122 p->desktops.erase(pos: i);
123 vd->release();
124 vd->destroy();
125 vd->deleteLater();
126 Q_EMIT p->q->desktopRemoved(id: stringId);
127}
128
129void PlasmaVirtualDesktopManagement::Private::rowsCallback(void *data,
130 org_kde_plasma_virtual_desktop_management *org_kde_plasma_virtual_desktop_management,
131 uint32_t rows)
132{
133 auto p = reinterpret_cast<PlasmaVirtualDesktopManagement::Private *>(data);
134 Q_ASSERT(p->plasmavirtualdesktopmanagement == org_kde_plasma_virtual_desktop_management);
135 if (rows == 0) {
136 return;
137 }
138 p->rows = rows;
139 Q_EMIT p->q->rowsChanged(rows);
140}
141
142void PlasmaVirtualDesktopManagement::Private::doneCallback(void *data, org_kde_plasma_virtual_desktop_management *org_kde_plasma_virtual_desktop_management)
143{
144 auto p = reinterpret_cast<PlasmaVirtualDesktopManagement::Private *>(data);
145 Q_ASSERT(p->plasmavirtualdesktopmanagement == org_kde_plasma_virtual_desktop_management);
146 Q_EMIT p->q->done();
147}
148
149PlasmaVirtualDesktopManagement::PlasmaVirtualDesktopManagement(QObject *parent)
150 : QObject(parent)
151 , d(new Private(this))
152{
153}
154
155PlasmaVirtualDesktopManagement::Private::Private(PlasmaVirtualDesktopManagement *q)
156 : q(q)
157{
158}
159
160void PlasmaVirtualDesktopManagement::Private::setup(org_kde_plasma_virtual_desktop_management *arg)
161{
162 Q_ASSERT(arg);
163 Q_ASSERT(!plasmavirtualdesktopmanagement);
164 plasmavirtualdesktopmanagement.setup(pointer: arg);
165 org_kde_plasma_virtual_desktop_management_add_listener(org_kde_plasma_virtual_desktop_management: plasmavirtualdesktopmanagement, listener: &s_listener, data: this);
166}
167
168PlasmaVirtualDesktopManagement::~PlasmaVirtualDesktopManagement()
169{
170 release();
171}
172
173void PlasmaVirtualDesktopManagement::setup(org_kde_plasma_virtual_desktop_management *plasmavirtualdesktopmanagement)
174{
175 d->setup(plasmavirtualdesktopmanagement);
176}
177
178void PlasmaVirtualDesktopManagement::release()
179{
180 d->plasmavirtualdesktopmanagement.release();
181}
182
183void PlasmaVirtualDesktopManagement::destroy()
184{
185 d->plasmavirtualdesktopmanagement.destroy();
186}
187
188PlasmaVirtualDesktopManagement::operator org_kde_plasma_virtual_desktop_management *()
189{
190 return d->plasmavirtualdesktopmanagement;
191}
192
193PlasmaVirtualDesktopManagement::operator org_kde_plasma_virtual_desktop_management *() const
194{
195 return d->plasmavirtualdesktopmanagement;
196}
197
198bool PlasmaVirtualDesktopManagement::isValid() const
199{
200 return d->plasmavirtualdesktopmanagement.isValid();
201}
202
203void PlasmaVirtualDesktopManagement::setEventQueue(EventQueue *queue)
204{
205 d->queue = queue;
206}
207
208EventQueue *PlasmaVirtualDesktopManagement::eventQueue()
209{
210 return d->queue;
211}
212
213PlasmaVirtualDesktop *PlasmaVirtualDesktopManagement::getVirtualDesktop(const QString &id)
214{
215 Q_ASSERT(isValid());
216
217 if (id.isEmpty()) {
218 return nullptr;
219 }
220
221 auto i = d->constFindDesktop(id);
222 if (i != d->desktops.constEnd()) {
223 return *i;
224 }
225
226 auto w = org_kde_plasma_virtual_desktop_management_get_virtual_desktop(org_kde_plasma_virtual_desktop_management: d->plasmavirtualdesktopmanagement, desktop_id: id.toUtf8());
227
228 if (!w) {
229 return nullptr;
230 }
231
232 if (d->queue) {
233 d->queue->addProxy(proxy: w);
234 }
235
236 auto desktop = new PlasmaVirtualDesktop(this);
237 desktop->setup(w);
238 desktop->d->id = id;
239
240 return desktop;
241}
242
243void PlasmaVirtualDesktopManagement::requestRemoveVirtualDesktop(const QString &id)
244{
245 Q_ASSERT(isValid());
246
247 org_kde_plasma_virtual_desktop_management_request_remove_virtual_desktop(org_kde_plasma_virtual_desktop_management: d->plasmavirtualdesktopmanagement, desktop_id: id.toUtf8());
248}
249
250void PlasmaVirtualDesktopManagement::requestCreateVirtualDesktop(const QString &name, quint32 position)
251{
252 Q_ASSERT(isValid());
253
254 org_kde_plasma_virtual_desktop_management_request_create_virtual_desktop(org_kde_plasma_virtual_desktop_management: d->plasmavirtualdesktopmanagement, name: name.toUtf8(), position);
255}
256
257QList<PlasmaVirtualDesktop *> PlasmaVirtualDesktopManagement::desktops() const
258{
259 return d->desktops;
260}
261
262quint32 PlasmaVirtualDesktopManagement::rows() const
263{
264 return d->rows;
265}
266
267const org_kde_plasma_virtual_desktop_listener PlasmaVirtualDesktop::Private::s_listener =
268 {.desktop_id: idCallback, .name: nameCallback, .activated: activatedCallback, .deactivated: deactivatedCallback, .done: doneCallback, .removed: removedCallback};
269
270void PlasmaVirtualDesktop::Private::idCallback(void *data, org_kde_plasma_virtual_desktop *org_kde_plasma_virtual_desktop, const char *id)
271{
272 auto p = reinterpret_cast<PlasmaVirtualDesktop::Private *>(data);
273 Q_ASSERT(p->plasmavirtualdesktop == org_kde_plasma_virtual_desktop);
274 p->id = QString::fromUtf8(utf8: id);
275}
276
277void PlasmaVirtualDesktop::Private::nameCallback(void *data, org_kde_plasma_virtual_desktop *org_kde_plasma_virtual_desktop, const char *name)
278{
279 auto p = reinterpret_cast<PlasmaVirtualDesktop::Private *>(data);
280 Q_ASSERT(p->plasmavirtualdesktop == org_kde_plasma_virtual_desktop);
281 p->name = QString::fromUtf8(utf8: name);
282}
283
284void PlasmaVirtualDesktop::Private::activatedCallback(void *data, org_kde_plasma_virtual_desktop *org_kde_plasma_virtual_desktop)
285{
286 auto p = reinterpret_cast<PlasmaVirtualDesktop::Private *>(data);
287 Q_ASSERT(p->plasmavirtualdesktop == org_kde_plasma_virtual_desktop);
288 p->active = true;
289 Q_EMIT p->q->activated();
290}
291
292void PlasmaVirtualDesktop::Private::deactivatedCallback(void *data, org_kde_plasma_virtual_desktop *org_kde_plasma_virtual_desktop)
293{
294 auto p = reinterpret_cast<PlasmaVirtualDesktop::Private *>(data);
295 Q_ASSERT(p->plasmavirtualdesktop == org_kde_plasma_virtual_desktop);
296 p->active = false;
297 Q_EMIT p->q->deactivated();
298}
299
300void PlasmaVirtualDesktop::Private::doneCallback(void *data, org_kde_plasma_virtual_desktop *org_kde_plasma_virtual_desktop)
301{
302 auto p = reinterpret_cast<PlasmaVirtualDesktop::Private *>(data);
303 Q_ASSERT(p->plasmavirtualdesktop == org_kde_plasma_virtual_desktop);
304 Q_EMIT p->q->done();
305}
306
307void PlasmaVirtualDesktop::Private::removedCallback(void *data, org_kde_plasma_virtual_desktop *org_kde_plasma_virtual_desktop)
308{
309 auto p = reinterpret_cast<PlasmaVirtualDesktop::Private *>(data);
310 Q_ASSERT(p->plasmavirtualdesktop == org_kde_plasma_virtual_desktop);
311 Q_EMIT p->q->removed();
312}
313
314PlasmaVirtualDesktop::Private::Private(PlasmaVirtualDesktop *q)
315 : q(q)
316{
317}
318
319PlasmaVirtualDesktop::PlasmaVirtualDesktop(QObject *parent)
320 : QObject(parent)
321 , d(new Private(this))
322{
323}
324
325void PlasmaVirtualDesktop::Private::setup(org_kde_plasma_virtual_desktop *arg)
326{
327 Q_ASSERT(arg);
328 Q_ASSERT(!plasmavirtualdesktop);
329 plasmavirtualdesktop.setup(pointer: arg);
330 org_kde_plasma_virtual_desktop_add_listener(org_kde_plasma_virtual_desktop: plasmavirtualdesktop, listener: &s_listener, data: this);
331}
332
333PlasmaVirtualDesktop::~PlasmaVirtualDesktop()
334{
335 release();
336}
337
338void PlasmaVirtualDesktop::setup(org_kde_plasma_virtual_desktop *plasmavirtualdesktop)
339{
340 d->setup(plasmavirtualdesktop);
341}
342
343void PlasmaVirtualDesktop::release()
344{
345 d->plasmavirtualdesktop.release();
346}
347
348void PlasmaVirtualDesktop::destroy()
349{
350 d->plasmavirtualdesktop.destroy();
351}
352
353PlasmaVirtualDesktop::operator org_kde_plasma_virtual_desktop *()
354{
355 return d->plasmavirtualdesktop;
356}
357
358PlasmaVirtualDesktop::operator org_kde_plasma_virtual_desktop *() const
359{
360 return d->plasmavirtualdesktop;
361}
362
363bool PlasmaVirtualDesktop::isValid() const
364{
365 return d->plasmavirtualdesktop.isValid();
366}
367
368void PlasmaVirtualDesktop::requestActivate()
369{
370 Q_ASSERT(isValid());
371 org_kde_plasma_virtual_desktop_request_activate(org_kde_plasma_virtual_desktop: d->plasmavirtualdesktop);
372}
373
374QString PlasmaVirtualDesktop::id() const
375{
376 return d->id;
377}
378
379QString PlasmaVirtualDesktop::name() const
380{
381 return d->name;
382}
383
384bool PlasmaVirtualDesktop::isActive() const
385{
386 return d->active;
387}
388
389}
390}
391
392#include "moc_plasmavirtualdesktop.cpp"
393

source code of kwayland/src/client/plasmavirtualdesktop.cpp