Skip to content

Conversation

@caixr23
Copy link
Contributor

@caixr23 caixr23 commented Feb 2, 2026

Enhanced the navigation object tracking mechanism to properly handle page transitions and object activation. The changes include:

  1. Added new triggeredObjects list to track the complete navigation path from root to current object
  2. Improved object activation sequence by setting current objects for parent items
  3. Fixed animation mode detection by comparing against triggered objects instead of current objects
  4. Added proper signal emission for triggered objects changes
  5. Updated header files to expose new triggeredObjects property and signals

Log: Improved navigation tracking and page transition animations in control center

Influence:

  1. Test navigation between different control center modules
  2. Verify proper animation transitions when switching pages
  3. Check that current object tracking works correctly in complex navigation scenarios
  4. Test backward navigation to ensure proper object deactivation
  5. Verify signal emissions for object changes

fix: 优化控制中心导航对象跟踪机制

增强导航对象跟踪机制以正确处理页面切换和对象激活。更改包括:

  1. 新增 triggeredObjects 列表用于跟踪从根对象到当前对象的完整导航路径
  2. 通过为父项设置当前对象改进了对象激活顺序
  3. 通过比较触发对象而非当前对象修复了动画模式检测
  4. 添加了触发对象变化的正确信号发射
  5. 更新头文件以暴露新的 triggeredObjects 属性和信号

Log: 优化控制中心导航跟踪和页面切换动画

Influence:

  1. 测试不同控制中心模块间的导航功能
  2. 验证页面切换时的动画过渡是否正确
  3. 检查复杂导航场景下的当前对象跟踪是否正常工作
  4. 测试后退导航以确保对象停用正确
  5. 验证对象变化时的信号发射

PMS: BUG-326725

Summary by Sourcery

Improve control center navigation tracking and page transition behavior by distinguishing between current pages and fully triggered navigation paths.

Bug Fixes:

  • Ensure animation mode selection during navigation is based on the full set of triggered navigation objects rather than only current page objects.
  • Fix inconsistent activation and deactivation of navigation objects when moving between nested pages and controls.

Enhancements:

  • Track a complete list of triggered navigation objects from root to the active control to support more accurate navigation state management.
  • Expose currentObjects and triggeredObjects as Q_PROPERTY values with corresponding signals for better integration with QML and plugins.

@sourcery-ai
Copy link

sourcery-ai bot commented Feb 2, 2026

Reviewer's Guide

Refactors how the control center tracks navigation objects by distinguishing between the module path and the fully triggered object chain, updating activation/deactivation and animation decisions to be based on this new triggered path, and exposing both paths as properties/signals in the plugin API.

Sequence diagram for doShowPage navigation and triggeredObjects update

sequenceDiagram
    actor User
    participant UI as QML_UI
    participant Manager as DccManager
    participant Obj as DccObject
    participant Parent as DccObject_parent
    participant DccObject_Private

    User ->> UI: request navigation(target, cmd)
    UI ->> Manager: doShowPage(obj, cmd)

    activate Manager
    Manager->>Obj: pageType()
    alt obj is MenuEditor with children
        Manager->>Obj: getChildren()
        Manager->>Obj: setCurrentObject(null)
        Manager->>Obj: active("")
        Note over Manager,Obj: triggeredObj set to first child
    else
        Manager->>Obj: setCurrentObject(null)
        Manager->>Obj: active("")
    end

    loop build_triggered_chain_until_Menu
        Manager->>Obj: pageType()
        alt Obj is not Menu
            Manager->>Manager: triggeredObjs.prepend(Obj)
            Manager->>DccObject_Private: FromObject(Obj)
            DccObject_Private-->>Manager: Parent
            alt Parent exists
                Manager->>Parent: setCurrentObject(Obj)
                Manager->>Parent: active("")
            end
            Manager->>Manager: Obj = Parent
        else
            Manager->>Manager: break
        end
    end

    Manager->>Manager: compute modules path
    Manager->>Manager: triggeredObjs = modules + triggeredObjs

    Manager->>Manager: determine animationMode
    loop for each oldObj in m_triggeredObjects
        alt oldObj not in triggeredObjs
            Manager->>oldObj: setCurrentObject(null)
            Manager->>Manager: animationMode = AnimationPop
        end
        alt oldObj != m_root and oldObj != triggeredObjs.last
            Manager->>oldObj: deactive()
        end
    end
    Manager->>Manager: setAnimationMode(animationMode)

    Manager->>Manager: m_currentObjects = modules
    Manager->>Manager: m_triggeredObjects = triggeredObjs
    Manager-->>UI: triggeredObjectsChanged(m_triggeredObjects)

    alt lastObj in m_currentObjects != m_activeObject
        Manager->>Manager: m_activeObject = lastObj
        Manager-->>UI: activeObjectChanged(m_activeObject)
    end
    deactivate Manager
