Skip to content

Conversation

@yixinshark
Copy link
Contributor

@yixinshark yixinshark commented Aug 25, 2025

…lugin docked to tray

as title

Log: as title
Pms: BUG-299881

Summary by Sourcery

Trigger the pluginVisibleChanged signal over D-Bus whenever a tray plugin’s visibility changes (e.g., when dragging into or out of the tray)

Bug Fixes:

  • Ensure pluginVisibleChanged is sent when a tray plugin is shown via drop
  • Send pluginVisibleChanged when setting surface visibility
  • Send pluginVisibleChanged when hiding a plugin section

Enhancements:

  • Add handlePluginVisibleChanged method to send setItemOnDock calls over D-Bus
  • Include QDBus includes and error handling for the D-Bus call

@sourcery-ai
Copy link

sourcery-ai bot commented Aug 25, 2025

Reviewer's Guide

Introduce a dedicated helper to emit plugin visibility updates over D-Bus and invoke it across all workflows that change tray plugin visibility (drag-drop, show/hide toggles, section hides).

Sequence diagram for plugin visibility change via drag-and-drop

sequenceDiagram
    participant TraySortOrderModel
    participant QDBusConnection
    participant Dock1Service
    TraySortOrderModel->>TraySortOrderModel: dropToDockTray(draggedSurfaceId, ...)
    TraySortOrderModel->>TraySortOrderModel: handlePluginVisibleChanged(draggedSurfaceId, true)
    TraySortOrderModel->>QDBusConnection: send setItemOnDock(pluginId, true)
    QDBusConnection->>Dock1Service: setItemOnDock(Dock_Quick_Plugins, pluginId, true)
    Dock1Service-->>QDBusConnection: reply (success or error)
    QDBusConnection-->>TraySortOrderModel: reply (success or error)
Loading

Sequence diagram for plugin visibility change via show/hide toggle

sequenceDiagram
    participant TraySortOrderModel
    participant QDBusConnection
    participant Dock1Service
    TraySortOrderModel->>TraySortOrderModel: setSurfaceVisible(surfaceId, visible)
    TraySortOrderModel->>TraySortOrderModel: handlePluginVisibleChanged(surfaceId, visible)
    TraySortOrderModel->>QDBusConnection: send setItemOnDock(pluginId, visible)
    QDBusConnection->>Dock1Service: setItemOnDock(Dock_Quick_Plugins, pluginId, visible)
    Dock1Service-->>QDBusConnection: reply (success or error)
    QDBusConnection-->>TraySortOrderModel: reply (success or error)
Loading

Sequence diagram for plugin visibility change via section hide

sequenceDiagram
    participant TraySortOrderModel
    participant QDBusConnection
    participant Dock1Service
    TraySortOrderModel->>TraySortOrderModel: findSection(surfaceId, ...)
    TraySortOrderModel->>TraySortOrderModel: handlePluginVisibleChanged(surfaceId, false)
    TraySortOrderModel->>QDBusConnection: send setItemOnDock(pluginId, false)
    QDBusConnection->>Dock1Service: setItemOnDock(Dock_Quick_Plugins, pluginId, false)
    Dock1Service-->>QDBusConnection: reply (success or error)
    QDBusConnection-->>TraySortOrderModel: reply (success or error)
Loading

Class diagram for updated TraySortOrderModel

classDiagram
    class TraySortOrderModel {
        +registerSurfaceId(surfaceData: QVariantMap) : QString
        +loadDataFromDConfig()
        +saveDataToDConfig()
        +handlePluginVisibleChanged(surfaceId: QString, visible: bool)
        -m_hiddenIds: QList<QString>
        ...
    }
Loading

File-Level Changes

Change Details Files
Add handlePluginVisibleChanged helper to send D-Bus visibility notifications
  • Extract pluginId from surfaceId
  • Create and send QDBusMessage to Dock1 setItemOnDock
  • Log D-Bus errors or success
panels/dock/tray/traysortordermodel.cpp
panels/dock/tray/traysortordermodel.h
Invoke visibility helper in existing tray model operations
  • Call helper after un-hiding in dropToDockTray
  • Trigger helper in setSurfaceVisible for show/hide toggles
  • Invoke helper in findSection when hiding plugins
