Skip to content

feat: add dock library and refactor dock plugin management#1560

Merged
wjyrich merged 1 commit intolinuxdeepin:masterfrom
wjyrich:feat-dockapplete
Apr 17, 2026
Merged

feat: add dock library and refactor dock plugin management#1560
wjyrich merged 1 commit intolinuxdeepin:masterfrom
wjyrich:feat-dockapplete

Conversation

@wjyrich
Copy link
Copy Markdown
Contributor

@wjyrich wjyrich commented Apr 16, 2026

  1. Added new libdde-shell-dock library to provide dock item interface
  2. Created DAppletDock abstract base class for dock plugins with dockItemInfo() and setVisible() methods
  3. Refactored dock plugin management to use new library instead of hardcoded plugin IDs
  4. Updated build system to include new library and development packages
  5. Modified multitaskview plugin to inherit from DAppletDock instead of DApplet
  6. Added dockVersion metadata field to identify dock-compatible plugins
  7. Fixed installation paths for header files and libraries in Debian packaging

Log: Improved dock plugin architecture with standardized interface

Influence:

  1. Test dock plugin visibility management through settings
  2. Verify multitaskview plugin still works correctly
  3. Check that tray functionality remains unchanged
  4. Test building and installation of new libdde-shell-dock packages
  5. Verify backward compatibility with existing dock plugins
  6. Test dock item information retrieval through D-Bus interface

feat: 新增Dock库并重构Dock插件管理

  1. 新增libdde-shell-dock库,提供Dock项目接口
  2. 创建DAppletDock抽象基类,包含dockItemInfo()和setVisible()方法
  3. 重构Dock插件管理,使用新库替代硬编码的插件ID
  4. 更新构建系统以包含新库和开发包
  5. 修改multitaskview插件继承自DAppletDock而非DApplet
  6. 新增dockVersion元数据字段以识别Dock兼容插件
  7. 修复Debian打包中头文件和库的安装路径

Log: 改进Dock插件架构,提供标准化接口

Influence:

  1. 测试通过设置管理Dock插件可见性
  2. 验证multitaskview插件仍正常工作
  3. 检查托盘功能是否保持不变
  4. 测试新建libdde-shell-dock包的构建和安装
  5. 验证与现有Dock插件的向后兼容性
  6. 测试通过D-Bus接口获取Dock项目信息

PMS: TASK-388449

Summary by Sourcery

Introduce a shared dock library and unify dock plugin handling around a standard dock applet interface.

New Features:

  • Add the shared libdde-shell-dock library providing common dock item types and the DAppletDock base class for dock plugins.
  • Make the multitaskview dock plugin inherit from DAppletDock and expose standardized dock item metadata.

Bug Fixes:

  • Correct Debian installation paths for dock-related headers and libraries via new packaging entries.

Enhancements:

  • Refactor dock D-Bus proxy logic to discover and control dock plugins dynamically using dockVersion metadata instead of hardcoded plugin IDs.
  • Centralize DockItemInfo and related types in the new dock library and link existing dock components against it.

Build:

  • Extend the build configuration to build and install the new dde-shell-dock library and link dock-related plugins against it.

Deployment:

  • Add Debian packaging entries for the new libdde-shell-dock runtime and -dev packages.

@sourcery-ai
Copy link
Copy Markdown

sourcery-ai bot commented Apr 16, 2026

Reviewer's Guide

Introduces a new shared dock library (libdde-shell-dock) with a DAppletDock base class and central DockItemInfo type, refactors dock plugin discovery/visibility logic to use metadata and the new interface instead of hardcoded IDs, updates existing plugins (notably multitaskview) and build/packaging to consume the new library, and cleans up Debian install paths for headers and libraries.

Sequence diagram for dock plugin visibility update via DAppletDock

sequenceDiagram
    actor UserSettings
    participant SettingsUI
    participant DockSettings
    participant DockDBusProxy
    participant DockPanel
    participant DAppletDockPlugin as DAppletDock_plugin
    participant TrayApplet

    UserSettings->>SettingsUI: toggle plugin visibility
    SettingsUI->>DockSettings: setPluginsVisible(pluginsVisible)
    DockSettings-->>DockSettings: update internal map
    DockSettings->>DockDBusProxy: pluginsVisibleChanged(pluginsVisible)

    DockDBusProxy->>DockPanel: applets()
    DockPanel-->>DockDBusProxy: list of applets

    loop for each applet with dockVersion 1.0
        DockDBusProxy->>DAppletDock_plugin: dockItemInfo()
        DAppletDock_plugin-->>DockDBusProxy: DockItemInfo(itemKey)
        alt pluginsVisible contains itemKey
            DockDBusProxy->>DAppletDock_plugin: setVisible(visible)
        else
            DockDBusProxy->>DockSettings: pluginsVisible()
            DockSettings-->>DockDBusProxy: current map
            DockDBusProxy->>DockSettings: setPluginsVisible(updatedMap)
        end
    end

    alt tray item affected
        DockDBusProxy->>TrayApplet: setItemOnDock(settingKey, itemKey, visible)
        DockDBusProxy-->>UserSettings: pluginVisibleChanged(itemKey, visible)
    end
Loading

Class diagram for new dock library and updated dock plugins

classDiagram
    class DApplet {
    }

    class DockItemInfo {
        +QString itemKey
    }

    class DAppletDock {
        <<abstract>>
        +DAppletDock(QObject *parent)
        +~DAppletDock()
        +DockItemInfo dockItemInfo()
        +void setVisible(bool visible)
    }

    class MultiTaskView {
        +MultiTaskView(QObject *parent)
        +bool init()
        +QString iconName
        +void setIconName(QString iconName)
    }

    class DockPanel {
        +QList~QObject*~ applets()
    }

    class DockDBusProxy {
        -DockPanel* m_parent
        -DAppletProxy* m_oldDockApplet
        -DAppletProxy* m_trayApplet
        +DockItemInfos plugins()
        +QRect geometry()
        +void setItemOnDock(QString settingKey, QString itemKey, bool visible)
        -void updateDockPluginsVisible(QVariantMap pluginsVisible)
    }

    class DockSettings {
        +static DockSettings* instance()
        +QVariantMap pluginsVisible()
        +void setPluginsVisible(QVariantMap pluginsVisible)
    }

    class DAppletProxy {
    }

    DAppletDock --|> DApplet
    MultiTaskView --|> DAppletDock

    DockDBusProxy --> DockPanel : parent()
    DockPanel "1" o-- "*" DApplet : applets()

    DockDBusProxy --> DockSettings : read_write_pluginsVisible
    DockDBusProxy --> DAppletProxy : use_tray_applet
    DockDBusProxy --> DAppletDock : cast_from_applets
    DAppletDock --> DockItemInfo : returns
Loading

File-Level Changes

Change Details Files
Refactor dock D-Bus proxy to use generic dock plugin metadata and DAppletDock interface instead of hardcoded multitaskview handling.
  • Replace setPluginVisible helper with updateDockPluginsVisible that iterates over parent applets and filters by dockVersion metadata
  • Use qobject_cast<DAppletDock*> and direct C++ calls to dockItemInfo() and setVisible() instead of QMetaObject::invokeMethod on specific plugins
  • Remove stored multitaskview applet proxy and associated initialization logic
  • Update plugins() to collect DockItemInfo from all DAppletDock-based applets discovered via metadata
  • Update setItemOnDock() to locate the matching DAppletDock by itemKey and fall back to forwarding to tray if none found
panels/dock/dockdbusproxy.cpp
panels/dock/dockdbusproxy.h
Introduce dde-shell-dock shared library providing common dock abstractions and wire it into the build.
  • Create frame/dock CMake target dde-shell-dock exporting public headers dockiteminfo.h and dappletdock.h and linking against dde-shell-frame and Qt modules
  • Set proper target properties (VERSION, SOVERSION, OUTPUT_NAME, EXPORT_NAME) and DS_LIB compile definition
  • Configure include and link directories for both build and install interfaces
  • Install dde-shell-dock library and its public headers under an include/dock subdirectory and export via DDEShellTargets
  • Add frame/dock subdirectory to top-level frame CMakeLists and link dockpanel, multitaskview, tray, and appruntimeitem targets against dde-shell-dock instead of local dockiteminfo sources
frame/dock/CMakeLists.txt
frame/dock/dappletdock.h
frame/dock/dappletdock.cpp
frame/dock/dockiteminfo.h
frame/dock/dockiteminfo.cpp
frame/CMakeLists.txt
panels/dock/CMakeLists.txt
panels/dock/multitaskview/CMakeLists.txt
panels/dock/tray/CMakeLists.txt
panels/dock/appruntimeitem/CMakeLists.txt
Update multitaskview plugin to be a dock-aware plugin by inheriting from DAppletDock and using shared dock types.
  • Change includes in multitaskview sources/headers to use dock/dappletdock.h and dock/dockiteminfo.h from the new library
  • Change MultiTaskView base class from DApplet to DS_NAMESPACE::DAppletDock and adjust constructor base initialization
  • Call DAppletDock::init() during initialization to align with new base class expectations
  • Ensure build links multitaskview against dde-shell-dock and stops compiling its own copy of dockiteminfo
panels/dock/multitaskview/multitaskview.cpp
panels/dock/multitaskview/multitaskview.h
panels/dock/multitaskview/CMakeLists.txt
Switch existing dock components to consume shared DockItemInfo from the new dock library.
  • Replace local dockiteminfo includes with dock/dockiteminfo.h in appruntimeitem and tray code
  • Update appruntimeitem CMake to reference dockiteminfo sources from frame/dock instead of panels/dock
  • Remove dockiteminfo.cpp/h from dockpanel, multitaskview, and tray library source lists now that they come from dde-shell-dock
panels/dock/appruntimeitem/appruntimeitem.h
panels/dock/tray/trayitem.h
panels/dock/appruntimeitem/CMakeLists.txt
panels/dock/CMakeLists.txt
panels/dock/multitaskview/CMakeLists.txt
panels/dock/tray/CMakeLists.txt
Adjust Debian packaging to ship the new dock library and development headers with correct installation paths.
  • Add libdde-shell-dock and libdde-shell-dock-dev install stanzas for library and headers
  • Update existing dde-shell and libdde-shell-dev .install files to align with the new library layout and header install locations
  • Ensure public dock headers are placed under an include/dock subdirectory as referenced by CMake
debian/control
debian/dde-shell.install
debian/libdde-shell-dev.install
debian/libdde-shell-dock.install
debian/libdde-shell-dock-dev.install
Add dockVersion metadata to multitaskview package to mark it as dock-compatible.
  • Update plugin metadata.json for multitaskview to include a dockVersion field used by DockDBusProxy when discovering dock applets
panels/dock/multitaskview/package/metadata.json

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

  • The repeated inline checks for pluginMetaData().value("dockVersion").toString() == "1.0" would be easier to maintain and less error-prone if encapsulated in a small helper (e.g. isDockApplet() / dockApplets() and a shared constexpr key/version string) rather than hardcoded strings scattered across DockDBusProxy.
  • In both updateDockPluginsVisible and setItemOnDock, DockSettings::instance()->pluginsVisible() is read and written inside per-applet branches; consider fetching and updating this map once per call (and only writing back once) to avoid redundant lookups and potential inconsistencies when multiple dock items are processed.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The repeated inline checks for `pluginMetaData().value("dockVersion").toString() == "1.0"` would be easier to maintain and less error-prone if encapsulated in a small helper (e.g. `isDockApplet()` / `dockApplets()` and a shared `constexpr` key/version string) rather than hardcoded strings scattered across `DockDBusProxy`.
- In both `updateDockPluginsVisible` and `setItemOnDock`, `DockSettings::instance()->pluginsVisible()` is read and written inside per-applet branches; consider fetching and updating this map once per call (and only writing back once) to avoid redundant lookups and potential inconsistencies when multiple dock items are processed.

## Individual Comments

### Comment 1
<location path="panels/dock/dockdbusproxy.cpp" line_range="76-85" />
<code_context>
+void DockDBusProxy::updateDockPluginsVisible(const QVariantMap &pluginsVisible)
</code_context>
<issue_to_address>
**suggestion (performance):** Avoid repeated reads/writes to DockSettings when normalizing pluginsVisible defaults.

In `updateDockPluginsVisible`, each missing key triggers a fresh `DockSettings::instance()->pluginsVisible()` read and a `setPluginsVisible()` write, possibly multiple times per call. This can cause unnecessary I/O or signal emissions. Instead, copy the current `QVariantMap` once, update it for all missing keys inside the loop, and then call `setPluginsVisible()` a single time if any changes were made.

Suggested implementation:

```cpp
void DockDBusProxy::updateDockPluginsVisible(const QVariantMap &pluginsVisible)
{
    // Cache the current pluginsVisible settings once and track whether we modify them.
    QVariantMap settingPluginsVisible = DockSettings::instance()->pluginsVisible();
    bool pluginsVisibleChanged = false;

    for (auto *applet : parent()->applets()) {

```

```cpp
                if (pluginsVisible.contains(itemKey)) {
                    dockApplet->setVisible(pluginsVisible[itemKey].toBool());
                } else {
                    // We already have a cached settingPluginsVisible; mark that we may update it.
                    pluginsVisibleChanged = true;

```

To fully implement the optimization and avoid repeated writes:

1. Replace any *subsequent* `DockSettings::instance()->pluginsVisible()` reads inside `updateDockPluginsVisible` with reads from the cached `settingPluginsVisible` introduced at the top of the function.
2. Ensure all code that mutates the plugins-visible map updates `settingPluginsVisible` instead of a local variable (e.g. `settingPluginsVisible.insert(itemKey, ...)`).
3. Move any existing `DockSettings::instance()->setPluginsVisible(...)` calls out of the loop and replace them with a **single** call at the end of the function, guarded by the boolean:
   ```cpp
   if (pluginsVisibleChanged) {
       DockSettings::instance()->setPluginsVisible(settingPluginsVisible);
   }
   ```
4. Preserve the original default-visibility behavior for missing keys (whatever logic currently decides the default) when you migrate the mutations into `settingPluginsVisible`.
</issue_to_address>

### Comment 2
<location path="panels/dock/dockdbusproxy.cpp" line_range="79" />
<code_context>
+void DockDBusProxy::updateDockPluginsVisible(const QVariantMap &pluginsVisible)
+{
+    for (auto *applet : parent()->applets()) {
+        if (applet->pluginMetaData().value("dockVersion").toString() == "1.0") {
+            if (auto dockApplet = qobject_cast<DS_NAMESPACE::DAppletDock *>(applet)) {
+                DockItemInfo itemInfo = dockApplet->dockItemInfo();
</code_context>
<issue_to_address>
**suggestion:** Consider avoiding hard-coded dockVersion string comparisons.

This `pluginMetaData().value("dockVersion").toString() == "1.0"` check is repeated in several places. Hard-coding the version string makes future version changes or multi-version support harder and fragile. Prefer either a dedicated metadata flag (e.g. `isDockApplet`) or a shared version constant defined in one header and reused here.
</issue_to_address>

### Comment 3
<location path="panels/dock/dockdbusproxy.cpp" line_range="80" />
<code_context>
+{
+    for (auto *applet : parent()->applets()) {
+        if (applet->pluginMetaData().value("dockVersion").toString() == "1.0") {
+            if (auto dockApplet = qobject_cast<DS_NAMESPACE::DAppletDock *>(applet)) {
+                DockItemInfo itemInfo = dockApplet->dockItemInfo();
+                QString itemKey = itemInfo.itemKey;
</code_context>
<issue_to_address>
**question (bug_risk):** Check threading assumptions when calling setVisible directly instead of via QMetaObject::invokeMethod.

Previously this was done via `QMetaObject::invokeMethod(..., Qt::QueuedConnection, ...)`, guaranteeing execution on the receiver’s thread. Now `dockApplet->setVisible()` is called directly. If `pluginsVisibleChanged` (or callers of `updateDockPluginsVisible` / `setItemOnDock`) can run off the GUI thread while `DAppletDock` expects GUI-thread access, this risks race conditions or thread violations. If these signals are always emitted on the GUI thread, this is fine; otherwise, consider restoring queued delivery or clearly documenting the threading guarantees.
</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 thread panels/dock/dockdbusproxy.cpp Outdated
Comment thread panels/dock/dockdbusproxy.cpp Outdated
Comment thread panels/dock/dockdbusproxy.cpp Outdated
@wjyrich wjyrich force-pushed the feat-dockapplete branch 2 times, most recently from cc86ac8 to 1b664e7 Compare April 16, 2026 08:02
Comment thread frame/dock/dappletdock.h Outdated
Comment thread debian/libdde-shell-dock.install Outdated
@wjyrich wjyrich force-pushed the feat-dockapplete branch 4 times, most recently from 9560252 to 9f3bbf4 Compare April 16, 2026 11:43
Comment thread frame/dock/dappletdockitem.h Outdated
Comment thread frame/dock/dappletdockitem.h Outdated
Comment thread panels/dock/dockdbusproxy.cpp Outdated
Comment thread panels/dock/multitaskview/multitaskview.h Outdated
@wjyrich wjyrich force-pushed the feat-dockapplete branch 3 times, most recently from 02d2270 to c966f80 Compare April 17, 2026 03:39
{
"Plugin": {
"Version": "1.0",
"dockVersion": "1.0",
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.

改成 "dock": {
"version": "1.0"
}
这样吧,方便之后扩展,

Comment thread panels/dock/frame/CMakeLists.txt Outdated
Comment on lines +29 to +32
PRIVATE
Qt${QT_VERSION_MAJOR}::QuickTemplates2Private
Qt${QT_VERSION_MAJOR}::QuickPrivate
Qt${QT_VERSION_MAJOR}::GuiPrivate
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.

这些应该不需要吧,

property bool shouldVisible: Applet.visible
dockOrder: 15
// 1:4 the distance between app : dock height; get width/height≈0.8
implicitWidth: useColumnLayout ? Panel.rootObject.dockSize : Panel.rootObject.dockItemMaxSize * 0.8
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.

这些是不是都可以放在AppletDockItem里呀,

explicit DAppletDock(QObject *parent = nullptr);
virtual ~DAppletDock() override;

virtual DockItemInfo dockItemInfo();
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.

还需要这个DockItemInfo么,它是不是可以拆开了呀,分成不同的接口出去,

Comment thread panels/dock/frame/dappletdock.h Outdated
void visibleChanged();

private:
bool m_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.

这种用d指针的方式吧,m_visible放在private里,保持之后的兼容性,

Comment thread panels/dock/dockdbusproxy.cpp
Comment thread panels/dock/frame/dappletdock.h Outdated
Comment thread panels/dock/frame/CMakeLists.txt Outdated
@@ -0,0 +1,2 @@
usr/include/dde-shell/dock/*.h
usr/lib/*/libdde-shell-dock.so*
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.

这个libdde-shell-dock.so,不安装-dev包就不用安装了么?

Comment thread panels/dock/frame/CMakeLists.txt Outdated

target_compile_definitions(dde-shell-dock PRIVATE DS_LIB)

install(TARGETS dde-shell-dock EXPORT DDEShellTargets DESTINATION "${LIB_INSTALL_DIR}" PUBLIC_HEADER DESTINATION "${INCLUDE_INSTALL_DIR}/dock") No newline at end of file
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.

@wjyrich wjyrich force-pushed the feat-dockapplete branch 3 times, most recently from a9016eb to c90840e Compare April 17, 2026 07:37
18202781743
18202781743 previously approved these changes Apr 17, 2026
@deepin-ci-robot
Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: mhduiy, 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

1. Added new libdde-shell-dock library to provide dock item interface
2. Created DAppletDock abstract base class for dock plugins with
dockItemInfo() and setVisible() methods
3. Refactored dock plugin management to use new library instead of
hardcoded plugin IDs
4. Updated build system to include new library and development packages
5. Modified multitaskview plugin to inherit from DAppletDock instead
of DApplet
6. Added dockVersion metadata field to identify dock-compatible plugins
7. Fixed installation paths for header files and libraries in Debian
packaging

Log: Improved dock plugin architecture with standardized interface

Influence:
1. Test dock plugin visibility management through settings
2. Verify multitaskview plugin still works correctly
3. Check that tray functionality remains unchanged
4. Test building and installation of new libdde-shell-dock packages
5. Verify backward compatibility with existing dock plugins
6. Test dock item information retrieval through D-Bus interface

feat: 新增Dock库并重构Dock插件管理

1. 新增libdde-shell-dock库,提供Dock项目接口
2. 创建DAppletDock抽象基类,包含dockItemInfo()和setVisible()方法
3. 重构Dock插件管理,使用新库替代硬编码的插件ID
4. 更新构建系统以包含新库和开发包
5. 修改multitaskview插件继承自DAppletDock而非DApplet
6. 新增dockVersion元数据字段以识别Dock兼容插件
7. 修复Debian打包中头文件和库的安装路径

Log: 改进Dock插件架构,提供标准化接口

Influence:
1. 测试通过设置管理Dock插件可见性
2. 验证multitaskview插件仍正常工作
3. 检查托盘功能是否保持不变
4. 测试新建libdde-shell-dock包的构建和安装
5. 验证与现有Dock插件的向后兼容性
6. 测试通过D-Bus接口获取Dock项目信息

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

deepin pr auto review

这份代码 diff 展示了对 DDE Shell Dock 组件的一次重要重构,主要目的是将 dock 相关的通用功能(如 DockItemInfoDAppletDock)从 panels/dock 目录下抽离出来,形成一个新的共享库 libdde-shell-dock,并更新了依赖它的其他模块(如 multitaskview, tray, appruntimeitem)。

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

1. 语法逻辑

  • Debian 包管理与依赖关系:

    • debian/control: 新增了 libdde-shell-dock-dev 包,并正确声明了它依赖于 libdde-shell-dev 和 Qt6 相关开发包。这是合理的。
    • debian/libdde-shell-dock-dev.install: 安装了头文件、共享库和 CMake 配置文件。路径规范。
    • debian/libdde-shell-dev.install: 修改了安装路径,从通配符 usr/include 变更为具体的 usr/include/dde-shell/*.h。这非常好,避免了污染系统全局 include 目录,是更规范的做法。
    • debian/dde-shell.install: 将 libds-notification-shared.so.* 修改为 libds-notification-shared.so*。注意,* 会匹配 .so (符号链接) 和 .so.x.y.z (实际文件)。通常在运行时包中安装 .so.x (SONAME) 链接和实际库文件,在开发包中安装 .so (用于链接) 链接。如果 dde-shell 是运行时包,这里可能需要注意是否应该只安装带版本号的库文件,或者确认 .so 链接是否确实需要在此处安装。
  • CMake 构建系统:

    • panels/dock/frame/CMakeLists.txt: 新增的共享库构建脚本配置完整,包含了 install(TARGETS ... EXPORT ...)write_basic_package_version_file,这允许其他项目通过 CMake 的 find_package 轻松找到并链接该库。
    • panels/dock/frame/DDEShellDockConfig.cmake.in: 配置文件模板正确地查找了依赖项(Qt 和 DDEShell)。
    • panels/dock/CMakeLists.txt: 移除了 dockiteminfo 的源文件,并链接了新的 dde-shell-dock 库。逻辑正确。
    • panels/dock/multitaskview/CMakeLists.txtpanels/dock/tray/CMakeLists.txt: 同样移除了本地源文件,转而链接 dde-shell-dock
  • C++ 代码逻辑:

    • panels/dock/frame/dappletdock.h/cpp: 定义了基类 DAppletDock,继承自 DApplet。它提供了 visible 属性和纯虚函数 dockItemInfo()。这是良好的面向对象设计,为所有 Dock 插件提供了统一接口。
    • panels/dock/multitaskview/multitaskview.h/cpp: MultiTaskView 现在继承自 DAppletDock,并移除了重复的 visible 属性和相关逻辑,改为直接使用基类实现。代码复用性提高。
    • panels/dock/dockdbusproxy.cpp:
      • 引入了匿名命名空间和 dockApplets 辅助函数,用于遍历并筛选出实现了 Dock V1 接口的插件。这比之前硬编码 m_multitaskviewApplet 要灵活得多,支持了动态插件。
      • updateDockPluginsVisibleplugins 方法现在遍历所有符合条件的 Dock 插件,而不是只处理 multitaskview。逻辑正确。
      • setItemOnDock 方法也更新为遍历查找匹配的 itemKey 并设置可见性。
  • QML 代码逻辑:

    • panels/dock/AppletDockItem.qml: 新增了一个通用的 Dock 项 QML 组件。它封装了根据 Dock 位置(水平/垂直)计算尺寸的逻辑。
    • panels/dock/multitaskview/package/multitaskview.qml: 现在继承自 AppletDockItem,复用了尺寸计算逻辑,代码更简洁。
    • panels/dock/multitaskview/package/metadata.json: 添加了 "dock": {"version": "1.0"} 元数据,这与 C++ 中的 DockVersionV1 检查逻辑相匹配。

2. 代码质量

  • 模块化与解耦: 将通用的 Dock 功能抽离到 dde-shell-dock 库中,大大降低了 dockpanelmultitaskviewtray 之间的耦合度。这是一个显著的代码质量提升。
  • 代码复用: AppletDockItemDAppletDock 的引入消除了多个插件中重复的代码(如可见性管理、尺寸计算)。
  • 头文件包含: 检查了头文件路径的修改(例如 #include "dockiteminfo.h" 改为 #include "../frame/dockiteminfo.h"#include "frame/dockiteminfo.h"),确保了在新结构下引用路径的正确性。
  • 版权年份: 部分文件的版权年份更新为 "2023 - 2026" 或 "2024 - 2026",这是好的维护习惯。

3. 代码性能

  • 运行时查找: dockdbusproxy.cpp 中的 dockApplets 函数在每次调用时都会遍历 panel->applets() 并进行字符串比较和类型转换 (qobject_cast)。
    • 建议: 虽然插件数量通常不多,性能影响可能微乎其微,但如果 applets() 列表很大或这些函数调用非常频繁,可以考虑在 DockDBusProxy 中缓存 DAppletDock 指针列表,并监听 appletListChanged 信号来更新缓存。
  • QML 属性绑定: AppletDockItem.qml 中的 implicitWidthimplicitHeight 依赖于 Panel.rootObject.dockSize。这会创建属性绑定。只要 dockSize 变化,尺寸就会自动更新。这是 QML 的标准做法,性能通常是可接受的。

4. 代码安全

  • 空指针检查: dockApplets 函数中包含了 if (!panel) return list; 的检查,防止了空指针解引用。
  • 类型安全: 使用 qobject_cast 而非 C 风格强制转换,提高了类型安全性。
  • 版本控制: 通过元数据中的 dock.version 字段来筛选插件,这是一种防止接口不兼容导致崩溃的安全机制。只有声明了兼容版本的插件才会被当作 Dock 插件处理。

改进意见

  1. CMake 导出目标名称一致性:

    • panels/dock/frame/CMakeLists.txt 中,EXPORT_NAME 设置为 ShellDock,生成的命名空间是 Dde::(见 DDEShellDockConfig.cmake.in)。
    • panels/dock/CMakeLists.txt 中,链接时使用的是 dde-shell-dock(目标名)。
    • 建议: 确保使用者知道应该通过 target_link_libraries(... Dde::ShellDock) 还是 target_link_libraries(... dde-shell-dock) 来链接。通常推荐使用带命名空间的导入目标(即 Dde::ShellDock)。目前的配置看起来是正确的,但在文档中应明确指出。
  2. dockdbusproxy.cpp 中的性能优化:

    • 如前所述,dockApplets 每次都遍历查找。
    • 建议: 可以在 DockDBusProxy 类中添加一个 QList<DS_NAMESPACE::DAppletDock*> m_cachedDockApplets; 成员变量。在构造函数或初始化时填充它,并连接到 Panel 的相关信号(如果有 applet 变化的信号)来更新缓存。在 dockApplets 函数中直接返回缓存列表。
  3. DAppletDock::dockItemInfo() 的默认实现:

    • dappletdock.cppDockItemInfo DAppletDock::dockItemInfo() { return {}; } 返回了一个空的 DockItemInfo
    • 建议: 考虑将其声明为纯虚函数 virtual DockItemInfo dockItemInfo() = 0;,强制所有继承的子类必须实现该方法,提供有意义的信息。如果确实需要默认实现(虽然不太可能),建议添加注释说明为什么默认返回空对象。
  4. QML 中的属性命名:

    • AppletDockItem.qml 中的 shouldVisible 属性。
    • 建议: 在 Qt/QML 中,通常使用 visible 作为属性名。shouldVisible 听起来更像是一个内部逻辑判断变量。如果是为了避免与基类的 visible 冲突,可以考虑重命名为 effectiveVisiblecanVisible,或者检查是否可以直接使用基类的 visible 属性并绑定。目前的代码中 property bool shouldVisible: Applet.visible 看起来只是做了一个转发,如果基类是 DAppletDock 且它有 visible 属性,直接使用可能更简洁。
  5. Debian 安装文件中的通配符:

    • debian/dde-shell.installusr/lib/*/libds-notification-shared.so*
    • 建议: 确认 dde-shell 包的定位。如果是运行时库包,通常只安装带版本号的库文件(如 .so.1)。不带版本号的 .so 链接通常放在 -dev 包中,供编译时链接使用。除非 dde-shell 本身就是一个开发包或者有特殊需求,否则建议将 .so 链接移至对应的 -dev 包(如果存在),或者确认这样做不会违反 Debian 打包策略。

总结

这次重构是一个高质量的改动,成功地实现了代码的模块化和解耦,提高了可维护性和扩展性。新的插件系统通过元数据版本控制,更加灵活和安全。代码风格保持一致,版权信息更新及时。

主要的改进点集中在性能微优化(缓存插件列表)和接口设计的严谨性(纯虚函数)上,但这些都不是严重问题,属于锦上添花。整体逻辑清晰,符合现代 C++ 和 QML 的最佳实践。

@wjyrich wjyrich merged commit 89ded03 into linuxdeepin:master Apr 17, 2026
10 of 12 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.

4 participants