Loading

Class diagram for updated navigation tracking in DccApp and DccManager

classDiagram
    class DccObject {
        +enum PageType
        +PageType pageType()
        +QList~DccObject*~ getChildren()
        +void setCurrentObject(DccObject* object)
        +void active(QString cmd)
        +void deactive()
    }

    class DccApp {
        <<abstract>>
        +int width()
        +int height()
        +DccObject* root()
        +DccObject* activeObject()
        +const QVector~DccObject*~ & currentObjects()
        +const QVector~DccObject*~ & triggeredObjects()
        +AnimationMode animationMode()
        +void setAnimationMode(AnimationMode mode)
        +void sidebarWidthChanged(int width)
        +void rootChanged(DccObject* root)
        +void activeObjectChanged(DccObject* activeObject)
        +void currentObjectsChanged(QVector~DccObject*~ triggeredObjects)
        +void triggeredObjectsChanged(QVector~DccObject*~ triggeredObjects)
        +void activeItemChanged(QQuickItem* item)
        +void animationModeChanged(AnimationMode mode)
        -AnimationMode m_animationMode
    }

    class DccManager {
        +DccObject* activeObject()
        +const QVector~DccObject*~ & currentObjects()
        +const QVector~DccObject*~ & triggeredObjects()
        +void doShowPage(DccObject* obj, QString cmd)
        -QVector~DccObject*~ m_currentObjects
        -QVector~DccObject*~ m_triggeredObjects
        -DccObject* m_root
        -DccObject* m_activeObject
        -DccObject* m_noAddObjects
        -DccObject* m_noParentObjects
        -PluginManager* m_plugins
        -QPointer~QWindow~ m_window
    }

    class DccObject_Private {
        +static DccObject_Private* FromObject(DccObject* object)
        +DccObject* getParent()
    }

    DccManager --|> DccApp
    DccManager o--> DccObject : uses
    DccManager ..> DccObject_Private : FromObject
    DccApp o--> DccObject : root
Loading

File-Level Changes

Change Details Files
Reworked doShowPage navigation flow to build and use a triggered object chain separate from module path, and to adjust activation/deactivation and animation mode based on it.
  • Introduce a local triggeredObjs list and populate it while walking up from the triggered object to the menu root
  • Reset the initially triggered object’s currentObject and active state before rebuilding parent relationships
  • For each ancestor, set its currentObject to the child and call active() to ensure proper activation ordering
  • Concatenate the module path and the control/child chain into a single triggered object list
  • Switch animation mode selection logic from comparing old current objects vs modules to comparing previous triggered objects vs new triggered objects
  • Deactive old objects that are no longer in the triggered chain or are not the root or last triggered object
  • Update m_currentObjects with the modules path and add m_triggeredObjects with the full triggered chain, emitting triggeredObjectsChanged
src/dde-control-center/dccmanager.cpp
Extended DccManager and DccApp interfaces to expose current and triggered object chains as Qt properties with corresponding accessors and change signals.
  • Make DccManager::currentObjects override the pure virtual currentObjects() from DccApp instead of being Q_INVOKABLE
  • Add triggeredObjects() accessor in DccManager overriding the new virtual in DccApp
  • Add m_triggeredObjects member in DccManager, documenting the semantic difference between currentObjects and triggeredObjects
  • Expose currentObjects and triggeredObjects as Q_PROPERTYs on DccApp, each with READ accessors and NOTIFY signals
  • Declare pure virtual accessors currentObjects() and triggeredObjects() in DccApp so implementations must provide them
  • Add currentObjectsChanged and triggeredObjectsChanged signals to DccApp for QML/clients to react to navigation chain updates
