From 3b789f13450d57b206120fdea33e0e0cc54212f1 Mon Sep 17 00:00:00 2001 From: Wu JiangYu Date: Thu, 5 Nov 2026 20:07:42 +0800 Subject: [PATCH] fix: handle source model reset in dock item proxy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Connect to source model's modelAboutToBeReset and modelReset signals in DockItemModel to properly begin and end model resets, setting m_isUpdating flag to prevent redundant row operations during reset 2. Replace unconditional rebuildTreeSource on grouping role changes in RoleGroupModel with selective validation that checks whether grouping actually changed 3. Handle cases where grouping role is in the changed roles list but the actual grouping value remains the same, avoiding unnecessary full tree rebuilds 4. Add handling for rows that lose their grouping id (empty group), ensuring they are removed from their previous group 5. Include algorithm header for std::any_of These changes fix model consistency issues during source model resets and reduce unnecessary rebuilds when dataChanged signals fire for grouping-related roles without actual grouping changes. Influence: 1. Test dock task manager behavior when source model resets (e.g., application list changes) 2. Verify dock items update correctly when application metadata changes 3. Test grouping behavior when app grouping ids change 4. Verify rows that lose grouping ids are properly removed from groups 5. Test performance with frequent dataChanged signals on grouping roles 6. Verify no visual glitches or crashes during model resets 7. Test with applications that have empty grouping ids fix: 处理停靠项代理中的源模型重置 1. 在 DockItemModel 中连接源模型的 modelAboutToBeReset 和 modelReset 信 号,正确开始和结束模型重置,设置 m_isUpdating 标志以避免重置期间冗余的行 操作 2. 将 RoleGroupModel 中分组角色变化时的无条件 rebuildTreeSource 替换为选 择性验证,检查分组是否实际发生变化 3. 处理分组角色在变化角色列表中但实际分组值未变的情况,避免不必要的完整 树重建 4. 添加对失去分组 id(空分组)的行的处理,确保从之前的分组中移除 5. 包含 algorithm 头文件以使用 std::any_of 这些变更修复了源模型重置期间的模型一致性问题,并减少了当分组相关角色触发 dataChanged 信号但实际分组未变时的不必要重建。 Influence: 1. 测试源模型重置时停靠任务管理器的行为(例如应用程序列表变化) 2. 验证应用程序元数据变化时停靠项正确更新 3. 测试应用程序分组 id 变化时的分组行为 4. 验证失去分组 id 的行正确从分组中移除 5. 测试分组角色频繁触发 dataChanged 信号时的性能 6. 验证模型重置期间无视觉故障或崩溃 7. 测试分组 id 为空的应用程序 PMS: TASK-398199 --- panels/dock/taskmanager/dockitemmodel.cpp | 9 +++++++++ panels/dock/taskmanager/rolegroupmodel.cpp | 21 +++++++++++++++++---- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/panels/dock/taskmanager/dockitemmodel.cpp b/panels/dock/taskmanager/dockitemmodel.cpp index 0a63d3160..b31682fa9 100644 --- a/panels/dock/taskmanager/dockitemmodel.cpp +++ b/panels/dock/taskmanager/dockitemmodel.cpp @@ -52,6 +52,15 @@ void DockItemModel::setSourceModel(QAbstractItemModel *model) QAbstractProxyModel::setSourceModel(model); endResetModel(); + connect(sourceModel(), &QAbstractItemModel::modelAboutToBeReset, this, [this]() { + m_isUpdating = true; + beginResetModel(); + }); + connect(sourceModel(), &QAbstractItemModel::modelReset, this, [this]() { + endResetModel(); + m_isUpdating = false; + }); + connect(sourceModel(), &QAbstractItemModel::rowsInserted, this, [this](const QModelIndex &parent, int first, int last) { if (parent.isValid() || m_isUpdating) return; diff --git a/panels/dock/taskmanager/rolegroupmodel.cpp b/panels/dock/taskmanager/rolegroupmodel.cpp index 6ae68d032..40d3a6e52 100644 --- a/panels/dock/taskmanager/rolegroupmodel.cpp +++ b/panels/dock/taskmanager/rolegroupmodel.cpp @@ -5,6 +5,7 @@ #include "rolegroupmodel.h" #include +#include RoleGroupModel::RoleGroupModel(QAbstractItemModel *sourceModel, int role, QObject *parent) : QAbstractProxyModel(parent) @@ -94,10 +95,22 @@ void RoleGroupModel::setSourceModel(QAbstractItemModel *model) }); connect(sourceModel(), &QAbstractItemModel::dataChanged, this, [this](const QModelIndex &topLeft, const QModelIndex &bottomRight, const QList &roles) { - // TODO: if roles contains m_roleForDeduplication, need update from topLeft 2 bottomRight or just send dataChanged - if (roles.contains(m_roleForDeduplication)) { - rebuildTreeSource(); - return; + // An advertised grouping role need not have changed. Keep delegates + // intact for ordinary application updates, including all-role updates. + if (roles.isEmpty() || roles.contains(m_roleForDeduplication)) { + for (int i = topLeft.row(); i <= bottomRight.row(); ++i) { + const auto group = sourceModel()->index(i, 0).data(m_roleForDeduplication).toString(); + const auto rows = m_map.value(group, nullptr); + // Empty ids are not grouped, but a row that just lost its id + // must be removed from its previous group. + const bool changed = group.isEmpty() + ? std::any_of(m_rowMap.cbegin(), m_rowMap.cend(), [i](const QList *rows) { return rows->contains(i); }) + : !rows || !rows->contains(i); + if (changed) { + rebuildTreeSource(); + return; + } + } } for (int i = topLeft.row(); i <= bottomRight.row(); ++i) {