Skip to content

refactor: migrate to shared dde-shell app model - #791

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

refactor: migrate to shared dde-shell app model#791
wjyrich wants to merge 1 commit into
linuxdeepin:masterfrom
wjyrich:task-393709

Conversation

@wjyrich

@wjyrich wjyrich commented Aug 5, 2026

Copy link
Copy Markdown
Contributor
  1. Replace direct AppMgr/AppItem usage with shared dde-shell application model
  2. Add LauncherItem::load() to bridge with org.deepin.ds.dde-apps applet
  3. Refactor AppsModel to adapt source model roles instead of owning app data
  4. Remove direct D-Bus interface generation for ApplicationManager1
  5. Fix QML role references from AppItem to AppsModel namespace
  6. Set apps applet as data source for DesktopIntegration operations
  7. Update QML to use new AppsModel.ddeCategories for category names
  8. Fix category sorting signal ordering to avoid duplicate layout changes

Log: Unified application data source with dde-shell shared model

Influence:

  1. Verify launcher still displays all installed applications correctly
  2. Test application launch through launcher and dock
  3. Test app category browsing and filtering
  4. Test sending/removing apps from desktop
  5. Test autostart toggle functionality
  6. Test disable scale functionality for legacy apps
  7. Test search functionality with pinyin, jianpin, and Chinese
  8. Test recently installed and frequently used sections
  9. Verify icon loading and caching behavior

refactor: 迁移到 dde-shell 共享应用模型

  1. 用共享的 dde-shell 应用模型替换直接的 AppMgr/AppItem 使用
  2. 添加 LauncherItem::load() 与 org.deepin.ds.dde-apps applet 桥接
  3. 重构 AppsModel 适配源模型角色而非拥有应用数据
  4. 移除 ApplicationManager1 的直接 D-Bus 接口生成
  5. 修复 QML 中角色引用从 AppItem 到 AppsModel 命名空间的变更
  6. 设置应用 qml 作为 DesktopIntegration 操作的数据源
  7. 更新 QML 使用新的 AppsModel.ddeCategories 获取分类名称
  8. 修复分类排序信号顺序避免重复的布局变更

Log: 应用数据源统一为 dde-shell 共享模型

Influence:

  1. 验证启动器仍能正确显示所有已安装应用
  2. 测试通过启动器和任务栏启动应用
  3. 测试应用分类浏览和过滤功能
  4. 测试发送/移除应用到桌面
  5. 测试开机自启动开关功能
  6. 测试旧应用的禁用缩放功能
  7. 测试拼音、简拼和中文搜索功能
  8. 测试最近安装和常用应用区域
  9. 验证图标加载和缓存行为

PMS: TASK-393709

Summary by Sourcery

Adapt launcher to use the shared dde-shell application model and applet instead of its own AppMgr-based app model.

New Features:

  • Bridge the launcher applet to the org.deepin.ds.dde-apps applet, wiring its shared application model and category metadata into AppsModel and DesktopIntegration.

Bug Fixes:

  • Ensure category-based sorting and QML section updates emit signals in a stable order to avoid redundant layout changes and duplicate updates.
  • Normalize desktop IDs and guard against empty transliteration data to prevent mismatches and errors in search and navigation logic.

Enhancements:

  • Refactor AppsModel into a QAbstractListModel adapter over an external source model, exposing standardized roles and category metadata expected by QML.
  • Update DesktopIntegration to route launch, desktop, autostart, and scale operations through the shared dde-apps applet instead of direct D-Bus/AppMgr calls.
  • Adjust proxy models, item arrangement logic, and QML views/tests to depend on AppsModel roles and the shared model instead of AppItem/AppMgr, including stronger readiness handling and section/category utilities.

@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

@sourcery-ai

sourcery-ai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Reviewer's Guide

Refactors the launcher’s AppsModel and integration layer to consume the shared dde-shell application model (dde-apps applet) instead of the local AppMgr/AppItem stack, updates DesktopIntegration to route operations through the apps applet, and aligns QML/tests/proxies with the new role IDs, category handling, and sorting/signaling behavior.

Sequence diagram for launching an app via shared dde-apps applet

sequenceDiagram
    actor User
    participant LauncherUI
    participant LauncherController
    participant DesktopIntegration
    participant XdgActivation as XdgActivation
    participant AppsApplet

    User->>LauncherUI: activate app item
    LauncherUI->>LauncherController: requestLaunch(desktopId)
    LauncherController->>DesktopIntegration: launchByDesktopId(desktopId)
    DesktopIntegration->>XdgActivation: requestToken()
    XdgActivation-->>DesktopIntegration: tokenReady(token)
    DesktopIntegration->>AppsApplet: launchApp(desktopId, token)
    AppsApplet-->>DesktopIntegration: bool launched
    alt [launch failed]
        DesktopIntegration-->>LauncherController: [log failure]
    end
