diff --git a/applets/pager/package/contents/ui/main.qml b/applets/pager/package/contents/ui/main.qml --- a/applets/pager/package/contents/ui/main.qml +++ b/applets/pager/package/contents/ui/main.qml @@ -51,9 +51,9 @@ Layout.fillHeight: !root.vertical property bool dragging: false - property int dragId + property string dragId - property int dragSwitchDesktopId: -1 + property string dragSwitchDesktopId property int wheelDelta: 0 @@ -302,7 +302,7 @@ PlasmaCore.ToolTipArea { id: desktop - property int desktopId: index + property string desktopId: isActivityPager ? model.TasksModel.activity : model.TasksModel.virtualDesktop property bool active: (index == pagerModel.currentPage) mainText: model.display @@ -390,7 +390,7 @@ dragTimer.start(); } onDragLeave: { - root.dragSwitchDesktopId = -1; + root.dragSwitchDesktopId = ""; dragTimer.stop(); } onDrop: { @@ -404,7 +404,7 @@ id: desktopMouseArea anchors.fill: parent hoverEnabled : true - onClicked: pagerModel.changePage(desktopId); + onClicked: pagerModel.changePage(index); } Item { @@ -429,7 +429,7 @@ z: 1 + model.StackingOrder property rect geometry: model.Geometry - property int windowId: model.LegacyWinIdList[0] + property int windowId: model.WinIdList[0] property string visibleName: model.display property bool minimized: (model.IsMinimized === true) onMinimizedChanged: desktop.updateSubText() diff --git a/applets/pager/plugin/pagermodel.h b/applets/pager/plugin/pagermodel.h --- a/applets/pager/plugin/pagermodel.h +++ b/applets/pager/plugin/pagermodel.h @@ -100,10 +100,10 @@ Q_INVOKABLE void refresh(); - Q_INVOKABLE void moveWindow(int window, double x, double y, int targetItemId, int sourceItemId, + Q_INVOKABLE void moveWindow(int window, double x, double y, const QVariant &targetItemId, const QVariant &sourceItemId, qreal widthScaleFactor, qreal heightScaleFactor); Q_INVOKABLE void changePage(int page); - Q_INVOKABLE void drop(QMimeData *mimeData, int itemId); + Q_INVOKABLE void drop(QMimeData *mimeData, const QVariant &itemId); Q_INVOKABLE void addDesktop(); Q_INVOKABLE void removeDesktop(); diff --git a/applets/pager/plugin/pagermodel.cpp b/applets/pager/plugin/pagermodel.cpp --- a/applets/pager/plugin/pagermodel.cpp +++ b/applets/pager/plugin/pagermodel.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -359,7 +360,7 @@ int PagerModel::currentPage() const { if (d->pagerType == VirtualDesktops) { - return d->virtualDesktopInfo->currentDesktop() - 1; + return d->virtualDesktopInfo->desktopIds().indexOf(d->virtualDesktopInfo->currentDesktop()); } else { return d->activityInfo->runningActivities().indexOf(d->activityInfo->currentActivity()); } @@ -427,10 +428,10 @@ } if (d->pagerType == VirtualDesktops) { - int virtualDesktop = 1; + int virtualDesktop = 0; for (auto windowModel : d->windowModels) { - windowModel->setVirtualDesktop(virtualDesktop); + windowModel->setVirtualDesktop(d->virtualDesktopInfo->desktopIds().at(virtualDesktop)); ++virtualDesktop; windowModel->setActivity(d->activityInfo->currentActivity()); @@ -440,7 +441,7 @@ const QStringList &runningActivities = d->activityInfo->runningActivities(); for (auto windowModel : d->windowModels) { - windowModel->setVirtualDesktop(0); + windowModel->setVirtualDesktop(); windowModel->setActivity(runningActivities.at(activityIndex)); ++activityIndex; @@ -461,79 +462,94 @@ emit countChanged(); } -void PagerModel::moveWindow(int window, double x, double y, int targetItemId, int sourceItemId, +void PagerModel::moveWindow(int window, double x, double y, const QVariant &targetItemId, const QVariant &sourceItemId, qreal widthScaleFactor, qreal heightScaleFactor) { #if HAVE_X11 - if (!KWindowSystem::isPlatformX11()) { - return; - } - - const WId windowId = (WId)window; - - QPointF dest(x / widthScaleFactor, y / heightScaleFactor); + if (KWindowSystem::isPlatformX11()) { + const WId windowId = (WId)window; - // Don't move windows to negative positions. - dest = QPointF(qMax(dest.x(), qreal(0.0)), qMax(dest.y(), qreal(0.0))); + QPointF dest(x / widthScaleFactor, y / heightScaleFactor); - // Use _NET_MOVERESIZE_WINDOW rather than plain move, so that the WM knows this is a pager request. - NETRootInfo info(QX11Info::connection(), NET::Properties()); - const int flags = (0x20 << 12) | (0x03 << 8) | 1; // From tool, x/y, northwest gravity. + // Don't move windows to negative positions. + dest = QPointF(qMax(dest.x(), qreal(0.0)), qMax(dest.y(), qreal(0.0))); - if (!KWindowSystem::mapViewport()) { - KWindowInfo windowInfo(windowId, NET::WMDesktop | NET::WMState, NET::WM2Activities); + // Use _NET_MOVERESIZE_WINDOW rather than plain move, so that the WM knows this is a pager request. + NETRootInfo info(QX11Info::connection(), NET::Properties()); + const int flags = (0x20 << 12) | (0x03 << 8) | 1; // From tool, x/y, northwest gravity. - if (d->pagerType == VirtualDesktops) { - if (!windowInfo.onAllDesktops()) { - KWindowSystem::setOnDesktop(windowId, targetItemId + 1); - } - } else { - const QStringList &runningActivities = d->activityInfo->runningActivities(); + if (!KWindowSystem::mapViewport()) { + KWindowInfo windowInfo(windowId, NET::WMDesktop | NET::WMState, NET::WM2Activities); - if (targetItemId < runningActivities.length()) { - const QString &newActivity = runningActivities.at(targetItemId); - QStringList activities = windowInfo.activities(); - - if (!activities.contains(newActivity)) { - activities.removeOne(runningActivities.at(sourceItemId)); - activities.append(newActivity); - KWindowSystem::setOnActivities(windowId, activities); + if (d->pagerType == VirtualDesktops) { + if (!windowInfo.onAllDesktops()) { + KWindowSystem::setOnDesktop(windowId, targetItemId.toInt()); + } + } else { + const QStringList &runningActivities = d->activityInfo->runningActivities(); + + if (targetItemId < runningActivities.length()) { + const QString &newActivity = targetItemId.toString(); + QStringList activities = windowInfo.activities(); + + if (!activities.contains(newActivity)) { + activities.removeOne(sourceItemId.toString()); + activities.append(newActivity); + KWindowSystem::setOnActivities(windowId, activities); + } } } - } - // Only move the window if it is not full screen and if it is kept within the same desktop. - // Moving when dropping between desktop is too annoying due to the small drop area. - if (!(windowInfo.state() & NET::FullScreen) && - (targetItemId == sourceItemId || windowInfo.onAllDesktops())) { - const QPoint &d = dest.toPoint(); + // Only move the window if it is not full screen and if it is kept within the same desktop. + // Moving when dropping between desktop is too annoying due to the small drop area. + if (!(windowInfo.state() & NET::FullScreen) && + (targetItemId == sourceItemId || windowInfo.onAllDesktops())) { + const QPoint &d = dest.toPoint(); + info.moveResizeWindowRequest(windowId, flags, d.x(), d.y(), 0, 0); + } + } else { + // setOnDesktop() with viewports is also moving a window, and since it takes a moment + // for the WM to do the move, there's a race condition with figuring out how much to move, + // so do it only as one move. + dest += KWindowSystem::desktopToViewport(targetItemId.toInt(), false); + const QPoint &d = KWindowSystem::constrainViewportRelativePosition(dest.toPoint()); info.moveResizeWindowRequest(windowId, flags, d.x(), d.y(), 0, 0); } - } else { - // setOnDesktop() with viewports is also moving a window, and since it takes a moment - // for the WM to do the move, there's a race condition with figuring out how much to move, - // so do it only as one move. - dest += KWindowSystem::desktopToViewport(targetItemId + 1, false); - const QPoint &d = KWindowSystem::constrainViewportRelativePosition(dest.toPoint()); - info.moveResizeWindowRequest(windowId, flags, d.x(), d.y(), 0, 0); } #else Q_UNUSED(window) Q_UNUSED(x) Q_UNUSED(y) - Q_UNUSED(targetDesktop) - Q_UNUSED(sourceDesktop) + Q_UNUSED(sourceItemId) #endif -} -void PagerModel::changePage(int page) -{ + if (KWindowSystem::isPlatformWayland()) { + if (d->pagerType == VirtualDesktops) { + QAbstractItemModel *model = d->windowModels.at(0)->sourceModel(); + TaskManager::WindowTasksModel *tasksModel = static_cast(model); -#if HAVE_X11 - if (!KWindowSystem::isPlatformX11()) { - return; + for (int i = 0; i < tasksModel->rowCount(); ++i) { + const QModelIndex &idx = tasksModel->index(i, 0); + + if (idx.data(TaskManager::AbstractTasksModel::IsOnAllVirtualDesktops).toBool()) { + break; + } + + const QVariantList &winIds = idx.data(TaskManager::AbstractTasksModel::WinIdList).toList(); + + if (!winIds.isEmpty() && winIds.at(0).toUInt() == window) { + tasksModel->requestVirtualDesktops(idx, QVariantList() << targetItemId.toString()); + break; + } + } + } else { + //FIXME TODO: Activities support. + } } +} +void PagerModel::changePage(int page) +{ if (currentPage() == page) { if (d->showDesktop) { QDBusConnection::sessionBus().asyncCall(QDBusMessage::createMethodCall(QLatin1String("org.kde.plasmashell"), @@ -543,22 +559,18 @@ } } else { if (d->pagerType == VirtualDesktops) { - KWindowSystem::setCurrentDesktop(page + 1); + d->virtualDesktopInfo->requestActivate(d->virtualDesktopInfo->desktopIds().at(page)); } else { const QStringList &runningActivities = d->activityInfo->runningActivities(); if (page < runningActivities.length()) { KActivities::Controller activitiesController; activitiesController.setCurrentActivity(runningActivities.at(page)); } } } - -#else - Q_UNUSED(itemId) -#endif } -void PagerModel::drop(QMimeData *mimeData, int itemId) +void PagerModel::drop(QMimeData *mimeData, const QVariant &itemId) { if (!mimeData) { return; @@ -576,14 +588,14 @@ if (d->pagerType == VirtualDesktops) { for (const auto &id : ids) { - KWindowSystem::setOnDesktop(id, itemId + 1); + KWindowSystem::setOnDesktop(id, itemId.toInt()); } } else { QString newActivity; const QStringList &runningActivities = d->activityInfo->runningActivities(); if (itemId < runningActivities.length()) { - newActivity = runningActivities.at(itemId); + newActivity = itemId.toString(); } if (newActivity.isEmpty()) { @@ -598,37 +610,56 @@ } } } + + return; } -#else - Q_UNUSED(itemId) #endif + + if (KWindowSystem::isPlatformWayland()) { + bool ok; + + const QList &ids = TaskManager::WaylandTasksModel::winIdsFromMimeData(mimeData, &ok); + + if (!ok) { + return; + } + + if (d->pagerType == VirtualDesktops) { + for (const quint32 &id : ids) { + QAbstractItemModel *model = d->windowModels.at(0)->sourceModel(); + TaskManager::WindowTasksModel *tasksModel = static_cast(model); + + for (int i = 0; i < tasksModel->rowCount(); ++i) { + const QModelIndex &idx = tasksModel->index(i, 0); + + if (idx.data(TaskManager::AbstractTasksModel::IsOnAllVirtualDesktops).toBool()) { + break; + } + + const QVariantList &winIds = idx.data(TaskManager::AbstractTasksModel::WinIdList).toList(); + + if (!winIds.isEmpty() && winIds.at(0).toUInt() == id) { + tasksModel->requestVirtualDesktops(idx, QVariantList() << itemId.toString()); + break; + } + } + } + } + } } void PagerModel::addDesktop() { -#if HAVE_X11 - if (!KWindowSystem::isPlatformX11()) { - return; - } - - NETRootInfo info(QX11Info::connection(), NET::NumberOfDesktops); - info.setNumberOfDesktops(info.numberOfDesktops() + 1); -#endif + d->virtualDesktopInfo->requestCreateDesktop(d->virtualDesktopInfo->numberOfDesktops()); } void PagerModel::removeDesktop() { -#if HAVE_X11 - if (!KWindowSystem::isPlatformX11()) { + if (d->virtualDesktopInfo->numberOfDesktops() == 1) { return; } - NETRootInfo info(QX11Info::connection(), NET::NumberOfDesktops); - - if (info.numberOfDesktops() > 1) { - info.setNumberOfDesktops(info.numberOfDesktops() - 1); - } -#endif + d->virtualDesktopInfo->requestRemoveDesktop(d->virtualDesktopInfo->numberOfDesktops() - 1); } void PagerModel::classBegin() diff --git a/applets/pager/plugin/windowmodel.cpp b/applets/pager/plugin/windowmodel.cpp --- a/applets/pager/plugin/windowmodel.cpp +++ b/applets/pager/plugin/windowmodel.cpp @@ -122,7 +122,7 @@ return windowGeo; } else if (role == StackingOrder) { #if HAVE_X11 - const QVariantList &winIds = TaskFilterProxyModel::data(index, AbstractTasksModel::LegacyWinIdList).toList(); + const QVariantList &winIds = TaskFilterProxyModel::data(index, AbstractTasksModel::WinIdList).toList(); if (winIds.count()) { const WId winId = winIds.at(0).toLongLong();