panels/dock/tray/traysortordermodel.cpp
Add required D-Bus header imports
  • Include QDBusMessage header
  • Include QDBusConnection header
panels/dock/tray/traysortordermodel.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

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 there - I've reviewed your changes and they look great!

Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments

### Comment 1
<location> `panels/dock/tray/traysortordermodel.cpp:527` </location>
<code_context>

+void TraySortOrderModel::handlePluginVisibleChanged(const QString &surfaceId, bool visible)
+{
+    QString pluginId = surfaceId.split("::").last();
+    if (pluginId.isEmpty()) {
+        qWarning() << "surfaceId format has error:" << surfaceId;
</code_context>

<issue_to_address>
Splitting surfaceId by '::' may not be robust for all input formats.

If '::' is missing, pluginId will equal surfaceId, which may be incorrect. Please validate the input format or clarify the expected format in documentation.
</issue_to_address>

<suggested_fix>
<<<<<<< SEARCH
void TraySortOrderModel::handlePluginVisibleChanged(const QString &surfaceId, bool visible)
{
    QString pluginId = surfaceId.split("::").last();
    if (pluginId.isEmpty()) {
        qWarning() << "surfaceId format has error:" << surfaceId;
        return;
    }
=======
/**
 * Handles plugin visibility changes.
 * @param surfaceId Expected format: "prefix::pluginId"
 * @param visible   Whether the plugin is visible
 */
void TraySortOrderModel::handlePluginVisibleChanged(const QString &surfaceId, bool visible)
{
    if (!surfaceId.contains("::")) {
        qWarning() << "surfaceId format error: missing '::' delimiter:" << surfaceId;
        return;
    }
    QString pluginId = surfaceId.split("::").last();
    if (pluginId.isEmpty()) {
        qWarning() << "surfaceId format has error: pluginId is empty:" << surfaceId;
        return;
    }
>>>>>>> REPLACE

</suggested_fix>

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 525 to 531
qWarning() << "surfaceId format has error:" << surfaceId;
return;
}

QDBusMessage msg = QDBusMessage::createMethodCall(
"org.deepin.dde.Dock1",
"/org/deepin/dde/Dock1",
Copy link

Choose a reason for hiding this comment

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

suggestion: Splitting surfaceId by '::' may not be robust for all input formats.

If '::' is missing, pluginId will equal surfaceId, which may be incorrect. Please validate the input format or clarify the expected format in documentation.

Suggested change
void TraySortOrderModel::handlePluginVisibleChanged(const QString &surfaceId, bool visible)
{
QString pluginId = surfaceId.split("::").last();
if (pluginId.isEmpty()) {
qWarning() << "surfaceId format has error:" << surfaceId;
return;
}
/**
* Handles plugin visibility changes.
* @param surfaceId Expected format: "prefix::pluginId"
* @param visible Whether the plugin is visible
*/
void TraySortOrderModel::handlePluginVisibleChanged(const QString &surfaceId, bool visible)
{
if (!surfaceId.contains("::")) {
qWarning() << "surfaceId format error: missing '::' delimiter:" << surfaceId;
return;
}
QString pluginId = surfaceId.split("::").last();
if (pluginId.isEmpty()) {
qWarning() << "surfaceId format has error: pluginId is empty:" << surfaceId;
return;
}

@yixinshark yixinshark force-pushed the fix-dragToDockSendSignal branch 2 times, most recently from f91440c to be87ecd Compare August 25, 2025 09:52
@deepin-ci-robot
Copy link

deepin pr auto review

我对这段代码进行了审查,发现以下几个需要改进的地方:

  1. 代码结构和设计:
  • handlePluginVisibleChanged 函数的实现可以进一步优化,目前将DBus调用逻辑直接放在模型类中,违反了单一职责原则。建议将DBus通信逻辑抽取到单独的服务类或工具类中。
  • 函数中硬编码的DBus服务名、路径和接口名应该定义为常量,以提高代码的可维护性。
  1. 错误处理:
  • DBus调用失败时仅打印警告,但没有采取恢复措施。建议增加重试机制或回滚逻辑。
  • handlePluginVisibleChanged 函数中对surfaceId的校验可以更严格,应该验证两部分内容的有效性。
  1. 性能优化:
  • DBus调用是同步的,可能会阻塞UI线程。建议改为异步调用,使用QDBusPendingCall和相关类。
  • updateVisualIndexes() 在多处被调用,可以考虑使用防抖(debounce)技术来优化性能。
  1. 代码安全:
  • parts.last() 的使用没有进行边界检查,虽然前面已经验证了parts.size(),但最好再添加一层保护。
  • DBus消息的构建应该考虑参数的合法性检查。
  1. 日志记录:
  • 当前的日志记录不够完善,建议增加更详细的日志信息,包括参数值和操作结果。
  • 考虑使用统一的日志级别和格式。

改进建议:

  1. 将DBus相关逻辑抽取到单独的类中:
class DockDBusService {
public:
    static void setItemOnDock(const QString &pluginId, bool visible);
private:
    static constexpr const char* SERVICE_NAME = "org.deepin.dde.Dock1";
    static constexpr const char* OBJECT_PATH = "/org/deepin/dde/Dock1";
    static constexpr const char* INTERFACE_NAME = "org.deepin.dde.Dock1";
    static constexpr const char* METHOD_NAME = "setItemOnDock";
};
  1. 改进错误处理和参数验证:
void TraySortOrderModel::handlePluginVisibleChanged(const QString &surfaceId, bool visible)
{
    if (surfaceId.isEmpty()) {
        qWarning() << "Empty surfaceId";
        return;
    }

    QStringList parts = surfaceId.split("::");
    if (parts.size() != 2 || parts.at(0).isEmpty() || parts.at(1).isEmpty()) {
        qWarning() << "Invalid surfaceId format:" << surfaceId;
        return;
    }

    // 使用异步DBus调用
    QDBusMessage msg = QDBusMessage::createMethodCall(
        DockDBusService::SERVICE_NAME,
        DockDBusService::OBJECT_PATH,
        DockDBusService::INTERFACE_NAME,
        DockDBusService::METHOD_NAME
    );
    
    msg << DockQuickPlugins << parts.at(1) << visible;
    
    QDBusPendingCall asyncCall = QDBusConnection::sessionBus().asyncCall(msg);
    QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(asyncCall, this);
    QObject::connect(watcher, &QDBusPendingCallWatcher::finished,
                     [this, surfaceId, visible](QDBusPendingCallWatcher *watcher) {
        QDBusPendingReply<> reply = *watcher;
        if (reply.isError()) {
            qWarning() << "DBus call failed for" << surfaceId 
                      << "error:" << reply.error().message();
            // 这里可以添加重试或回滚逻辑
        } else {
            qDebug() << "Successfully updated visibility for" << surfaceId;
        }
        watcher->deleteLater();
    });
}
  1. 添加防抖机制:
void TraySortOrderModel::updateVisualIndexes()
{
    if (m_updateTimer) {
        m_updateTimer->start(100); // 100ms的防抖延迟
        return;
    }
    
    m_updateTimer = new QTimer(this);
    m_updateTimer->setSingleShot(true);
    connect(m_updateTimer, &QTimer::timeout, this, [this]() {
        // 原有的updateVisualIndexes实现
        m_updateTimer->deleteLater();
        m_updateTimer = nullptr;
    });
    m_updateTimer->start(100);
}
  1. 在头文件中添加必要的成员变量:
class TraySortOrderModel : public QStandardItemModel
{
    // ... 其他成员 ...
private:
    QTimer *m_updateTimer = nullptr;
    static constexpr const char* DockQuickPlugins = "Dock_Quick_Plugins";
};

这些改进将提高代码的可维护性、性能和健壮性,同时降低耦合度。

…lugin docked to tray

as title

Log: as title
Pms: BUG-299881
@yixinshark yixinshark force-pushed the fix-dragToDockSendSignal branch from be87ecd to 0e639ff Compare August 26, 2025 07:03
@deepin-ci-robot
Copy link

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: 18202781743, mhduiy, yixinshark

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

@yixinshark
Copy link
Contributor Author

/forcemerge

@deepin-bot
Copy link

deepin-bot bot commented Aug 26, 2025

This pr force merged! (status: blocked)

@deepin-bot deepin-bot bot merged commit 446c89a into linuxdeepin:master Aug 26, 2025
7 of 9 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