Skip to content

fix(wallpaper): refresh stale thumbnails - #207

Merged
deepin-bot[bot] merged 1 commit into
linuxdeepin:masterfrom
mhduiy:bug-381229-thumbnail-cache
Oct 29, 2026
Merged

deepin-bot[bot] merged 1 commit into
linuxdeepin:masterfrom
mhduiy:bug-381229-thumbnail-cache

Conversation

@mhduiy

@mhduiy mhduiy commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

PMS: BUG-381229

修改

  • 使用 Qt 文件状态变更时间判断缩略图缓存是否过期,原图同路径替换后按需重新生成。
  • 路径和 FD 入口都使用原图时间;FD 使用 DontCloseHandle,不接管调用方的描述符。
  • 保留现有缓存命名、异步缩放和模糊处理逻辑;按要求不修改 changelog。

验证

  • wallpaper-cache-unit:通过(1/1 CTest 目标),包含路径/FD 同路径替换、mtime 保持不变及回退的回归检查。
  • 隔离 session D-Bus 实际调用:正常缓存命中、暖缓存换图、重启后复用及过期重建均通过,已检查生成图片的尺寸和像素。

边界

  • Qt 文件时间使用毫秒精度;原图更新在下一次请求时触发缓存检查。

Summary by Sourcery

Invalidate stale wallpaper thumbnails based on source file changes and regenerate them on demand.

Bug Fixes:

  • Refresh cached wallpaper thumbnails when the source image has been replaced, including requests made through file paths and file descriptors.
  • Preserve caller ownership of file descriptors while using the source file’s metadata change time for cache validation.

Enhancements:

  • Retain existing thumbnail naming, asynchronous scaling, and blur-processing behavior while adding source-change validation.

Tests:

  • Add regression coverage for path- and file-descriptor-based source replacement, including unchanged and reverted modification times.

1. Check thumbnail freshness with Qt metadata change times.
2. Use original file times for path and file-descriptor requests.
3. Cover same-path replacements with preserved or older modification times.

Log: Refresh outdated thumbnails after source replacement.
Influence: Replaced wallpapers display updated thumbnails.

fix(wallpaper): 修复壁纸缩略图缓存不刷新

1. 使用 Qt 文件状态变更时间判断缩略图缓存是否过期。
2. 路径和文件描述符入口均使用原图时间进行校验。
3. 覆盖同路径换图且修改时间保持不变或回退的回归场景。

Log: 原图替换后重新生成过期缩略图。
PMS: BUG-381229
Influence: 替换壁纸后显示更新的缩略图。
@mhduiy
mhduiy force-pushed the bug-381229-thumbnail-cache branch from b3f59c2 to 3b074cb Compare October 29, 2026 08:16
@mhduiy
mhduiy requested a review from yixinshark October 29, 2026 08:16
@sourcery-ai

sourcery-ai Bot commented Oct 29, 2026

Copy link
Copy Markdown

Reviewer's Guide

The PR prevents stale wallpaper thumbnails by validating cache entries against the source file’s Qt metadata-change timestamp, applies the check consistently to path and FD requests while preserving FD ownership, and adds regression tests for same-path replacement, timestamp rollback, and regenerated image contents.

Sequence diagram for timestamp-validated wallpaper cache lookup

sequenceDiagram
    participant Client
    participant Service as WallpaperCacheService
    participant Source as OriginalFile
    participant Cache as CachedWallpaper
    participant Scaler as ScaleImageThread

    Client->>Service: GetProcessedImagePaths(originalPath, sizes)
    Service->>Source: metadataChangeTime()
    Service->>Cache: getCachedImagePaths(originalPath, sizes, sourceChangeTime)
    Cache->>Cache: findCachedImagePaths(pathMd5, sizes, sourceChangeTime)
    Cache->>Cache: metadataChangeTime() on cached image
    alt cache timestamp is current
        Cache-->>Service: cached paths
        Service-->>Client: cached paths
    else cache is missing or stale
        Cache->>Scaler: generate thumbnails
        Scaler-->>Cache: processed paths
        Cache-->>Service: regenerated paths
        Service-->>Client: regenerated paths
    end
Loading

Sequence diagram for FD-based wallpaper cache refresh

sequenceDiagram
    participant Client
    participant Service as WallpaperCacheService
    participant FD as SourceFileDescriptor
    participant Cache as CachedWallpaper
    participant Scaler as ScaleImageThread

    Client->>Service: GetProcessedImagePathByFd(fd, imagePathMd5, sizes)
    Service->>FD: open(ReadOnly, DontCloseHandle)
    Service->>FD: fileTime(FileMetadataChangeTime)
    Service->>Cache: findCachedImagePaths(imagePathMd5, sizes, sourceChangeTime)
    alt cache is current
        Cache-->>Service: cached paths
        Service-->>Client: cached paths
    else cache is missing or stale
        Service->>Scaler: import and generate thumbnails
        Scaler-->>Service: processed paths
        Service->>Cache: getCachedImagePaths(destinationPath, sizes, true, sourceChangeTime)
        Cache-->>Service: refreshed paths
        Service-->>Client: refreshed paths
    end
