Skip to content

fix: improve window icon handling and model reset logic#1578

Open
wjyrich wants to merge 1 commit intolinuxdeepin:masterfrom
wjyrich:feat-hoverpreview
Open

fix: improve window icon handling and model reset logic#1578
wjyrich wants to merge 1 commit intolinuxdeepin:masterfrom
wjyrich:feat-hoverpreview

Conversation

@wjyrich
Copy link
Copy Markdown
Contributor

@wjyrich wjyrich commented Apr 29, 2026

  1. Fixed DockCombineModel to respect window split setting for icon display
  2. Simplified DockItemModel source model change to use full reset instead of incremental updates
  3. Optimized AppItem icon loading to avoid retaining while window is active
  4. Added explicit icon update for X11 windows on mapping

The changes fix icon display inconsistencies where window-specific icons were incorrectly overridden by application icons when window split is disabled. The model reset simplification fixes edge cases where incremental row updates could cause state corruption. The icon loading optimization improves performance by not retaining loading states for active windows.

Log: Fixed window icon display logic and model synchronization

Influence:

  1. Test dock icon display with multiple windows, verify window-specific icons show correctly
  2. Test window split mode toggle, verify icon behavior changes accordingly
  3. Test quick window switching, verify no icon loading artifacts
  4. Test X11 window mapping, verify icons update immediately
  5. Test model source changes, verify no crashes or data corruption
  6. Test with high window count, verify performance is not degraded

fix: 改进窗口图标处理和模型重置逻辑

  1. 修复 DockCombineModel 中图标显示逻辑,遵循窗口分裂设置
  2. 简化 DockItemModel 源模型变更时的处理,使用全量重置替代增量更新
  3. 优化 AppItem 图标加载,窗口活跃时不再保留加载状态
  4. 为 X11 窗口映射时添加显式图标更新

这些修改修复了当窗口分裂功能禁用时,窗口特定图标被应用程序图标错误覆盖的
问题。模型重置的简化修复了增量行更新可能导致的内部状态损坏问题。图标加载
优化通过不在活动窗口中保留加载状态来提高性能。

Log: 修复了窗口图标显示逻辑和模型同步问题

Influence:

  1. 测试多窗口 dock 图标显示,验证窗口特定图标正确显示
  2. 测试窗口分裂模式切换,验证图标行为相应变更
  3. 测试快速窗口切换,验证无图标加载残留
  4. 测试 X11 窗口映射,验证图标立即更新
  5. 测试模型源变更,验证无崩溃或数据损坏
  6. 测试高窗口数量场景,验证性能不下降

PMS: TASK-389031

Summary by Sourcery

Improve dock task manager icon handling and model synchronization for better window-specific icon display and stability.

Bug Fixes:

  • Ensure DockCombineModel prefers window icons over application icons when window split mode is enabled and avoids overriding valid window icons.
  • Prevent potential model state corruption by resetting DockItemModel fully when the source model changes instead of performing partial row updates.
  • Ensure X11 windows refresh their icons immediately upon mapping to avoid stale or missing icons.

Enhancements:

  • Adjust AppItem icon loading behavior to avoid retaining loading state for active windows, reducing visual artifacts and improving performance.

1. Fixed DockCombineModel to respect window split setting for icon
display
2. Simplified DockItemModel source model change to use full reset
instead of incremental updates
3. Optimized AppItem icon loading to avoid retaining while window is
active
4. Added explicit icon update for X11 windows on mapping

The changes fix icon display inconsistencies where window-specific
icons were incorrectly overridden by application icons when window
split is disabled. The model reset simplification fixes edge cases where
incremental row updates could cause state corruption. The icon loading
optimization improves performance by not retaining loading states for
active windows.

Log: Fixed window icon display logic and model synchronization

Influence:
1. Test dock icon display with multiple windows, verify window-specific
icons show correctly
2. Test window split mode toggle, verify icon behavior changes
accordingly
3. Test quick window switching, verify no icon loading artifacts
4. Test X11 window mapping, verify icons update immediately
5. Test model source changes, verify no crashes or data corruption
6. Test with high window count, verify performance is not degraded

fix: 改进窗口图标处理和模型重置逻辑

1. 修复 DockCombineModel 中图标显示逻辑,遵循窗口分裂设置
2. 简化 DockItemModel 源模型变更时的处理,使用全量重置替代增量更新
3. 优化 AppItem 图标加载,窗口活跃时不再保留加载状态
4. 为 X11 窗口映射时添加显式图标更新

