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 | |
15 | namespace KWayland |
16 | { |
17 | namespace Client |
18 | { |
19 | class Q_DECL_HIDDEN PlasmaVirtualDesktopManagement::Private |
20 | { |
21 | public: |
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 | |
35 | private: |
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 | |
47 | class Q_DECL_HIDDEN PlasmaVirtualDesktop::Private |
48 | { |
49 | public: |
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 | |
60 | private: |
61 | PlasmaVirtualDesktop *q; |
62 | |
63 | private: |
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 | |
75 | inline 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 | |
82 | inline 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 | |
89 | const 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 | |
94 | void 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 | |
111 | void 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 | |
129 | void 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 | |
142 | void 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 | |
149 | PlasmaVirtualDesktopManagement::PlasmaVirtualDesktopManagement(QObject *parent) |
150 | : QObject(parent) |
151 | , d(new Private(this)) |
152 | { |
153 | } |
154 | |
155 | PlasmaVirtualDesktopManagement::Private::Private(PlasmaVirtualDesktopManagement *q) |
156 | : q(q) |
157 | { |
158 | } |
159 | |
160 | void 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 | |
168 | PlasmaVirtualDesktopManagement::~PlasmaVirtualDesktopManagement() |
169 | { |
170 | release(); |
171 | } |
172 | |
173 | void PlasmaVirtualDesktopManagement::setup(org_kde_plasma_virtual_desktop_management *plasmavirtualdesktopmanagement) |
174 | { |
175 | d->setup(plasmavirtualdesktopmanagement); |
176 | } |
177 | |
178 | void PlasmaVirtualDesktopManagement::release() |
179 | { |
180 | d->plasmavirtualdesktopmanagement.release(); |
181 | } |
182 | |
183 | void PlasmaVirtualDesktopManagement::destroy() |
184 | { |
185 | d->plasmavirtualdesktopmanagement.destroy(); |
186 | } |
187 | |
188 | PlasmaVirtualDesktopManagement::operator org_kde_plasma_virtual_desktop_management *() |
189 | { |
190 | return d->plasmavirtualdesktopmanagement; |
191 | } |
192 | |
193 | PlasmaVirtualDesktopManagement::operator org_kde_plasma_virtual_desktop_management *() const |
194 | { |
195 | return d->plasmavirtualdesktopmanagement; |
196 | } |
197 | |
198 | bool PlasmaVirtualDesktopManagement::isValid() const |
199 | { |
200 | return d->plasmavirtualdesktopmanagement.isValid(); |
201 | } |
202 | |
203 | void PlasmaVirtualDesktopManagement::setEventQueue(EventQueue *queue) |
204 | { |
205 | d->queue = queue; |
206 | } |
207 | |
208 | EventQueue *PlasmaVirtualDesktopManagement::eventQueue() |
209 | { |
210 | return d->queue; |
211 | } |
212 | |
213 | PlasmaVirtualDesktop *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 | |
243 | void 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 | |
250 | void 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 | |
257 | QList<PlasmaVirtualDesktop *> PlasmaVirtualDesktopManagement::desktops() const |
258 | { |
259 | return d->desktops; |
260 | } |
261 | |
262 | quint32 PlasmaVirtualDesktopManagement::rows() const |
263 | { |
264 | return d->rows; |
265 | } |
266 | |
267 | const 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 | |
270 | void 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 | |
277 | void 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 | |
284 | void 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 | |
292 | void 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 | |
300 | void 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 | |
307 | void 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 | |
314 | PlasmaVirtualDesktop::Private::Private(PlasmaVirtualDesktop *q) |
315 | : q(q) |
316 | { |
317 | } |
318 | |
319 | PlasmaVirtualDesktop::PlasmaVirtualDesktop(QObject *parent) |
320 | : QObject(parent) |
321 | , d(new Private(this)) |
322 | { |
323 | } |
324 | |
325 | void 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 | |
333 | PlasmaVirtualDesktop::~PlasmaVirtualDesktop() |
334 | { |
335 | release(); |
336 | } |
337 | |
338 | void PlasmaVirtualDesktop::setup(org_kde_plasma_virtual_desktop *plasmavirtualdesktop) |
339 | { |
340 | d->setup(plasmavirtualdesktop); |
341 | } |
342 | |
343 | void PlasmaVirtualDesktop::release() |
344 | { |
345 | d->plasmavirtualdesktop.release(); |
346 | } |
347 | |
348 | void PlasmaVirtualDesktop::destroy() |
349 | { |
350 | d->plasmavirtualdesktop.destroy(); |
351 | } |
352 | |
353 | PlasmaVirtualDesktop::operator org_kde_plasma_virtual_desktop *() |
354 | { |
355 | return d->plasmavirtualdesktop; |
356 | } |
357 | |
358 | PlasmaVirtualDesktop::operator org_kde_plasma_virtual_desktop *() const |
359 | { |
360 | return d->plasmavirtualdesktop; |
361 | } |
362 | |
363 | bool PlasmaVirtualDesktop::isValid() const |
364 | { |
365 | return d->plasmavirtualdesktop.isValid(); |
366 | } |
367 | |
368 | void PlasmaVirtualDesktop::requestActivate() |
369 | { |
370 | Q_ASSERT(isValid()); |
371 | org_kde_plasma_virtual_desktop_request_activate(org_kde_plasma_virtual_desktop: d->plasmavirtualdesktop); |
372 | } |
373 | |
374 | QString PlasmaVirtualDesktop::id() const |
375 | { |
376 | return d->id; |
377 | } |
378 | |
379 | QString PlasmaVirtualDesktop::name() const |
380 | { |
381 | return d->name; |
382 | } |
383 | |
384 | bool PlasmaVirtualDesktop::isActive() const |
385 | { |
386 | return d->active; |
387 | } |
388 | |
389 | } |
390 | } |
391 | |
392 | #include "moc_plasmavirtualdesktop.cpp" |
393 | |