Skip to content

Conversation

@re2zero
Copy link
Contributor

@re2zero re2zero commented Feb 10, 2026

Root cause: When expanded app notification collapses, removeDisplaced transition blocks delegate updates for displaced items. Next app's overlap delegate appears transparent (position exists but content invisible).

Solution: Emit layoutChanged() signal after collapseApp completes. This forces ListView to completely refresh all delegates, ensuring displaced items render correctly.

根本原因:展开的应用通知收起时,removeDisplaced transition阻塞被移位项目的 delegate更新。下一个应用的overlap delegate显示透明(位置存在但内容不可见)。

解决方案:collapseApp完成后发出layoutChanged()信号,强制ListView完全刷新 所有delegate,确保被移位项目正确渲染。

Log: 使用layoutChanged()强制刷新ListView修复收起后delegate不显示问题
PMS: BUG-350789
Influence: 收起超出屏幕的应用通知后,下方通知正常显示

Summary by Sourcery

Bug Fixes:

  • Fix invisible notification delegates after collapsing an expanded app notification by forcing a ListView layout refresh.

Root cause: When expanded app notification collapses, removeDisplaced transition
blocks delegate updates for displaced items. Next app's overlap delegate appears
transparent (position exists but content invisible).

Solution: Emit layoutChanged() signal after collapseApp completes. This forces
ListView to completely refresh all delegates, ensuring displaced items render correctly.

根本原因:展开的应用通知收起时,removeDisplaced transition阻塞被移位项目的
delegate更新。下一个应用的overlap delegate显示透明(位置存在但内容不可见)。

解决方案:collapseApp完成后发出layoutChanged()信号,强制ListView完全刷新
所有delegate,确保被移位项目正确渲染。

Log: 使用layoutChanged()强制刷新ListView修复收起后delegate不显示问题
PMS: BUG-350789
Influence: 收起超出屏幕的应用通知后,下方通知正常显示
@deepin-ci-robot
Copy link

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: re2zero

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
Copy link

sourcery-ai bot commented Feb 10, 2026

Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

NotifyModel now emits layoutChanged() after collapsing an app’s notifications so that the ListView fully refreshes its delegates and correctly re-renders displaced notification items.

Sequence diagram for collapseApp triggering ListView refresh via layoutChanged

sequenceDiagram
    actor User
    participant NotificationCenterView
    participant NotifyModel
    participant ListView

    User->>NotificationCenterView: clickCollapse(appRow)
    NotificationCenterView->>NotifyModel: collapseApp(row)
    NotifyModel->>NotifyModel: removeDisplaced transitions
    NotifyModel->>NotifyModel: update m_appNotifies
    NotifyModel-->>NotificationCenterView: collapseApp returns
    NotifyModel-->>ListView: layoutChanged
    ListView->>ListView: rebuild all delegates
    ListView->>User: render displaced notifications correctly
Loading

Updated class diagram for NotifyModel emitting layoutChanged after collapseApp

classDiagram
    class NotifyModel {
        - m_appNotifies
        + collapseApp(row int) void
        + close() void
        + layoutChanged()
    }

    class NotificationListView {
        - model NotifyModel
        + refreshDelegates() void
    }

    class AppNotify {
        + id int
        + content
    }

    class OverlapDelegate {
        + position int
        + render() void
    }

    NotifyModel "1" o-- "*" AppNotify
    NotifyModel "*" o-- "*" OverlapDelegate
    NotificationListView --> NotifyModel : uses model
    NotificationListView ..> OverlapDelegate : displays
    NotificationListView ..> AppNotify : displays
Loading

File-Level Changes

Change Details Files
Trigger a full ListView layout refresh after app notification collapse to ensure delegates update correctly.
  • Emit layoutChanged() at the end of NotifyModel::collapseApp after any insert/move operations on app notification items
panels/notification/center/notifymodel.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

这段代码主要是在 NotifyModel 类的 collapseApp 函数中添加了一行 emit layoutChanged()。下面我将从多个角度对这段代码进行审查:

1. 语法逻辑

  • 审查结果:语法正确,符合 Qt/C++ 编程规范。
  • 分析emit layoutChanged() 是 QAbstractItemModel 的标准信号,用于通知视图(如 QListView)整个模型的结构发生了变化。在 beginInsertRows()endInsertRows() 之后发出此信号在逻辑上是可以的,但这通常意味着比单纯的"插入行"更剧烈的更新。

2. 代码质量

  • 审查结果:存在改进空间,存在"过度通知"的风险。
  • 分析
    • 冗余信号:代码中已经使用了 beginInsertRows()endInsertRows()。这两个函数已经会内部发出 rowsInserted() 信号,视图会据此自动更新并显示新插入的行。
    • 性能影响layoutChanged() 信号会导致视图重新查询所有可见项的数据(如 data()),并可能重新计算布局。如果列表很长,这会导致明显的界面卡顿。仅仅为了插入一行而刷新整个布局是不必要的。
    • 标准做法:通常 layoutChanged() 用于排序、筛选或改变模型结构导致现有索引失效的情况。对于简单的插入、删除或移动,应优先使用 beginInsertRows/endInsertRowsbeginRemoveRows/endRemoveRows 等专用函数。

3. 代码性能

  • 审查结果:性能较差。
  • 分析:如上所述,触发 layoutChanged() 会引发全量刷新。如果通知中心有几十上百条通知,每次折叠一个应用都触发全量刷新,会造成 CPU 浪费和 UI 掉帧。

4. 代码安全

  • 审查结果:无明显安全问题。
  • 分析:这段代码主要涉及 UI 更新,不涉及内存管理、指针操作或外部输入处理,因此没有直接的安全漏洞。

改进建议

建议删除 emit layoutChanged(); 这行代码。

除非 collapseApp 函数中除了插入行之外,还改变了其他行的顺序、或者改变了数据的显示方式(例如改变了分组结构),否则仅依靠 beginInsertRowsendInsertRows 就足够了。

修改后的代码建议:

void NotifyModel::collapseApp(int row)
{
    // ... 前面的逻辑保持不变 ...
    
    if (overlap) {
        beginInsertRows(QModelIndex(), row, row);
        m_appNotifies.insert(row, overlap);
        endInsertRows();
    }
    // 删除 emit layoutChanged(); 以避免不必要的全量刷新
}

特殊情况处理:
如果添加这行代码是为了解决某种特定的 UI Bug(例如折叠后视图没有正确更新,或者重叠项显示错乱),那么问题可能出在数据结构的逻辑上,而不是缺少 layoutChanged()。建议检查 overlap 对象的构建逻辑,或者是否需要使用 beginResetModel() / endResetModel() 来彻底重置模型(如果结构变化非常剧烈)。

总结:
目前的修改虽然语法正确,但引入了性能开销。建议移除该行,除非有充分的理由证明必须刷新整个布局。如果是为了修复显示 Bug,请寻找更精准的修复方式。

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:

  • Emitting layoutChanged() without a preceding layoutAboutToBeChanged() breaks the usual Qt model pattern; consider wrapping the affected operations in a proper layoutAboutToBeChanged()/layoutChanged() pair if the layout truly changes, or use a more targeted signal if it’s only about delegate refresh.
  • Since collapseApp already uses beginInsertRows/endInsertRows, double-check whether a full layoutChanged() is necessary or if a narrower update (e.g., dataChanged or rowsMoved) can achieve the same visual fix with less impact on view performance.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Emitting `layoutChanged()` without a preceding `layoutAboutToBeChanged()` breaks the usual Qt model pattern; consider wrapping the affected operations in a proper `layoutAboutToBeChanged()`/`layoutChanged()` pair if the layout truly changes, or use a more targeted signal if it’s only about delegate refresh.
- Since `collapseApp` already uses `beginInsertRows`/`endInsertRows`, double-check whether a full `layoutChanged()` is necessary or if a narrower update (e.g., `dataChanged` or `rowsMoved`) can achieve the same visual fix with less impact on view performance.

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.

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