这些修改修复了当窗口分裂功能禁用时,窗口特定图标被应用程序图标错误覆盖的
问题。模型重置的简化修复了增量行更新可能导致的内部状态损坏问题。图标加载
优化通过不在活动窗口中保留加载状态来提高性能。

Log: 修复了窗口图标显示逻辑和模型同步问题

Influence:
1. 测试多窗口 dock 图标显示,验证窗口特定图标正确显示
2. 测试窗口分裂模式切换,验证图标行为相应变更
3. 测试快速窗口切换,验证无图标加载残留
4. 测试 X11 窗口映射,验证图标立即更新
5. 测试模型源变更,验证无崩溃或数据损坏
6. 测试高窗口数量场景,验证性能不下降

PMS: TASK-389031
@deepin-ci-robot
Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: wjyrich

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

sourcery-ai Bot commented Apr 29, 2026

Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Refactors dock task manager models and related window/icon handling to use a full model reset on source changes, respect window-split settings for choosing window vs. app icons, optimize QML icon loading for active windows, and immediately refresh X11 window icons upon mapping.

Sequence diagram for X11 window mapping and immediate icon update

sequenceDiagram
    participant XServer
    participant X11WindowMonitor
    participant Window
    participant AbstractWindowMonitor

    XServer->>X11WindowMonitor: MapNotify(xcb_window)
    activate X11WindowMonitor
    X11WindowMonitor->>X11WindowMonitor: onWindowMapped(xcb_window)
    X11WindowMonitor->>X11WindowMonitor: xcb_change_window_attributes
    X11WindowMonitor->>Window: trackWindow(window)
    X11WindowMonitor->>Window: updateIcon()
    X11WindowMonitor->>AbstractWindowMonitor: windowAdded(window)
    deactivate X11WindowMonitor
Loading

Class diagram for updated dock task manager models and window/icon handling

classDiagram
    class DockItemModel {
        +bool m_isUpdating
        +void setSourceModel(QAbstractItemModel *model)
    }

    class QAbstractProxyModel {
        +void setSourceModel(QAbstractItemModel *model)
        +int rowCount()
    }

    DockItemModel --|> QAbstractProxyModel

    class DockCombineModel {
        +QVariant data(const QModelIndex &index, int role) const
        -QHash<int,int> m_roleMaps
        +DockCombineModel(QAbstractItemModel *major, QAbstractItemModel *minor, int majorRoles, CombineFunc func, QObject *parent)
    }

    class RoleCombineModel {
        +QVariant data(const QModelIndex &index, int role) const
    }

    DockCombineModel --|> RoleCombineModel

    class TaskManager {
        <<enumeration>>
        +int IconNameRole
        +int WinIconRole
    }

    DockCombineModel ..> TaskManager : uses roles

    class TaskManagerSettings {
        +static TaskManagerSettings* instance()
        +bool isWindowSplit() const
    }

    DockCombineModel ..> TaskManagerSettings : queries isWindowSplit

    class X11WindowMonitor {
        +void onWindowMapped(xcb_window_t xcb_window)
        +void trackWindow(Window *window)
    }

    class AbstractWindowMonitor {
        +void windowAdded(QPointer<AbstractWindow> window)
    }

    X11WindowMonitor --|> AbstractWindowMonitor

    class Window {
        +void updateIcon()
    }

    X11WindowMonitor ..> Window : trackWindow

    class AppItem {
        +bool titleActive
        +Image iconImage
    }

    class Image {
        +bool retainWhileLoading
    }

    AppItem *-- Image : contains iconImage
Loading

Flow diagram for DockCombineModel icon selection logic

flowchart TD
    A(Start) --> B[Request data for IconNameRole]
    B --> C[Read winIcon from WinIconRole]
    C --> D{isWindowSplit and winIcon not empty}
    D -- Yes --> E[Return winIcon]
    D -- No --> F[Read icon from IconNameRole]
    F --> G{icon empty}
    G -- Yes --> H[Set icon to winIcon]
    G -- No --> I[Keep app icon]
    H --> J[Return icon]
    I --> J[Return icon]
    E --> K(End)
    J --> K(End)
Loading

Flow diagram for DockItemModel source model reset logic

