From 10f1a492281814dab7f29f45852909ad9eda5d21 Mon Sep 17 00:00:00 2001 From: zhangkun2 Date: Tue, 15 Sep 2026 16:52:28 +0800 Subject: [PATCH] fix(appsmodel): integrate TrashMonitor for dynamic trash icon 1. Instantiate TrashMonitor in AppsModel constructor and connect its trashAttributeChanged() signal to a new onTrashAttributeChanged() slot 2. In data() IconNameRole branch, return user-trash-full or user-trash based on trashItemCount() when desktopId is dde-trash.desktop 3. Emit dataChanged for the trash row on attribute change so QML refreshes the icon immediately Log: Integrate the existing TrashMonitor into AppsModel so the trash icon dynamically switches between user-trash and user-trash-full based on item count. PMS: BUG-285725 Influence: Trash icon in launcher now reflects actual trash state. --- src/models/appsmodel.cpp | 16 ++++++++++++++++ src/models/appsmodel.h | 3 +++ 2 files changed, 19 insertions(+) diff --git a/src/models/appsmodel.cpp b/src/models/appsmodel.cpp index cebe3b34..e45b3133 100644 --- a/src/models/appsmodel.cpp +++ b/src/models/appsmodel.cpp @@ -6,6 +6,7 @@ #include "../ddeintegration/appmgr.h" #include "iconutils.h" +#include "trashmonitor.h" #include #include @@ -57,6 +58,8 @@ AppsModel::AppsModel(QObject *parent) connect(m_iconCacheWatcher, &DFileWatcherManager::fileModified, m_iconUpdateTimer, qOverload<>(&QTimer::start)); connect(m_iconCacheWatcher, &DFileWatcherManager::fileAttributeChanged, m_iconUpdateTimer, qOverload<>(&QTimer::start)); connect(m_iconUpdateTimer, &QTimer::timeout, this, &AppsModel::updateIconData); + m_trashMonitor = new TrashMonitor(this); + connect(m_trashMonitor, &TrashMonitor::trashAttributeChanged, this, &AppsModel::onTrashAttributeChanged); connect(AppMgr::instance(), &AppMgr::pendingAppItemReady, this, [this](const QString &desktopId) { if (!m_sourceModel) return; @@ -175,6 +178,12 @@ QVariant AppsModel::data(const QModelIndex &index, int role) const case AppsModel::DDECategoryRole: return sourceData(sourceIndex, DDECategoryRoleName); case AppsModel::IconNameRole: { + const QString desktopId = normalizedDesktopId(sourceData(sourceIndex, DesktopIdRoleName).toString()); + if (desktopId == QStringLiteral("dde-trash.desktop") && m_trashMonitor) { + return m_trashMonitor->trashItemCount() > 0 + ? QStringLiteral("user-trash-full") + : QStringLiteral("user-trash"); + } const QString iconName = sourceData(sourceIndex, IconNameRoleName).toString(); if (iconName.isEmpty()) return QStringLiteral("application-x-desktop"); @@ -426,3 +435,10 @@ void AppsModel::updateIconData() if (rowCount() > 0) Q_EMIT dataChanged(index(0, 0), index(rowCount() - 1, 0), { AppsModel::IconNameRole }); } + +void AppsModel::onTrashAttributeChanged() +{ + const QModelIndex trashIndex = indexFromDesktopId(QStringLiteral("dde-trash")); + if (trashIndex.isValid()) + Q_EMIT dataChanged(trashIndex, trashIndex, { AppsModel::IconNameRole }); +} diff --git a/src/models/appsmodel.h b/src/models/appsmodel.h index 5ca0a80d..831e11dd 100644 --- a/src/models/appsmodel.h +++ b/src/models/appsmodel.h @@ -16,6 +16,7 @@ class DFileWatcherManager; } class QTimer; +class TrashMonitor; // Adapts dde-shell's application model to the roles and desktop IDs expected by launchpad. class AppsModel : public QAbstractListModel @@ -91,10 +92,12 @@ public Q_SLOTS: bool acceptsSourceIndex(const QModelIndex &sourceIndex) const; bool shouldDelaySourceIndex(const QModelIndex &sourceIndex) const; void updateIconData(); + void onTrashAttributeChanged(); QStringList m_excludedAppIdList; Dtk::Core::DFileWatcherManager *m_iconCacheWatcher = nullptr; QTimer *m_iconUpdateTimer = nullptr; + TrashMonitor *m_trashMonitor = nullptr; QPointer m_sourceModel; QList m_rows; QList m_sourceConnections;