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 | return; | ||
470 | } | 471 | } | ||
471 | 472 | | |||
472 | const WId windowId = (WId)window; | 473 | const WId windowId = (WId)window; | ||
473 | 474 | | |||
474 | QPointF dest(x / widthScaleFactor, y / heightScaleFactor); | 475 | QPointF dest(x / widthScaleFactor, y / heightScaleFactor); | ||
475 | 476 | | |||
476 | // Don't move windows to negative positions. | 477 | // Don't move windows to negative positions. | ||
477 | dest = QPointF(qMax(dest.x(), qreal(0.0)), qMax(dest.y(), qreal(0.0))); | 478 | dest = QPointF(qMax(dest.x(), qreal(0.0)), qMax(dest.y(), qreal(0.0))); | ||
478 | 479 | | |||
479 | // Use _NET_MOVERESIZE_WINDOW rather than plain move, so that the WM knows this is a pager request. | 480 | // Use _NET_MOVERESIZE_WINDOW rather than plain move, so that the WM knows this is a pager request. | ||
480 | NETRootInfo info(QX11Info::connection(), 0); | 481 | NETRootInfo info(QX11Info::connection(), 0); | ||
481 | const int flags = (0x20 << 12) | (0x03 << 8) | 1; // From tool, x/y, northwest gravity. | 482 | const int flags = (0x20 << 12) | (0x03 << 8) | 1; // From tool, x/y, northwest gravity. | ||
482 | 483 | | |||
483 | if (!KWindowSystem::mapViewport()) { | 484 | if (!KWindowSystem::mapViewport()) { | ||
484 | KWindowInfo windowInfo(windowId, NET::WMDesktop | NET::WMState, NET::WM2Activities); | 485 | KWindowInfo windowInfo(windowId, NET::WMDesktop | NET::WMState, NET::WM2Activities); | ||
485 | 486 | | |||
486 | if (d->pagerType == VirtualDesktops) { | 487 | if (d->pagerType == VirtualDesktops) { | ||
487 | if (!windowInfo.onAllDesktops()) { | 488 | if (!windowInfo.onAllDesktops()) { | ||
488 | KWindowSystem::setOnDesktop(windowId, targetItemId + 1); | 489 | KWindowSystem::setOnDesktop(windowId, targetItemId.toInt()); | ||
489 | } | 490 | } | ||
490 | } else { | 491 | } else { | ||
491 | const QStringList &runningActivities = d->activityInfo->runningActivities(); | 492 | const QStringList &runningActivities = d->activityInfo->runningActivities(); | ||
492 | 493 | | |||
493 | if (targetItemId < runningActivities.length()) { | 494 | if (targetItemId < runningActivities.length()) { | ||
494 | const QString &newActivity = runningActivities.at(targetItemId); | 495 | const QString &newActivity = targetItemId.toString(); | ||
495 | QStringList activities = windowInfo.activities(); | 496 | QStringList activities = windowInfo.activities(); | ||
496 | 497 | | |||
497 | if (!activities.contains(newActivity)) { | 498 | if (!activities.contains(newActivity)) { | ||
498 | activities.removeOne(runningActivities.at(sourceItemId)); | 499 | activities.removeOne(sourceItemId.toString()); | ||
499 | activities.append(newActivity); | 500 | activities.append(newActivity); | ||
500 | KWindowSystem::setOnActivities(windowId, activities); | 501 | KWindowSystem::setOnActivities(windowId, activities); | ||
501 | } | 502 | } | ||
502 | } | 503 | } | ||
503 | } | 504 | } | ||
504 | 505 | | |||
505 | // Only move the window if it is not full screen and if it is kept within the same desktop. | 506 | // 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. | 507 | // Moving when dropping between desktop is too annoying due to the small drop area. | ||
507 | if (!(windowInfo.state() & NET::FullScreen) && | 508 | if (!(windowInfo.state() & NET::FullScreen) && | ||
508 | (targetItemId == sourceItemId || windowInfo.onAllDesktops())) { | 509 | (targetItemId == sourceItemId || windowInfo.onAllDesktops())) { | ||
509 | const QPoint &d = dest.toPoint(); | 510 | const QPoint &d = dest.toPoint(); | ||
510 | info.moveResizeWindowRequest(windowId, flags, d.x(), d.y(), 0, 0); | 511 | info.moveResizeWindowRequest(windowId, flags, d.x(), d.y(), 0, 0); | ||
511 | } | 512 | } | ||
512 | } else { | 513 | } else { | ||
513 | // setOnDesktop() with viewports is also moving a window, and since it takes a moment | 514 | // 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, | 515 | // 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. | 516 | // so do it only as one move. | ||
516 | dest += KWindowSystem::desktopToViewport(targetItemId + 1, false); | 517 | dest += KWindowSystem::desktopToViewport(targetItemId.toInt(), false); | ||
517 | const QPoint &d = KWindowSystem::constrainViewportRelativePosition(dest.toPoint()); | 518 | const QPoint &d = KWindowSystem::constrainViewportRelativePosition(dest.toPoint()); | ||
518 | info.moveResizeWindowRequest(windowId, flags, d.x(), d.y(), 0, 0); | 519 | info.moveResizeWindowRequest(windowId, flags, d.x(), d.y(), 0, 0); | ||
519 | } | 520 | } | ||
520 | #else | 521 | #else | ||
521 | Q_UNUSED(window) | 522 | Q_UNUSED(window) | ||
522 | Q_UNUSED(x) | 523 | Q_UNUSED(x) | ||
523 | Q_UNUSED(y) | 524 | Q_UNUSED(y) | ||
524 | Q_UNUSED(targetDesktop) | 525 | Q_UNUSED(sourceItemId) | ||
525 | Q_UNUSED(sourceDesktop) | 526 | | ||
526 | #endif | 527 | if (KWindowSystem::isPlatformWayland()) { | ||
528 | if (d->pagerType == VirtualDesktops) { | ||||
529 | QAbstractItemModel *model = nullptr; | ||||
530 | | ||||
531 | foreach (WindowModel *windowModel, d->windowModels) { | ||||
532 | if (windowModel->virtualDesktop() == sourceItemId) { | ||||
533 | model = windowModel; | ||||
534 | | ||||
535 | break; | ||||
536 | } | ||||
527 | } | 537 | } | ||
528 | 538 | | |||
529 | void PagerModel::changePage(int page) | 539 | TaskManager::AbstractTasksModel *tasksModel = static_cast<TaskManager::AbstractTasksModel *>(model); | ||
530 | { | | |||
531 | 540 | | |||
532 | #if HAVE_X11 | 541 | for (int i = 0; i < tasksModel->rowCount(); ++i) { | ||
533 | if (!KWindowSystem::isPlatformX11()) { | 542 | const QModelIndex &idx = tasksModel->index(i, 0); | ||
534 | return; | 543 | | ||
544 | if (idx.data(TaskManager::AbstractTasksModel::IsOnAllVirtualDesktops).toBool()) { | ||||
545 | break; | ||||
535 | } | 546 | } | ||
536 | 547 | | |||
548 | const QVariantList &winIds = idx.data(TaskManager::AbstractTasksModel::WinIdList).toList(); | ||||
549 | | ||||
550 | if (!winIds.isEmpty() && winIds.at(0).toInt() == window) { | ||||
551 | tasksModel->requestVirtualDesktops(idx, QVariantList() << itemId.toString()); | ||||
552 | } | ||||
553 | } | ||||
554 | } | ||||
555 | } | ||||
556 | #endif | ||||
557 | } | ||||
558 | | ||||
559 | void PagerModel::changePage(int page) | ||||
560 | { | ||||
537 | if (currentPage() == page) { | 561 | if (currentPage() == page) { | ||
538 | if (d->showDesktop) { | 562 | if (d->showDesktop) { | ||
539 | QDBusConnection::sessionBus().asyncCall(QDBusMessage::createMethodCall(QLatin1String("org.kde.plasmashell"), | 563 | QDBusConnection::sessionBus().asyncCall(QDBusMessage::createMethodCall(QLatin1String("org.kde.plasmashell"), | ||
540 | QLatin1String("/PlasmaShell"), | 564 | QLatin1String("/PlasmaShell"), | ||
541 | QLatin1String("org.kde.PlasmaShell"), | 565 | QLatin1String("org.kde.PlasmaShell"), | ||
542 | QLatin1String("toggleDashboard"))); | 566 | QLatin1String("toggleDashboard"))); | ||
543 | } | 567 | } | ||
544 | } else { | 568 | } else { | ||
545 | if (d->pagerType == VirtualDesktops) { | 569 | if (d->pagerType == VirtualDesktops) { | ||
546 | KWindowSystem::setCurrentDesktop(page + 1); | 570 | d->virtualDesktopInfo->requestActivate(d->virtualDesktopInfo->desktopIds().at(page)); | ||
547 | } else { | 571 | } else { | ||
548 | const QStringList &runningActivities = d->activityInfo->runningActivities(); | 572 | const QStringList &runningActivities = d->activityInfo->runningActivities(); | ||
549 | if (page < runningActivities.length()) { | 573 | if (page < runningActivities.length()) { | ||
550 | KActivities::Controller activitiesController; | 574 | KActivities::Controller activitiesController; | ||
551 | activitiesController.setCurrentActivity(runningActivities.at(page)); | 575 | activitiesController.setCurrentActivity(runningActivities.at(page)); | ||
552 | } | 576 | } | ||
553 | } | 577 | } | ||
554 | } | 578 | } | ||
555 | | ||||
556 | #else | | |||
557 | Q_UNUSED(itemId) | | |||
558 | #endif | | |||
559 | } | 579 | } | ||
560 | 580 | | |||
561 | void PagerModel::drop(QMimeData *mimeData, int itemId) | 581 | void PagerModel::drop(QMimeData *mimeData, const QVariant &itemId) | ||
562 | { | 582 | { | ||
563 | if (!mimeData) { | 583 | if (!mimeData) { | ||
564 | return; | 584 | return; | ||
565 | } | 585 | } | ||
566 | 586 | | |||
567 | #if HAVE_X11 | 587 | #if HAVE_X11 | ||
568 | if (KWindowSystem::isPlatformX11()) { | 588 | if (KWindowSystem::isPlatformX11()) { | ||
569 | bool ok; | 589 | bool ok; | ||
570 | 590 | | |||
571 | const QList<WId> &ids = TaskManager::XWindowTasksModel::winIdsFromMimeData(mimeData, &ok); | 591 | const QList<WId> &ids = TaskManager::XWindowTasksModel::winIdsFromMimeData(mimeData, &ok); | ||
572 | 592 | | |||
573 | if (!ok) { | 593 | if (!ok) { | ||
574 | return; | 594 | return; | ||
575 | } | 595 | } | ||
576 | 596 | | |||
577 | if (d->pagerType == VirtualDesktops) { | 597 | if (d->pagerType == VirtualDesktops) { | ||
578 | for (const auto &id : ids) { | 598 | for (const auto &id : ids) { | ||
579 | KWindowSystem::setOnDesktop(id, itemId + 1); | 599 | KWindowSystem::setOnDesktop(id, itemId.toInt()); | ||
580 | } | 600 | } | ||
581 | } else { | 601 | } else { | ||
582 | QString newActivity; | 602 | QString newActivity; | ||
583 | const QStringList &runningActivities = d->activityInfo->runningActivities(); | 603 | const QStringList &runningActivities = d->activityInfo->runningActivities(); | ||
584 | 604 | | |||
585 | if (itemId < runningActivities.length()) { | 605 | if (itemId < runningActivities.length()) { | ||
586 | newActivity = runningActivities.at(itemId); | 606 | newActivity = itemId.toString(); | ||
587 | } | 607 | } | ||
588 | 608 | | |||
589 | if (newActivity.isEmpty()) { | 609 | if (newActivity.isEmpty()) { | ||
590 | return; | 610 | return; | ||
591 | } | 611 | } | ||
592 | 612 | | |||
593 | for (const auto &id : ids) { | 613 | for (const auto &id : ids) { | ||
594 | QStringList activities = KWindowInfo(id, 0, NET::WM2Activities).activities(); | 614 | QStringList activities = KWindowInfo(id, 0, NET::WM2Activities).activities(); | ||
595 | 615 | | |||
596 | if (!activities.contains(newActivity)) { | 616 | if (!activities.contains(newActivity)) { | ||
597 | KWindowSystem::setOnActivities(id, activities << newActivity); | 617 | KWindowSystem::setOnActivities(id, activities << newActivity); | ||
598 | } | 618 | } | ||
599 | } | 619 | } | ||
600 | } | 620 | } | ||
621 | | ||||
622 | return; | ||||
601 | } | 623 | } | ||
602 | #else | | |||
603 | Q_UNUSED(itemId) | | |||
604 | #endif | 624 | #endif | ||
625 | | ||||
626 | if (KWindowSystem::isPlatformWayland()) { | ||||
627 | bool ok; | ||||
628 | | ||||
629 | const QList<quint32> &ids = TaskManager::WaylandTasksModel::winIdsFromMimeData(mimeData, &ok); | ||||
630 | | ||||
631 | if (!ok) { | ||||
632 | return; | ||||
633 | } | ||||
634 | | ||||
635 | if (d->pagerType == VirtualDesktops) { | ||||
636 | for (const quint32 &id : ids) { | ||||
637 | QAbstractItemModel *model = d->windowModels.at(0)->sourceModel(); | ||||
638 | TaskManager::AbstractTasksModel *tasksModel = static_cast<TaskManager::AbstractTasksModel *>(model); | ||||
639 | | ||||
640 | for (int i = 0; i < tasksModel->rowCount(); ++i) { | ||||
641 | const QModelIndex &idx = tasksModel->index(i, 0); | ||||
642 | | ||||
643 | if (idx.data(TaskManager::AbstractTasksModel::IsOnAllVirtualDesktops).toBool()) { | ||||
644 | break; | ||||
645 | } | ||||
646 | | ||||
647 | const QVariantList &winIds = idx.data(TaskManager::AbstractTasksModel::WinIdList).toList(); | ||||
648 | | ||||
649 | if (!winIds.isEmpty() && winIds.at(0).toUInt() == id) { | ||||
650 | tasksModel->requestVirtualDesktops(idx, QVariantList() << itemId.toString()); | ||||
mart: {} initializer? | |||||
651 | break; | ||||
652 | } | ||||
653 | } | ||||
654 | } | ||||
655 | } | ||||
656 | } | ||||
605 | } | 657 | } | ||
606 | 658 | | |||
607 | void PagerModel::addDesktop() | 659 | void PagerModel::addDesktop() | ||
608 | { | 660 | { | ||
609 | #if HAVE_X11 | 661 | #if HAVE_X11 | ||
610 | if (!KWindowSystem::isPlatformX11()) { | 662 | if (!KWindowSystem::isPlatformX11()) { | ||
611 | return; | 663 | return; | ||
612 | } | 664 | } | ||
Show All 35 Lines |
would it be possible to avoid default arguments?