flowchart TD
    A(Start setSourceModel) --> B{Existing sourceModel}
    B -- Yes --> C[Disconnect old source model signals]
    B -- No --> D[Skip disconnect]
    C --> E
    D --> E
    E[beginResetModel] --> F["QAbstractProxyModel::setSourceModel new model"]
    F --> G[endResetModel]
    G --> H[Connect rowsInserted, rowsRemoved, rowsMoved, dataChanged signals]
    H --> I[Set m_isUpdating to false]
    I --> J(End)
Loading

File-Level Changes

Change Details Files
Switch DockItemModel source model updates to a full model reset instead of manual row insert/remove and dataChanged handling.
  • Wrap QAbstractProxyModel::setSourceModel in beginResetModel/endResetModel when changing the source model.
  • Remove manual row count comparison and beginInsertRows/beginRemoveRows logic.
  • Remove explicit dataChanged emission after adjusting rows and rely on the reset to notify views.
  • Keep existing row-inserted/removed/moved signal connections unchanged.
panels/dock/taskmanager/dockitemmodel.cpp
Adjust DockCombineModel icon selection to respect window-split settings and favor per-window icons only when appropriate.
  • Include TaskManagerSettings to access dock configuration.
  • Retrieve the window icon separately and return it directly when non-empty and window split is enabled.
  • Fall back to the application icon first, and only then to the window icon if the app icon is empty, when window split is disabled.
  • Update SPDX copyright header to cover years 2025-2026.
panels/dock/taskmanager/dockcombinemodel.cpp
Optimize QML AppItem icon loading behavior for active windows to avoid unnecessary retention of loading placeholders.
  • Change the Image element's retainWhileLoading property to be disabled while the window title is active by binding it to !root.titleActive.
panels/dock/taskmanager/package/AppItem.qml
Ensure X11 window icons are refreshed immediately when a window is mapped.
  • After tracking a newly mapped X11 window, explicitly call updateIcon() before emitting windowAdded.
  • Leave existing X11 event mask setup and windowAdded emission logic intact.
panels/dock/taskmanager/x11windowmonitor.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

这份代码变更主要涉及任务栏管理器的图标显示逻辑、模型更新机制以及窗口监控优化。以下是对每个变更文件的详细审查和改进建议:

1. dockcombinemodel.cpp 变更分析

变更内容:

  • 修改了版权年份
  • 新增了 TaskManagerSettings 头文件引用
  • 优化了 IconNameRole 的逻辑,增加了窗口拆分模式下的图标处理

审查意见:

  1. 逻辑正确性:

    • ✅ 逻辑清晰,当窗口拆分模式开启时(isWindowSplit()为真),优先使用窗口图标(WinIconRole),否则使用应用图标(IconNameRole)
    • ✅ 保留了原有的回退机制:当应用图标为空时,使用窗口图标
  2. 代码质量:

    • ✅ 变量命名 winIconwinTitle 更准确
    • ⚠️ 建议检查 TaskManagerSettings::instance() 的生命周期管理,确保不会出现空指针
  3. 性能:

    • ✅ 减少了不必要的字符串转换和比较
  4. 安全性:

    • ⚠️ 没有对 TaskManagerSettings::instance() 返回值进行空指针检查
    • 建议修改为:
      auto settings = TaskManagerSettings::instance();
      if (settings && !winIcon.isEmpty() && settings->isWindowSplit()) {
          return winIcon;
      }

2. dockitemmodel.cpp 变更分析

变更内容:

  • 简化了 setSourceModel 方法,使用 beginResetModel()/endResetModel() 替代了手动计算行数变化的逻辑

审查意见:

  1. 逻辑正确性:

    • ✅ 使用 beginResetModel()/endResetModel() 是处理模型完全重置的标准做法
    • ✅ 保留了信号连接逻辑
  2. 代码质量:

    • ✅ 代码更简洁,减少了出错的可能性
    • ✅ 移除了冗余的 dataChanged 信号发射
  3. 性能:

    • ⚠️ beginResetModel()/endResetModel() 会导致所有视图完全重建,对于大型模型可能性能较差
    • 如果模型更新频繁且数据量大,可以考虑更细粒度的更新
  4. 安全性:

    • ✅ 没有明显的安全问题

3. AppItem.qml 变更分析

变更内容:

  • 修改了 retainWhileLoading 属性,使其依赖于 root.titleActive 状态

