Changeset View
Changeset View
Standalone View
Standalone View
libtaskmanager/waylandtasksmodel.cpp
Show All 14 Lines | |||||
15 | Lesser General Public License for more details. | 15 | Lesser General Public License for more details. | ||
16 | 16 | | |||
17 | You should have received a copy of the GNU Lesser General Public | 17 | You should have received a copy of the GNU Lesser General Public | ||
18 | License along with this library. If not, see <http://www.gnu.org/licenses/>. | 18 | License along with this library. If not, see <http://www.gnu.org/licenses/>. | ||
19 | *********************************************************************/ | 19 | *********************************************************************/ | ||
20 | 20 | | |||
21 | #include "waylandtasksmodel.h" | 21 | #include "waylandtasksmodel.h" | ||
22 | #include "tasktools.h" | 22 | #include "tasktools.h" | ||
23 | #include "virtualdesktopinfo.h" | ||||
23 | 24 | | |||
24 | #include <KActivities/ResourceInstance> | 25 | #include <KActivities/ResourceInstance> | ||
25 | #include <KDirWatch> | 26 | #include <KDirWatch> | ||
26 | #include <KRun> | 27 | #include <KRun> | ||
27 | #include <KService> | 28 | #include <KService> | ||
28 | #include <KSharedConfig> | 29 | #include <KSharedConfig> | ||
29 | #include <KWayland/Client/connection_thread.h> | 30 | #include <KWayland/Client/connection_thread.h> | ||
30 | #include <KWayland/Client/plasmawindowmanagement.h> | 31 | #include <KWayland/Client/plasmawindowmanagement.h> | ||
31 | #include <KWayland/Client/registry.h> | 32 | #include <KWayland/Client/registry.h> | ||
32 | #include <KWayland/Client/surface.h> | 33 | #include <KWayland/Client/surface.h> | ||
33 | #include <KWindowSystem> | 34 | #include <KWindowSystem> | ||
34 | 35 | | |||
35 | #include <QGuiApplication> | 36 | #include <QGuiApplication> | ||
37 | #include <QMimeData> | ||||
36 | #include <QQuickItem> | 38 | #include <QQuickItem> | ||
37 | #include <QQuickWindow> | 39 | #include <QQuickWindow> | ||
38 | #include <QSet> | 40 | #include <QSet> | ||
39 | #include <QUrl> | 41 | #include <QUrl> | ||
42 | #include <QUuid> | ||||
40 | #include <QWindow> | 43 | #include <QWindow> | ||
41 | 44 | | |||
42 | namespace TaskManager | 45 | namespace TaskManager | ||
43 | { | 46 | { | ||
44 | 47 | | |||
45 | class Q_DECL_HIDDEN WaylandTasksModel::Private | 48 | class Q_DECL_HIDDEN WaylandTasksModel::Private | ||
46 | { | 49 | { | ||
47 | public: | 50 | public: | ||
48 | Private(WaylandTasksModel *q); | 51 | Private(WaylandTasksModel *q); | ||
49 | QList<KWayland::Client::PlasmaWindow*> windows; | 52 | QList<KWayland::Client::PlasmaWindow*> windows; | ||
50 | QHash<KWayland::Client::PlasmaWindow*, AppData> appDataCache; | 53 | QHash<KWayland::Client::PlasmaWindow*, AppData> appDataCache; | ||
51 | KWayland::Client::PlasmaWindowManagement *windowManagement = nullptr; | 54 | KWayland::Client::PlasmaWindowManagement *windowManagement = nullptr; | ||
52 | KSharedConfig::Ptr rulesConfig; | 55 | KSharedConfig::Ptr rulesConfig; | ||
53 | KDirWatch *configWatcher = nullptr; | 56 | KDirWatch *configWatcher = nullptr; | ||
57 | VirtualDesktopInfo *virtualDesktopInfo = nullptr; | ||||
58 | static QUuid uuid; | ||||
54 | 59 | | |||
55 | void init(); | 60 | void init(); | ||
56 | void initWayland(); | 61 | void initWayland(); | ||
57 | void addWindow(KWayland::Client::PlasmaWindow *window); | 62 | void addWindow(KWayland::Client::PlasmaWindow *window); | ||
58 | 63 | | |||
59 | AppData appData(KWayland::Client::PlasmaWindow *window); | 64 | AppData appData(KWayland::Client::PlasmaWindow *window); | ||
60 | 65 | | |||
61 | QIcon icon(KWayland::Client::PlasmaWindow *window); | 66 | QIcon icon(KWayland::Client::PlasmaWindow *window); | ||
62 | 67 | | |||
68 | static QString mimeType(); | ||||
69 | static QString groupMimeType(); | ||||
70 | | ||||
63 | void dataChanged(KWayland::Client::PlasmaWindow *window, int role); | 71 | void dataChanged(KWayland::Client::PlasmaWindow *window, int role); | ||
64 | void dataChanged(KWayland::Client::PlasmaWindow *window, const QVector<int> &roles); | 72 | void dataChanged(KWayland::Client::PlasmaWindow *window, const QVector<int> &roles); | ||
65 | 73 | | |||
66 | private: | 74 | private: | ||
67 | WaylandTasksModel *q; | 75 | WaylandTasksModel *q; | ||
68 | }; | 76 | }; | ||
69 | 77 | | |||
78 | QUuid WaylandTasksModel::Private::uuid = QUuid::createUuid(); | ||||
79 | | ||||
70 | WaylandTasksModel::Private::Private(WaylandTasksModel *q) | 80 | WaylandTasksModel::Private::Private(WaylandTasksModel *q) | ||
71 | : q(q) | 81 | : q(q) | ||
72 | { | 82 | { | ||
73 | } | 83 | } | ||
74 | 84 | | |||
75 | void WaylandTasksModel::Private::init() | 85 | void WaylandTasksModel::Private::init() | ||
76 | { | 86 | { | ||
77 | auto clearCacheAndRefresh = [this] { | 87 | auto clearCacheAndRefresh = [this] { | ||
Show All 22 Lines | 109 | auto rulesConfigChange = [this, clearCacheAndRefresh] { | |||
100 | rulesConfig->reparseConfiguration(); | 110 | rulesConfig->reparseConfiguration(); | ||
101 | clearCacheAndRefresh(); | 111 | clearCacheAndRefresh(); | ||
102 | }; | 112 | }; | ||
103 | 113 | | |||
104 | QObject::connect(configWatcher, &KDirWatch::dirty, rulesConfigChange); | 114 | QObject::connect(configWatcher, &KDirWatch::dirty, rulesConfigChange); | ||
105 | QObject::connect(configWatcher, &KDirWatch::created, rulesConfigChange); | 115 | QObject::connect(configWatcher, &KDirWatch::created, rulesConfigChange); | ||
106 | QObject::connect(configWatcher, &KDirWatch::deleted, rulesConfigChange); | 116 | QObject::connect(configWatcher, &KDirWatch::deleted, rulesConfigChange); | ||
107 | 117 | | |||
118 | virtualDesktopInfo = new VirtualDesktopInfo(q); | ||||
119 | | ||||
108 | initWayland(); | 120 | initWayland(); | ||
109 | } | 121 | } | ||
110 | 122 | | |||
111 | void WaylandTasksModel::Private::initWayland() | 123 | void WaylandTasksModel::Private::initWayland() | ||
112 | { | 124 | { | ||
113 | if (!KWindowSystem::isPlatformWayland()) { | 125 | if (!KWindowSystem::isPlatformWayland()) { | ||
114 | return; | 126 | return; | ||
115 | } | 127 | } | ||
▲ Show 20 Lines • Show All 138 Lines • ▼ Show 20 Line(s) | 166 | { | |||
254 | QObject::connect(window, &KWayland::Client::PlasmaWindow::keepBelowChanged, q, | 266 | QObject::connect(window, &KWayland::Client::PlasmaWindow::keepBelowChanged, q, | ||
255 | [window, this] { this->dataChanged(window, IsKeepBelow); } | 267 | [window, this] { this->dataChanged(window, IsKeepBelow); } | ||
256 | ); | 268 | ); | ||
257 | 269 | | |||
258 | QObject::connect(window, &KWayland::Client::PlasmaWindow::shadeableChanged, q, | 270 | QObject::connect(window, &KWayland::Client::PlasmaWindow::shadeableChanged, q, | ||
259 | [window, this] { this->dataChanged(window, IsShadeable); } | 271 | [window, this] { this->dataChanged(window, IsShadeable); } | ||
260 | ); | 272 | ); | ||
261 | 273 | | |||
262 | QObject::connect(window, &KWayland::Client::PlasmaWindow::virtualDesktopChangeableChanged, q, | 274 | // FIXME | ||
263 | [window, this] { this->dataChanged(window, IsVirtualDesktopChangeable); } | 275 | // QObject::connect(window, &KWayland::Client::PlasmaWindow::virtualDesktopChangeableChanged, q, | ||
264 | ); | 276 | // // TODO: This is marked deprecated in KWayland, but (IMHO) shouldn't be. | ||
277 | // [window, this] { this->dataChanged(window, IsVirtualDesktopsChangeable); } | ||||
278 | // ); | ||||
279 | | ||||
280 | QObject::connect(window, &KWayland::Client::PlasmaWindow::plasmaVirtualDesktopEntered, q, | ||||
281 | [window, this] { | ||||
282 | this->dataChanged(window, VirtualDesktops); | ||||
265 | 283 | | |||
266 | QObject::connect(window, &KWayland::Client::PlasmaWindow::virtualDesktopChanged, q, | 284 | // If the count has changed from 0, the window may no longer be on all virtual | ||
267 | [window, this] { this->dataChanged(window, VirtualDesktop); } | 285 | // desktops. | ||
286 | if (window->plasmaVirtualDesktops().count() > 0) { | ||||
287 | this->dataChanged(window, VirtualDesktops); | ||||
288 | } | ||||
289 | } | ||||
268 | ); | 290 | ); | ||
269 | 291 | | |||
270 | QObject::connect(window, &KWayland::Client::PlasmaWindow::onAllDesktopsChanged, q, | 292 | QObject::connect(window, &KWayland::Client::PlasmaWindow::plasmaVirtualDesktopLeft, q, | ||
271 | [window, this] { this->dataChanged(window, IsOnAllVirtualDesktops); } | 293 | [window, this] { | ||
294 | this->dataChanged(window, VirtualDesktops); | ||||
295 | | ||||
296 | // If the count has changed to 0, the window is now on all virtual desktops. | ||||
297 | if (window->plasmaVirtualDesktops().count() == 0) { | ||||
298 | this->dataChanged(window, VirtualDesktops); | ||||
299 | } | ||||
300 | } | ||||
272 | ); | 301 | ); | ||
273 | 302 | | |||
274 | QObject::connect(window, &KWayland::Client::PlasmaWindow::geometryChanged, q, | 303 | QObject::connect(window, &KWayland::Client::PlasmaWindow::geometryChanged, q, | ||
275 | [window, this] { this->dataChanged(window, QVector<int>{Geometry, ScreenGeometry}); } | 304 | [window, this] { this->dataChanged(window, QVector<int>{Geometry, ScreenGeometry}); } | ||
276 | ); | 305 | ); | ||
277 | 306 | | |||
278 | QObject::connect(window, &KWayland::Client::PlasmaWindow::demandsAttentionChanged, q, | 307 | QObject::connect(window, &KWayland::Client::PlasmaWindow::demandsAttentionChanged, q, | ||
279 | [window, this] { this->dataChanged(window, IsDemandingAttention); } | 308 | [window, this] { this->dataChanged(window, IsDemandingAttention); } | ||
Show All 28 Lines | 336 | if (!app.icon.isNull()) { | |||
308 | return app.icon; | 337 | return app.icon; | ||
309 | } | 338 | } | ||
310 | 339 | | |||
311 | appDataCache[window].icon = window->icon(); | 340 | appDataCache[window].icon = window->icon(); | ||
312 | 341 | | |||
313 | return window->icon(); | 342 | return window->icon(); | ||
314 | } | 343 | } | ||
315 | 344 | | |||
345 | QString WaylandTasksModel::Private::mimeType() | ||||
346 | { | ||||
347 | // Use a unique format id to make this intentionally useless for | ||||
348 | // cross-process DND. | ||||
349 | return QString("windowsystem/winid+" + uuid.toString().toAscii()); | ||||
350 | } | ||||
351 | | ||||
352 | QString WaylandTasksModel::Private::groupMimeType() | ||||
353 | { | ||||
354 | // Use a unique format id to make this intentionally useless for | ||||
355 | // cross-process DND. | ||||
356 | return QString("windowsystem/multiple-winids+" + uuid.toString().toAscii()); | ||||
357 | } | ||||
358 | | ||||
316 | void WaylandTasksModel::Private::dataChanged(KWayland::Client::PlasmaWindow *window, int role) | 359 | void WaylandTasksModel::Private::dataChanged(KWayland::Client::PlasmaWindow *window, int role) | ||
317 | { | 360 | { | ||
318 | QModelIndex idx = q->index(windows.indexOf(window)); | 361 | QModelIndex idx = q->index(windows.indexOf(window)); | ||
319 | emit q->dataChanged(idx, idx, QVector<int>{role}); | 362 | emit q->dataChanged(idx, idx, QVector<int>{role}); | ||
320 | } | 363 | } | ||
321 | 364 | | |||
322 | void WaylandTasksModel::Private::dataChanged(KWayland::Client::PlasmaWindow *window, const QVector<int> &roles) | 365 | void WaylandTasksModel::Private::dataChanged(KWayland::Client::PlasmaWindow *window, const QVector<int> &roles) | ||
323 | { | 366 | { | ||
Show All 31 Lines | 397 | } else { | |||
355 | return id; | 398 | return id; | ||
356 | } | 399 | } | ||
357 | } else if (role == AppName) { | 400 | } else if (role == AppName) { | ||
358 | return d->appData(window).name; | 401 | return d->appData(window).name; | ||
359 | } else if (role == GenericName) { | 402 | } else if (role == GenericName) { | ||
360 | return d->appData(window).genericName; | 403 | return d->appData(window).genericName; | ||
361 | } else if (role == LauncherUrl || role == LauncherUrlWithoutIcon) { | 404 | } else if (role == LauncherUrl || role == LauncherUrlWithoutIcon) { | ||
362 | return d->appData(window).url; | 405 | return d->appData(window).url; | ||
406 | } else if (role == WinIdList) { | ||||
407 | return QVariantList() << window->internalId(); | ||||
408 | } else if (role == MimeType) { | ||||
409 | return d->mimeType(); | ||||
410 | } else if (role == MimeData) { | ||||
411 | return QByteArray::number(window->internalId()); | ||||
363 | } else if (role == IsWindow) { | 412 | } else if (role == IsWindow) { | ||
364 | return true; | 413 | return true; | ||
365 | } else if (role == IsActive) { | 414 | } else if (role == IsActive) { | ||
366 | return window->isActive(); | 415 | return window->isActive(); | ||
367 | } else if (role == IsClosable) { | 416 | } else if (role == IsClosable) { | ||
368 | return window->isCloseable(); | 417 | return window->isCloseable(); | ||
369 | } else if (role == IsMovable) { | 418 | } else if (role == IsMovable) { | ||
370 | return window->isMovable(); | 419 | return window->isMovable(); | ||
Show All 14 Lines | |||||
385 | } else if (role == IsFullScreenable) { | 434 | } else if (role == IsFullScreenable) { | ||
386 | return window->isFullscreenable(); | 435 | return window->isFullscreenable(); | ||
387 | } else if (role == IsFullScreen) { | 436 | } else if (role == IsFullScreen) { | ||
388 | return window->isFullscreen(); | 437 | return window->isFullscreen(); | ||
389 | } else if (role == IsShadeable) { | 438 | } else if (role == IsShadeable) { | ||
390 | return window->isShadeable(); | 439 | return window->isShadeable(); | ||
391 | } else if (role == IsShaded) { | 440 | } else if (role == IsShaded) { | ||
392 | return window->isShaded(); | 441 | return window->isShaded(); | ||
393 | } else if (role == IsVirtualDesktopChangeable) { | 442 | } else if (role == IsVirtualDesktopsChangeable) { | ||
394 | return window->isVirtualDesktopChangeable(); | 443 | // FIXME Currently not implemented in KWayland. | ||
395 | } else if (role == VirtualDesktop) { | 444 | return true; | ||
396 | return window->virtualDesktop(); | 445 | } else if (role == VirtualDesktops) { | ||
446 | return window->plasmaVirtualDesktops(); | ||||
397 | } else if (role == IsOnAllVirtualDesktops) { | 447 | } else if (role == IsOnAllVirtualDesktops) { | ||
398 | return window->isOnAllDesktops(); | 448 | return window->plasmaVirtualDesktops().isEmpty(); | ||
399 | } else if (role == Geometry) { | 449 | } else if (role == Geometry) { | ||
mart: note that the protocol ensures the list of desktops is empty when is on all virtual desktops… | |||||
400 | return window->geometry(); | 450 | return window->geometry(); | ||
401 | } else if (role == ScreenGeometry) { | 451 | } else if (role == ScreenGeometry) { | ||
402 | return screenGeometry(window->geometry().center()); | 452 | return screenGeometry(window->geometry().center()); | ||
403 | } else if (role == Activities) { | 453 | } else if (role == Activities) { | ||
404 | // FIXME Implement. | 454 | // FIXME Implement. | ||
405 | } else if (role == IsDemandingAttention) { | 455 | } else if (role == IsDemandingAttention) { | ||
406 | return window->isDemandingAttention(); | 456 | return window->isDemandingAttention(); | ||
407 | } else if (role == SkipTaskbar) { | 457 | } else if (role == SkipTaskbar) { | ||
▲ Show 20 Lines • Show All 54 Lines • ▼ Show 20 Line(s) | 511 | if (!index.isValid() || index.model() != this || index.row() < 0 || index.row() >= d->windows.count()) { | |||
462 | return; | 512 | return; | ||
463 | } | 513 | } | ||
464 | 514 | | |||
465 | d->windows.at(index.row())->requestClose(); | 515 | d->windows.at(index.row())->requestClose(); | ||
466 | } | 516 | } | ||
467 | 517 | | |||
468 | void WaylandTasksModel::requestMove(const QModelIndex &index) | 518 | void WaylandTasksModel::requestMove(const QModelIndex &index) | ||
469 | { | 519 | { | ||
470 | // FIXME Move-to-desktop logic from XWindows version. (See also others.) | | |||
471 | | ||||
472 | if (!index.isValid() || index.model() != this || index.row() < 0 || index.row() >= d->windows.count()) { | 520 | if (!index.isValid() || index.model() != this || index.row() < 0 || index.row() >= d->windows.count()) { | ||
473 | return; | 521 | return; | ||
474 | } | 522 | } | ||
475 | 523 | | |||
476 | d->windows.at(index.row())->requestMove(); | 524 | KWayland::Client::PlasmaWindow *window = d->windows.at(index.row()); | ||
525 | | ||||
526 | const QString ¤tDesktop = d->virtualDesktopInfo->currentDesktop().toString(); | ||||
527 | | ||||
528 | if (!currentDesktop.isEmpty()) { | ||||
529 | window->requestEnterVirtualDesktop(currentDesktop); | ||||
530 | } | ||||
531 | | ||||
532 | window->requestMove(); | ||||
477 | } | 533 | } | ||
478 | 534 | | |||
479 | void WaylandTasksModel::requestResize(const QModelIndex &index) | 535 | void WaylandTasksModel::requestResize(const QModelIndex &index) | ||
480 | { | 536 | { | ||
481 | // FIXME Move-to-desktop logic from XWindows version. (See also others.) | | |||
482 | | ||||
483 | if (!index.isValid() || index.model() != this || index.row() < 0 || index.row() >= d->windows.count()) { | 537 | if (!index.isValid() || index.model() != this || index.row() < 0 || index.row() >= d->windows.count()) { | ||
484 | return; | 538 | return; | ||
485 | } | 539 | } | ||
486 | 540 | | |||
487 | d->windows.at(index.row())->requestResize(); | 541 | KWayland::Client::PlasmaWindow *window = d->windows.at(index.row()); | ||
542 | | ||||
543 | const QString ¤tDesktop = d->virtualDesktopInfo->currentDesktop().toString(); | ||||
544 | | ||||
545 | if (!currentDesktop.isEmpty()) { | ||||
546 | window->requestEnterVirtualDesktop(currentDesktop); | ||||
547 | } | ||||
548 | | ||||
549 | window->requestResize(); | ||||
488 | } | 550 | } | ||
489 | 551 | | |||
490 | void WaylandTasksModel::requestToggleMinimized(const QModelIndex &index) | 552 | void WaylandTasksModel::requestToggleMinimized(const QModelIndex &index) | ||
491 | { | 553 | { | ||
492 | // FIXME Move-to-desktop logic from XWindows version. (See also others.) | | |||
493 | | ||||
494 | if (!index.isValid() || index.model() != this || index.row() < 0 || index.row() >= d->windows.count()) { | 554 | if (!index.isValid() || index.model() != this || index.row() < 0 || index.row() >= d->windows.count()) { | ||
495 | return; | 555 | return; | ||
496 | } | 556 | } | ||
497 | 557 | | |||
498 | d->windows.at(index.row())->requestToggleMinimized(); | 558 | KWayland::Client::PlasmaWindow *window = d->windows.at(index.row()); | ||
559 | | ||||
560 | const QString ¤tDesktop = d->virtualDesktopInfo->currentDesktop().toString(); | ||||
561 | | ||||
562 | if (!currentDesktop.isEmpty()) { | ||||
563 | window->requestEnterVirtualDesktop(currentDesktop); | ||||
564 | } | ||||
565 | | ||||
566 | window->requestToggleMinimized(); | ||||
499 | } | 567 | } | ||
500 | 568 | | |||
501 | void WaylandTasksModel::requestToggleMaximized(const QModelIndex &index) | 569 | void WaylandTasksModel::requestToggleMaximized(const QModelIndex &index) | ||
502 | { | 570 | { | ||
503 | // FIXME Move-to-desktop logic from XWindows version. (See also others.) | | |||
504 | | ||||
505 | if (!index.isValid() || index.model() != this || index.row() < 0 || index.row() >= d->windows.count()) { | 571 | if (!index.isValid() || index.model() != this || index.row() < 0 || index.row() >= d->windows.count()) { | ||
506 | return; | 572 | return; | ||
507 | } | 573 | } | ||
508 | 574 | | |||
509 | d->windows.at(index.row())->requestToggleMaximized(); | 575 | KWayland::Client::PlasmaWindow *window = d->windows.at(index.row()); | ||
576 | | ||||
577 | const QString ¤tDesktop = d->virtualDesktopInfo->currentDesktop().toString(); | ||||
578 | | ||||
579 | if (!currentDesktop.isEmpty()) { | ||||
580 | window->requestEnterVirtualDesktop(currentDesktop); | ||||
581 | } | ||||
582 | | ||||
583 | window->requestToggleMaximized(); | ||||
510 | } | 584 | } | ||
511 | 585 | | |||
512 | void WaylandTasksModel::requestToggleKeepAbove(const QModelIndex &index) | 586 | void WaylandTasksModel::requestToggleKeepAbove(const QModelIndex &index) | ||
513 | { | 587 | { | ||
514 | if (!index.isValid() || index.model() != this || index.row() < 0 || index.row() >= d->windows.count()) { | 588 | if (!index.isValid() || index.model() != this || index.row() < 0 || index.row() >= d->windows.count()) { | ||
515 | return; | 589 | return; | ||
516 | } | 590 | } | ||
517 | 591 | | |||
Show All 20 Lines | |||||
538 | { | 612 | { | ||
539 | if (!index.isValid() || index.model() != this || index.row() < 0 || index.row() >= d->windows.count()) { | 613 | if (!index.isValid() || index.model() != this || index.row() < 0 || index.row() >= d->windows.count()) { | ||
540 | return; | 614 | return; | ||
541 | } | 615 | } | ||
542 | 616 | | |||
543 | d->windows.at(index.row())->requestToggleShaded(); | 617 | d->windows.at(index.row())->requestToggleShaded(); | ||
544 | } | 618 | } | ||
545 | 619 | | |||
546 | void WaylandTasksModel::requestVirtualDesktop(const QModelIndex &index, qint32 desktop) | 620 | void WaylandTasksModel::requestVirtualDesktops(const QModelIndex &index, const QVariantList &desktops) | ||
547 | { | 621 | { | ||
548 | // FIXME Lacks add-new-desktop code from XWindows version. | 622 | // FIXME TODO: Lacks the "if we've requested the current desktop, force-activate | ||
549 | // FIXME Does this do the set-on-all-desktops stuff from the XWindows version? | 623 | // the window" logic from X11 version. This behavior should be in KWin rather than | ||
624 | // libtm however. | ||||
625 | | ||||
626 | if (!index.isValid() || index.model() != this || index.row() < 0 || index.row() >= d->windows.count()) { | ||||
627 | return; | ||||
628 | } | ||||
629 | | ||||
630 | KWayland::Client::PlasmaWindow *window = d->windows.at(index.row()); | ||||
631 | | ||||
632 | if (desktops.isEmpty()) { | ||||
633 | foreach (const QVariant &desktop, window->plasmaVirtualDesktops()) { | ||||
634 | window->requestLeaveVirtualDesktop(desktop.toString()); | ||||
635 | } | ||||
636 | } else { | ||||
637 | const QStringList &now = window->plasmaVirtualDesktops(); | ||||
638 | QStringList next; | ||||
639 | | ||||
640 | foreach (const QVariant &desktop, desktops) { | ||||
641 | const QString &desktopId = desktop.toString(); | ||||
642 | | ||||
643 | if (!desktopId.isEmpty()) { | ||||
644 | next << desktopId; | ||||
645 | | ||||
646 | if (!now.contains(desktopId)) { | ||||
647 | window->requestEnterVirtualDesktop(desktopId); | ||||
648 | } | ||||
649 | } | ||||
650 | } | ||||
550 | 651 | | |||
652 | foreach (const QString &desktop, now) { | ||||
653 | if (!next.contains(desktop)) { | ||||
654 | window->requestLeaveVirtualDesktop(desktop); | ||||
655 | } | ||||
656 | } | ||||
657 | } | ||||
658 | } | ||||
659 | | ||||
660 | void WaylandTasksModel::requestNewVirtualDesktop(const QModelIndex &index) | ||||
661 | { | ||||
551 | if (!index.isValid() || index.model() != this || index.row() < 0 || index.row() >= d->windows.count()) { | 662 | if (!index.isValid() || index.model() != this || index.row() < 0 || index.row() >= d->windows.count()) { | ||
552 | return; | 663 | return; | ||
553 | } | 664 | } | ||
554 | 665 | | |||
555 | d->windows.at(index.row())->requestVirtualDesktop(desktop); | 666 | d->windows.at(index.row())->requestEnterNewVirtualDesktop(); | ||
556 | } | 667 | } | ||
557 | 668 | | |||
558 | void WaylandTasksModel::requestActivities(const QModelIndex &index, const QStringList &activities) | 669 | void WaylandTasksModel::requestActivities(const QModelIndex &index, const QStringList &activities) | ||
559 | { | 670 | { | ||
560 | Q_UNUSED(index) | 671 | Q_UNUSED(index) | ||
561 | Q_UNUSED(activities) | 672 | Q_UNUSED(activities) | ||
562 | } | 673 | } | ||
563 | 674 | | |||
Show All 35 Lines | 676 | { | |||
599 | QRect rect(item->x(), item->y(), item->width(), item->height()); | 710 | QRect rect(item->x(), item->y(), item->width(), item->height()); | ||
600 | rect.moveTopLeft(item->parentItem()->mapToScene(rect.topLeft()).toPoint()); | 711 | rect.moveTopLeft(item->parentItem()->mapToScene(rect.topLeft()).toPoint()); | ||
601 | 712 | | |||
602 | KWayland::Client::PlasmaWindow *window = d->windows.at(index.row()); | 713 | KWayland::Client::PlasmaWindow *window = d->windows.at(index.row()); | ||
603 | 714 | | |||
604 | window->setMinimizedGeometry(surface, rect); | 715 | window->setMinimizedGeometry(surface, rect); | ||
605 | } | 716 | } | ||
606 | 717 | | |||
718 | quint32 WaylandTasksModel::winIdFromMimeData(const QMimeData *mimeData, bool *ok) | ||||
719 | { | ||||
720 | Q_ASSERT(mimeData); | ||||
721 | | ||||
722 | if (ok) { | ||||
723 | *ok = false; | ||||
724 | } | ||||
725 | | ||||
726 | if (!mimeData->hasFormat(Private::mimeType())) { | ||||
727 | return 0; | ||||
728 | } | ||||
729 | | ||||
730 | quint32 id = mimeData->data(Private::mimeType()).toUInt(ok); | ||||
731 | | ||||
732 | return id; | ||||
733 | } | ||||
734 | | ||||
735 | QList<quint32> WaylandTasksModel::winIdsFromMimeData(const QMimeData *mimeData, bool *ok) | ||||
736 | { | ||||
737 | Q_ASSERT(mimeData); | ||||
738 | QList<quint32> ids; | ||||
739 | | ||||
740 | if (ok) { | ||||
741 | *ok = false; | ||||
742 | } | ||||
743 | | ||||
744 | if (!mimeData->hasFormat(Private::groupMimeType())) { | ||||
745 | // Try to extract single window id. | ||||
746 | bool singularOk; | ||||
747 | WId id = winIdFromMimeData(mimeData, &singularOk); | ||||
748 | | ||||
749 | if (ok) { | ||||
750 | *ok = singularOk; | ||||
751 | } | ||||
752 | | ||||
753 | if (singularOk) { | ||||
754 | ids << id; | ||||
755 | } | ||||
756 | | ||||
757 | return ids; | ||||
758 | } | ||||
759 | | ||||
760 | // FIXME: Extracting multiple winids is still unimplemented; | ||||
761 | // TaskGroupingProxy::data(..., ::MimeData) can't produce | ||||
762 | // a payload with them anyways. | ||||
763 | | ||||
764 | return ids; | ||||
765 | } | ||||
766 | | ||||
607 | } | 767 | } | ||
zzag: How about `static_cast<size_t>(data.size())`? | |||||
No strong opinion :). This code is based on the one in the X11 model, which is in turn from the original libtaskmanager. hein: No strong opinion :). This code is based on the one in the X11 model, which is in turn from the… |
note that the protocol ensures the list of desktops is empty when is on all virtual desktops, even when every desktop has been added by hand