Skip to content

fix(appsmodel): integrate TrashMonitor for dynamic trash icon - #814

Closed
mhduiy wants to merge 1 commit into
linuxdeepin:masterfrom
mhduiy:agent/pms-bug-bot/f76346c67964
Closed

mhduiy wants to merge 1 commit into
linuxdeepin:masterfrom
mhduiy:agent/pms-bug-bot/f76346c67964

Conversation

@mhduiy

@mhduiy mhduiy commented Sep 15, 2026 •

Copy link
Copy Markdown
Contributor

Root Cause Analysis

The TrashMonitor class in dde-launchpad implements trash state monitoring via GFileMonitor on trash:///, providing trashItemCount() and the trashAttributeChanged() signal. However, it was never instantiated or connected in AppsModel. The AppsModel::data() IconNameRole branch (appsmodel.cpp:177-181) directly passes through the static Icon=user-trash from dde-trash.desktop, with no dynamic switching logic. This causes the trash icon in the launcher's category view to always show a fixed style regardless of actual trash state.

Fix

Integrated the existing TrashMonitor into AppsModel: instantiate it in the constructor and connect its trashAttributeChanged() signal to a new onTrashAttributeChanged() slot. In data()'s IconNameRole branch, return user-trash-full (when trashItemCount() > 0) or user-trash for dde-trash.desktop. The slot emits dataChanged for the trash row so QML refreshes the icon immediately. This matches the approach suggested by the development team (PMS history #9).

Change Safety Assessment

Code Safety

  • Risk Level: Low
  • The target code (IconNameRole branch) was introduced in a refactoring commit (b3d8fbd7), not a bug fix — this change does not revert any historical fix.
  • No function signatures modified, no public interfaces removed; only an early return for dde-trash.desktop is added before the existing logic.

Business Impact Scope

  • Launcher category/all-apps views — trash icon display: the trash icon now dynamically switches between empty (user-trash) and full (user-trash-full) based on actual trash item count. Other app icons are unaffected.

Verification Suggestion

  • Verify the trash icon shows user-trash when the trash is empty and user-trash-full when files exist, and that it switches in real-time when adding/removing files while the launcher is open.

根因分析