Loading

File-Level Changes

Change Details Files
Add source-time validation to cached thumbnail lookup so replacing the original image invalidates stale thumbnails even when the path and cache key remain unchanged.
  • Thread an optional Qt metadata-change timestamp through cache lookup APIs.
  • Reject cached files whose metadata-change time predates the source timestamp, while retaining existing file validity checks.
  • Preserve existing cache naming, asynchronous scaling, and blur processing behavior.
src/plugin-qt/wallpapercache/cachedwallpaper.cpp
src/plugin-qt/wallpapercache/cachedwallpaper.h
Use the original file’s metadata-change time consistently for path and file-descriptor requests without taking ownership of caller resources.
  • Read the source timestamp from path-based requests and pass it into cache validation.
  • Open FD inputs with DontCloseHandle and use their timestamp before importing or regenerating cached images.
  • Compare FD requests against the original source timestamp rather than the imported destination copy.
src/plugin-qt/wallpapercache/wallpapercacheservice.cpp
Add regression coverage for thumbnail regeneration after same-path replacement through both supported request paths.
  • Exercise path and FD APIs with replacements that change or preserve modification time.
  • Verify cache misses trigger asynchronous regeneration and preserve dimensions and replacement pixel colors.
  • Cover timestamp rollback and confirm the caller-owned FD remains usable by using DontCloseHandle.
src/plugin-qt/wallpapercache/tests/test_wallpaper_cache_unit.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

@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.

Hey - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨

@deepin-ci-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: mhduiy, yixinshark

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

@deepin-ci-robot

Copy link
Copy Markdown

deepin pr auto review

🤖 AI 代码审查报告

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

Pass


📊 总体评价

项目 结果
审查结论 代码审查通过
评分详情 本次提交修复了壁纸缩略图缓存过期问题,通过引入源文件元数据变更时间(ctime)比较机制, 在源壁纸被替换后能正确检测并刷新过期的缩略图缓存。代码逻辑正确,新增了完善的单元测试覆盖 path 和 fd 两种调用路径。安全方面无漏洞引入。代码质量方面存在少量测试健壮性改进空间和 一个缓存查找逻辑的设计优化建议,但不影响整体功能正确性。

🔍 详细分析

1. 语法逻辑 ✅

评价: 语法正确,逻辑清晰 ✅ 通过

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

建议: []


2. 代码质量 ✅

评价: 代码结构清晰,存在少量测试健壮性改进空间 ✅ 通过

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

建议: ['在 findCachedImagePaths 中,将过期检测的 return {} 改为 continue,仅跳过过期条目,保留其他有效缓存路径', '在测试开头添加 QVERIFY(dir.isValid()) 以确保临时目录创建成功', '在测试函数末尾添加 worker.stopThread() 和 QVERIFY(worker.wait(5000)),与其他测试保持一致', '在测试 FD 路径中使用 QVERIFY2 替代静默返回空列表,提供明确的失败诊断信息']


3. 代码性能 ✅

评价: 性能良好,资源使用合理 ✅ 通过

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

建议: ['findCachedImagePaths 使用 continue 替代 return {} 可避免多 size 场景下的不必要重新生成']


4. 代码安全 🔒

评价: 存在0个安全漏洞 ✅ 通过

🔐 发现 0 个安全漏洞

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

建议: []


💡 改进建议代码示例

// cachedwallpaper.cpp - findCachedImagePaths 建议改用 continue
QStringList CachedWallpaper::findCachedImagePaths(const QString &pathMd5, const QList<QSize> &sizes,
                                                   const QDateTime &sourceChangeTime) const
{
    QStringList results;
    const auto it = m_cachedImages.constFind(pathMd5);
    if (it == m_cachedImages.constEnd())
        return results;

    for (const QString &path : it.value()) {
        const QFileInfo info(path);
        if (path.isEmpty() || !info.isFile() || !info.isReadable() || info.size() == 0)
            continue;  // 跳过无效条目,保留其他有效缓存
        const QDateTime cacheChangeTime = info.metadataChangeTime();
        if (!sourceChangeTime.isValid() || !cacheChangeTime.isValid() || cacheChangeTime < sourceChangeTime)
            continue;  // 跳过过期条目,保留其他有效缓存
        results.append(path);
    }
    return results;
}

// test_wallpaper_cache_unit.cpp - 建议补充验证和清理
void replacedThumbnailRefreshes()
{
    QFETCH(bool, useFd);
    QTemporaryDir dir;
    QVERIFY(dir.isValid());  // 确保临时目录创建成功
    // ... test body ...

    worker.stopThread();        // 显式停止 worker
    QVERIFY(worker.wait(5000)); // 确保线程退出
}

本报告由 AI 代码审查工具自动生成

@mhduiy

mhduiy commented Oct 29, 2026

Copy link
Copy Markdown
Contributor Author

/forcemerge

@deepin-bot

deepin-bot Bot commented Oct 29, 2026

Copy link
Copy Markdown

This pr force merged! (status: blocked)

@deepin-bot
deepin-bot Bot merged commit 3929df0 into linuxdeepin:master Oct 29, 2026
6 checks passed
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.

3 participants