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