src/dde-control-center/dccmanager.h
src/dde-control-center/plugin/dccapp.h

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

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 found 2 issues, and left some high level feedback:

  • When updating m_currentObjects in DccManager::doShowPage, consider emitting the new currentObjectsChanged(...) notifier so the Q_PROPERTY currentObjects bindings receive updates.
  • The parameter names for currentObjectsChanged(QVector<DccObject *> triggeredObjects) and triggeredObjectsChanged(QVector<DccObject *> triggeredObjects) are identical and misleading; renaming the first parameter to something like currentObjects would make the API clearer.
  • Previously triggeredObj->active(cmd) was emitted when cmd was non-empty, but the new logic only calls active(QString()); if external callers depend on the command string, consider preserving cmd where appropriate or explicitly documenting the behavior change.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- When updating `m_currentObjects` in `DccManager::doShowPage`, consider emitting the new `currentObjectsChanged(...)` notifier so the `Q_PROPERTY currentObjects` bindings receive updates.
- The parameter names for `currentObjectsChanged(QVector<DccObject *> triggeredObjects)` and `triggeredObjectsChanged(QVector<DccObject *> triggeredObjects)` are identical and misleading; renaming the first parameter to something like `currentObjects` would make the API clearer.
- Previously `triggeredObj->active(cmd)` was emitted when `cmd` was non-empty, but the new logic only calls `active(QString())`; if external callers depend on the command string, consider preserving `cmd` where appropriate or explicitly documenting the behavior change.

## Individual Comments

### Comment 1
<location> `src/dde-control-center/dccmanager.cpp:735-736` </location>
<code_context>
     }
     setAnimationMode(animationMode);

-    // 触发新对象
-    if (!cmd.isEmpty()) {
-        Q_EMIT triggeredObj->active(cmd);
-    }
</code_context>

<issue_to_address>
**issue (bug_risk):** Re-check whether the `cmd` argument still needs to be delivered to the triggered object.

Previously we called `triggeredObj->active(cmd)` when `cmd` was non-empty, so callers could rely on that string for navigation/initialization. Now only `active(QString())` on `tmpObj`/parents is used and `active(cmd)` is never invoked. Please confirm whether any existing call sites still depend on the non-empty `cmd`; if so, we likely need to emit `active(cmd)` on the final `triggeredObj` (or another suitable object). If `cmd` is being deprecated, ensure all callers have been updated accordingly.
</issue_to_address>

### Comment 2
<location> `src/dde-control-center/plugin/dccapp.h:80-81` </location>
<code_context>
     void sidebarWidthChanged(int width);
     void rootChanged(DccObject *root);
     void activeObjectChanged(DccObject *activeObject);
+    void currentObjectsChanged(QVector<DccObject *> triggeredObjects);
+    void triggeredObjectsChanged(QVector<DccObject *> triggeredObjects);
     void activeItemChanged(QQuickItem *item);
     void animationModeChanged(AnimationMode mode);
</code_context>

<issue_to_address>
**suggestion:** Consider using const references and consistent parameter naming in the change signals.

`currentObjectsChanged` and `triggeredObjectsChanged` currently take `QVector<DccObject *>` by value, causing a full copy on each emission. Taking a `const QVector<DccObject *> &` would avoid this overhead. Also, `currentObjectsChanged` uses the parameter name `triggeredObjects`, which can be misleading; renaming it to something like `currentObjects` would better match its meaning.

Suggested implementation:

```c
    void activeObjectChanged(DccObject *activeObject);
    void currentObjectsChanged(const QVector<DccObject *> &currentObjects);
    void triggeredObjectsChanged(const QVector<DccObject *> &triggeredObjects);
    void activeItemChanged(QQuickItem *item);

```

1. Update the corresponding signal definitions/implementations (if present) in the matching `.cpp` file so that their signatures exactly match:
   - `void DccApp::currentObjectsChanged(const QVector<DccObject *> &currentObjects)`
   - `void DccApp::triggeredObjectsChanged(const QVector<DccObject *> &triggeredObjects)`
