Skip to content

Conversation

@pengfeixx
Copy link
Contributor

@pengfeixx pengfeixx commented Jan 13, 2026

Fix the issue of copying the same image multiple times

Log: Fix the issue of copying the same image multiple times
pms: BUG-342451

Summary by Sourcery

Prevent duplicate image entries in the clipboard history while ensuring non-image clipboard content does not interfere with image deduplication.

Bug Fixes:

  • Always suppress consecutive clipboard entries containing the same image content, regardless of timestamp or platform conditions.
  • Reset the last-image tracking when handling file and text clipboard data so subsequent distinct images are not incorrectly treated as duplicates.

Fix the issue of copying the same image multiple times

Log: Fix the issue of copying the same image multiple times
pms: BUG-342451
@sourcery-ai
Copy link

sourcery-ai bot commented Jan 13, 2026

Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Simplifies clipboard image de-duplication logic to always suppress identical consecutive images, and ensures non-image clipboard updates (files/text) reset the last-image state so they don’t interfere with later image deduplication.

Sequence diagram for clipboard image deduplication after fix

sequenceDiagram
    actor User
    participant SystemClipboard
    participant ClipboardLoader
    participant HistoryStore

    User->>SystemClipboard: Copy image A
    SystemClipboard->>ClipboardLoader: clipboardChanged event
    ClipboardLoader->>ClipboardLoader: srcImage != m_lastImage
    ClipboardLoader->>HistoryStore: add image A
    ClipboardLoader->>ClipboardLoader: m_lastImage = image A

    User->>SystemClipboard: Copy same image A again
    SystemClipboard->>ClipboardLoader: clipboardChanged event
    ClipboardLoader->>ClipboardLoader: srcImage == m_lastImage
    ClipboardLoader->>ClipboardLoader: skip duplicate image

    User->>SystemClipboard: Copy file selection
    SystemClipboard->>ClipboardLoader: clipboardChanged event
    ClipboardLoader->>ClipboardLoader: detect File type
    ClipboardLoader->>ClipboardLoader: m_lastImage = empty QImage
    ClipboardLoader->>HistoryStore: add file entry

    User->>SystemClipboard: Copy image A again
    SystemClipboard->>ClipboardLoader: clipboardChanged event
    ClipboardLoader->>ClipboardLoader: m_lastImage is empty
    ClipboardLoader->>ClipboardLoader: srcImage != m_lastImage
    ClipboardLoader->>HistoryStore: add image A
    ClipboardLoader->>ClipboardLoader: m_lastImage = image A
Loading

Class diagram for ClipboardLoader clipboard handling changes

classDiagram
    class ClipboardLoader {
        QImage m_lastImage
        void doWork(int protocolType)
        void handleImageData(QImage srcImage)
        void handleFileData()
        void handleTextData(QString text)
    }

    class QImage

    ClipboardLoader "1" *-- "1" QImage : uses

    %% Behavioral constraints represented structurally
    class ClipboardImageLogic {
        QImage lastImage
        void updateOnImage(QImage newImage)
        void clearOnFile()
        void clearOnText()
    }

    ClipboardLoader --> ClipboardImageLogic : delegates dedup behavior

    class ClipboardInfo {
        int m_type
        QDateTime m_createTime
    }

    class QDateTime

    ClipboardLoader --> ClipboardInfo
    ClipboardInfo --> QDateTime
Loading

File-Level Changes

Change Details Files
Unify and relax the image de-duplication condition so any identical consecutive image is treated as a duplicate, regardless of timestamp, interval, or platform.
  • Remove timestamp, duration, and platform checks from the duplicate-image filtering condition in the clipboard worker.
  • Retain only an image-content equality check (srcImage == m_lastImage) before early-returning for duplicate images.
dde-clipboard-daemon/clipboardloader.cpp
Reset stored last-image state when handling non-image clipboard data so image deduplication only compares between consecutive image entries.
  • After recognizing a File-type clipboard entry, clear m_lastImage to an empty QImage before returning.
  • After recognizing a Text-type clipboard entry, clear m_lastImage to an empty QImage before returning.
dde-clipboard-daemon/clipboardloader.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

deepin pr auto review

这段代码的修改主要涉及剪贴板图片去重逻辑的优化。以下是对修改内容的详细审查和改进建议:

1. 代码逻辑审查

