Changeset View
Changeset View
Standalone View
Standalone View
applets/pager/plugin/pagermodel.cpp
Show All 20 Lines | |||||
21 | 21 | | |||
22 | #include "pagermodel.h" | 22 | #include "pagermodel.h" | ||
23 | #include "windowmodel.h" | 23 | #include "windowmodel.h" | ||
24 | 24 | | |||
25 | #include <activityinfo.h> | 25 | #include <activityinfo.h> | ||
26 | #include <virtualdesktopinfo.h> | 26 | #include <virtualdesktopinfo.h> | ||
27 | #include <windowtasksmodel.h> | 27 | #include <windowtasksmodel.h> | ||
28 | #include <xwindowtasksmodel.h> | 28 | #include <xwindowtasksmodel.h> | ||
29 | #include <waylandtasksmodel.h> | ||||
29 | 30 | | |||
30 | #include <QApplication> | 31 | #include <QApplication> | ||
31 | #include <QDBusConnection> | 32 | #include <QDBusConnection> | ||
32 | #include <QDBusMessage> | 33 | #include <QDBusMessage> | ||
33 | #include <QDBusPendingCall> | 34 | #include <QDBusPendingCall> | ||
34 | #include <QDesktopWidget> | 35 | #include <QDesktopWidget> | ||
35 | #include <QMetaEnum> | 36 | #include <QMetaEnum> | ||
36 | 37 | | |||
▲ Show 20 Lines • Show All 317 Lines • ▼ Show 20 Line(s) | 347 | if (d->screenGeometry != geometry) { | |||
354 | 355 | | |||
355 | emit showOnlyCurrentScreenChanged(); | 356 | emit showOnlyCurrentScreenChanged(); | ||
356 | } | 357 | } | ||
357 | } | 358 | } | ||
358 | 359 | | |||
359 | int PagerModel::currentPage() const | 360 | int PagerModel::currentPage() const | ||
360 | { | 361 | { | ||
361 | if (d->pagerType == VirtualDesktops) { | 362 | if (d->pagerType == VirtualDesktops) { | ||
362 | return d->virtualDesktopInfo->currentDesktop() - 1; | 363 | return d->virtualDesktopInfo->desktopIds().indexOf(d->virtualDesktopInfo->currentDesktop()); | ||
363 | } else { | 364 | } else { | ||
364 | return d->activityInfo->runningActivities().indexOf(d->activityInfo->currentActivity()); | 365 | return d->activityInfo->runningActivities().indexOf(d->activityInfo->currentActivity()); | ||
365 | } | 366 | } | ||
366 | } | 367 | } | ||
367 | 368 | | |||
368 | int PagerModel::layoutRows() const | 369 | int PagerModel::layoutRows() const | ||
369 | { | 370 | { | ||
370 | return qBound(1, d->virtualDesktopInfo->desktopLayoutRows(), | 371 | return qBound(1, d->virtualDesktopInfo->desktopLayoutRows(), | ||
▲ Show 20 Lines • Show All 51 Lines • ▼ Show 20 Line(s) | 418 | while (modelCount != modelsNeeded) { | |||
422 | windowModel->setDemandingAttentionSkipsFilters(false); | 423 | windowModel->setDemandingAttentionSkipsFilters(false); | ||
423 | windowModel->setSourceModel(d->tasksModel); | 424 | windowModel->setSourceModel(d->tasksModel); | ||
424 | d->windowModels.append(windowModel); | 425 | d->windowModels.append(windowModel); | ||
425 | ++modelCount; | 426 | ++modelCount; | ||
426 | } | 427 | } | ||
427 | } | 428 | } | ||
428 | 429 | | |||
429 | if (d->pagerType == VirtualDesktops) { | 430 | if (d->pagerType == VirtualDesktops) { | ||
430 | int virtualDesktop = 1; | 431 | int virtualDesktop = 0; | ||
431 | 432 | | |||
432 | for (auto windowModel : d->windowModels) { | 433 | for (auto windowModel : d->windowModels) { | ||
433 | windowModel->setVirtualDesktop(virtualDesktop); | 434 | windowModel->setVirtualDesktop(d->virtualDesktopInfo->desktopIds().at(virtualDesktop)); | ||
434 | ++virtualDesktop; | 435 | ++virtualDesktop; | ||
435 | 436 | | |||
436 | windowModel->setActivity(d->activityInfo->currentActivity()); | 437 | windowModel->setActivity(d->activityInfo->currentActivity()); | ||
437 | } | 438 | } | ||
438 | } else { | 439 | } else { | ||
439 | int activityIndex = 0; | 440 | int activityIndex = 0; | ||
440 | const QStringList &runningActivities = d->activityInfo->runningActivities(); | 441 | const QStringList &runningActivities = d->activityInfo->runningActivities(); | ||
441 | 442 | | |||
442 | for (auto windowModel : d->windowModels) { | 443 | for (auto windowModel : d->windowModels) { | ||
443 | windowModel->setVirtualDesktop(0); | 444 | windowModel->setVirtualDesktop(); | ||
mart: would it be possible to avoid default arguments? | |||||
444 | 445 | | |||
445 | windowModel->setActivity(runningActivities.at(activityIndex)); | 446 | windowModel->setActivity(runningActivities.at(activityIndex)); | ||
446 | ++activityIndex; | 447 | ++activityIndex; | ||
447 | } | 448 | } | ||
448 | } | 449 | } | ||
449 | 450 | | |||
450 | for (auto windowModel : d->windowModels) { | 451 | for (auto windowModel : d->windowModels) { | ||
451 | if (d->showOnlyCurrentScreen && d->screenGeometry.isValid()) { | 452 | if (d->showOnlyCurrentScreen && d->screenGeometry.isValid()) { | ||
452 | windowModel->setScreenGeometry(d->screenGeometry); | 453 | windowModel->setScreenGeometry(d->screenGeometry); | ||
453 | windowModel->setFilterByScreen(true); | 454 | windowModel->setFilterByScreen(true); | ||
454 | } else { | 455 | } else { | ||
455 | windowModel->setFilterByScreen(false); | 456 | windowModel->setFilterByScreen(false); | ||
456 | } | 457 | } | ||
457 | } | 458 | } | ||
458 | 459 | | |||
459 | endResetModel(); | 460 | endResetModel(); | ||
460 | 461 | | |||
461 | emit countChanged(); | 462 | emit countChanged(); | ||
462 | } | 463 | } | ||
463 | 464 | | |||
464 | void PagerModel::moveWindow(int window, double x, double y, int targetItemId, int sourceItemId, | 465 | void PagerModel::moveWindow(int window, double x, double y, const QVariant &targetItemId, const QVariant &sourceItemId, | ||
465 | qreal widthScaleFactor, qreal heightScaleFactor) | 466 | qreal widthScaleFactor, qreal heightScaleFactor) | ||
466 | { | 467 | { | ||
467 | #if HAVE_X11 | 468 | #if HAVE_X11 | ||
468 | if (!KWindowSystem::isPlatformX11()) { | 469 | if (KWindowSystem::isPlatformX11()) { | ||
469 | return; | | |||
470 | } | | |||
471 | | ||||
472 | const WId windowId = (WId)window; | 470 | const WId windowId = (WId)window; | ||
473 | 471 | | |||
474 | QPointF dest(x / widthScaleFactor, y / heightScaleFactor); | 472 | QPointF dest(x / widthScaleFactor, y / heightScaleFactor); | ||
475 | 473 | | |||
476 | // Don't move windows to negative positions. | 474 | // Don't move windows to negative positions. | ||
477 | dest = QPointF(qMax(dest.x(), qreal(0.0)), qMax(dest.y(), qreal(0.0))); | 475 | dest = QPointF(qMax(dest.x(), qreal(0.0)), qMax(dest.y(), qreal(0.0))); | ||
478 | 476 | | |||
479 | // Use _NET_MOVERESIZE_WINDOW rather than plain move, so that the WM knows this is a pager request. | 477 | // Use _NET_MOVERESIZE_WINDOW rather than plain move, so that the WM knows this is a pager request. | ||
480 | NETRootInfo info(QX11Info::connection(), NET::Properties()); | 478 | NETRootInfo info(QX11Info::connection(), NET::Properties()); | ||
481 | const int flags = (0x20 << 12) | (0x03 << 8) | 1; // From tool, x/y, northwest gravity. | 479 | const int flags = (0x20 << 12) | (0x03 << 8) | 1; // From tool, x/y, northwest gravity. | ||
482 | 480 | | |||
483 | if (!KWindowSystem::mapViewport()) { | 481 | if (!KWindowSystem::mapViewport()) { | ||
484 | KWindowInfo windowInfo(windowId, NET::WMDesktop | NET::WMState, NET::WM2Activities); | 482 | KWindowInfo windowInfo(windowId, NET::WMDesktop | NET::WMState, NET::WM2Activities); | ||
485 | 483 | | |||
486 | if (d->pagerType == VirtualDesktops) { | 484 | if (d->pagerType == VirtualDesktops) { | ||
487 | if (!windowInfo.onAllDesktops()) { | 485 | if (!windowInfo.onAllDesktops()) { | ||
488 | KWindowSystem::setOnDesktop(windowId, targetItemId + 1); | 486 | KWindowSystem::setOnDesktop(windowId, targetItemId.toInt()); | ||
489 | } | 487 | } | ||
490 | } else { | 488 | } else { | ||
491 | const QStringList &runningActivities = d->activityInfo->runningActivities(); | 489 | const QStringList &runningActivities = d->activityInfo->runningActivities(); | ||
492 | 490 | | |||
493 | if (targetItemId < runningActivities.length()) { | 491 | if (targetItemId < runningActivities.length()) { | ||
494 | const QString &newActivity = runningActivities.at(targetItemId); | 492 | const QString &newActivity = targetItemId.toString(); | ||
495 | QStringList activities = windowInfo.activities(); | 493 | QStringList activities = windowInfo.activities(); | ||
496 | 494 | | |||
497 | if (!activities.contains(newActivity)) { | 495 | if (!activities.contains(newActivity)) { | ||
498 | activities.removeOne(runningActivities.at(sourceItemId)); | 496 | activities.removeOne(sourceItemId.toString()); | ||
499 | activities.append(newActivity); | 497 | activities.append(newActivity); | ||
500 | KWindowSystem::setOnActivities(windowId, activities); | 498 | KWindowSystem::setOnActivities(windowId, activities); | ||
501 | } | 499 | } | ||
502 | } | 500 | } | ||
503 | } | 501 | } | ||
504 | 502 | | |||
505 | // Only move the window if it is not full screen and if it is kept within the same desktop. | 503 | // Only move the window if it is not full screen and if it is kept within the same desktop. | ||
506 | // Moving when dropping between desktop is too annoying due to the small drop area. | 504 | // Moving when dropping between desktop is too annoying due to the small drop area. | ||
507 | if (!(windowInfo.state() & NET::FullScreen) && | 505 | if (!(windowInfo.state() & NET::FullScreen) && | ||
508 | (targetItemId == sourceItemId || windowInfo.onAllDesktops())) { | 506 | (targetItemId == sourceItemId || windowInfo.onAllDesktops())) { | ||
509 | const QPoint &d = dest.toPoint(); | 507 | const QPoint &d = dest.toPoint(); | ||
510 | info.moveResizeWindowRequest(windowId, flags, d.x(), d.y(), 0, 0); | 508 | info.moveResizeWindowRequest(windowId, flags, d.x(), d.y(), 0, 0); | ||
511 | } | 509 | } | ||
512 | } else { | 510 | } else { | ||
513 | // setOnDesktop() with viewports is also moving a window, and since it takes a moment | 511 | // setOnDesktop() with viewports is also moving a window, and since it takes a moment | ||
514 | // for the WM to do the move, there's a race condition with figuring out how much to move, | 512 | // for the WM to do the move, there's a race condition with figuring out how much to move, | ||
515 | // so do it only as one move. | 513 | // so do it only as one move. | ||
516 | dest += KWindowSystem::desktopToViewport(targetItemId + 1, false); | 514 | dest += KWindowSystem::desktopToViewport(targetItemId.toInt(), false); | ||
517 | const QPoint &d = KWindowSystem::constrainViewportRelativePosition(dest.toPoint()); | 515 | const QPoint &d = KWindowSystem::constrainViewportRelativePosition(dest.toPoint()); | ||
518 | info.moveResizeWindowRequest(windowId, flags, d.x(), d.y(), 0, 0); | 516 | info.moveResizeWindowRequest(windowId, flags, d.x(), d.y(), 0, 0); | ||
519 | } | 517 | } | ||
518 | } | ||||
520 | #else | 519 | #else | ||
521 | Q_UNUSED(window) | 520 | Q_UNUSED(window) | ||
522 | Q_UNUSED(x) | 521 | Q_UNUSED(x) | ||
523 | Q_UNUSED(y) | 522 | Q_UNUSED(y) | ||
524 | Q_UNUSED(targetDesktop) | 523 | Q_UNUSED(sourceItemId) | ||
525 | Q_UNUSED(sourceDesktop) | | |||
526 | #endif | 524 | #endif | ||
525 | | ||||
526 | if (KWindowSystem::isPlatformWayland()) { | ||||
527 | if (d->pagerType == VirtualDesktops) { | ||||
528 | QAbstractItemModel *model = d->windowModels.at(0)->sourceModel(); | ||||
529 | TaskManager::WindowTasksModel *tasksModel = static_cast<TaskManager::WindowTasksModel *>(model); | ||||
530 | | ||||
531 | for (int i = 0; i < tasksModel->rowCount(); ++i) { | ||||
532 | const QModelIndex &idx = tasksModel->index(i, 0); | ||||
533 | | ||||
534 | if (idx.data(TaskManager::AbstractTasksModel::IsOnAllVirtualDesktops).toBool()) { | ||||
535 | break; | ||||
527 | } | 536 | } | ||
528 | 537 | | |||
529 | void PagerModel::changePage(int page) | 538 | const QVariantList &winIds = idx.data(TaskManager::AbstractTasksModel::WinIdList).toList(); | ||
530 | { | | |||
531 | 539 | | |||
532 | #if HAVE_X11 | 540 | if (!winIds.isEmpty() && winIds.at(0).toUInt() == window) { | ||
533 | if (!KWindowSystem::isPlatformX11()) { | 541 | tasksModel->requestVirtualDesktops(idx, QVariantList() << targetItemId.toString()); | ||
534 | return; | 542 | break; | ||
543 | } | ||||
544 | } | ||||
545 | } else { | ||||
546 | //FIXME TODO: Activities support. | ||||
547 | } | ||||
548 | } | ||||
535 | } | 549 | } | ||
536 | 550 | | |||
551 | void PagerModel::changePage(int page) | ||||
552 | { | ||||
537 | if (currentPage() == page) { | 553 | if (currentPage() == page) { | ||
538 | if (d->showDesktop) { | 554 | if (d->showDesktop) { | ||
539 | QDBusConnection::sessionBus().asyncCall(QDBusMessage::createMethodCall(QLatin1String("org.kde.plasmashell"), | 555 | QDBusConnection::sessionBus().asyncCall(QDBusMessage::createMethodCall(QLatin1String("org.kde.plasmashell"), | ||
540 | QLatin1String("/PlasmaShell"), | 556 | QLatin1String("/PlasmaShell"), | ||
541 | QLatin1String("org.kde.PlasmaShell"), | 557 | QLatin1String("org.kde.PlasmaShell"), | ||
542 | QLatin1String("toggleDashboard"))); | 558 | QLatin1String("toggleDashboard"))); | ||
543 | } | 559 | } | ||
544 | } else { | 560 | } else { | ||
545 | if (d->pagerType == VirtualDesktops) { | 561 | if (d->pagerType == VirtualDesktops) { | ||
546 | KWindowSystem::setCurrentDesktop(page + 1); | 562 | d->virtualDesktopInfo->requestActivate(d->virtualDesktopInfo->desktopIds().at(page)); | ||
547 | } else { | 563 | } else { | ||
548 | const QStringList &runningActivities = d->activityInfo->runningActivities(); | 564 | const QStringList &runningActivities = d->activityInfo->runningActivities(); | ||
549 | if (page < runningActivities.length()) { | 565 | if (page < runningActivities.length()) { | ||
550 | KActivities::Controller activitiesController; | 566 | KActivities::Controller activitiesController; | ||
551 | activitiesController.setCurrentActivity(runningActivities.at(page)); | 567 | activitiesController.setCurrentActivity(runningActivities.at(page)); | ||
552 | } | 568 | } | ||
553 | } | 569 | } | ||
554 | } | 570 | } | ||
555 | | ||||
556 | #else | | |||
557 | Q_UNUSED(itemId) | | |||
558 | #endif | | |||
559 | } | 571 | } | ||
560 | 572 | | |||
561 | void PagerModel::drop(QMimeData *mimeData, int itemId) | 573 | void PagerModel::drop(QMimeData *mimeData, const QVariant &itemId) | ||
562 | { | 574 | { | ||
563 | if (!mimeData) { | 575 | if (!mimeData) { | ||
564 | return; | 576 | return; | ||
565 | } | 577 | } | ||
566 | 578 | | |||
567 | #if HAVE_X11 | 579 | #if HAVE_X11 | ||
568 | if (KWindowSystem::isPlatformX11()) { | 580 | if (KWindowSystem::isPlatformX11()) { | ||
569 | bool ok; | 581 | bool ok; | ||
570 | 582 | | |||
571 | const QList<WId> &ids = TaskManager::XWindowTasksModel::winIdsFromMimeData(mimeData, &ok); | 583 | const QList<WId> &ids = TaskManager::XWindowTasksModel::winIdsFromMimeData(mimeData, &ok); | ||
572 | 584 | | |||
573 | if (!ok) { | 585 | if (!ok) { | ||
574 | return; | 586 | return; | ||
575 | } | 587 | } | ||
576 | 588 | | |||
577 | if (d->pagerType == VirtualDesktops) { | 589 | if (d->pagerType == VirtualDesktops) { | ||
578 | for (const auto &id : ids) { | 590 | for (const auto &id : ids) { | ||
579 | KWindowSystem::setOnDesktop(id, itemId + 1); | 591 | KWindowSystem::setOnDesktop(id, itemId.toInt()); | ||
580 | } | 592 | } | ||
581 | } else { | 593 | } else { | ||
582 | QString newActivity; | 594 | QString newActivity; | ||
583 | const QStringList &runningActivities = d->activityInfo->runningActivities(); | 595 | const QStringList &runningActivities = d->activityInfo->runningActivities(); | ||
584 | 596 | | |||
585 | if (itemId < runningActivities.length()) { | 597 | if (itemId < runningActivities.length()) { | ||
586 | newActivity = runningActivities.at(itemId); | 598 | newActivity = itemId.toString(); | ||
587 | } | 599 | } | ||
588 | 600 | | |||
589 | if (newActivity.isEmpty()) { | 601 | if (newActivity.isEmpty()) { | ||
590 | return; | 602 | return; | ||
591 | } | 603 | } | ||
592 | 604 | | |||
593 | for (const auto &id : ids) { | 605 | for (const auto &id : ids) { | ||
594 | QStringList activities = KWindowInfo(id, NET::Properties(), NET::WM2Activities).activities(); | 606 | QStringList activities = KWindowInfo(id, NET::Properties(), NET::WM2Activities).activities(); | ||
595 | 607 | | |||
596 | if (!activities.contains(newActivity)) { | 608 | if (!activities.contains(newActivity)) { | ||
597 | KWindowSystem::setOnActivities(id, activities << newActivity); | 609 | KWindowSystem::setOnActivities(id, activities << newActivity); | ||
598 | } | 610 | } | ||
599 | } | 611 | } | ||
600 | } | 612 | } | ||
613 | | ||||
614 | return; | ||||
601 | } | 615 | } | ||
602 | #else | | |||
603 | Q_UNUSED(itemId) | | |||
604 | #endif | 616 | #endif | ||
605 | } | | |||
606 | 617 | | |||
607 | void PagerModel::addDesktop() | 618 | if (KWindowSystem::isPlatformWayland()) { | ||
608 | { | 619 | bool ok; | ||
609 | #if HAVE_X11 | 620 | | ||
610 | if (!KWindowSystem::isPlatformX11()) { | 621 | const QList<quint32> &ids = TaskManager::WaylandTasksModel::winIdsFromMimeData(mimeData, &ok); | ||
622 | | ||||
623 | if (!ok) { | ||||
611 | return; | 624 | return; | ||
612 | } | 625 | } | ||
613 | 626 | | |||
614 | NETRootInfo info(QX11Info::connection(), NET::NumberOfDesktops); | 627 | if (d->pagerType == VirtualDesktops) { | ||
615 | info.setNumberOfDesktops(info.numberOfDesktops() + 1); | 628 | for (const quint32 &id : ids) { | ||
616 | #endif | 629 | QAbstractItemModel *model = d->windowModels.at(0)->sourceModel(); | ||
630 | TaskManager::WindowTasksModel *tasksModel = static_cast<TaskManager::WindowTasksModel *>(model); | ||||
631 | | ||||
632 | for (int i = 0; i < tasksModel->rowCount(); ++i) { | ||||
633 | const QModelIndex &idx = tasksModel->index(i, 0); | ||||
634 | | ||||
635 | if (idx.data(TaskManager::AbstractTasksModel::IsOnAllVirtualDesktops).toBool()) { | ||||
636 | break; | ||||
637 | } | ||||
638 | | ||||
639 | const QVariantList &winIds = idx.data(TaskManager::AbstractTasksModel::WinIdList).toList(); | ||||
640 | | ||||
641 | if (!winIds.isEmpty() && winIds.at(0).toUInt() == id) { | ||||
642 | tasksModel->requestVirtualDesktops(idx, QVariantList() << itemId.toString()); | ||||
mart: {} initializer? | |||||
643 | break; | ||||
644 | } | ||||
645 | } | ||||
646 | } | ||||
647 | } | ||||
648 | } | ||||
649 | } | ||||
650 | | ||||
651 | void PagerModel::addDesktop() | ||||
652 | { | ||||
653 | d->virtualDesktopInfo->requestCreateDesktop(d->virtualDesktopInfo->numberOfDesktops()); | ||||
617 | } | 654 | } | ||
618 | 655 | | |||
619 | void PagerModel::removeDesktop() | 656 | void PagerModel::removeDesktop() | ||
620 | { | 657 | { | ||
621 | #if HAVE_X11 | 658 | if (d->virtualDesktopInfo->numberOfDesktops() == 1) { | ||
622 | if (!KWindowSystem::isPlatformX11()) { | | |||
623 | return; | 659 | return; | ||
624 | } | 660 | } | ||
625 | 661 | | |||
626 | NETRootInfo info(QX11Info::connection(), NET::NumberOfDesktops); | 662 | d->virtualDesktopInfo->requestRemoveDesktop(d->virtualDesktopInfo->numberOfDesktops() - 1); | ||
627 | | ||||
628 | if (info.numberOfDesktops() > 1) { | | |||
629 | info.setNumberOfDesktops(info.numberOfDesktops() - 1); | | |||
630 | } | | |||
631 | #endif | | |||
632 | } | 663 | } | ||
633 | 664 | | |||
634 | void PagerModel::classBegin() | 665 | void PagerModel::classBegin() | ||
635 | { | 666 | { | ||
636 | } | 667 | } | ||
637 | 668 | | |||
638 | void PagerModel::componentComplete() | 669 | void PagerModel::componentComplete() | ||
639 | { | 670 | { | ||
640 | d->componentComplete = true; | 671 | d->componentComplete = true; | ||
641 | 672 | | |||
642 | if (d->enabled) { | 673 | if (d->enabled) { | ||
643 | refresh(); | 674 | refresh(); | ||
644 | } | 675 | } | ||
645 | } | 676 | } | ||
646 | 677 | | |||
647 | #include "moc_pagermodel.cpp" | 678 | #include "moc_pagermodel.cpp" |
would it be possible to avoid default arguments?