Skip to content

feat: add applet visibility control to DAppletItemModel and - #1676

Open
wjyrich wants to merge 1 commit into
linuxdeepin:masterfrom
wjyrich:task-393299-1
Open

feat: add applet visibility control to DAppletItemModel and#1676
wjyrich wants to merge 1 commit into
linuxdeepin:masterfrom
wjyrich:task-393299-1

Conversation

@wjyrich

@wjyrich wjyrich commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

DPluginLoader

Implement a framework-level hidden applets mechanism that allows suppressing individual applet root objects from the containment model without destroying them. The DAppletItemModel now maintains both a complete root objects list and a filtered visible subset. A new setRootObjectVisible method enables toggling visibility while preserving the original insertion order upon restoration. The DPluginLoader exposes hiddenApplets, isAppletHidden, and setHiddenApplets APIs, and the shell synchronizes these with a DConfig key hiddenApplets. Hidden applets remain loaded but their root objects are reparented to the applet and removed from the visual model. Unit tests verify order preservation and removal semantics.

Log: Added applet visibility control API and DConfig integration

Influence:

  1. Test applet hiding and showing via DConfig changes
  2. Verify that hidden applets remain loaded and their root objects are properly reparented
  3. Test that removing a plugin ID from the hidden list restores the applet in its original model order
  4. Verify that the model signals emit correctly on visibility changes
  5. Test interaction with applet creation, deletion, and root object changes
  6. Verify that the API works for multiple containments simultaneously

feat: 为 DAppletItemModel 和 DPluginLoader 添加 Applet 显隐控制

实现框架级隐藏 Applet 机制,可在不销毁实例的前提下将其根对象从容
器模型中移除。DAppletItemModel 维护完整的根对象列表和可见子集,
新增 setRootObjectVisible 方法支持按需切换显隐,恢复时保持原有
插入顺序。DPluginLoader 提供 hiddenAppletsisAppletHiddensetHiddenApplets 接口,Shell 通过 DConfig 键 hiddenApplets 同步配 置。隐藏的 Applet 仍保持加载,其根对象重新挂载到 Applet 自身并从视觉模型
中移除。单元测试验证了顺序保持和移除语义。

Log: 新增 Applet 显隐控制接口和 DConfig 集成

Influence:

  1. 通过 DConfig 变更测试 Applet 的隐藏和显示
  2. 验证隐藏的 Applet 依然保持加载,根对象正确重新挂载
  3. 测试从隐藏列表中移除插件 ID 后 Applet 按原有顺序恢复
  4. 验证模型信号在可见性变更时正确发出
  5. 测试与 Applet 创建、删除及根对象变更的交互
  6. 验证该 API 能同时作用于多个容器

PMS: TASK-393299

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

Sorry @wjyrich, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@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

Comment thread shell/shell.cpp Outdated
}