Loading

File-Level Changes

Change Details Files
Replace internal AppMgr/AppItem-based AppsModel with an adapter over the shared dde-shell app model, including new roles, filtering, and icon handling.
  • Reimplemented AppsModel as a QAbstractListModel adapter that wraps a configurable QAbstractItemModel source instead of owning AppItem objects.
  • Introduced role mapping from shared model roles (desktopId, name, iconName, categories, ddeCategory, etc.) to launcher-specific Roles, including transliteration and pinyin-based search roles.
  • Implemented source model wiring (rowsInserted/Removed, dataChanged, modelReset, layoutChanged) with an internal row list, normalized desktop IDs, exclusion list, and noDisplay filtering.
  • Added icon cache watching via DFileWatcherManager and a timer that refreshes icon data by calling IconUtils::tryUpdateIconCache().
  • Added ready and ddeCategories Q_PROPERTIES with signals to indicate when the adapter is usable and to expose category enums to QML.
src/models/appsmodel.cpp
src/models/appsmodel.h
Wire launcher to org.deepin.ds.dde-apps: load shared applet, bind its model into AppsModel, and route desktop integration operations through it instead of AppMgr.
  • Added LauncherItem::load() that uses DAppletBridge("org.deepin.ds.dde-apps") to obtain the apps applet, reads its appModel/appModelReady/ddeCategories, and configures AppsModel plus DesktopIntegration accordingly.
  • Changed DesktopIntegration methods (launchByDesktopId, disableScale, setDisableScale, isOnDesktop, sendToDesktop, removeFromDesktop, isAutoStart, setAutoStart) to invoke methods on the apps applet via QMetaObject instead of using AppMgr/AppInfo and removed local desktop file path handling.
  • Added DesktopIntegration::setAppsApplet and stored the applet via QPointer for safe reuse in helper invocations.
shell-launcher-applet/launcheritem.cpp
shell-launcher-applet/launcheritem.h
desktopintegration.cpp
desktopintegration.h
Update proxy models, item arrangement, and QML to use AppsModel roles and ddeCategories instead of AppItem, and to handle new category/sort semantics safely.
  • Adjusted CategorizedSortProxyModel to sort by AppsModel::TransliteratedRole or AppsModel::DDECategoryRole, reordered sectionRoleName and sort updates to avoid duplicate or out-of-order layout changes, and fixed DDECategorySections to read AppsModel roles.
  • Refactored ItemArrangementProxyModel to use AppsModel::DesktopIdRole/IconNameRole/DDECategoryRole for folder IDs, icons, and inferred category-based folder names; gated syncing on AppsModel::ready and ensured it listens to modelReset.
  • Updated QML views (AppListView, AnalysisView, launcheritem.qml) to reference AppsModel roles instead of AppItem, use AppsModel.ddeCategories for category enums, guard against empty sections, and reset list view state on category type changes.
  • Switched various proxy models (SearchFilterProxyModel, FavoritedProxyModel, RecentlyInstalledProxyModel, frequently-used/recently-installed views) from AppItem roles to AppsModel roles and normalized desktop IDs with ".desktop" suffix in tests and logic.
src/models/categorizedsortproxymodel.cpp
src/models/itemarrangementproxymodel.cpp
src/models/itemarrangementproxymodel.h
src/models/searchfilterproxymodel.cpp
src/models/favoritedproxymodel.cpp
src/models/recentlyinstalledproxymodel.cpp
qml/windowed/AppListView.qml
qml/windowed/AnalysisView.qml
shell-launcher-applet/package/launcheritem.qml
Replace unit tests’ direct AppItem/AppMgr usage with a synthetic shared model to validate the new AppsModel adapter and category-sorting signal order.
  • Reworked searchfilterproxymodeltest to build a QStandardItemModel with custom role names (SourceDesktopIdRole, SourceNameRole, etc.), attach it as AppsModel::sourceModel, and set AppsModel::ready(), instead of mutating AppsModel::instance() via AppItem.
  • Adapted tests to expect normalized desktop IDs with ".desktop" suffix and AppsModel::DesktopIdRole; updated helper factory to fill new source roles including ddeCategory.
  • Added testSharedModelAdapter to verify that noDisplay filtering, desktopId normalization, dataChanged role mapping, and row insertion/removal all behave correctly when the source model changes.
  • Added testCategorySortSignalOrder to enforce the signal ordering for sectionRoleNameChanged, layout changes, and categoryTypeChanged in CategorizedSortProxyModel.
