From 7907104c8e9d94fda7390f6c9ee8c1d225f9c5d5 Mon Sep 17 00:00:00 2001 From: wjyrich Date: Wed, 6 May 2026 10:24:04 +0800 Subject: [PATCH] feat: add window icon whitelist for dock task manager MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Add a new dconfig setting "windowIconWhitelist" with default value ["wechat"] 2. When window split mode is enabled, the dock now checks the whitelist to decide whether to use window icons instead of app icons for specific applications 3. Fix model reset in DockItemModel::setSourceModel to use beginResetModel/endResetModel instead of manual row insertion/removal for better model consistency 4. Update X11 window monitor to trigger icon update when a new window is mapped The window icon whitelist is needed for apps like WeChat that provide superior window icon quality compared to their app icons, enhancing the visual experience when window split is disabled. Log: Added window icon whitelist config for dock task manager Influence: 1. Verify WeChat and other whitelisted apps display correct icons when window split is disabled 2. Test default whitelist behavior with WeChat running 3. Check that non-whitelisted apps still use app icons when window split is disabled 4. Test the new dconfig setting can be modified and persists correctly 5. Ensure DockItemModel resets work correctly without data corruption 6. Verify X11 window monitor still functions properly with icon update call feat: 为任务栏任务管理器添加窗口图标白名单功能 1. 添加新的 dconfig 设置"windowIconWhitelist",默认值为["wechat"] 2. 当窗口拆分模式启用时,任务栏会检查白名单,决定是否对特定应用使用窗口 图标而非应用图标 3. 修复 DockItemModel::setSourceModel 中的模型重置,改用 beginResetModel/endResetModel 替代手动行插入/删除,以提高模型一致性 4. 更新 X11 窗口监视器,在新窗口映射时触发图标更新 对于微信等提供比应用图标更优质窗口图标的应用,窗口图标白名单是必要的,可 在窗口拆分禁用时提升视觉体验。 Log: 为任务栏添加窗口图标白名单配置 Influence: 1. 验证在白名单中的应用(如微信)在禁用窗口拆分时显示正确图标 2. 使用微信测试默认白名单行为 3. 检查非白名单应用在禁用窗口拆分时仍使用应用图标 4. 测试新的 dconfig 设置可以被修改并持久保存 5. 确保 DockItemModel 重置操作正常,无数据损坏 6. 验证 X11 窗口监视器在添加图标更新调用后仍正常工作 PMS: TASK-389031 --- .../org.deepin.ds.dock.taskmanager.json | 11 ++++++++++ panels/dock/taskmanager/dockcombinemodel.cpp | 22 +++++++++++++++---- panels/dock/taskmanager/dockitemmodel.cpp | 14 ++---------- panels/dock/taskmanager/globals.h | 1 + .../dock/taskmanager/taskmanagersettings.cpp | 6 +++++ panels/dock/taskmanager/taskmanagersettings.h | 3 +++ panels/dock/taskmanager/x11windowmonitor.cpp | 2 ++ 7 files changed, 43 insertions(+), 16 deletions(-) diff --git a/panels/dock/taskmanager/dconfig/org.deepin.ds.dock.taskmanager.json b/panels/dock/taskmanager/dconfig/org.deepin.ds.dock.taskmanager.json index 3ac48dc91..b93bcb8d8 100644 --- a/panels/dock/taskmanager/dconfig/org.deepin.ds.dock.taskmanager.json +++ b/panels/dock/taskmanager/dconfig/org.deepin.ds.dock.taskmanager.json @@ -96,6 +96,17 @@ "description": "The items which is docked when dock is started.", "permissions": "readwrite", "visibility": "private" + }, + "windowIconWhitelist": { + "value": ["wechat"], + "serial": 0, + "flags": [], + "name": "windowIconWhitelist", + "name[zh_CN]": "窗口图标白名单", + "description": "List of app id that should prefer window icon when window split is disabled", + "permissions": "readwrite", + "visibility": "private" } + } } diff --git a/panels/dock/taskmanager/dockcombinemodel.cpp b/panels/dock/taskmanager/dockcombinemodel.cpp index cba9d77be..2ba5bd0e7 100644 --- a/panels/dock/taskmanager/dockcombinemodel.cpp +++ b/panels/dock/taskmanager/dockcombinemodel.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd. +// SPDX-FileCopyrightText: 2025 - 2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: GPL-3.0-or-later @@ -7,7 +7,7 @@ #include "globals.h" #include "rolecombinemodel.h" #include "taskmanager.h" - +#include "taskmanagersettings.h" namespace dock { DockCombineModel::DockCombineModel(QAbstractItemModel *major, QAbstractItemModel *minor, int majorRoles, CombineFunc func, QObject *parent) @@ -55,10 +55,24 @@ QVariant DockCombineModel::data(const QModelIndex &index, int role) const return res; } case TaskManager::IconNameRole: { - QString winTitle = RoleCombineModel::data(index, m_roleMaps.value(TaskManager::WinIconRole)).toString(); + auto winIcon = RoleCombineModel::data(index, m_roleMaps.value(TaskManager::WinIconRole)).toString(); + bool useWinIcon = false; + if (!winIcon.isEmpty() && TaskManagerSettings::instance()->isWindowSplit()) { + auto desktopId = data(index, TaskManager::DesktopIdRole).toString(); + auto whitelist = TaskManagerSettings::instance()->windowIconWhitelist(); + for (const auto &id : whitelist) { + if (desktopId.contains(id)) { + useWinIcon = true; + break; + } + } + } + if (useWinIcon) { + return winIcon; + } auto icon = RoleCombineModel::data(index, m_roleMaps.value(TaskManager::IconNameRole)).toString(); if (icon.isEmpty()) { - icon = RoleCombineModel::data(index, m_roleMaps.value(TaskManager::WinIconRole)).toString(); + icon = winIcon; } return icon; } diff --git a/panels/dock/taskmanager/dockitemmodel.cpp b/panels/dock/taskmanager/dockitemmodel.cpp index d05965260..55d7316e7 100644 --- a/panels/dock/taskmanager/dockitemmodel.cpp +++ b/panels/dock/taskmanager/dockitemmodel.cpp @@ -48,17 +48,9 @@ void DockItemModel::setSourceModel(QAbstractItemModel *model) sourceModel()->disconnect(this); } - auto currentCount = this->rowCount(); - auto newCount = model->rowCount(); + beginResetModel(); QAbstractProxyModel::setSourceModel(model); - - if (newCount > currentCount) { - beginInsertRows(QModelIndex(), currentCount, newCount - 1); - endInsertRows(); - } else if (newCount < currentCount) { - beginRemoveRows(QModelIndex(), newCount, currentCount); - endRemoveRows(); - } + endResetModel(); connect(sourceModel(), &QAbstractItemModel::rowsInserted, this, [this](const QModelIndex &parent, int first, int last) { if (parent.isValid() || m_isUpdating) @@ -87,8 +79,6 @@ void DockItemModel::setSourceModel(QAbstractItemModel *model) endMoveRows(); }); - auto bottomRight = this->index(std::min(currentCount, newCount), 0); - Q_EMIT dataChanged(index(0, 0), bottomRight); m_isUpdating = false; } diff --git a/panels/dock/taskmanager/globals.h b/panels/dock/taskmanager/globals.h index 6db543a09..74509a1ab 100644 --- a/panels/dock/taskmanager/globals.h +++ b/panels/dock/taskmanager/globals.h @@ -26,6 +26,7 @@ static inline const QString TASKMANAGER_CGROUPS_BASED_GROUPING_SKIP_APPIDS = "cg static inline const QString TASKMANAGER_CGROUPS_BASED_GROUPING_SKIP_CATEGORIES = "cgroupsBasedGroupingSkipCategories"; static inline const QString TASKMANAGER_DOCKEDITEMS_KEY = "Docked_Items"; constexpr auto TASKMANAGER_DOCKEDELEMENTS_KEY = "dockedElements"; +constexpr auto TASKMANAGER_WINDOW_ICON_WHITELIST_KEY = "windowIconWhitelist"; // model roleNames constexpr auto MODEL_WINID = "winId"; diff --git a/panels/dock/taskmanager/taskmanagersettings.cpp b/panels/dock/taskmanager/taskmanagersettings.cpp index 9d1f05663..ed09ea9a4 100644 --- a/panels/dock/taskmanager/taskmanagersettings.cpp +++ b/panels/dock/taskmanager/taskmanagersettings.cpp @@ -59,6 +59,7 @@ TaskManagerSettings::TaskManagerSettings(QObject *parent) m_dockedElements = m_taskManagerDconfig->value(TASKMANAGER_DOCKEDELEMENTS_KEY, {}).toStringList(); m_cgroupsBasedGroupingSkipAppIds = m_taskManagerDconfig->value(TASKMANAGER_CGROUPS_BASED_GROUPING_SKIP_APPIDS, {"deepin-terminal"}).toStringList(); m_cgroupsBasedGroupingSkipCategories = m_taskManagerDconfig->value(TASKMANAGER_CGROUPS_BASED_GROUPING_SKIP_CATEGORIES, {"TerminalEmulator"}).toStringList(); + m_windowIconWhitelist = m_taskManagerDconfig->value(TASKMANAGER_WINDOW_ICON_WHITELIST_KEY, {"wechat"}).toStringList(); migrateFromDockedItems(); } @@ -104,6 +105,11 @@ QStringList TaskManagerSettings::cgroupsBasedGroupingSkipCategories() const return m_cgroupsBasedGroupingSkipCategories; } +QStringList TaskManagerSettings::windowIconWhitelist() const +{ + return m_windowIconWhitelist; +} + QStringList TaskManagerSettings::dockedElements() const { return m_dockedElements; diff --git a/panels/dock/taskmanager/taskmanagersettings.h b/panels/dock/taskmanager/taskmanagersettings.h index 31b360ece..9abab1b51 100644 --- a/panels/dock/taskmanager/taskmanagersettings.h +++ b/panels/dock/taskmanager/taskmanagersettings.h @@ -35,6 +35,8 @@ class TaskManagerSettings : public QObject QStringList cgroupsBasedGroupingSkipIds() const; QStringList cgroupsBasedGroupingSkipCategories() const; + QStringList windowIconWhitelist() const; + void setDockedElements(const QStringList &elements); void toggleDockedElement(const QString &element); void appendDockedElement(const QString &element); @@ -62,6 +64,7 @@ class TaskManagerSettings : public QObject bool m_windowSplit; bool m_cgroupsBasedGrouping; QStringList m_dockedElements; + QStringList m_windowIconWhitelist; QStringList m_cgroupsBasedGroupingSkipAppIds; QStringList m_cgroupsBasedGroupingSkipCategories; }; diff --git a/panels/dock/taskmanager/x11windowmonitor.cpp b/panels/dock/taskmanager/x11windowmonitor.cpp index 7eca4f72a..6116beede 100644 --- a/panels/dock/taskmanager/x11windowmonitor.cpp +++ b/panels/dock/taskmanager/x11windowmonitor.cpp @@ -185,6 +185,8 @@ void X11WindowMonitor::onWindowMapped(xcb_window_t xcb_window) uint32_t value_list[] = { XCB_EVENT_MASK_PROPERTY_CHANGE | XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_VISIBILITY_CHANGE}; xcb_change_window_attributes(X11->getXcbConnection(), xcb_window, XCB_CW_EVENT_MASK, value_list); trackWindow(window.get()); + + window->updateIcon(); Q_EMIT AbstractWindowMonitor::windowAdded(static_cast>(window.get())); }