File indexing completed on 2024-12-22 05:09:21

0001 /*
0002     SPDX-FileCopyrightText: 2018 Marco Martin <notmart@gmail.com>
0003 
0004     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0005 */
0006 #include "plasmavirtualdesktop.h"
0007 #include "event_queue.h"
0008 #include "wayland_pointer_p.h"
0009 
0010 #include <QDebug>
0011 #include <QMap>
0012 
0013 #include <wayland-plasma-virtual-desktop-client-protocol.h>
0014 
0015 namespace KWayland
0016 {
0017 namespace Client
0018 {
0019 class Q_DECL_HIDDEN PlasmaVirtualDesktopManagement::Private
0020 {
0021 public:
0022     Private(PlasmaVirtualDesktopManagement *q);
0023 
0024     void setup(org_kde_plasma_virtual_desktop_management *arg);
0025 
0026     WaylandPointer<org_kde_plasma_virtual_desktop_management, org_kde_plasma_virtual_desktop_management_destroy> plasmavirtualdesktopmanagement;
0027     EventQueue *queue = nullptr;
0028 
0029     quint32 rows = 1;
0030     QList<PlasmaVirtualDesktop *> desktops;
0031 
0032     inline QList<PlasmaVirtualDesktop *>::const_iterator constFindDesktop(const QString &id);
0033     inline QList<PlasmaVirtualDesktop *>::iterator findDesktop(const QString &id);
0034 
0035 private:
0036     static void
0037     createdCallback(void *data, org_kde_plasma_virtual_desktop_management *org_kde_plasma_virtual_desktop_management, const char *id, uint32_t position);
0038     static void removedCallback(void *data, org_kde_plasma_virtual_desktop_management *org_kde_plasma_virtual_desktop_management, const char *id);
0039     static void rowsCallback(void *data, org_kde_plasma_virtual_desktop_management *org_kde_plasma_virtual_desktop_management, uint32_t rows);
0040     static void doneCallback(void *data, org_kde_plasma_virtual_desktop_management *org_kde_plasma_virtual_desktop_management);
0041 
0042     PlasmaVirtualDesktopManagement *q;
0043 
0044     static const org_kde_plasma_virtual_desktop_management_listener s_listener;
0045 };
0046 
0047 class Q_DECL_HIDDEN PlasmaVirtualDesktop::Private
0048 {
0049 public:
0050     Private(PlasmaVirtualDesktop *q);
0051 
0052     void setup(org_kde_plasma_virtual_desktop *arg);
0053 
0054     WaylandPointer<org_kde_plasma_virtual_desktop, org_kde_plasma_virtual_desktop_destroy> plasmavirtualdesktop;
0055 
0056     QString id;
0057     QString name;
0058     bool active = false;
0059 
0060 private:
0061     PlasmaVirtualDesktop *q;
0062 
0063 private:
0064     static void idCallback(void *data, org_kde_plasma_virtual_desktop *org_kde_plasma_virtual_desktop, const char *id);
0065     static void nameCallback(void *data, org_kde_plasma_virtual_desktop *org_kde_plasma_virtual_desktop, const char *name);
0066 
0067     static void activatedCallback(void *data, org_kde_plasma_virtual_desktop *org_kde_plasma_virtual_desktop);
0068     static void deactivatedCallback(void *data, org_kde_plasma_virtual_desktop *org_kde_plasma_virtual_desktop);
0069     static void doneCallback(void *data, org_kde_plasma_virtual_desktop *org_kde_plasma_virtual_desktop);
0070     static void removedCallback(void *data, org_kde_plasma_virtual_desktop *org_kde_plasma_virtual_desktop);
0071 
0072     static const org_kde_plasma_virtual_desktop_listener s_listener;
0073 };
0074 
0075 inline QList<PlasmaVirtualDesktop *>::const_iterator PlasmaVirtualDesktopManagement::Private::constFindDesktop(const QString &id)
0076 {
0077     return std::find_if(desktops.constBegin(), desktops.constEnd(), [id](const PlasmaVirtualDesktop *desk) {
0078         return desk->id() == id;
0079     });
0080 }
0081 
0082 inline QList<PlasmaVirtualDesktop *>::iterator PlasmaVirtualDesktopManagement::Private::findDesktop(const QString &id)
0083 {
0084     return std::find_if(desktops.begin(), desktops.end(), [id](const PlasmaVirtualDesktop *desk) {
0085         return desk->id() == id;
0086     });
0087 }
0088 
0089 const org_kde_plasma_virtual_desktop_management_listener PlasmaVirtualDesktopManagement::Private::s_listener = {createdCallback,
0090                                                                                                                 removedCallback,
0091                                                                                                                 doneCallback,
0092                                                                                                                 rowsCallback};
0093 
0094 void PlasmaVirtualDesktopManagement::Private::createdCallback(void *data,
0095                                                               org_kde_plasma_virtual_desktop_management *org_kde_plasma_virtual_desktop_management,
0096                                                               const char *id,
0097                                                               uint32_t position)
0098 {
0099     auto p = reinterpret_cast<PlasmaVirtualDesktopManagement::Private *>(data);
0100     Q_ASSERT(p->plasmavirtualdesktopmanagement == org_kde_plasma_virtual_desktop_management);
0101     const QString stringId = QString::fromUtf8(id);
0102     PlasmaVirtualDesktop *vd = p->q->getVirtualDesktop(stringId);
0103     Q_ASSERT(vd);
0104 
0105     p->desktops.insert(position, vd);
0106     // TODO: emit a lot of desktopMoved?
0107 
0108     Q_EMIT p->q->desktopCreated(stringId, position);
0109 }
0110 
0111 void PlasmaVirtualDesktopManagement::Private::removedCallback(void *data,
0112                                                               org_kde_plasma_virtual_desktop_management *org_kde_plasma_virtual_desktop_management,
0113                                                               const char *id)
0114 {
0115     auto p = reinterpret_cast<PlasmaVirtualDesktopManagement::Private *>(data);
0116     Q_ASSERT(p->plasmavirtualdesktopmanagement == org_kde_plasma_virtual_desktop_management);
0117     const QString stringId = QString::fromUtf8(id);
0118     PlasmaVirtualDesktop *vd = p->q->getVirtualDesktop(stringId);
0119     // TODO: emit a lot of desktopMoved?
0120     Q_ASSERT(vd);
0121     auto i = p->findDesktop(stringId);
0122     p->desktops.erase(i);
0123     vd->release();
0124     vd->destroy();
0125     vd->deleteLater();
0126     Q_EMIT p->q->desktopRemoved(stringId);
0127 }
0128 
0129 void PlasmaVirtualDesktopManagement::Private::rowsCallback(void *data,
0130                                                            org_kde_plasma_virtual_desktop_management *org_kde_plasma_virtual_desktop_management,
0131                                                            uint32_t rows)
0132 {
0133     auto p = reinterpret_cast<PlasmaVirtualDesktopManagement::Private *>(data);
0134     Q_ASSERT(p->plasmavirtualdesktopmanagement == org_kde_plasma_virtual_desktop_management);
0135     if (rows == 0) {
0136         return;
0137     }
0138     p->rows = rows;
0139     Q_EMIT p->q->rowsChanged(rows);
0140 }
0141 
0142 void PlasmaVirtualDesktopManagement::Private::doneCallback(void *data, org_kde_plasma_virtual_desktop_management *org_kde_plasma_virtual_desktop_management)
0143 {
0144     auto p = reinterpret_cast<PlasmaVirtualDesktopManagement::Private *>(data);
0145     Q_ASSERT(p->plasmavirtualdesktopmanagement == org_kde_plasma_virtual_desktop_management);
0146     Q_EMIT p->q->done();
0147 }
0148 
0149 PlasmaVirtualDesktopManagement::PlasmaVirtualDesktopManagement(QObject *parent)
0150     : QObject(parent)
0151     , d(new Private(this))
0152 {
0153 }
0154 
0155 PlasmaVirtualDesktopManagement::Private::Private(PlasmaVirtualDesktopManagement *q)
0156     : q(q)
0157 {
0158 }
0159 
0160 void PlasmaVirtualDesktopManagement::Private::setup(org_kde_plasma_virtual_desktop_management *arg)
0161 {
0162     Q_ASSERT(arg);
0163     Q_ASSERT(!plasmavirtualdesktopmanagement);
0164     plasmavirtualdesktopmanagement.setup(arg);
0165     org_kde_plasma_virtual_desktop_management_add_listener(plasmavirtualdesktopmanagement, &s_listener, this);
0166 }
0167 
0168 PlasmaVirtualDesktopManagement::~PlasmaVirtualDesktopManagement()
0169 {
0170     release();
0171 }
0172 
0173 void PlasmaVirtualDesktopManagement::setup(org_kde_plasma_virtual_desktop_management *plasmavirtualdesktopmanagement)
0174 {
0175     d->setup(plasmavirtualdesktopmanagement);
0176 }
0177 
0178 void PlasmaVirtualDesktopManagement::release()
0179 {
0180     d->plasmavirtualdesktopmanagement.release();
0181 }
0182 
0183 void PlasmaVirtualDesktopManagement::destroy()
0184 {
0185     d->plasmavirtualdesktopmanagement.destroy();
0186 }
0187 
0188 PlasmaVirtualDesktopManagement::operator org_kde_plasma_virtual_desktop_management *()
0189 {
0190     return d->plasmavirtualdesktopmanagement;
0191 }
0192 
0193 PlasmaVirtualDesktopManagement::operator org_kde_plasma_virtual_desktop_management *() const
0194 {
0195     return d->plasmavirtualdesktopmanagement;
0196 }
0197 
0198 bool PlasmaVirtualDesktopManagement::isValid() const
0199 {
0200     return d->plasmavirtualdesktopmanagement.isValid();
0201 }
0202 
0203 void PlasmaVirtualDesktopManagement::setEventQueue(EventQueue *queue)
0204 {
0205     d->queue = queue;
0206 }
0207 
0208 EventQueue *PlasmaVirtualDesktopManagement::eventQueue()
0209 {
0210     return d->queue;
0211 }
0212 
0213 PlasmaVirtualDesktop *PlasmaVirtualDesktopManagement::getVirtualDesktop(const QString &id)
0214 {
0215     Q_ASSERT(isValid());
0216 
0217     if (id.isEmpty()) {
0218         return nullptr;
0219     }
0220 
0221     auto i = d->constFindDesktop(id);
0222     if (i != d->desktops.constEnd()) {
0223         return *i;
0224     }
0225 
0226     auto w = org_kde_plasma_virtual_desktop_management_get_virtual_desktop(d->plasmavirtualdesktopmanagement, id.toUtf8());
0227 
0228     if (!w) {
0229         return nullptr;
0230     }
0231 
0232     if (d->queue) {
0233         d->queue->addProxy(w);
0234     }
0235 
0236     auto desktop = new PlasmaVirtualDesktop(this);
0237     desktop->setup(w);
0238     desktop->d->id = id;
0239 
0240     return desktop;
0241 }
0242 
0243 void PlasmaVirtualDesktopManagement::requestRemoveVirtualDesktop(const QString &id)
0244 {
0245     Q_ASSERT(isValid());
0246 
0247     org_kde_plasma_virtual_desktop_management_request_remove_virtual_desktop(d->plasmavirtualdesktopmanagement, id.toUtf8());
0248 }
0249 
0250 void PlasmaVirtualDesktopManagement::requestCreateVirtualDesktop(const QString &name, quint32 position)
0251 {
0252     Q_ASSERT(isValid());
0253 
0254     org_kde_plasma_virtual_desktop_management_request_create_virtual_desktop(d->plasmavirtualdesktopmanagement, name.toUtf8(), position);
0255 }
0256 
0257 QList<PlasmaVirtualDesktop *> PlasmaVirtualDesktopManagement::desktops() const
0258 {
0259     return d->desktops;
0260 }
0261 
0262 quint32 PlasmaVirtualDesktopManagement::rows() const
0263 {
0264     return d->rows;
0265 }
0266 
0267 const org_kde_plasma_virtual_desktop_listener PlasmaVirtualDesktop::Private::s_listener =
0268     {idCallback, nameCallback, activatedCallback, deactivatedCallback, doneCallback, removedCallback};
0269 
0270 void PlasmaVirtualDesktop::Private::idCallback(void *data, org_kde_plasma_virtual_desktop *org_kde_plasma_virtual_desktop, const char *id)
0271 {
0272     auto p = reinterpret_cast<PlasmaVirtualDesktop::Private *>(data);
0273     Q_ASSERT(p->plasmavirtualdesktop == org_kde_plasma_virtual_desktop);
0274     p->id = QString::fromUtf8(id);
0275 }
0276 
0277 void PlasmaVirtualDesktop::Private::nameCallback(void *data, org_kde_plasma_virtual_desktop *org_kde_plasma_virtual_desktop, const char *name)
0278 {
0279     auto p = reinterpret_cast<PlasmaVirtualDesktop::Private *>(data);
0280     Q_ASSERT(p->plasmavirtualdesktop == org_kde_plasma_virtual_desktop);
0281     p->name = QString::fromUtf8(name);
0282 }
0283 
0284 void PlasmaVirtualDesktop::Private::activatedCallback(void *data, org_kde_plasma_virtual_desktop *org_kde_plasma_virtual_desktop)
0285 {
0286     auto p = reinterpret_cast<PlasmaVirtualDesktop::Private *>(data);
0287     Q_ASSERT(p->plasmavirtualdesktop == org_kde_plasma_virtual_desktop);
0288     p->active = true;
0289     Q_EMIT p->q->activated();
0290 }
0291 
0292 void PlasmaVirtualDesktop::Private::deactivatedCallback(void *data, org_kde_plasma_virtual_desktop *org_kde_plasma_virtual_desktop)
0293 {
0294     auto p = reinterpret_cast<PlasmaVirtualDesktop::Private *>(data);
0295     Q_ASSERT(p->plasmavirtualdesktop == org_kde_plasma_virtual_desktop);
0296     p->active = false;
0297     Q_EMIT p->q->deactivated();
0298 }
0299 
0300 void PlasmaVirtualDesktop::Private::doneCallback(void *data, org_kde_plasma_virtual_desktop *org_kde_plasma_virtual_desktop)
0301 {
0302     auto p = reinterpret_cast<PlasmaVirtualDesktop::Private *>(data);
0303     Q_ASSERT(p->plasmavirtualdesktop == org_kde_plasma_virtual_desktop);
0304     Q_EMIT p->q->done();
0305 }
0306 
0307 void PlasmaVirtualDesktop::Private::removedCallback(void *data, org_kde_plasma_virtual_desktop *org_kde_plasma_virtual_desktop)
0308 {
0309     auto p = reinterpret_cast<PlasmaVirtualDesktop::Private *>(data);
0310     Q_ASSERT(p->plasmavirtualdesktop == org_kde_plasma_virtual_desktop);
0311     Q_EMIT p->q->removed();
0312 }
0313 
0314 PlasmaVirtualDesktop::Private::Private(PlasmaVirtualDesktop *q)
0315     : q(q)
0316 {
0317 }
0318 
0319 PlasmaVirtualDesktop::PlasmaVirtualDesktop(QObject *parent)
0320     : QObject(parent)
0321     , d(new Private(this))
0322 {
0323 }
0324 
0325 void PlasmaVirtualDesktop::Private::setup(org_kde_plasma_virtual_desktop *arg)
0326 {
0327     Q_ASSERT(arg);
0328     Q_ASSERT(!plasmavirtualdesktop);
0329     plasmavirtualdesktop.setup(arg);
0330     org_kde_plasma_virtual_desktop_add_listener(plasmavirtualdesktop, &s_listener, this);
0331 }
0332 
0333 PlasmaVirtualDesktop::~PlasmaVirtualDesktop()
0334 {
0335     release();
0336 }
0337 
0338 void PlasmaVirtualDesktop::setup(org_kde_plasma_virtual_desktop *plasmavirtualdesktop)
0339 {
0340     d->setup(plasmavirtualdesktop);
0341 }
0342 
0343 void PlasmaVirtualDesktop::release()
0344 {
0345     d->plasmavirtualdesktop.release();
0346 }
0347 
0348 void PlasmaVirtualDesktop::destroy()
0349 {
0350     d->plasmavirtualdesktop.destroy();
0351 }
0352 
0353 PlasmaVirtualDesktop::operator org_kde_plasma_virtual_desktop *()
0354 {
0355     return d->plasmavirtualdesktop;
0356 }
0357 
0358 PlasmaVirtualDesktop::operator org_kde_plasma_virtual_desktop *() const
0359 {
0360     return d->plasmavirtualdesktop;
0361 }
0362 
0363 bool PlasmaVirtualDesktop::isValid() const
0364 {
0365     return d->plasmavirtualdesktop.isValid();
0366 }
0367 
0368 void PlasmaVirtualDesktop::requestActivate()
0369 {
0370     Q_ASSERT(isValid());
0371     org_kde_plasma_virtual_desktop_request_activate(d->plasmavirtualdesktop);
0372 }
0373 
0374 QString PlasmaVirtualDesktop::id() const
0375 {
0376     return d->id;
0377 }
0378 
0379 QString PlasmaVirtualDesktop::name() const
0380 {
0381     return d->name;
0382 }
0383 
0384 bool PlasmaVirtualDesktop::isActive() const
0385 {
0386     return d->active;
0387 }
0388 
0389 }
0390 }
0391 
0392 #include "moc_plasmavirtualdesktop.cpp"