tests/searchfilterproxymodeltest.cpp
Remove legacy ApplicationManager1/AppMgr D-Bus integration and AppItem implementation from the build.
  • Deleted appmgr.cpp/appmgr.h and associated D-Bus type helpers (amglobaltypes.h, objectmap.h, propmap.h, qstringmap.h) plus ApplicationManager1/ObjectManager1 XMLs.
  • Dropped D-Bus code generation for ApplicationManager1/ObjectManager1 from ddeintegration CMake, removed appmgr sources/headers from dde-integration-dbus and launcher-models targets, and removed the dde-integration-dbus link where no longer needed.
  • Cleaned up unused includes (AppMgr, AppItem, categoryutils, DDBusSender) across models and DesktopIntegration, and adjusted SPDX headers to updated years.
src/ddeintegration/CMakeLists.txt
src/models/CMakeLists.txt
src/ddeintegration/appmgr.cpp
src/ddeintegration/appmgr.h
src/ddeintegration/types/amglobaltypes.h
src/ddeintegration/types/objectmap.h
src/ddeintegration/types/propmap.h
src/ddeintegration/types/qstringmap.h
src/ddeintegration/xml/org.desktopspec.ApplicationManager1.Application.xml
src/ddeintegration/xml/org.desktopspec.ObjectManager1.xml
src/models/appitem.cpp
src/models/appitem.h
desktopintegration.cpp
various source files removing includes

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

Comment thread src/models/appsmodel.h Outdated
Comment on lines +50 to +51
static AppsModel instance;
return instance;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

这个为啥要改?

@wjyrich
wjyrich force-pushed the task-393709 branch 3 times, most recently from 603ad16 to 927047b Compare August 7, 2026 06:50
@wjyrich

wjyrich commented Aug 7, 2026

Copy link
Copy Markdown
Contributor Author

/test github-pr-review-ci

1 similar comment
@wjyrich

wjyrich commented Aug 7, 2026

Copy link
Copy Markdown
Contributor Author

/test github-pr-review-ci