审查意见:

  1. 逻辑正确性:

    • ⚠️ 这个变更需要更多上下文才能完全理解意图
    • 可能是为了在标题激活时不保留加载中的图像
  2. 代码质量:

    • ✅ 逻辑简单明了
  3. 性能:

    • ✅ 可能有助于减少不必要的图像保留,节省内存
  4. 安全性:

    • ✅ 没有明显的安全问题

4. x11windowmonitor.cpp 变更分析

变更内容:

  • 在窗口映射后添加了 window->updateIcon() 调用

审查意见:

  1. 逻辑正确性:

    • ✅ 确保窗口图标在映射后立即更新
    • ✅ 位置合理,在 trackWindow 之后,windowAdded 信号之前
  2. 代码质量:

    • ✅ 代码简洁
  3. 性能:

    • ⚠️ 需要确认 updateIcon() 是否会触发不必要的网络请求或磁盘IO
    • 如果图标更新是异步的,可能需要考虑是否会影响窗口显示的及时性
  4. 安全性:

    • ⚠️ 需要确保 window 指针在调用 updateIcon() 时是有效的
    • 虽然使用了 QPointer,但建议在调用前检查:
      if (window) {
          window->updateIcon();
      }

总体建议:

  1. 空指针检查: 在使用单例实例或指针前,建议添加空指针检查
  2. 性能测试:dockitemmodel.cpp 的变更进行性能测试,特别是在大量窗口场景下
  3. 文档更新: 建议更新相关文档,说明 retainWhileLoading 的新行为
  4. 单元测试: 为新增的窗口拆分模式图标逻辑添加单元测试
  5. 代码注释: 为关键逻辑变更添加注释,说明变更原因和预期行为

这些变更整体上是合理的,主要改进了图标显示逻辑和模型更新机制,但建议在上述几个方面进行加强。

Copy link
Copy Markdown

@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 found 1 issue, and left some high level feedback:

  • In DockItemModel::setSourceModel, consider skipping the beginResetModel/endResetModel path when the new source model is identical to the current one to avoid unnecessary full model resets and view churn.
  • DockCombineModel::data now depends on TaskManagerSettings::isWindowSplit(), but the model does not emit any dataChanged signals when this setting toggles; consider listening to the setting change and triggering a suitable dataChanged/model reset so views update their icons immediately when the split mode changes.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In DockItemModel::setSourceModel, consider skipping the beginResetModel/endResetModel path when the new source model is identical to the current one to avoid unnecessary full model resets and view churn.
- DockCombineModel::data now depends on TaskManagerSettings::isWindowSplit(), but the model does not emit any dataChanged signals when this setting toggles; consider listening to the setting change and triggering a suitable dataChanged/model reset so views update their icons immediately when the split mode changes.

## Individual Comments

### Comment 1
<location path="panels/dock/taskmanager/x11windowmonitor.cpp" line_range="189" />
<code_context>
     xcb_change_window_attributes(X11->getXcbConnection(), xcb_window, XCB_CW_EVENT_MASK, value_list);
     trackWindow(window.get());
+
+    window->updateIcon();
     Q_EMIT AbstractWindowMonitor::windowAdded(static_cast<QPointer<AbstractWindow>>(window.get()));
 }
</code_context>
<issue_to_address>
**question (bug_risk):** Check for any ordering assumptions between `updateIcon()` and `windowAdded`.

Calling `updateIcon()` before emitting `windowAdded` changes the lifecycle: listeners now see a window whose icon may already be updated, and any signals from `updateIcon()` fire first. Please confirm that no existing `windowAdded` consumers assume they run before icon‑related updates; if they do, consider keeping `updateIcon()` after `windowAdded` or clearly documenting this new ordering.
</issue_to_address>

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.

xcb_change_window_attributes(X11->getXcbConnection(), xcb_window, XCB_CW_EVENT_MASK, value_list);
trackWindow(window.get());

window->updateIcon();
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

question (bug_risk): Check for any ordering assumptions between updateIcon() and windowAdded.

Calling updateIcon() before emitting windowAdded changes the lifecycle: listeners now see a window whose icon may already be updated, and any signals from updateIcon() fire first. Please confirm that no existing windowAdded consumers assume they run before icon‑related updates; if they do, consider keeping updateIcon() after windowAdded or clearly documenting this new ordering.

@deepin-bot
Copy link
Copy Markdown

deepin-bot Bot commented Apr 29, 2026

TAG Bot

New tag: 2.0.39
DISTRIBUTION: unstable
Suggest: synchronizing this PR through rebase #1580

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