if (m_dconfig && m_dconfig->isValid()) {
connect(m_dconfig, &Dtk::Core::DConfig::valueChanged,

@18202781743 18202781743 Jul 28, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

配置用subpath的方式去获取,而不是把所有插件都放在一个hiddenApplets里,每个插件都有一个单独的配置,方便后面override, https://github.com/18202781743/cskills/blob/4745ee77b82d808182f2a8681db135b0933fb2ba/dtk-development/references/config/concepts.md?plain=1#L74

Comment thread frame/appletitemmodel.cpp
{
}

QList<QObject *> DAppletItemModel::rootObjects() const

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

这里rootObjects要改成visibleRootObjects么,要不要加个新的visibleRootObjects属性,

Comment thread frame/appletitemmodel.h Outdated

QList<QObject *> rootObjects() const;
void append(QObject *rootObject);
void append(QObject *rootObject, bool visible = true);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

这个是公共接口,不能直接加,另外也不需要,在添加的地方去拦截比较合适,

Add the ability to enable or disable DApplet instances via DConfig,
controlling whether their root objects appear in the parent containment
model.

The new `enable` property is exposed as a Q_PROPERTY on DApplet, backed
by a DConfig key `enable` under `org.deepin.dde.shell`. When loading,
DApplet reads this config and watches for changes.

Disabled applets remain loaded but their root objects are removed from
the containment's `appletItems` model; re-enabling re-inserts them.
This enables runtime toggling of applet visibility without unloading/
reloading plugins.

Unit tests are added for the DAppletItemModel (append/remove) and the
enable property change notification logic.

Log: Added DApplet enable/disable feature via DConfig

Influence:
1. Test creating an applet and verifying its enable property is true
by default
2. Set enable to false via dde-dconfig and verify the applet root object
is removed from the containment model
3. Set enable to true and verify the root object reappears
4. Verify that setEnable with the same value does not emit enableChanged
signal
5. Test loading a root plugin (like dock) - its enable should not be
affected (skipped)
6. Verify DConfig changes are watched and applied dynamically at runtime
7. Run unit tests: EnablePropertyNotifiesOnlyOnChange,
AppendsRootObjects, RemovesRootObject

feat: 添加支持通过 DConfig 启用/禁用 Applet 的接口

新增通过 DConfig 控制 DApplet 实例启用的能力,决定其根对象是否显示在父容
器模型中。

新的 `enable` 属性作为 DApplet 的 Q_PROPERTY 暴露,由
`org.deepin.dde.shell` 下的 DConfig 键 `enable` 驱动。加载时 DApplet 读
取该配置并监听变化。

被禁用的 Applet 实例仍保持加载,但根对象从容器的 `appletItems` 模型中
移除;重新启用后会重新追加。这实现了无需卸载/重新加载插件即可运行时切换
Applet 可见性。

新增了 DAppletItemModel(追加/移除)以及 enable 属性变更通知逻辑的单元
测试。

Log: 新增 DApplet 启用/禁用功能

Influence:
1. 测试创建 Applet 并验证其 enable 属性默认为 true
2. 通过 dde-dconfig 将 enable 设为 false,验证根对象已从容器模型中移除
3. 设为 true 后验证根对象重新出现
4. 验证 setEnable 相同值时不会触发 enableChanged 信号
5. 测试加载根插件(如 dock),其 enable 不应受影响(跳过)
6. 验证 DConfig 变化能被监听并在运行时动态生效
7. 运行单元测试:EnablePropertyNotifiesOnlyOnChange、
AppendsRootObjects、RemovesRootObject

PMS: TASK-393299
@deepin-ci-robot

Copy link
Copy Markdown

deepin pr auto review

★ 总体评分:95分

■ 【总体评价】

代码实现了DApplet的enable属性控制显隐功能,逻辑严谨且包含完善的单元测试
代码结构清晰,生命周期管理安全,无安全漏洞,因部分性能细节可优化扣5分

■ 【详细分析】

  • 1.语法逻辑 完全正确 ✓

在 frame/applet.cpp 的 setMetaData 函数中,正确初始化了 DConfig 并绑定了 valueChanged 信号;在 frame/containment.cpp 的 createApplet 函数中,updateAppletItem lambda 正确处理了 rootObject 的添加与移除逻辑,并通过 preserveDisabledRootObject 防止了 QML delegate 销毁 root object 的问题。
潜在问题:无
建议:无需修改

  • 2.代码质量 优秀 ✓

代码遵循了良好的命名规范,注释清晰解释了 preserveDisabledRootObject 的作用。同时补充了中英文 API 文档和针对 DAppletItemModel 与 DApplet.EnableProperty 的单元测试,测试覆盖了边界情况。
潜在问题:无
建议:无需修改

  • 3.代码性能 无性能问题 ✓

updateAppletItem 中调用了 d->model()->rootObjects().contains(object),由于 applet 数量通常有限,O(n) 的查找开销可接受。DConfig 的读取仅在属性变化时触发,不会造成性能瓶颈。
潜在问题:无
建议:若未来 applet 数量剧增,可考虑优化 rootObjects 的数据结构以提供 O(1) 查找

  • 4.代码安全 存在0个安全漏洞 ✓

漏洞对比统计:新增漏洞 0 个,减少漏洞 0 个,持平 0 个
代码未引入外部输入处理,DConfig 配置项 visibility 设为 private,无路径遍历或注入风险。指针对象均有明确的父对象管理生命周期,无内存泄漏风险。

  • 建议:无需修改

■ 【改进建议代码示例】

// 当前代码已足够健壮,无需修改。以下为性能优化的潜在方向示例(非必须):
// 在 DAppletItemModel 中使用 QSet<QObject*> 加速 contains 查找
// class DAppletItemModel {
//     ...
//     QSet<QObject*> m_objectSet;
//     bool contains(QObject *obj) const { return m_objectSet.contains(obj); }
// };

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