File indexing completed on 2024-12-22 05:09:21
0001 /* 0002 SPDX-FileCopyrightText: 2015 Martin Gräßlin <mgraesslin@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0005 */ 0006 #include "plasmawindowmanagement.h" 0007 #include "event_queue.h" 0008 #include "output.h" 0009 #include "plasmavirtualdesktop.h" 0010 #include "plasmawindowmodel.h" 0011 #include "surface.h" 0012 #include "wayland_pointer_p.h" 0013 // Wayland 0014 #include <wayland-plasma-window-management-client-protocol.h> 0015 0016 #include <QFutureWatcher> 0017 #include <QTimer> 0018 #include <QtConcurrentRun> 0019 #include <qplatformdefs.h> 0020 0021 #include <cerrno> 0022 0023 namespace KWayland 0024 { 0025 namespace Client 0026 { 0027 class Q_DECL_HIDDEN PlasmaWindowManagement::Private 0028 { 0029 public: 0030 Private(PlasmaWindowManagement *q); 0031 WaylandPointer<org_kde_plasma_window_management, org_kde_plasma_window_management_destroy> wm; 0032 EventQueue *queue = nullptr; 0033 bool showingDesktop = false; 0034 QList<PlasmaWindow *> windows; 0035 PlasmaWindow *activeWindow = nullptr; 0036 QList<quint32> stackingOrder; 0037 QList<QByteArray> stackingOrderUuids; 0038 0039 void setup(org_kde_plasma_window_management *wm); 0040 0041 private: 0042 static void showDesktopCallback(void *data, org_kde_plasma_window_management *org_kde_plasma_window_management, uint32_t state); 0043 static void windowCallback(void *data, org_kde_plasma_window_management *org_kde_plasma_window_management, uint32_t id); 0044 static void windowWithUuidCallback(void *data, org_kde_plasma_window_management *org_kde_plasma_window_management, uint32_t id, const char *uuid); 0045 static void stackingOrderCallback(void *data, org_kde_plasma_window_management *org_kde_plasma_window_management, wl_array *ids); 0046 static void stackingOrderUuidsCallback(void *data, org_kde_plasma_window_management *org_kde_plasma_window_management, const char *uuids); 0047 void setShowDesktop(bool set); 0048 void windowCreated(org_kde_plasma_window *id, quint32 internalId, const char *uuid); 0049 void setStackingOrder(const QList<quint32> &ids); 0050 void setStackingOrder(const QList<QByteArray> &uuids); 0051 0052 static struct org_kde_plasma_window_management_listener s_listener; 0053 PlasmaWindowManagement *q; 0054 }; 0055 0056 class Q_DECL_HIDDEN PlasmaWindow::Private 0057 { 0058 public: 0059 Private(org_kde_plasma_window *window, quint32 internalId, const char *uuid, PlasmaWindow *q); 0060 WaylandPointer<org_kde_plasma_window, org_kde_plasma_window_destroy> window; 0061 quint32 internalId; ///< @deprecated 0062 QByteArray uuid; 0063 QString title; 0064 QString appId; 0065 quint32 desktop = 0; 0066 bool active = false; 0067 bool minimized = false; 0068 bool maximized = false; 0069 bool fullscreen = false; 0070 bool keepAbove = false; 0071 bool keepBelow = false; 0072 bool onAllDesktops = false; 0073 bool demandsAttention = false; 0074 bool closeable = false; 0075 bool minimizeable = false; 0076 bool maximizeable = false; 0077 bool fullscreenable = false; 0078 bool skipTaskbar = false; 0079 bool skipSwitcher = false; 0080 bool shadeable = false; 0081 bool shaded = false; 0082 bool movable = false; 0083 bool resizable = false; 0084 bool virtualDesktopChangeable = false; 0085 QIcon icon; 0086 PlasmaWindowManagement *wm = nullptr; 0087 bool unmapped = false; 0088 QPointer<PlasmaWindow> parentWindow; 0089 QMetaObject::Connection parentWindowUnmappedConnection; 0090 QStringList plasmaVirtualDesktops; 0091 QStringList plasmaActivities; 0092 QRect geometry; 0093 quint32 pid = 0; 0094 QString resourceName; 0095 QString applicationMenuServiceName; 0096 QString applicationMenuObjectPath; 0097 0098 private: 0099 static void titleChangedCallback(void *data, org_kde_plasma_window *window, const char *title); 0100 static void appIdChangedCallback(void *data, org_kde_plasma_window *window, const char *app_id); 0101 static void pidChangedCallback(void *data, org_kde_plasma_window *window, uint32_t pid); 0102 static void resourceNameChangedCallback(void *data, org_kde_plasma_window *window, const char *resourceName); 0103 static void stateChangedCallback(void *data, org_kde_plasma_window *window, uint32_t state); 0104 static void virtualDesktopChangedCallback(void *data, org_kde_plasma_window *window, int32_t number); 0105 static void themedIconNameChangedCallback(void *data, org_kde_plasma_window *window, const char *name); 0106 static void unmappedCallback(void *data, org_kde_plasma_window *window); 0107 static void initialStateCallback(void *data, org_kde_plasma_window *window); 0108 static void parentWindowCallback(void *data, org_kde_plasma_window *window, org_kde_plasma_window *parent); 0109 static void windowGeometryCallback(void *data, org_kde_plasma_window *window, int32_t x, int32_t y, uint32_t width, uint32_t height); 0110 static void iconChangedCallback(void *data, org_kde_plasma_window *org_kde_plasma_window); 0111 static void virtualDesktopEnteredCallback(void *data, org_kde_plasma_window *org_kde_plasma_window, const char *id); 0112 static void virtualDesktopLeftCallback(void *data, org_kde_plasma_window *org_kde_plasma_window, const char *id); 0113 static void appmenuChangedCallback(void *data, org_kde_plasma_window *org_kde_plasma_window, const char *service_name, const char *object_path); 0114 static void activityEnteredCallback(void *data, org_kde_plasma_window *org_kde_plasma_window, const char *id); 0115 static void activityLeftCallback(void *data, org_kde_plasma_window *org_kde_plasma_window, const char *id); 0116 void setActive(bool set); 0117 void setMinimized(bool set); 0118 void setMaximized(bool set); 0119 void setFullscreen(bool set); 0120 void setKeepAbove(bool set); 0121 void setKeepBelow(bool set); 0122 void setOnAllDesktops(bool set); 0123 void setDemandsAttention(bool set); 0124 void setCloseable(bool set); 0125 void setMinimizeable(bool set); 0126 void setMaximizeable(bool set); 0127 void setFullscreenable(bool set); 0128 void setSkipTaskbar(bool skip); 0129 void setSkipSwitcher(bool skip); 0130 void setShadeable(bool set); 0131 void setShaded(bool set); 0132 void setMovable(bool set); 0133 void setResizable(bool set); 0134 void setVirtualDesktopChangeable(bool set); 0135 void setParentWindow(PlasmaWindow *parentWindow); 0136 void setPid(const quint32 pid); 0137 0138 static Private *cast(void *data) 0139 { 0140 return reinterpret_cast<Private *>(data); 0141 } 0142 0143 PlasmaWindow *q; 0144 0145 static struct org_kde_plasma_window_listener s_listener; 0146 }; 0147 0148 PlasmaWindowManagement::Private::Private(PlasmaWindowManagement *q) 0149 : q(q) 0150 { 0151 } 0152 0153 org_kde_plasma_window_management_listener PlasmaWindowManagement::Private::s_listener = { 0154 showDesktopCallback, 0155 windowCallback, 0156 stackingOrderCallback, 0157 stackingOrderUuidsCallback, 0158 windowWithUuidCallback, 0159 }; 0160 0161 void PlasmaWindowManagement::Private::setup(org_kde_plasma_window_management *windowManagement) 0162 { 0163 Q_ASSERT(!wm); 0164 Q_ASSERT(windowManagement); 0165 wm.setup(windowManagement); 0166 org_kde_plasma_window_management_add_listener(windowManagement, &s_listener, this); 0167 } 0168 0169 void PlasmaWindowManagement::Private::showDesktopCallback(void *data, org_kde_plasma_window_management *org_kde_plasma_window_management, uint32_t state) 0170 { 0171 auto wm = reinterpret_cast<PlasmaWindowManagement::Private *>(data); 0172 Q_ASSERT(wm->wm == org_kde_plasma_window_management); 0173 switch (state) { 0174 case ORG_KDE_PLASMA_WINDOW_MANAGEMENT_SHOW_DESKTOP_ENABLED: 0175 wm->setShowDesktop(true); 0176 break; 0177 case ORG_KDE_PLASMA_WINDOW_MANAGEMENT_SHOW_DESKTOP_DISABLED: 0178 wm->setShowDesktop(false); 0179 break; 0180 default: 0181 Q_UNREACHABLE(); 0182 break; 0183 } 0184 } 0185 0186 void PlasmaWindowManagement::Private::setShowDesktop(bool set) 0187 { 0188 if (showingDesktop == set) { 0189 return; 0190 } 0191 showingDesktop = set; 0192 Q_EMIT q->showingDesktopChanged(showingDesktop); 0193 } 0194 0195 void PlasmaWindowManagement::Private::windowCallback(void *data, org_kde_plasma_window_management *interface, uint32_t id) 0196 { 0197 auto wm = reinterpret_cast<PlasmaWindowManagement::Private *>(data); 0198 Q_ASSERT(wm->wm == interface); 0199 QTimer *timer = new QTimer(); 0200 timer->setSingleShot(true); 0201 timer->setInterval(0); 0202 QObject::connect( 0203 timer, 0204 &QTimer::timeout, 0205 wm->q, 0206 [timer, wm, id] { 0207 wm->windowCreated(org_kde_plasma_window_management_get_window(wm->wm, id), id, "unavailable"); 0208 timer->deleteLater(); 0209 }, 0210 Qt::QueuedConnection); 0211 timer->start(); 0212 } 0213 0214 void PlasmaWindowManagement::Private::windowWithUuidCallback(void *data, org_kde_plasma_window_management *interface, uint32_t id, const char *_uuid) 0215 { 0216 QByteArray uuid(_uuid); 0217 auto wm = reinterpret_cast<PlasmaWindowManagement::Private *>(data); 0218 Q_ASSERT(wm->wm == interface); 0219 QTimer *timer = new QTimer(); 0220 timer->setSingleShot(true); 0221 timer->setInterval(0); 0222 QObject::connect( 0223 timer, 0224 &QTimer::timeout, 0225 wm->q, 0226 [timer, wm, id, uuid] { 0227 wm->windowCreated(org_kde_plasma_window_management_get_window_by_uuid(wm->wm, uuid), id, uuid); 0228 timer->deleteLater(); 0229 }, 0230 Qt::QueuedConnection); 0231 timer->start(); 0232 } 0233 0234 void PlasmaWindowManagement::Private::windowCreated(org_kde_plasma_window *id, quint32 internalId, const char *uuid) 0235 { 0236 if (queue) { 0237 queue->addProxy(id); 0238 } 0239 PlasmaWindow *window = new PlasmaWindow(q, id, internalId, uuid); 0240 window->d->wm = q; 0241 windows << window; 0242 0243 const auto windowRemoved = [this, window] { 0244 windows.removeAll(window); 0245 if (activeWindow == window) { 0246 activeWindow = nullptr; 0247 Q_EMIT q->activeWindowChanged(); 0248 } 0249 }; 0250 0251 QObject::connect(window, &QObject::destroyed, q, windowRemoved); 0252 // unmapped is emitted earlier than QObject::destroyed. We want to update windows earlier to ensure other slot will see the up to date value of 0253 // PlasmaWindowManagement::windows(). 0254 QObject::connect(window, &PlasmaWindow::unmapped, q, windowRemoved); 0255 QObject::connect(window, &PlasmaWindow::activeChanged, q, [this, window] { 0256 if (window->d->unmapped) { 0257 return; 0258 } 0259 if (window->isActive()) { 0260 if (activeWindow == window) { 0261 return; 0262 } 0263 activeWindow = window; 0264 Q_EMIT q->activeWindowChanged(); 0265 } else { 0266 if (activeWindow == window) { 0267 activeWindow = nullptr; 0268 Q_EMIT q->activeWindowChanged(); 0269 } 0270 } 0271 }); 0272 } 0273 0274 void PlasmaWindowManagement::Private::stackingOrderCallback(void *data, org_kde_plasma_window_management *interface, wl_array *ids) 0275 { 0276 // This is no-op since setStackingOrder(const QList<quint32> &ids) is deprecated since 5.73, 0277 // but we can't remove this method because it's needed in 0278 // PlasmaWindowManagement::Private::s_listener struct 0279 } 0280 0281 void PlasmaWindowManagement::Private::stackingOrderUuidsCallback(void *data, org_kde_plasma_window_management *interface, const char *uuids) 0282 { 0283 auto wm = reinterpret_cast<PlasmaWindowManagement::Private *>(data); 0284 Q_ASSERT(wm->wm == interface); 0285 wm->setStackingOrder(QByteArray(uuids).split(';').toVector()); 0286 } 0287 0288 void PlasmaWindowManagement::Private::setStackingOrder(const QList<QByteArray> &uuids) 0289 { 0290 if (stackingOrderUuids == uuids) { 0291 return; 0292 } 0293 stackingOrderUuids = uuids; 0294 Q_EMIT q->stackingOrderUuidsChanged(); 0295 } 0296 0297 PlasmaWindowManagement::PlasmaWindowManagement(QObject *parent) 0298 : QObject(parent) 0299 , d(new Private(this)) 0300 { 0301 } 0302 0303 PlasmaWindowManagement::~PlasmaWindowManagement() 0304 { 0305 release(); 0306 } 0307 0308 void PlasmaWindowManagement::destroy() 0309 { 0310 if (!d->wm) { 0311 return; 0312 } 0313 Q_EMIT interfaceAboutToBeDestroyed(); 0314 d->wm.destroy(); 0315 } 0316 0317 void PlasmaWindowManagement::release() 0318 { 0319 if (!d->wm) { 0320 return; 0321 } 0322 Q_EMIT interfaceAboutToBeReleased(); 0323 d->wm.release(); 0324 } 0325 0326 void PlasmaWindowManagement::setup(org_kde_plasma_window_management *wm) 0327 { 0328 d->setup(wm); 0329 } 0330 0331 void PlasmaWindowManagement::setEventQueue(EventQueue *queue) 0332 { 0333 d->queue = queue; 0334 } 0335 0336 EventQueue *PlasmaWindowManagement::eventQueue() 0337 { 0338 return d->queue; 0339 } 0340 0341 bool PlasmaWindowManagement::isValid() const 0342 { 0343 return d->wm.isValid(); 0344 } 0345 0346 PlasmaWindowManagement::operator org_kde_plasma_window_management *() 0347 { 0348 return d->wm; 0349 } 0350 0351 PlasmaWindowManagement::operator org_kde_plasma_window_management *() const 0352 { 0353 return d->wm; 0354 } 0355 0356 void PlasmaWindowManagement::hideDesktop() 0357 { 0358 setShowingDesktop(false); 0359 } 0360 0361 void PlasmaWindowManagement::showDesktop() 0362 { 0363 setShowingDesktop(true); 0364 } 0365 0366 void PlasmaWindowManagement::setShowingDesktop(bool show) 0367 { 0368 org_kde_plasma_window_management_show_desktop(d->wm, 0369 show ? ORG_KDE_PLASMA_WINDOW_MANAGEMENT_SHOW_DESKTOP_ENABLED 0370 : ORG_KDE_PLASMA_WINDOW_MANAGEMENT_SHOW_DESKTOP_DISABLED); 0371 } 0372 0373 bool PlasmaWindowManagement::isShowingDesktop() const 0374 { 0375 return d->showingDesktop; 0376 } 0377 0378 QList<PlasmaWindow *> PlasmaWindowManagement::windows() const 0379 { 0380 return d->windows; 0381 } 0382 0383 PlasmaWindow *PlasmaWindowManagement::activeWindow() const 0384 { 0385 return d->activeWindow; 0386 } 0387 0388 PlasmaWindowModel *PlasmaWindowManagement::createWindowModel() 0389 { 0390 return new PlasmaWindowModel(this); 0391 } 0392 0393 QList<QByteArray> PlasmaWindowManagement::stackingOrderUuids() const 0394 { 0395 return d->stackingOrderUuids; 0396 } 0397 0398 org_kde_plasma_window_listener PlasmaWindow::Private::s_listener = { 0399 titleChangedCallback, 0400 appIdChangedCallback, 0401 stateChangedCallback, 0402 virtualDesktopChangedCallback, 0403 themedIconNameChangedCallback, 0404 unmappedCallback, 0405 initialStateCallback, 0406 parentWindowCallback, 0407 windowGeometryCallback, 0408 iconChangedCallback, 0409 pidChangedCallback, 0410 virtualDesktopEnteredCallback, 0411 virtualDesktopLeftCallback, 0412 appmenuChangedCallback, 0413 activityEnteredCallback, 0414 activityLeftCallback, 0415 resourceNameChangedCallback, 0416 }; 0417 0418 void PlasmaWindow::Private::appmenuChangedCallback(void *data, org_kde_plasma_window *window, const char *service_name, const char *object_path) 0419 { 0420 Q_UNUSED(window) 0421 0422 Private *p = cast(data); 0423 0424 p->applicationMenuServiceName = QString::fromUtf8(service_name); 0425 p->applicationMenuObjectPath = QString::fromUtf8(object_path); 0426 0427 Q_EMIT p->q->applicationMenuChanged(); 0428 } 0429 0430 void PlasmaWindow::Private::parentWindowCallback(void *data, org_kde_plasma_window *window, org_kde_plasma_window *parent) 0431 { 0432 Q_UNUSED(window) 0433 Private *p = cast(data); 0434 const auto windows = p->wm->windows(); 0435 auto it = std::find_if(windows.constBegin(), windows.constEnd(), [parent](const PlasmaWindow *w) { 0436 return *w == parent; 0437 }); 0438 p->setParentWindow(it != windows.constEnd() ? *it : nullptr); 0439 } 0440 0441 void PlasmaWindow::Private::windowGeometryCallback(void *data, org_kde_plasma_window *window, int32_t x, int32_t y, uint32_t width, uint32_t height) 0442 { 0443 Q_UNUSED(window) 0444 Private *p = cast(data); 0445 QRect geo(x, y, width, height); 0446 if (geo == p->geometry) { 0447 return; 0448 } 0449 p->geometry = geo; 0450 Q_EMIT p->q->geometryChanged(); 0451 } 0452 0453 void PlasmaWindow::Private::setParentWindow(PlasmaWindow *parent) 0454 { 0455 const auto old = parentWindow; 0456 QObject::disconnect(parentWindowUnmappedConnection); 0457 if (parent && !parent->d->unmapped) { 0458 parentWindow = QPointer<PlasmaWindow>(parent); 0459 parentWindowUnmappedConnection = QObject::connect(parent, &PlasmaWindow::unmapped, q, [this] { 0460 setParentWindow(nullptr); 0461 }); 0462 } else { 0463 parentWindow = QPointer<PlasmaWindow>(); 0464 parentWindowUnmappedConnection = QMetaObject::Connection(); 0465 } 0466 if (parentWindow.data() != old.data()) { 0467 Q_EMIT q->parentWindowChanged(); 0468 } 0469 } 0470 0471 void PlasmaWindow::Private::initialStateCallback(void *data, org_kde_plasma_window *window) 0472 { 0473 Q_UNUSED(window) 0474 Private *p = cast(data); 0475 if (!p->unmapped) { 0476 Q_EMIT p->wm->windowCreated(p->q); 0477 } 0478 } 0479 0480 void PlasmaWindow::Private::titleChangedCallback(void *data, org_kde_plasma_window *window, const char *title) 0481 { 0482 Q_UNUSED(window) 0483 Private *p = cast(data); 0484 const QString t = QString::fromUtf8(title); 0485 if (p->title == t) { 0486 return; 0487 } 0488 p->title = t; 0489 Q_EMIT p->q->titleChanged(); 0490 } 0491 0492 void PlasmaWindow::Private::appIdChangedCallback(void *data, org_kde_plasma_window *window, const char *appId) 0493 { 0494 Q_UNUSED(window) 0495 Private *p = cast(data); 0496 const QString s = QString::fromUtf8(appId); 0497 if (s == p->appId) { 0498 return; 0499 } 0500 p->appId = s; 0501 Q_EMIT p->q->appIdChanged(); 0502 } 0503 0504 void PlasmaWindow::Private::pidChangedCallback(void *data, org_kde_plasma_window *window, uint32_t pid) 0505 { 0506 Q_UNUSED(window) 0507 Private *p = cast(data); 0508 if (p->pid == static_cast<quint32>(pid)) { 0509 return; 0510 } 0511 p->pid = pid; 0512 } 0513 0514 void PlasmaWindow::Private::resourceNameChangedCallback(void *data, org_kde_plasma_window *window, const char *resourceName) 0515 { 0516 Q_UNUSED(window) 0517 Private *p = cast(data); 0518 const QString s = QString::fromUtf8(resourceName); 0519 if (s == p->resourceName) { 0520 return; 0521 } 0522 p->resourceName = s; 0523 Q_EMIT p->q->resourceNameChanged(); 0524 } 0525 0526 void PlasmaWindow::Private::virtualDesktopChangedCallback([[maybe_unused]] void *data, 0527 [[maybe_unused]] org_kde_plasma_window *window, 0528 [[maybe_unused]] int32_t number) 0529 { 0530 // Can't remove this method as it's used in PlasmaWindow::Private::s_listener struct 0531 } 0532 0533 void PlasmaWindow::Private::unmappedCallback(void *data, org_kde_plasma_window *window) 0534 { 0535 auto p = cast(data); 0536 Q_UNUSED(window); 0537 p->unmapped = true; 0538 Q_EMIT p->q->unmapped(); 0539 p->q->deleteLater(); 0540 } 0541 0542 void PlasmaWindow::Private::virtualDesktopEnteredCallback(void *data, org_kde_plasma_window *window, const char *id) 0543 { 0544 auto p = cast(data); 0545 Q_UNUSED(window); 0546 const QString stringId(QString::fromUtf8(id)); 0547 p->plasmaVirtualDesktops << stringId; 0548 Q_EMIT p->q->plasmaVirtualDesktopEntered(stringId); 0549 if (p->plasmaVirtualDesktops.count() == 1) { 0550 Q_EMIT p->q->onAllDesktopsChanged(); 0551 } 0552 } 0553 0554 void PlasmaWindow::Private::virtualDesktopLeftCallback(void *data, org_kde_plasma_window *window, const char *id) 0555 { 0556 auto p = cast(data); 0557 Q_UNUSED(window); 0558 const QString stringId(QString::fromUtf8(id)); 0559 p->plasmaVirtualDesktops.removeAll(stringId); 0560 Q_EMIT p->q->plasmaVirtualDesktopLeft(stringId); 0561 if (p->plasmaVirtualDesktops.isEmpty()) { 0562 Q_EMIT p->q->onAllDesktopsChanged(); 0563 } 0564 } 0565 0566 void PlasmaWindow::Private::activityEnteredCallback(void *data, org_kde_plasma_window *window, const char *id) 0567 { 0568 auto p = cast(data); 0569 Q_UNUSED(window); 0570 const QString stringId(QString::fromUtf8(id)); 0571 p->plasmaActivities << stringId; 0572 Q_EMIT p->q->plasmaActivityEntered(stringId); 0573 } 0574 0575 void PlasmaWindow::Private::activityLeftCallback(void *data, org_kde_plasma_window *window, const char *id) 0576 { 0577 auto p = cast(data); 0578 Q_UNUSED(window); 0579 const QString stringId(QString::fromUtf8(id)); 0580 p->plasmaActivities.removeAll(stringId); 0581 Q_EMIT p->q->plasmaActivityLeft(stringId); 0582 } 0583 0584 void PlasmaWindow::Private::stateChangedCallback(void *data, org_kde_plasma_window *window, uint32_t state) 0585 { 0586 auto p = cast(data); 0587 Q_UNUSED(window); 0588 p->setActive(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_ACTIVE); 0589 p->setMinimized(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_MINIMIZED); 0590 p->setMaximized(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_MAXIMIZED); 0591 p->setFullscreen(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_FULLSCREEN); 0592 p->setKeepAbove(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_KEEP_ABOVE); 0593 p->setKeepBelow(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_KEEP_BELOW); 0594 p->setOnAllDesktops(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_ON_ALL_DESKTOPS); 0595 p->setDemandsAttention(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_DEMANDS_ATTENTION); 0596 p->setCloseable(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_CLOSEABLE); 0597 p->setFullscreenable(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_FULLSCREENABLE); 0598 p->setMaximizeable(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_MAXIMIZABLE); 0599 p->setMinimizeable(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_MINIMIZABLE); 0600 p->setSkipTaskbar(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_SKIPTASKBAR); 0601 p->setSkipSwitcher(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_SKIPSWITCHER); 0602 p->setShadeable(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_SHADEABLE); 0603 p->setShaded(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_SHADED); 0604 p->setMovable(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_MOVABLE); 0605 p->setResizable(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_RESIZABLE); 0606 p->setVirtualDesktopChangeable(state & ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_VIRTUAL_DESKTOP_CHANGEABLE); 0607 } 0608 0609 void PlasmaWindow::Private::themedIconNameChangedCallback(void *data, org_kde_plasma_window *window, const char *name) 0610 { 0611 auto p = cast(data); 0612 Q_UNUSED(window); 0613 const QString themedName = QString::fromUtf8(name); 0614 if (!themedName.isEmpty()) { 0615 QIcon icon = QIcon::fromTheme(themedName); 0616 p->icon = icon; 0617 } else { 0618 p->icon = QIcon(); 0619 } 0620 Q_EMIT p->q->iconChanged(); 0621 } 0622 0623 static int readData(int fd, QByteArray &data) 0624 { 0625 // implementation based on QtWayland file qwaylanddataoffer.cpp 0626 char buf[4096]; 0627 int retryCount = 0; 0628 int n; 0629 while (true) { 0630 n = QT_READ(fd, buf, sizeof buf); 0631 if (n > 0) { 0632 data.append(buf, n); 0633 } else if (n == -1 && (errno == EAGAIN) && ++retryCount < 1000) { 0634 usleep(1000); 0635 } else { 0636 break; 0637 } 0638 } 0639 return n; 0640 } 0641 0642 void PlasmaWindow::Private::iconChangedCallback(void *data, org_kde_plasma_window *window) 0643 { 0644 auto p = cast(data); 0645 Q_UNUSED(window); 0646 int pipeFds[2]; 0647 if (pipe2(pipeFds, O_CLOEXEC | O_NONBLOCK) != 0) { 0648 return; 0649 } 0650 org_kde_plasma_window_get_icon(p->window, pipeFds[1]); 0651 close(pipeFds[1]); 0652 const int pipeFd = pipeFds[0]; 0653 auto readIcon = [pipeFd]() -> QIcon { 0654 QByteArray content; 0655 if (readData(pipeFd, content) != 0) { 0656 close(pipeFd); 0657 return QIcon(); 0658 } 0659 close(pipeFd); 0660 QDataStream ds(content); 0661 QIcon icon; 0662 ds >> icon; 0663 return icon; 0664 }; 0665 QFutureWatcher<QIcon> *watcher = new QFutureWatcher<QIcon>(p->q); 0666 QObject::connect(watcher, &QFutureWatcher<QIcon>::finished, p->q, [p, watcher] { 0667 watcher->deleteLater(); 0668 QIcon icon = watcher->result(); 0669 if (!icon.isNull()) { 0670 p->icon = icon; 0671 } else { 0672 p->icon = QIcon::fromTheme(QStringLiteral("wayland")); 0673 } 0674 Q_EMIT p->q->iconChanged(); 0675 }); 0676 watcher->setFuture(QtConcurrent::run(readIcon)); 0677 } 0678 0679 void PlasmaWindow::Private::setActive(bool set) 0680 { 0681 if (active == set) { 0682 return; 0683 } 0684 active = set; 0685 Q_EMIT q->activeChanged(); 0686 } 0687 0688 void PlasmaWindow::Private::setFullscreen(bool set) 0689 { 0690 if (fullscreen == set) { 0691 return; 0692 } 0693 fullscreen = set; 0694 Q_EMIT q->fullscreenChanged(); 0695 } 0696 0697 void PlasmaWindow::Private::setKeepAbove(bool set) 0698 { 0699 if (keepAbove == set) { 0700 return; 0701 } 0702 keepAbove = set; 0703 Q_EMIT q->keepAboveChanged(); 0704 } 0705 0706 void PlasmaWindow::Private::setKeepBelow(bool set) 0707 { 0708 if (keepBelow == set) { 0709 return; 0710 } 0711 keepBelow = set; 0712 Q_EMIT q->keepBelowChanged(); 0713 } 0714 0715 void PlasmaWindow::Private::setMaximized(bool set) 0716 { 0717 if (maximized == set) { 0718 return; 0719 } 0720 maximized = set; 0721 Q_EMIT q->maximizedChanged(); 0722 } 0723 0724 void PlasmaWindow::Private::setMinimized(bool set) 0725 { 0726 if (minimized == set) { 0727 return; 0728 } 0729 minimized = set; 0730 Q_EMIT q->minimizedChanged(); 0731 } 0732 0733 void PlasmaWindow::Private::setOnAllDesktops(bool set) 0734 { 0735 if (onAllDesktops == set) { 0736 return; 0737 } 0738 onAllDesktops = set; 0739 Q_EMIT q->onAllDesktopsChanged(); 0740 } 0741 0742 void PlasmaWindow::Private::setDemandsAttention(bool set) 0743 { 0744 if (demandsAttention == set) { 0745 return; 0746 } 0747 demandsAttention = set; 0748 Q_EMIT q->demandsAttentionChanged(); 0749 } 0750 0751 void PlasmaWindow::Private::setCloseable(bool set) 0752 { 0753 if (closeable == set) { 0754 return; 0755 } 0756 closeable = set; 0757 Q_EMIT q->closeableChanged(); 0758 } 0759 0760 void PlasmaWindow::Private::setFullscreenable(bool set) 0761 { 0762 if (fullscreenable == set) { 0763 return; 0764 } 0765 fullscreenable = set; 0766 Q_EMIT q->fullscreenableChanged(); 0767 } 0768 0769 void PlasmaWindow::Private::setMaximizeable(bool set) 0770 { 0771 if (maximizeable == set) { 0772 return; 0773 } 0774 maximizeable = set; 0775 Q_EMIT q->maximizeableChanged(); 0776 } 0777 0778 void PlasmaWindow::Private::setMinimizeable(bool set) 0779 { 0780 if (minimizeable == set) { 0781 return; 0782 } 0783 minimizeable = set; 0784 Q_EMIT q->minimizeableChanged(); 0785 } 0786 0787 void PlasmaWindow::Private::setSkipTaskbar(bool skip) 0788 { 0789 if (skipTaskbar == skip) { 0790 return; 0791 } 0792 skipTaskbar = skip; 0793 Q_EMIT q->skipTaskbarChanged(); 0794 } 0795 0796 void PlasmaWindow::Private::setSkipSwitcher(bool skip) 0797 { 0798 if (skipSwitcher == skip) { 0799 return; 0800 } 0801 skipSwitcher = skip; 0802 Q_EMIT q->skipSwitcherChanged(); 0803 } 0804 0805 void PlasmaWindow::Private::setShadeable(bool set) 0806 { 0807 if (shadeable == set) { 0808 return; 0809 } 0810 shadeable = set; 0811 Q_EMIT q->shadeableChanged(); 0812 } 0813 0814 void PlasmaWindow::Private::setShaded(bool set) 0815 { 0816 if (shaded == set) { 0817 return; 0818 } 0819 shaded = set; 0820 Q_EMIT q->shadedChanged(); 0821 } 0822 0823 void PlasmaWindow::Private::setMovable(bool set) 0824 { 0825 if (movable == set) { 0826 return; 0827 } 0828 movable = set; 0829 Q_EMIT q->movableChanged(); 0830 } 0831 0832 void PlasmaWindow::Private::setResizable(bool set) 0833 { 0834 if (resizable == set) { 0835 return; 0836 } 0837 resizable = set; 0838 Q_EMIT q->resizableChanged(); 0839 } 0840 0841 void PlasmaWindow::Private::setVirtualDesktopChangeable(bool set) 0842 { 0843 if (virtualDesktopChangeable == set) { 0844 return; 0845 } 0846 virtualDesktopChangeable = set; 0847 Q_EMIT q->virtualDesktopChangeableChanged(); 0848 } 0849 0850 PlasmaWindow::Private::Private(org_kde_plasma_window *w, quint32 internalId, const char *uuid, PlasmaWindow *q) 0851 : internalId(internalId) 0852 , uuid(uuid) 0853 , q(q) 0854 { 0855 Q_ASSERT(!this->uuid.isEmpty()); 0856 window.setup(w); 0857 org_kde_plasma_window_add_listener(w, &s_listener, this); 0858 } 0859 0860 PlasmaWindow::PlasmaWindow(PlasmaWindowManagement *parent, org_kde_plasma_window *window, quint32 internalId, const char *uuid) 0861 : QObject(parent) 0862 , d(new Private(window, internalId, uuid, this)) 0863 { 0864 } 0865 0866 PlasmaWindow::~PlasmaWindow() 0867 { 0868 release(); 0869 } 0870 0871 void PlasmaWindow::destroy() 0872 { 0873 d->window.destroy(); 0874 } 0875 0876 void PlasmaWindow::release() 0877 { 0878 d->window.release(); 0879 } 0880 0881 bool PlasmaWindow::isValid() const 0882 { 0883 return d->window.isValid(); 0884 } 0885 0886 PlasmaWindow::operator org_kde_plasma_window *() const 0887 { 0888 return d->window; 0889 } 0890 0891 PlasmaWindow::operator org_kde_plasma_window *() 0892 { 0893 return d->window; 0894 } 0895 0896 QString PlasmaWindow::appId() const 0897 { 0898 return d->appId; 0899 } 0900 0901 quint32 PlasmaWindow::pid() const 0902 { 0903 return d->pid; 0904 } 0905 0906 QString PlasmaWindow::resourceName() const 0907 { 0908 return d->resourceName; 0909 } 0910 0911 QString PlasmaWindow::title() const 0912 { 0913 return d->title; 0914 } 0915 0916 bool PlasmaWindow::isActive() const 0917 { 0918 return d->active; 0919 } 0920 0921 bool PlasmaWindow::isFullscreen() const 0922 { 0923 return d->fullscreen; 0924 } 0925 0926 bool PlasmaWindow::isKeepAbove() const 0927 { 0928 return d->keepAbove; 0929 } 0930 0931 bool PlasmaWindow::isKeepBelow() const 0932 { 0933 return d->keepBelow; 0934 } 0935 0936 bool PlasmaWindow::isMaximized() const 0937 { 0938 return d->maximized; 0939 } 0940 0941 bool PlasmaWindow::isMinimized() const 0942 { 0943 return d->minimized; 0944 } 0945 0946 bool PlasmaWindow::isOnAllDesktops() const 0947 { 0948 // from protocol version 8 virtual desktops are managed by plasmaVirtualDesktops 0949 if (org_kde_plasma_window_get_version(d->window) < 8) { 0950 return d->onAllDesktops; 0951 } else { 0952 return d->plasmaVirtualDesktops.isEmpty(); 0953 } 0954 } 0955 0956 bool PlasmaWindow::isDemandingAttention() const 0957 { 0958 return d->demandsAttention; 0959 } 0960 0961 bool PlasmaWindow::isCloseable() const 0962 { 0963 return d->closeable; 0964 } 0965 0966 bool PlasmaWindow::isFullscreenable() const 0967 { 0968 return d->fullscreenable; 0969 } 0970 0971 bool PlasmaWindow::isMaximizeable() const 0972 { 0973 return d->maximizeable; 0974 } 0975 0976 bool PlasmaWindow::isMinimizeable() const 0977 { 0978 return d->minimizeable; 0979 } 0980 0981 bool PlasmaWindow::skipTaskbar() const 0982 { 0983 return d->skipTaskbar; 0984 } 0985 0986 bool PlasmaWindow::skipSwitcher() const 0987 { 0988 return d->skipSwitcher; 0989 } 0990 0991 QIcon PlasmaWindow::icon() const 0992 { 0993 return d->icon; 0994 } 0995 0996 bool PlasmaWindow::isShadeable() const 0997 { 0998 return d->shadeable; 0999 } 1000 1001 bool PlasmaWindow::isShaded() const 1002 { 1003 return d->shaded; 1004 } 1005 1006 bool PlasmaWindow::isResizable() const 1007 { 1008 return d->resizable; 1009 } 1010 1011 bool PlasmaWindow::isMovable() const 1012 { 1013 return d->movable; 1014 } 1015 1016 bool PlasmaWindow::isVirtualDesktopChangeable() const 1017 { 1018 return d->virtualDesktopChangeable; 1019 } 1020 1021 QString PlasmaWindow::applicationMenuObjectPath() const 1022 { 1023 return d->applicationMenuObjectPath; 1024 } 1025 1026 QString PlasmaWindow::applicationMenuServiceName() const 1027 { 1028 return d->applicationMenuServiceName; 1029 } 1030 1031 void PlasmaWindow::requestActivate() 1032 { 1033 org_kde_plasma_window_set_state(d->window, ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_ACTIVE, ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_ACTIVE); 1034 } 1035 1036 void PlasmaWindow::requestClose() 1037 { 1038 org_kde_plasma_window_close(d->window); 1039 } 1040 1041 void PlasmaWindow::requestMove() 1042 { 1043 org_kde_plasma_window_request_move(d->window); 1044 } 1045 1046 void PlasmaWindow::requestResize() 1047 { 1048 org_kde_plasma_window_request_resize(d->window); 1049 } 1050 1051 void PlasmaWindow::requestToggleKeepAbove() 1052 { 1053 if (d->keepAbove) { 1054 org_kde_plasma_window_set_state(d->window, ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_KEEP_ABOVE, 0); 1055 } else { 1056 org_kde_plasma_window_set_state(d->window, ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_KEEP_ABOVE, ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_KEEP_ABOVE); 1057 } 1058 } 1059 1060 void PlasmaWindow::requestToggleKeepBelow() 1061 { 1062 if (d->keepBelow) { 1063 org_kde_plasma_window_set_state(d->window, ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_KEEP_BELOW, 0); 1064 } else { 1065 org_kde_plasma_window_set_state(d->window, ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_KEEP_BELOW, ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_KEEP_BELOW); 1066 } 1067 } 1068 1069 void PlasmaWindow::requestToggleMinimized() 1070 { 1071 if (d->minimized) { 1072 org_kde_plasma_window_set_state(d->window, ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_MINIMIZED, 0); 1073 } else { 1074 org_kde_plasma_window_set_state(d->window, ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_MINIMIZED, ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_MINIMIZED); 1075 } 1076 } 1077 1078 void PlasmaWindow::requestToggleMaximized() 1079 { 1080 if (d->maximized) { 1081 org_kde_plasma_window_set_state(d->window, ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_MAXIMIZED, 0); 1082 } else { 1083 org_kde_plasma_window_set_state(d->window, ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_MAXIMIZED, ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_MAXIMIZED); 1084 } 1085 } 1086 1087 void PlasmaWindow::requestToggleFullscreen() 1088 { 1089 if (d->fullscreen) { 1090 org_kde_plasma_window_set_state(d->window, ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_FULLSCREEN, 0); 1091 } else { 1092 org_kde_plasma_window_set_state(d->window, ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_FULLSCREEN, ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_FULLSCREEN); 1093 } 1094 } 1095 1096 void PlasmaWindow::setMinimizedGeometry(Surface *panel, const QRect &geom) 1097 { 1098 org_kde_plasma_window_set_minimized_geometry(d->window, *panel, geom.x(), geom.y(), geom.width(), geom.height()); 1099 } 1100 1101 void PlasmaWindow::unsetMinimizedGeometry(Surface *panel) 1102 { 1103 org_kde_plasma_window_unset_minimized_geometry(d->window, *panel); 1104 } 1105 1106 void PlasmaWindow::requestToggleShaded() 1107 { 1108 if (d->shaded) { 1109 org_kde_plasma_window_set_state(d->window, ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_SHADED, 0); 1110 } else { 1111 org_kde_plasma_window_set_state(d->window, ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_SHADED, ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_SHADED); 1112 } 1113 } 1114 1115 QByteArray PlasmaWindow::uuid() const 1116 { 1117 return d->uuid; 1118 } 1119 1120 QPointer<PlasmaWindow> PlasmaWindow::parentWindow() const 1121 { 1122 return d->parentWindow; 1123 } 1124 1125 QRect PlasmaWindow::geometry() const 1126 { 1127 return d->geometry; 1128 } 1129 1130 void PlasmaWindow::requestEnterVirtualDesktop(const QString &id) 1131 { 1132 org_kde_plasma_window_request_enter_virtual_desktop(d->window, id.toUtf8()); 1133 } 1134 1135 void PlasmaWindow::requestEnterNewVirtualDesktop() 1136 { 1137 org_kde_plasma_window_request_enter_new_virtual_desktop(d->window); 1138 } 1139 1140 void PlasmaWindow::requestLeaveVirtualDesktop(const QString &id) 1141 { 1142 org_kde_plasma_window_request_leave_virtual_desktop(d->window, id.toUtf8()); 1143 } 1144 1145 QStringList PlasmaWindow::plasmaVirtualDesktops() const 1146 { 1147 return d->plasmaVirtualDesktops; 1148 } 1149 1150 void PlasmaWindow::requestEnterActivity(const QString &id) 1151 { 1152 org_kde_plasma_window_request_enter_activity(d->window, id.toUtf8()); 1153 } 1154 1155 void PlasmaWindow::requestLeaveActivity(const QString &id) 1156 { 1157 org_kde_plasma_window_request_leave_activity(d->window, id.toUtf8()); 1158 } 1159 1160 QStringList PlasmaWindow::plasmaActivities() const 1161 { 1162 return d->plasmaActivities; 1163 } 1164 1165 void PlasmaWindow::sendToOutput(KWayland::Client::Output *output) const 1166 { 1167 if (org_kde_plasma_window_get_version(d->window) >= ORG_KDE_PLASMA_WINDOW_SEND_TO_OUTPUT_SINCE_VERSION) { 1168 org_kde_plasma_window_send_to_output(d->window, *output); 1169 } 1170 } 1171 1172 class Q_DECL_HIDDEN PlasmaActivationFeedback::Private 1173 { 1174 public: 1175 Private(PlasmaActivationFeedback *q); 1176 WaylandPointer<org_kde_plasma_activation_feedback, org_kde_plasma_activation_feedback_destroy> feedback; 1177 EventQueue *queue = nullptr; 1178 1179 void setup(org_kde_plasma_activation_feedback *feedback); 1180 1181 private: 1182 static void activationCallback(void *data, struct org_kde_plasma_activation_feedback *feedback, struct org_kde_plasma_activation *id); 1183 1184 static struct org_kde_plasma_activation_feedback_listener s_listener; 1185 PlasmaActivationFeedback *q; 1186 }; 1187 1188 PlasmaActivationFeedback::Private::Private(PlasmaActivationFeedback *q) 1189 : q(q) 1190 { 1191 } 1192 1193 org_kde_plasma_activation_feedback_listener PlasmaActivationFeedback::Private::s_listener = { 1194 activationCallback, 1195 }; 1196 1197 void PlasmaActivationFeedback::Private::activationCallback(void *data, org_kde_plasma_activation_feedback *interface, struct org_kde_plasma_activation *id) 1198 { 1199 auto feedbackPrivate = reinterpret_cast<PlasmaActivationFeedback::Private *>(data); 1200 Q_ASSERT(feedbackPrivate->feedback == interface); 1201 auto activation = new PlasmaActivation(feedbackPrivate->q, id); 1202 Q_EMIT feedbackPrivate->q->activation(activation); 1203 } 1204 1205 void PlasmaActivationFeedback::Private::setup(org_kde_plasma_activation_feedback *m) 1206 { 1207 Q_ASSERT(!feedback); 1208 Q_ASSERT(m); 1209 feedback.setup(m); 1210 org_kde_plasma_activation_feedback_add_listener(m, &s_listener, this); 1211 } 1212 1213 PlasmaActivationFeedback::PlasmaActivationFeedback(QObject *parent) 1214 : QObject(parent) 1215 , d(new Private(this)) 1216 { 1217 } 1218 1219 PlasmaActivationFeedback::~PlasmaActivationFeedback() 1220 { 1221 release(); 1222 } 1223 1224 void PlasmaActivationFeedback::destroy() 1225 { 1226 if (!d->feedback) { 1227 return; 1228 } 1229 Q_EMIT interfaceAboutToBeDestroyed(); 1230 d->feedback.destroy(); 1231 } 1232 1233 void PlasmaActivationFeedback::release() 1234 { 1235 if (!d->feedback) { 1236 return; 1237 } 1238 Q_EMIT interfaceAboutToBeReleased(); 1239 d->feedback.release(); 1240 } 1241 1242 void PlasmaActivationFeedback::setup(org_kde_plasma_activation_feedback *wm) 1243 { 1244 d->setup(wm); 1245 } 1246 1247 void PlasmaActivationFeedback::setEventQueue(EventQueue *queue) 1248 { 1249 d->queue = queue; 1250 } 1251 1252 EventQueue *PlasmaActivationFeedback::eventQueue() 1253 { 1254 return d->queue; 1255 } 1256 1257 bool PlasmaActivationFeedback::isValid() const 1258 { 1259 return d->feedback.isValid(); 1260 } 1261 1262 PlasmaActivationFeedback::operator org_kde_plasma_activation_feedback *() 1263 { 1264 return d->feedback; 1265 } 1266 1267 PlasmaActivationFeedback::operator org_kde_plasma_activation_feedback *() const 1268 { 1269 return d->feedback; 1270 } 1271 1272 class Q_DECL_HIDDEN PlasmaActivation::Private 1273 { 1274 public: 1275 Private(org_kde_plasma_activation *activation, PlasmaActivation *q) 1276 : activation(activation) 1277 { 1278 org_kde_plasma_activation_add_listener(activation, &s_listener, q); 1279 } 1280 1281 static PlasmaActivation *cast(void *data) 1282 { 1283 return reinterpret_cast<PlasmaActivation *>(data); 1284 } 1285 WaylandPointer<org_kde_plasma_activation, org_kde_plasma_activation_destroy> activation; 1286 1287 static org_kde_plasma_activation_listener s_listener; 1288 static void app_idCallback(void *data, struct org_kde_plasma_activation *org_kde_plasma_activation, const char *app_id); 1289 static void finishedCallback(void *data, struct org_kde_plasma_activation *org_kde_plasma_activation); 1290 }; 1291 1292 org_kde_plasma_activation_listener PlasmaActivation::Private::s_listener = { 1293 app_idCallback, 1294 finishedCallback, 1295 }; 1296 1297 void PlasmaActivation::Private::app_idCallback(void *data, org_kde_plasma_activation *activation, const char *appId) 1298 { 1299 Q_UNUSED(activation) 1300 Q_EMIT cast(data)->applicationId(QString::fromUtf8(appId)); 1301 } 1302 1303 void PlasmaActivation::Private::finishedCallback(void *data, org_kde_plasma_activation *) 1304 { 1305 auto q = cast(data); 1306 Q_EMIT q->finished(); 1307 Q_EMIT q->deleteLater(); 1308 q->d->activation.release(); 1309 } 1310 1311 PlasmaActivation::PlasmaActivation(PlasmaActivationFeedback *parent, org_kde_plasma_activation *activation) 1312 : QObject(parent) 1313 , d(new PlasmaActivation::Private(activation, this)) 1314 { 1315 } 1316 1317 PlasmaActivation::~PlasmaActivation() = default; 1318 } 1319 } 1320 1321 #include "moc_plasmawindowmanagement.cpp"