修改点分析:

  1. 移除了时间戳和平台判断:原代码通过时间戳(currTimeStamp)、时间间隔(offerDuration)和平台名称(wayland)来判断是否重复,现在简化为仅比较图片内容(srcImage == m_lastImage)。
  2. 新增清空操作:在处理文件和文本类型时,显式清空m_lastImage,避免影响后续图片去重判断。

潜在问题:

  • 过度简化:完全移除时间戳判断可能导致某些场景下误判。例如,当用户快速复制同一张图片时,可能不希望每次都触发剪贴板更新事件。
  • 平台兼容性:原代码特别处理了Wayland平台,新代码移除了这个判断,可能在Wayland环境下引入未知行为。

2. 代码质量建议

  1. 添加注释说明
// 仅通过图片内容判断是否重复,简化了逻辑但可能增加剪贴板更新频率
if (srcImage == m_lastImage) {
    qDebug() << "system repeat image";
    return;
}
  1. 统一清空操作
// 在函数开始处统一清空非图片类型的m_lastImage
if (info.m_type != Image) {
    m_lastImage = QImage();
}

3. 代码性能建议

  1. 图片比较优化
// 使用更高效的图片比较方式
if (srcImage.size() == m_lastImage.size() && 
    srcImage.constBits() != m_lastImage.constBits() && 
    srcImage == m_lastImage) {
    // 先检查尺寸和内存地址,避免不必要的深度比较
    qDebug() << "system repeat image";
    return;
}
  1. 避免频繁构造
// 将QStringLiteral("wayland")改为静态常量
static const QLatin1String waylandPlatform("wayland");
if (waylandPlatform != qGuiApp->platformName()) {
    // ...
}

4. 代码安全建议

  1. 添加边界检查
if (srcImage.isNull() || m_lastImage.isNull()) {
    // 处理空图片情况
    return;
}
  1. 线程安全
    如果m_lastImage可能被多线程访问,应该添加互斥锁保护:
QMutexLocker locker(&m_imageMutex);
if (srcImage == m_lastImage) {
    // ...
}

5. 综合改进建议

void ClipboardLoader::doWork(int protocolType)
{
    // ... 其他代码 ...
    
    if (!info.m_variantImage.isNull()) {
        // 添加空值检查
        if (srcImage.isNull() || m_lastImage.isNull()) {
            return;
        }
        
        // 优化后的比较逻辑
        if (srcImage.size() == m_lastImage.size() && 
            srcImage.constBits() != m_lastImage.constBits() && 
            srcImage == m_lastImage) {
            qDebug() << "system repeat image";
            return;
        }
        
        m_lastImage = srcImage; // 更新最后图片记录
    }
    
    // 统一处理非图片类型
    if (info.m_type != Image) {
        m_lastImage = QImage();
    }
    
    // ... 其他代码 ...
}

总结

这次修改简化了图片去重逻辑,但可能引入以下问题:

  1. 增加了剪贴板更新频率(因为移除了时间间隔判断)
  2. 可能影响Wayland平台的兼容性
  3. 缺少必要的边界检查和线程安全保护

建议保留部分原有逻辑,特别是时间间隔判断,同时优化图片比较性能。

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey - I've left some high level feedback:

  • The new srcImage == m_lastImage check now suppresses repeats unconditionally, removing the previous timestamp and platform constraints; consider whether users may legitimately copy the same image twice and, if so, whether a time-based or event-based threshold is still needed to avoid over-filtering.
  • The logic to clear m_lastImage when handling non-image clipboard types is duplicated in both the File and Text branches; consider extracting this into a small helper or centralizing the reset to keep the state handling easier to reason about.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The new `srcImage == m_lastImage` check now suppresses repeats unconditionally, removing the previous timestamp and platform constraints; consider whether users may legitimately copy the same image twice and, if so, whether a time-based or event-based threshold is still needed to avoid over-filtering.
- The logic to clear `m_lastImage` when handling non-image clipboard types is duplicated in both the File and Text branches; consider extracting this into a small helper or centralizing the reset to keep the state handling easier to reason about.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@deepin-ci-robot
Copy link

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: 18202781743, pengfeixx

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

@pengfeixx
Copy link
Contributor Author

/merge

@deepin-bot deepin-bot bot merged commit 8956b06 into linuxdeepin:master Jan 14, 2026
18 checks passed
@pengfeixx pengfeixx deleted the fix-342451 branch January 14, 2026 02:56
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