2. Update all `emit currentObjectsChanged(...)` and `emit triggeredObjectsChanged(...)` call sites to pass an lvalue `QVector<DccObject *>` (or a temporary that can bind to a `const &`), and adjust the parameter names if used inside the function bodies.
</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.

Comment on lines -735 to -736
// 触发新对象
if (!cmd.isEmpty()) {
Copy link

Choose a reason for hiding this comment

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

issue (bug_risk): Re-check whether the cmd argument still needs to be delivered to the triggered object.

Previously we called triggeredObj->active(cmd) when cmd was non-empty, so callers could rely on that string for navigation/initialization. Now only active(QString()) on tmpObj/parents is used and active(cmd) is never invoked. Please confirm whether any existing call sites still depend on the non-empty cmd; if so, we likely need to emit active(cmd) on the final triggeredObj (or another suitable object). If cmd is being deprecated, ensure all callers have been updated accordingly.

Comment on lines 80 to 81
void currentObjectsChanged(QVector<DccObject *> triggeredObjects);
void triggeredObjectsChanged(QVector<DccObject *> triggeredObjects);
Copy link

Choose a reason for hiding this comment

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

suggestion: Consider using const references and consistent parameter naming in the change signals.

currentObjectsChanged and triggeredObjectsChanged currently take QVector<DccObject *> by value, causing a full copy on each emission. Taking a const QVector<DccObject *> & would avoid this overhead. Also, currentObjectsChanged uses the parameter name triggeredObjects, which can be misleading; renaming it to something like currentObjects would better match its meaning.

Suggested implementation:

    void activeObjectChanged(DccObject *activeObject);
    void currentObjectsChanged(const QVector<DccObject *> &currentObjects);
    void triggeredObjectsChanged(const QVector<DccObject *> &triggeredObjects);
    void activeItemChanged(QQuickItem *item);
  1. Update the corresponding signal definitions/implementations (if present) in the matching .cpp file so that their signatures exactly match:
    • void DccApp::currentObjectsChanged(const QVector<DccObject *> &currentObjects)
    • void DccApp::triggeredObjectsChanged(const QVector<DccObject *> &triggeredObjects)
  2. Update all emit currentObjectsChanged(...) and emit triggeredObjectsChanged(...) call sites to pass an lvalue QVector<DccObject *> (or a temporary that can bind to a const &), and adjust the parameter names if used inside the function bodies.

@caixr23 caixr23 force-pushed the master branch 3 times, most recently from c5a10be to b5b9224 Compare February 2, 2026 07:03
@deepin-ci-robot
Copy link

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: caixr23, xionglinlin

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

Enhanced the navigation object tracking mechanism to properly handle
page transitions and object activation. The changes include:
1. Added new triggeredObjects list to track the complete navigation path
from root to current object
2. Improved object activation sequence by setting current objects for
parent items
3. Fixed animation mode detection by comparing against triggered objects
instead of current objects
4. Added proper signal emission for triggered objects changes
5. Updated header files to expose new triggeredObjects property and
signals

Log: Improved navigation tracking and page transition animations in
control center

Influence:
1. Test navigation between different control center modules
2. Verify proper animation transitions when switching pages
3. Check that current object tracking works correctly in complex
navigation scenarios
4. Test backward navigation to ensure proper object deactivation
5. Verify signal emissions for object changes

fix: 优化控制中心导航对象跟踪机制

增强导航对象跟踪机制以正确处理页面切换和对象激活。更改包括:
1. 新增 triggeredObjects 列表用于跟踪从根对象到当前对象的完整导航路径
2. 通过为父项设置当前对象改进了对象激活顺序
3. 通过比较触发对象而非当前对象修复了动画模式检测
4. 添加了触发对象变化的正确信号发射
5. 更新头文件以暴露新的 triggeredObjects 属性和信号

Log: 优化控制中心导航跟踪和页面切换动画

Influence:
1. 测试不同控制中心模块间的导航功能
2. 验证页面切换时的动画过渡是否正确
3. 检查复杂导航场景下的当前对象跟踪是否正常工作
4. 测试后退导航以确保对象停用正确
5. 验证对象变化时的信号发射

PMS: BUG-326725
@deepin-ci-robot
Copy link

deepin pr auto review

这份代码 diff 主要针对 DccManagerDccApp 类进行了重构,核心目的是区分并管理“当前显示的页面路径”和“用户交互触发的对象路径”。

以下是对语法逻辑、代码质量、代码性能和代码安全方面的详细审查与改进意见:

1. 语法逻辑

  • 逻辑变更分析
    • 引入了 m_triggeredObjects 成员变量,用于存储从根菜单到当前触发子控件的完整路径。
    • 原有逻辑主要关注页面栈(modules),新逻辑通过 triggeredObjs 追踪了更细粒度的控件层级。
    • while 循环中增加了对父节点状态的设置(setCurrentObjectactive),这确保了在向上遍历树时,路径上的每个节点都被正确激活。
  • 潜在逻辑风险
    • std::reverse 的使用:代码中先将元素 appendQVector,然后使用 std::reverse 进行反转。
      • 在第一个循环(向上遍历父节点)中,使用了 modules.append(p),随后 std::reverse。这在逻辑上是正确的,因为是从子节点向根节点遍历,最终需要根节点在前。
      • 在第二个循环(处理 triggeredObjs)中,同样是先添加后反转。
    • 空指针检查:在 while (tmpObj && (tmpObj->pageType() != DccObject::Menu)) 循环内部,获取父节点 tmpObjParent 后进行了 if (tmpObjParent) 检查,这是安全的。但在循环外部,if (!tmpObj) 检查了 tmpObj 是否为空,这也是安全的。
    • active 信号的触发时机:原代码在 doShowPage 开始处如果 obj 没有父节点则直接 Q_EMIT obj->active(cmd)。新代码中,active 信号的触发被分散到了构建路径的过程中(tmpObjParent->active(QString())p->active(QString()))。注意:新代码似乎移除了针对 cmd 参数的 active(cmd) 发送(除了开头那个 return 分支),这可能是一个逻辑变更,需要确认是否故意为之。如果 cmd 包含了需要传递给最终页面的参数,这部分逻辑可能丢失了。

2. 代码质量

  • 命名与注释
    • 新增的 m_triggeredObjects 变量名清晰,且头文件中添加了注释 // 用户交互触发的对象路径,从根菜单到当前子控件,这非常好,有助于维护。
    • 变量 modules 现在仅包含页面类型的对象(Menu 等),而 triggeredObjs 包含了更详细的控件路径。建议在头文件中也给 m_currentObjects 添加更详细的注释,明确其仅包含页面层级。
  • 代码结构
    • QList 改为 QVector 是好的实践,因为 QVector 在内存布局上更连续,通常性能更好(尤其是对于较小对象或指针)。
    • 使用了 std::as_const(m_currentObjects) 进行遍历,避免了不必要的拷贝,符合现代 C++ 最佳实践。
  • 一致性
    • dccapp.h 中将 currentObjectstriggeredObjects 暴露为 Q_PROPERTY,但在 dccmanager.h 中对应的 getter 函数 currentObjects()triggeredObjects() 没有标记为 Q_INVOKABLE
    • 问题:虽然 Q_PROPERTY 的 READ 函数通常可以被 QML 访问,但如果这些函数需要在 C++ 中通过元对象系统调用(如 QMetaObject::invokeMethod),或者为了保持与 activeObject() 等其他函数的一致性,建议显式添加 Q_INVOKABLE。不过,对于 QML 绑定来说,目前的写法是足够的。

3. 代码性能

  • 容器操作
    • QVector::append 通常是均摊 O(1) 的时间复杂度。
    • std::reverse 是 O(N) 的时间复杂度。
    • QVector::contains 在最坏情况下是 O(N)。
    • 优化建议:在循环 for (auto *oldObj : std::as_const(m_triggeredObjects)) 中调用了 triggeredObjs.contains(oldObj)。如果对象层级很深,这会导致 O(N^2) 的复杂度。
    • 改进方案:可以将 triggeredObjs 转换为 QSet<DccObject *> 进行查找,这样查找操作就是 O(1)。由于 DccObject * 是指针,转换开销很小。但考虑到控制中心的层级通常不会特别深(一般 < 10 层),目前的 O(N^2) 性能损耗可能可以忽略不计,属于微优化范畴。

4. 代码安全

  • 内存管理
    • 代码中大量使用了原始指针 DccObject *。从 diff 看,这些指针似乎由对象树(Parent-Child relationship)管理,生命周期由框架控制,没有看到明显的内存泄漏风险。
    • QVector<DccObject *> 存储的是裸指针,如果 DccObject 被外部删除,这里的指针将变为悬空指针。
    • 建议:确保 DccManager 能够接收到 DccObject 销毁的通知(例如通过 QObject::destroyed 信号),并及时清理 m_currentObjectsm_triggeredObjects 中的无效指针,或者在析构时置空。不过,如果架构保证了 DccManager 销毁时才销毁这些对象,则无需担心。
  • 数据一致性
    • 新代码中 m_currentObjectsm_triggeredObjects 是分开更新的,最后统一赋值。这保证了在更新过程中状态的一致性,没有中间状态被外部观察到,这是线程安全(如果在 UI 线程运行则无所谓)和逻辑安全的好做法。

总结与改进建议

总体来说,这是一份质量较高的重构代码,逻辑清晰,注释完善。

具体的改进建议如下:

  1. 补充 Q_INVOKABLE (代码质量/一致性)
    dccmanager.h 中,建议为新增的 getter 添加 Q_INVOKABLE 以保持一致性,尽管 QML 绑定可能不需要它。

    // dccmanager.h
    Q_INVOKABLE inline const QVector<DccObject *> &currentObjects() const override { return m_currentObjects; }
    Q_INVOKABLE inline const QVector<DccObject *> &triggeredObjects() const override { return m_triggeredObjects; }
  2. 检查 cmd 参数的传递 (逻辑)
    原代码中有 if (!cmd.isEmpty()) { Q_EMIT triggeredObj->active(cmd); }。新代码中移除了这一块(除了函数开头的 return 分支)。如果 cmd 包含了页面初始化的关键参数(如跳转到某个子页面的具体项),新逻辑可能导致功能缺失。请确认是否需要保留对 cmd 的处理,或者在构建路径的循环中将其传递给最终的 active 调用。

  3. 优化查找性能 (性能 - 可选)
    如果考虑到极端情况下的层级深度,可以使用 QSet 优化 contains 查找。

    // 在 dccmanager.cpp doShowPage 中
    QSet<DccObject *> triggeredSet(triggeredObjs.begin(), triggeredObjs.end());
    for (auto *oldObj : std::as_const(m_triggeredObjects)) {
        if (!triggeredSet.contains(oldObj)) { // O(1) lookup
            // ...
        }
    }
  4. 使用 prepend 替代 append + reverse (代码风格/性能)
    QVectorprepend 操作虽然比 append 慢(因为需要移动元素),但在控制中心这种层级数量级下(通常很少超过 10 层),性能差异微乎其微。使用 prepend 可以避免显式调用 std::reverse,使代码意图更直接("我要把它放在最前面")。

    • QListprepend 性能很好,但你们已经改用了 QVector。在 QVector 中,如果频繁 prepend 确实有性能问题,但这里只发生一次。目前的 append + reverse 也是完全标准的写法。此处仅为风格建议,目前的写法没有问题。
  5. 空指针保护细节
    代码中有 if (auto *lastObj = m_currentObjects.last(); ...
    如果 m_currentObjects 为空,调用 last() 会导致未定义行为(断言失败或崩溃)。
    虽然逻辑上 doShowPage 应该保证 modules 不为空(因为至少有 root),但为了防御性编程,建议增加检查:

    if (!m_currentObjects.isEmpty()) {
        if (auto *lastObj = m_currentObjects.last(); lastObj != m_activeObject) {
            m_activeObject = lastObj;
            Q_EMIT activeObjectChanged(m_activeObject);
        }
    }

@caixr23
Copy link
Contributor Author

caixr23 commented Feb 2, 2026

/forcemerge

@deepin-bot
Copy link

deepin-bot bot commented Feb 2, 2026

This pr force merged! (status: blocked)

@deepin-bot deepin-bot bot merged commit f58abaa into linuxdeepin:master Feb 2, 2026
16 of 18 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