dde-launchpad 中 TrashMonitor 类已实现回收站状态监听(通过 GFileMonitor 监听 trash:///,提供 trashItemCount() 和 trashAttributeChanged() 信号),但在 AppsModel 中从未被实例化或连接。AppsModel::data() 的 IconNameRole 分支(appsmodel.cpp:177-181)直接透传 dde-trash.desktop 中的静态 Icon=user-trash,无动态切换逻辑,导致启动器分类视图中回收站图标始终显示固定样式,不随回收站实际状态变化。

修复方案

在 AppsModel 中集成已有的 TrashMonitor:构造函数中实例化并连接 trashAttributeChanged() 信号到新增的 onTrashAttributeChanged() 槽;data() 的 IconNameRole 分支中对 dde-trash.desktop 根据 trashItemCount() 返回 user-trash-full(>0)或 user-trash(=0);槽函数发射 dataChanged 通知 QML 即时刷新图标。符合开发团队在 PMS 历史记录 #9 中指明的技术方向。

改动安全评估

代码安全评估

  • 风险等级: 低风险
  • 目标代码(IconNameRole 分支)由重构提交 b3d8fbd7 引入,非 bug 修复产物,本次改动不会撤销历史修复。
  • 未修改任何函数签名、未删除公开接口,仅在现有逻辑前为 dde-trash.desktop 增加 early return。

业务影响范围

  • 启动器分类视图/所有应用视图 — 回收站图标显示:回收站图标将根据实际文件数量在空(user-trash)和有文件(user-trash-full)样式间动态切换。其他应用图标不受影响。

验证建议

  • 验证回收站为空时图标显示为 user-trash、有文件时显示为 user-trash-full,且在启动器打开状态下放入/清空文件时图标能实时切换。

Summary by Sourcery

Integrate trash monitoring into AppsModel so the launcher dynamically displays the empty or full trash icon.

Bug Fixes:

  • Make the launcher trash icon reflect whether the trash contains items and update immediately when its state changes.

Enhancements:

  • Integrate trash state monitoring into AppsModel without affecting other application icons.

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.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @mhduiy, you've used your own review budget of 250,000 diff characters for the last 7 days.

You can request another review in 5 hours and 26 minutes by commenting @sourcery-ai review. Upgrade to get a review now.

@deepin-ci-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: mhduiy

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@sourcery-ai

sourcery-ai Bot commented Sep 15, 2026

Copy link
Copy Markdown
Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

AppsModel now owns and observes TrashMonitor, dynamically returns the appropriate empty/full trash icon, and notifies QML to refresh the trash row when the monitored trash state changes.

Sequence diagram for dynamic trash icon updates

sequenceDiagram
    participant TrashMonitor
    participant AppsModel
    participant QML
    TrashMonitor-->>AppsModel: trashAttributeChanged()
    AppsModel->>AppsModel: onTrashAttributeChanged()
    AppsModel-->>QML: dataChanged(trashIndex, IconNameRole)
    QML->>AppsModel: data(index, IconNameRole)
    AppsModel->>TrashMonitor: trashItemCount()
    TrashMonitor-->>AppsModel: item count
    AppsModel-->>QML: user-trash or user-trash-full
Loading

File-Level Changes

Change Details Files
Integrate TrashMonitor into AppsModel to track trash state and trigger model refreshes.
  • Instantiate TrashMonitor with AppsModel ownership.
  • Connect trash state changes to a dedicated slot.
  • Emit IconNameRole dataChanged for the trash item when its state changes.
src/models/appsmodel.cpp
src/models/appsmodel.h
Select the trash icon dynamically based on the current item count.
  • Detect the normalized dde-trash.desktop entry in the IconNameRole path.
  • Return user-trash-full for non-empty trash and user-trash for empty trash.
  • Preserve existing icon fallback behavior for all other applications.
src/models/appsmodel.cpp

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@deepin-ci-robot

Copy link
Copy Markdown

deepin pr auto review

🤖 AI 代码审查报告

总体评分: 97 分 (通过阈值: 70分)

Pass


📊 总体评价

项目 结果
审查结论 代码审查通过
PR 标题 fix(appsmodel): integrate TrashMonitor for dynamic trash icon
PR 地址 #814
修改文件 src/models/appsmodel.cpp, src/models/appsmodel.h
分析模式 全量分析(GitHub PR)
评分详情 未发现安全漏洞,代码实现逻辑清晰,与 PR 目的(集成 TrashMonitor 实现回收站图标动态切换)一致。仅有轻微的代码质量和性能改进建议。

🔍 详细分析

1. 语法逻辑 ✓(25/25 分)

评价: 语法正确,逻辑清晰 ✓

潜在问题:
✅ 未发现明显问题

分析说明:

  • 头文件包含 #include "trashmonitor.h" 正确引入,位于项目头文件区域
  • 前向声明 class TrashMonitor; 正确使用(头文件中仅使用指针,无需完整定义)
  • m_trashMonitor = new TrashMonitor(this); 使用 this 作为 parent,Qt 父子对象机制确保生命周期管理正确,无内存泄漏
  • 信号槽连接使用 Qt 5 类型安全的函数指针语法,正确
  • data() 方法中访问 m_trashMonitor 前进行了空指针检查(&& m_trashMonitor),防御性编程正确
  • onTrashAttributeChanged() 中 indexFromDesktopId("dde-trash") 经 normalizedDesktopId 规范化为 "dde-trash.desktop",与 data() 中的比较逻辑一致
  • dataChanged 信号正确指定 IconNameRole 角色

建议: 无


2. 代码质量 ✓(24/25 分)

评价: 代码结构清晰,注释完整 ✓

潜在问题:

  1. src/models/appsmodel.cpp:182, AppsModel::data() — 字符串字面量 "dde-trash.desktop"(line 182)和 "dde-trash"(line 441)分散在两处,可考虑提取为常量以保证一致性,但符合现有代码风格(-1 分)

分析说明:

  • 新增代码完全遵循现有代码风格和模式
  • onTrashAttributeChanged() 是小而专注的函数,职责单一
  • 无代码重复、无残留调试代码
  • 新增函数未添加注释,但与类中其他私有槽函数风格一致

建议:

  • 考虑将 "dde-trash.desktop" 提取为类常量,避免字符串不一致风险:
// 在 appsmodel.h 中添加
static constexpr auto kTrashDesktopId = "dde-trash.desktop";

3. 代码性能 ✓(18/20 分)

评价: 性能良好,资源使用合理 ✓

潜在问题:

  1. src/models/appsmodel.cpp:183, AppsModel::data() — data() 路径中 trashItemCount() 调用 g_file_query_info() 执行同步 I/O 操作。虽然仅对 dde-trash.desktop 单一项触发,但如果 data() 频繁被调用(如 Qt 委托绘制时),可能引入轻微延迟(-2 分)

分析说明:

  • 使用 GFileMonitor 监听回收站变化,事件驱动而非轮询,设计合理
  • onTrashAttributeChanged() 仅对回收站项的索引发出 dataChanged,而非对所有行发出通知,性能更优
  • 使用 QStringLiteral 避免临时 QString 构造
  • 无算法复杂度问题

建议:

  • 考虑缓存 trashItemCount 值,在 trashAttributeChanged 信号触发时更新,data() 中读取缓存值:
// 在 TrashMonitor 中缓存 trash item count
// int m_trashItemCount = 0;
// 在 onTrashMonitorChanged() 中更新缓存值
// 在 data() 中读取缓存值而非同步查询

4. 代码安全 ✓(30/30 分)

评价: 存在0个安全漏洞 ✓

🔐 存在 0 个安全漏洞

安全漏洞详情:
✅ 未发现安全漏洞

漏洞对比统计:新增漏洞 0 个,减少漏洞 0 个,持平 0 个

分析说明:

  • desktopId 比较是安全的字符串比较操作,无注入风险
  • 无命令注入、SQL 注入、路径遍历风险
  • 无硬编码密钥、凭证或敏感信息
  • 无不安全密码算法使用
  • 使用 Qt QString,边界安全,无缓冲区溢出风险
  • GIO 调用使用 NULL 作为 cancellable 和 error 参数,在此上下文中可接受(非安全敏感操作)
  • 日志中无敏感信息泄露

建议: 无


📋 OCR 审查结果

编号 严重级别 文件 行号 描述 判定
1 bug/critical appsmodel.cpp 183 在 const 方法 data() 中调用非 const 的 trashItemCount() 会导致编译失败 误报 — m_trashMonitor 是指针成员,在 const 方法中指针变为 const 但所指对象仍为非 const,调用非 const 方法合法,代码可正常编译
2 low appsmodel.h 95 "dde-trash.desktop" 与 "dde-trash" 字符串不一致 有效 — 已在代码质量维度记录
3 low appsmodel.h 100 m_trashMonitor 空指针检查冗余 部分有效 — 属防御性编程,可接受
4 medium appsmodel.h 95 同步 GIO 调用可能影响性能 有效 — 已在代码性能维度记录

💡 改进建议代码示例

// 建议优化:缓存 trashItemCount 并使用常量

// appsmodel.h 中添加常量
private:
    static constexpr auto kTrashDesktopId = "dde-trash.desktop";

// appsmodel.cpp 中 data() 修改
case AppsModel::IconNameRole: {
    const QString desktopId = normalizedDesktopId(sourceData(sourceIndex, DesktopIdRoleName).toString());
    if (desktopId == QLatin1String(kTrashDesktopId) && m_trashMonitor) {
        // 使用缓存的 trashItemCount 而非每次同步查询
        return m_trashMonitor->trashItemCount() > 0
            ? QStringLiteral("user-trash-full")
            : QStringLiteral("user-trash");
    }
    // ...
}

📝 审查结论

本次 PR 修改了 src/models/appsmodel.cpp 和 src/models/appsmodel.h 两个文件,目的是集成 TrashMonitor 实现回收站图标的动态切换(根据回收站是否有内容在 user-trash-full 和 user-trash 图标之间切换)。

代码实现与 PR 目的完全一致,逻辑清晰,无安全漏洞。仅有轻微的代码质量(魔法字符串不一致)和性能(同步 GIO 调用)改进建议,不影响代码的正确性和可用性。

总分:97 分 — 代码审查通过


本报告由 AI 代码审查工具自动生成
审查时间:2026-09-15
平台:GitHub PR

@mhduiy

mhduiy commented Sep 15, 2026

Copy link
Copy Markdown
Contributor Author

经讨论,文件管理器侧修复,实时更换图标来实现这个功能,我们无需修改

@mhduiy mhduiy closed this Sep 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants