File indexing completed on 2024-05-19 16:35:23
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_interface.h" 0007 #include "display.h" 0008 0009 #include <QDebug> 0010 #include <QTimer> 0011 0012 #include <qwayland-server-org-kde-plasma-virtual-desktop.h> 0013 #include <wayland-server.h> 0014 0015 namespace KWaylandServer 0016 { 0017 static const quint32 s_version = 2; 0018 0019 class PlasmaVirtualDesktopInterfacePrivate : public QtWaylandServer::org_kde_plasma_virtual_desktop 0020 { 0021 public: 0022 PlasmaVirtualDesktopInterfacePrivate(PlasmaVirtualDesktopInterface *q, PlasmaVirtualDesktopManagementInterface *c); 0023 ~PlasmaVirtualDesktopInterfacePrivate(); 0024 0025 PlasmaVirtualDesktopInterface *q; 0026 PlasmaVirtualDesktopManagementInterface *vdm; 0027 0028 QString id; 0029 QString name; 0030 bool active = false; 0031 0032 protected: 0033 void org_kde_plasma_virtual_desktop_bind_resource(Resource *resource) override; 0034 void org_kde_plasma_virtual_desktop_request_activate(Resource *resource) override; 0035 }; 0036 0037 class PlasmaVirtualDesktopManagementInterfacePrivate : public QtWaylandServer::org_kde_plasma_virtual_desktop_management 0038 { 0039 public: 0040 PlasmaVirtualDesktopManagementInterfacePrivate(PlasmaVirtualDesktopManagementInterface *_q, Display *display); 0041 0042 QList<PlasmaVirtualDesktopInterface *> desktops; 0043 quint32 rows = 0; 0044 quint32 columns = 0; 0045 PlasmaVirtualDesktopManagementInterface *q; 0046 0047 inline QList<PlasmaVirtualDesktopInterface *>::const_iterator constFindDesktop(const QString &id); 0048 inline QList<PlasmaVirtualDesktopInterface *>::iterator findDesktop(const QString &id); 0049 0050 protected: 0051 void org_kde_plasma_virtual_desktop_management_get_virtual_desktop(Resource *resource, uint32_t id, const QString &desktop_id) override; 0052 void org_kde_plasma_virtual_desktop_management_request_create_virtual_desktop(Resource *resource, const QString &name, uint32_t position) override; 0053 void org_kde_plasma_virtual_desktop_management_request_remove_virtual_desktop(Resource *resource, const QString &desktop_id) override; 0054 void org_kde_plasma_virtual_desktop_management_bind_resource(Resource *resource) override; 0055 }; 0056 0057 inline QList<PlasmaVirtualDesktopInterface *>::const_iterator PlasmaVirtualDesktopManagementInterfacePrivate::constFindDesktop(const QString &id) 0058 { 0059 return std::find_if(desktops.constBegin(), desktops.constEnd(), [id](const PlasmaVirtualDesktopInterface *desk) { 0060 return desk->id() == id; 0061 }); 0062 } 0063 0064 inline QList<PlasmaVirtualDesktopInterface *>::iterator PlasmaVirtualDesktopManagementInterfacePrivate::findDesktop(const QString &id) 0065 { 0066 return std::find_if(desktops.begin(), desktops.end(), [id](const PlasmaVirtualDesktopInterface *desk) { 0067 return desk->id() == id; 0068 }); 0069 } 0070 0071 void PlasmaVirtualDesktopManagementInterfacePrivate::org_kde_plasma_virtual_desktop_management_get_virtual_desktop(Resource *resource, 0072 uint32_t id, 0073 const QString &desktop_id) 0074 { 0075 auto i = constFindDesktop(desktop_id); 0076 if (i == desktops.constEnd()) { 0077 return; 0078 } 0079 0080 (*i)->d->add(resource->client(), id, resource->version()); 0081 } 0082 0083 void PlasmaVirtualDesktopManagementInterfacePrivate::org_kde_plasma_virtual_desktop_management_request_create_virtual_desktop(Resource *resource, 0084 const QString &name, 0085 uint32_t position) 0086 { 0087 Q_EMIT q->desktopCreateRequested(name, std::clamp<quint32>(position, 0, desktops.size())); 0088 } 0089 0090 void PlasmaVirtualDesktopManagementInterfacePrivate::org_kde_plasma_virtual_desktop_management_request_remove_virtual_desktop(Resource *resource, 0091 const QString &desktop_id) 0092 { 0093 Q_EMIT q->desktopRemoveRequested(desktop_id); 0094 } 0095 0096 PlasmaVirtualDesktopManagementInterfacePrivate::PlasmaVirtualDesktopManagementInterfacePrivate(PlasmaVirtualDesktopManagementInterface *_q, Display *display) 0097 : QtWaylandServer::org_kde_plasma_virtual_desktop_management(*display, s_version) 0098 , q(_q) 0099 { 0100 } 0101 0102 void PlasmaVirtualDesktopManagementInterfacePrivate::org_kde_plasma_virtual_desktop_management_bind_resource(Resource *resource) 0103 { 0104 quint32 i = 0; 0105 for (auto it = desktops.constBegin(); it != desktops.constEnd(); ++it) { 0106 send_desktop_created(resource->handle, (*it)->id(), i++); 0107 } 0108 0109 if (resource->version() >= ORG_KDE_PLASMA_VIRTUAL_DESKTOP_MANAGEMENT_ROWS_SINCE_VERSION) { 0110 send_rows(resource->handle, rows); 0111 } 0112 0113 send_done(resource->handle); 0114 } 0115 0116 PlasmaVirtualDesktopManagementInterface::PlasmaVirtualDesktopManagementInterface(Display *display, QObject *parent) 0117 : QObject(parent) 0118 , d(new PlasmaVirtualDesktopManagementInterfacePrivate(this, display)) 0119 { 0120 } 0121 0122 PlasmaVirtualDesktopManagementInterface::~PlasmaVirtualDesktopManagementInterface() 0123 { 0124 qDeleteAll(d->desktops); 0125 } 0126 0127 void PlasmaVirtualDesktopManagementInterface::setRows(quint32 rows) 0128 { 0129 if (rows == 0 || d->rows == rows) { 0130 return; 0131 } 0132 0133 d->rows = rows; 0134 0135 const auto clientResources = d->resourceMap(); 0136 for (auto resource : clientResources) { 0137 if (resource->version() < ORG_KDE_PLASMA_VIRTUAL_DESKTOP_MANAGEMENT_ROWS_SINCE_VERSION) { 0138 continue; 0139 } 0140 d->send_rows(resource->handle, rows); 0141 } 0142 } 0143 0144 PlasmaVirtualDesktopInterface *PlasmaVirtualDesktopManagementInterface::desktop(const QString &id) 0145 { 0146 auto i = d->constFindDesktop(id); 0147 if (i != d->desktops.constEnd()) { 0148 return *i; 0149 } 0150 return nullptr; 0151 } 0152 0153 PlasmaVirtualDesktopInterface *PlasmaVirtualDesktopManagementInterface::createDesktop(const QString &id, quint32 position) 0154 { 0155 auto i = d->constFindDesktop(id); 0156 if (i != d->desktops.constEnd()) { 0157 return *i; 0158 } 0159 0160 const quint32 actualPosition = std::min(position, (quint32)d->desktops.count()); 0161 0162 auto desktop = new PlasmaVirtualDesktopInterface(this); 0163 desktop->d->id = id; 0164 0165 const auto desktopClientResources = desktop->d->resourceMap(); 0166 for (auto resource : desktopClientResources) { 0167 desktop->d->send_desktop_id(resource->handle, id); 0168 } 0169 0170 // activate the first desktop TODO: to be done here? 0171 if (d->desktops.isEmpty()) { 0172 desktop->d->active = true; 0173 } 0174 0175 d->desktops.insert(actualPosition, desktop); 0176 0177 const auto clientResources = d->resourceMap(); 0178 for (auto resource : clientResources) { 0179 d->send_desktop_created(resource->handle, id, actualPosition); 0180 } 0181 0182 return desktop; 0183 } 0184 0185 void PlasmaVirtualDesktopManagementInterface::removeDesktop(const QString &id) 0186 { 0187 auto deskIt = d->findDesktop(id); 0188 if (deskIt == d->desktops.end()) { 0189 return; 0190 } 0191 0192 const auto desktopClientResources = (*deskIt)->d->resourceMap(); 0193 for (auto resource : desktopClientResources) { 0194 (*deskIt)->d->send_removed(resource->handle); 0195 } 0196 0197 const auto clientResources = d->resourceMap(); 0198 for (auto resource : clientResources) { 0199 d->send_desktop_removed(resource->handle, id); 0200 } 0201 0202 (*deskIt)->deleteLater(); 0203 d->desktops.erase(deskIt); 0204 } 0205 0206 QList<PlasmaVirtualDesktopInterface *> PlasmaVirtualDesktopManagementInterface::desktops() const 0207 { 0208 return d->desktops; 0209 } 0210 0211 void PlasmaVirtualDesktopManagementInterface::sendDone() 0212 { 0213 const auto clientResources = d->resourceMap(); 0214 for (auto resource : clientResources) { 0215 d->send_done(resource->handle); 0216 } 0217 } 0218 0219 //// PlasmaVirtualDesktopInterface 0220 0221 void PlasmaVirtualDesktopInterfacePrivate::org_kde_plasma_virtual_desktop_request_activate(Resource *resource) 0222 { 0223 Q_EMIT q->activateRequested(); 0224 } 0225 0226 PlasmaVirtualDesktopInterfacePrivate::PlasmaVirtualDesktopInterfacePrivate(PlasmaVirtualDesktopInterface *q, PlasmaVirtualDesktopManagementInterface *c) 0227 : QtWaylandServer::org_kde_plasma_virtual_desktop() 0228 , q(q) 0229 , vdm(c) 0230 { 0231 } 0232 0233 PlasmaVirtualDesktopInterfacePrivate::~PlasmaVirtualDesktopInterfacePrivate() 0234 { 0235 const auto clientResources = resourceMap(); 0236 for (Resource *resource : clientResources) { 0237 send_removed(resource->handle); 0238 wl_resource_destroy(resource->handle); 0239 } 0240 } 0241 0242 void PlasmaVirtualDesktopInterfacePrivate::org_kde_plasma_virtual_desktop_bind_resource(Resource *resource) 0243 { 0244 send_desktop_id(resource->handle, id); 0245 0246 if (!name.isEmpty()) { 0247 send_name(resource->handle, name); 0248 } 0249 0250 if (active) { 0251 send_activated(resource->handle); 0252 } 0253 } 0254 0255 PlasmaVirtualDesktopInterface::PlasmaVirtualDesktopInterface(PlasmaVirtualDesktopManagementInterface *parent) 0256 : QObject() 0257 , d(new PlasmaVirtualDesktopInterfacePrivate(this, parent)) 0258 { 0259 } 0260 0261 PlasmaVirtualDesktopInterface::~PlasmaVirtualDesktopInterface() 0262 { 0263 d->vdm->removeDesktop(id()); 0264 } 0265 0266 QString PlasmaVirtualDesktopInterface::id() const 0267 { 0268 return d->id; 0269 } 0270 0271 void PlasmaVirtualDesktopInterface::setName(const QString &name) 0272 { 0273 if (d->name == name) { 0274 return; 0275 } 0276 0277 d->name = name; 0278 0279 const auto clientResources = d->resourceMap(); 0280 for (auto resource : clientResources) { 0281 d->send_name(resource->handle, name); 0282 } 0283 } 0284 0285 QString PlasmaVirtualDesktopInterface::name() const 0286 { 0287 return d->name; 0288 } 0289 0290 void PlasmaVirtualDesktopInterface::setActive(bool active) 0291 { 0292 if (d->active == active) { 0293 return; 0294 } 0295 0296 d->active = active; 0297 const auto clientResources = d->resourceMap(); 0298 0299 if (active) { 0300 for (auto resource : clientResources) { 0301 d->send_activated(resource->handle); 0302 } 0303 } else { 0304 for (auto resource : clientResources) { 0305 d->send_deactivated(resource->handle); 0306 } 0307 } 0308 } 0309 0310 bool PlasmaVirtualDesktopInterface::isActive() const 0311 { 0312 return d->active; 0313 } 0314 0315 void PlasmaVirtualDesktopInterface::sendDone() 0316 { 0317 const auto clientResources = d->resourceMap(); 0318 for (auto resource : clientResources) { 0319 d->send_done(resource->handle); 0320 } 0321 } 0322 0323 }