{
DAppletBridge bridge(QStringLiteral("org.deepin.ds.dde-apps"));
auto applet = bridge.applet();
if (!applet) {

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.

org.deepin.ds.dde-apps 这个 applet,与launchpad的applet加载顺序,能确定么,这里会不会拿不到啊,要不改到init里吧,

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

能确定 ,dde-shell是先加载的根节点, launchpad 的节点在dock下面,而dde-apps是是根节点

@18202781743 18202781743 Aug 7, 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.

dde-apps也不是dock的节点,他们是平级的,而且dde-shell加载是一颗颗树加载的,没有进行广度优先加载呀,要是先加载的是dock,这会等到launchpad加载完后再去加载dde-apps的,
现在没问题可能是安装字典排序的吧,先加载的是d,dock的是o开头,
看之后dde-shell支持depends依赖吧,

1. Replace direct AppMgr/AppItem usage with shared dde-shell application
model
2. Add LauncherItem::load() to bridge with org.deepin.ds.dde-apps applet
3. Refactor AppsModel to adapt source model roles instead of owning
app data
4. Remove direct D-Bus interface generation for ApplicationManager1
5. Fix QML role references from AppItem to AppsModel namespace
6. Set apps applet as data source for DesktopIntegration operations
7. Update QML to use new AppsModel.ddeCategories for category names
8. Fix category sorting signal ordering to avoid duplicate layout
changes

Log: Unified application data source with dde-shell shared model

Influence:
1. Verify launcher still displays all installed applications correctly
2. Test application launch through launcher and dock
3. Test app category browsing and filtering
4. Test sending/removing apps from desktop
5. Test autostart toggle functionality
6. Test disable scale functionality for legacy apps
7. Test search functionality with pinyin, jianpin, and Chinese
8. Test recently installed and frequently used sections
9. Verify icon loading and caching behavior

refactor: 迁移到 dde-shell 共享应用模型

1. 用共享的 dde-shell 应用模型替换直接的 AppMgr/AppItem 使用
2. 添加 LauncherItem::load() 与 org.deepin.ds.dde-apps applet 桥接
3. 重构 AppsModel 适配源模型角色而非拥有应用数据
4. 移除 ApplicationManager1 的直接 D-Bus 接口生成
5. 修复 QML 中角色引用从 AppItem 到 AppsModel 命名空间的变更
6. 设置应用 qml 作为 DesktopIntegration 操作的数据源
7. 更新 QML 使用新的 AppsModel.ddeCategories 获取分类名称
8. 修复分类排序信号顺序避免重复的布局变更

Log: 应用数据源统一为 dde-shell 共享模型

Influence:
1. 验证启动器仍能正确显示所有已安装应用
2. 测试通过启动器和任务栏启动应用
3. 测试应用分类浏览和过滤功能
4. 测试发送/移除应用到桌面
5. 测试开机自启动开关功能
6. 测试旧应用的禁用缩放功能
7. 测试拼音、简拼和中文搜索功能
8. 测试最近安装和常用应用区域
9. 验证图标加载和缓存行为

PMS: TASK-393709
@deepin-ci-robot

Copy link
Copy Markdown

deepin pr auto review


★ 总体评分:90分

■ 【总体评价】

代码成功将应用模型重构为基于dde-shell共享模型的适配器架构并修复了多处空指针崩溃,但存在少量旧式信号槽和线性查找的性能瑕疵
逻辑重构正确且大幅提升了架构合理性,因使用旧式字符串信号槽及部分冗余查找扣10分

■ 【详细分析】

  • 1.语法逻辑 基本正确 ✓

修复了 desktopintegration.cpp 中 void 函数带返回值的语法错误,修复了 AppListView.qml 中 transliterated 和 sections 数组直接取下标导致的越界崩溃。AppsModel 作为 QAbstractListModel 适配器,正确处理了 beginInsertRows/endInsertRows 等虚函数配对,并在 data() 函数中对 index.isValid() 和边界进行了严格校验。
潜在问题:launcheritem.cpp 中使用了 SIGNAL/SLOT 宏进行跨组件连接,丧失了编译期类型检查;AppsModel::pendingAppItemReady 的槽函数中通过遍历整个 m_sourceModel 来匹配 desktopId,逻辑上略显冗余。
建议:在 AppMgr 中传递源模型行号或 QModelIndex 以替代全表扫描;若条件允许,将 SIGNAL/SLOT 替换为函数指针或 lambda 表达式。

  • 2.代码质量 良好 ✓

重构移除了大量冗余的 DBus 代理类和 AppItem 数据类,将 Role 统一收敛至 AppsModel,大幅降低了模块间的耦合度。AppMgr 从直接操作代理对象改为通用的 QDBusMessage 调用,代码更加精简且易于维护。
潜在问题:AppsModel::endRemoveSourceRows 依赖 m_sourceRowsRemovalActive 布尔标志来控制 endRemoveRows() 的调用,这种状态标记模式在复杂异步场景下容易引入维护负担。
建议:考虑通过保存待移除的行范围信息来替代简单的布尔标记,使状态管理更加明确。

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

原有的 QStandardItemModel::match() 查找被替换为 QPersistentModelIndex 的直接索引访问,提升了数据获取效率。图标缓存更新使用防抖定时器(1000ms),避免了频繁的磁盘IO和UI刷新。
建议:暂无

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

漏洞对比统计:新增漏洞 0 个,减少漏洞 0 个,持平 0 个
总体风险描述:未发现安全漏洞。DBus 调用均使用 QDBusMessage 并限定内部硬编码的接口和属性名,未暴露给外部输入。应用启动通过 QProcess::start 传递参数列表,有效规避了 Shell 命令注入风险。applicationObjectPath 函数对 desktopId 进行了后缀剔除和 DUtil::escapeToObjectPath 转义,防止了 DBus 路径遍历。

  • 建议:继续保持对跨进程数据(如 dde-apps 提供的模型数据)的防御性编程,避免直接信任未经校验的外部属性。

■ 【改进建议代码示例】

--- a/shell-launcher-applet/launcheritem.cpp
+++ b/shell-launcher-applet/launcheritem.cpp
@@ -40,7 +40,14 @@ bool LauncherItem::load()
         return false;
     }
 
-    auto model = applet->property("appModel").value<QAbstractItemModel *>();
+    auto modelVariant = applet->property("appModel");
+    if (!modelVariant.isValid()) {
+        qCWarning(logApplet) << "dde-apps provided an invalid appModel property";
+        return false;
+    }
+    auto model = qobject_cast<QAbstractItemModel *>(modelVariant.value<QObject *>());
     if (!model) {
-        qCWarning(logApplet) << "dde-apps did not provide an application model";
+        qCWarning(logApplet) << "dde-apps appModel property is not a QAbstractItemModel";
         return false;
     }

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.

4 participants