libtaskmanager: Fix dragging launcher icon when separateLaunchers is false

When separateLaunchers is false and there are two opened pinned tasks
and one launcher icon, dragging the launcher icon to a position between
the two pinned tasks always fails for the first time.

The general idea of this fix is to make sure after every move operation,
pinned launhcer item and the corresponding opened window still stay
together.

BUG: 448912
FIXED-IN: 5.26
wilder-5.26
Fushan Wen 4 years ago
parent 300f491d7f
commit a85eaedaae
No known key found for this signature in database
GPG Key ID: 2E48D1487C91DCAA
  1. 19
      libtaskmanager/launchertasksmodel.cpp
  2. 50
      libtaskmanager/tasksmodel.cpp

@ -446,6 +446,24 @@ void LauncherTasksModel::setLauncherList(const QStringList &serializedLaunchers)
} }
if (newLaunchersOrder != d->launchersOrder) { if (newLaunchersOrder != d->launchersOrder) {
const bool isOrderChanged = std::all_of(newLaunchersOrder.cbegin(),
newLaunchersOrder.cend(),
[this](const QUrl &url) {
return d->launchersOrder.contains(url);
})
&& newLaunchersOrder.size() == d->launchersOrder.size();
if (isOrderChanged) {
for (int i = 0; i < newLaunchersOrder.size(); i++) {
int oldRow = d->launchersOrder.indexOf(newLaunchersOrder.at(i));
if (oldRow != i) {
beginMoveRows(QModelIndex(), oldRow, oldRow, QModelIndex(), i);
d->launchersOrder.move(oldRow, i);
endMoveRows();
}
}
} else {
// Use Remove/Insert to update the manual sort map in TasksModel // Use Remove/Insert to update the manual sort map in TasksModel
if (!d->launchersOrder.empty()) { if (!d->launchersOrder.empty()) {
beginRemoveRows(QModelIndex(), 0, d->launchersOrder.size() - 1); beginRemoveRows(QModelIndex(), 0, d->launchersOrder.size() - 1);
@ -464,6 +482,7 @@ void LauncherTasksModel::setLauncherList(const QStringList &serializedLaunchers)
endInsertRows(); endInsertRows();
} }
}
Q_EMIT launcherListChanged(); Q_EMIT launcherListChanged();

@ -1715,7 +1715,8 @@ bool TasksModel::move(int row, int newPos, const QModelIndex &parent)
// Resort. // Resort.
d->forceResort(); d->forceResort();
if (!d->separateLaunchers && isLauncherMove) { if (!d->separateLaunchers) {
if (isLauncherMove) {
const QModelIndex &idx = d->concatProxyModel->index(d->sortedPreFilterRows.at(newPos), 0); const QModelIndex &idx = d->concatProxyModel->index(d->sortedPreFilterRows.at(newPos), 0);
const QUrl &launcherUrl = idx.data(AbstractTasksModel::LauncherUrlWithoutIcon).toUrl(); const QUrl &launcherUrl = idx.data(AbstractTasksModel::LauncherUrlWithoutIcon).toUrl();
@ -1728,6 +1729,32 @@ bool TasksModel::move(int row, int newPos, const QModelIndex &parent)
const QModelIndex &launcherIndex = d->launcherTasksModel->index(launcherPos, 0); const QModelIndex &launcherIndex = d->launcherTasksModel->index(launcherPos, 0);
const int sortIndex = d->sortedPreFilterRows.indexOf(d->concatProxyModel->mapFromSource(launcherIndex).row()); const int sortIndex = d->sortedPreFilterRows.indexOf(d->concatProxyModel->mapFromSource(launcherIndex).row());
d->sortedPreFilterRows.move(sortIndex, newPos); d->sortedPreFilterRows.move(sortIndex, newPos);
/*
* Before moving:
* [pinned 2 (launcher)] [pinned 2 (window)] [pinned 1 (launcher)] [pinned 1 (window)]
* After moving [pinned 1], sortedPreFilterRows may become:
* - row > newPos: [pinned 2 (launcher)] [pinned 1 (launcher)] [pinned 1 (window)] [pinned 2 (window)]
* - row < newPos: [pinned 2 (window)] [pinned 1 (window)] [pinned 1 (launcher)] [pinned 2 (launcher)]
* We need to move [pinned 2 (launcher)] to the left of [pinned 2 (window)]
*/
if (row > newPos && newPos - 1 >= 0 && newPos + 2 < d->sortedPreFilterRows.size()) {
const QModelIndex beforeIdx = d->concatProxyModel->index(d->sortedPreFilterRows.at(newPos - 1), 0); // [pinned 2 (launcher)]
const QModelIndex afterIdx = d->concatProxyModel->index(d->sortedPreFilterRows.at(newPos + 2), 0); // [pinned 2 (window)]
if (appsMatch(beforeIdx, afterIdx)) {
// Move [pinned 2 (launcher)] before [pinned 2 (window)]
d->sortedPreFilterRows.move(newPos - 1, newPos + 2);
}
} else if (row < newPos && newPos - 2 >= 0 && newPos + 1 < d->sortedPreFilterRows.size()) {
const QModelIndex beforeIdx = d->concatProxyModel->index(d->sortedPreFilterRows.at(newPos - 2), 0); // [pinned 2 (window)]
const QModelIndex afterIdx = d->concatProxyModel->index(d->sortedPreFilterRows.at(newPos + 1), 0); // [pinned 2 (launcher)]
if (appsMatch(beforeIdx, afterIdx)) {
// Move [pinned 2 (launcher)] before [pinned 2 (window)]
d->sortedPreFilterRows.move(newPos + 1, newPos - 2);
}
}
// Otherwise move matching windows to after the launcher task (they are // Otherwise move matching windows to after the launcher task (they are
// currently hidden but might be on another virtual desktop). // currently hidden but might be on another virtual desktop).
} else { } else {
@ -1743,6 +1770,22 @@ bool TasksModel::move(int row, int newPos, const QModelIndex &parent)
} }
} }
} }
} else if (newPos > 0 && newPos < d->sortedPreFilterRows.size() - 1) {
/*
* When dragging an unpinned task, a pinned task can also be moved.
* In this case, sortedPreFilterRows is like:
* - before moving: [pinned 1 (launcher item)] [pinned 1 (window)] [unpinned]
* - after moving: [pinned 1 (launcher item)] [unpinned] [pinned 1 (window)]
* So also check the indexes before and after the unpinned task.
*/
const QModelIndex beforeIdx = d->concatProxyModel->index(d->sortedPreFilterRows.at(newPos - 1), 0);
const QModelIndex afterIdx = d->concatProxyModel->index(d->sortedPreFilterRows.at(newPos + 1), 0);
if (appsMatch(beforeIdx, afterIdx)) {
// after adjusting: [unpinned] [pinned 1 (launcher item)] [pinned 1]
d->sortedPreFilterRows.move(newPos, newPos + (row < newPos ? 1 : -1));
}
}
} }
// Setup for syncLaunchers(). // Setup for syncLaunchers().
@ -1818,6 +1861,11 @@ void TasksModel::syncLaunchers()
} }
setLauncherList(sortedShownLaunchers.values() + sortedHiddenLaunchers); setLauncherList(sortedShownLaunchers.values() + sortedHiddenLaunchers);
// The accepted rows are outdated after the item order is changed
invalidateFilter();
d->forceResort();
d->launcherSortingDirty = false; d->launcherSortingDirty = false;
} }

Loading…
Cancel
Save