Skip to content

feat: Add support for modifying the plugin popup cursor shape via the…#1434

Open
yixinshark wants to merge 1 commit intolinuxdeepin:masterfrom
yixinshark:feat-addCursorShape
Open

feat: Add support for modifying the plugin popup cursor shape via the…#1434
yixinshark wants to merge 1 commit intolinuxdeepin:masterfrom
yixinshark:feat-addCursorShape

Conversation

@yixinshark
Copy link
Contributor

@yixinshark yixinshark commented Feb 5, 2026

… protocol.

add support in plugin-manager-v1.xml

Log: Add support for modifying the plugin popup cursor shape via the protocol.

Summary by Sourcery

Add protocol and UI support for plugin popups to request and update the cursor shape.

New Features:

  • Allow plugin popups to request cursor shape changes via the plugin manager protocol.
  • Expose a configurable cursor shape property on shell surface items used for plugin popups.

@sourcery-ai
Copy link

sourcery-ai bot commented Feb 5, 2026

Reviewer's Guide

Adds protocol and implementation support for plugin popups to request cursor shape changes, plumbing the request from the Wayland plugin manager extension through to the QML shell surface proxy and exposing it as a cursorShape property with bounds checking.

Sequence diagram for plugin popup cursor shape update flow

sequenceDiagram
    actor PluginClient
    participant WaylandPluginProtocol
    participant PluginPopup
    participant ShellSurfaceItemProxy_qml as ShellSurfaceItemProxy
    participant HoverHandler_qml as HoverHandler

    PluginClient->>WaylandPluginProtocol: plugin_popup_set_cursor(cursor_shape)
    WaylandPluginProtocol->>PluginPopup: plugin_popup_set_cursor(resource, cursor_shape)
    PluginPopup->>PluginPopup: plugin_popup_set_cursor(resource, cursor_shape)
    PluginPopup-->>ShellSurfaceItemProxy_qml: cursorShapeRequested(cursor_shape)
    ShellSurfaceItemProxy_qml->>ShellSurfaceItemProxy_qml: onCursorShapeRequested(cursor_shape)
    ShellSurfaceItemProxy_qml->>ShellSurfaceItemProxy_qml: validate cursor_shape range 0-21,24,25
    alt cursor_shape out of range
        ShellSurfaceItemProxy_qml->>ShellSurfaceItemProxy_qml: root.cursorShape = Qt.ArrowCursor
    else cursor_shape in range
        ShellSurfaceItemProxy_qml->>ShellSurfaceItemProxy_qml: root.cursorShape = cursor_shape
    end
    ShellSurfaceItemProxy_qml->>HoverHandler_qml: cursorShape = root.cursorShape
Loading

Class diagram for PluginPopup and ShellSurfaceItemProxy cursor shape support

classDiagram
    class PluginPopup {
        +plugin_popup_source_size(resource: Resource, width: int32_t, height: int32_t)
        +plugin_popup_set_cursor(resource: Resource, cursor_shape: int32_t)
        +plugin_popup_destroy_resource(resource: Resource)
        +plugin_popup_destroy(resource: Resource)
        +cursorShapeRequested(cursorShape: int)
        -m_manager: PluginManager*
    }

    class ShellSurfaceItemProxy {
        +inputEventsEnabled: bool
        +hovered: bool
        +pressed: bool
        +cursorShape: int
        +onCursorShapeRequested(cursorShape: int)
    }

    class HoverHandler_qml {
        +hovered: bool
        +cursorShape: int
    }

    ShellSurfaceItemProxy --> HoverHandler_qml: sets cursorShape
    PluginPopup --> ShellSurfaceItemProxy: emits cursorShapeRequested
Loading

Flow diagram for cursorShape bounds checking in ShellSurfaceItemProxy

flowchart TD
    A[onCursorShapeRequested cursorShape param received] --> B[Check if cursorShape < 0 or cursorShape > 25]
    B -->|yes| C[Set root.cursorShape to Qt.ArrowCursor]
    B -->|no| D[Set root.cursorShape to cursorShape]
    C --> E[HoverHandler.cursorShape uses root.cursorShape]
    D --> E[HoverHandler.cursorShape uses root.cursorShape]
Loading

File-Level Changes

Change Details Files
Wire plugin popup cursor-shape requests from the Wayland protocol into the QML shell surface proxy and expose a configurable cursorShape with validation.
  • Add a cursorShape int property on the shell surface proxy root item with default Qt.ArrowCursor
  • Bind the HoverHandler cursorShape to the root cursorShape property so hover cursor reflects requested value
  • Introduce an onCursorShapeRequested handler in QML that logs the value, validates it against the Qt::CursorShape range, and falls back to ArrowCursor when out of bounds
  • Extend PluginPopup interface to handle the new plugin_popup_set_cursor request and emit a cursorShapeRequested signal carrying the requested cursor shape
panels/dock/tray/ShellSurfaceItemProxy.qml
panels/dock/pluginmanagerextension.cpp
panels/dock/pluginmanagerextension_p.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 1 issue, and left some high level feedback:

  • The onCursorShapeRequested handler in ShellSurfaceItemProxy.qml is currently just a standalone function; unless it is explicitly connected to the PluginPopup::cursorShapeRequested signal elsewhere, this callback will never run—consider wiring the signal to this handler or using a Connections object in the QML to make the linkage explicit.
  • The console.log("onCursorShapeRequested:", cursorShape) in QML will spam logs on every cursor update; consider removing it or guarding it behind a runtime debug flag to avoid excessive logging in normal operation.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The `onCursorShapeRequested` handler in `ShellSurfaceItemProxy.qml` is currently just a standalone function; unless it is explicitly connected to the `PluginPopup::cursorShapeRequested` signal elsewhere, this callback will never run—consider wiring the signal to this handler or using a `Connections` object in the QML to make the linkage explicit.
- The `console.log("onCursorShapeRequested:", cursorShape)` in QML will spam logs on every cursor update; consider removing it or guarding it behind a runtime debug flag to avoid excessive logging in normal operation.

## Individual Comments

### Comment 1
<location> `panels/dock/tray/ShellSurfaceItemProxy.qml:117-122` </location>
<code_context>
             })
         }
+
+        function onCursorShapeRequested(cursorShape)
+        {
+            console.log("onCursorShapeRequested:", cursorShape)
+            // Qt::CursorShape range is 0-21, plus 24 (BitmapCursor) and 25 (CustomCursor).
+            // We set a default if the value is out of logical bounds.
+            if (cursorShape < 0 || cursorShape > 25) {
+                root.cursorShape = Qt.ArrowCursor
+            } else {
</code_context>

<issue_to_address>
**issue (bug_risk):** The cursorShape bounds check lets invalid enum values 22 and 23 through.

The check only filters values < 0 or > 25, so 22 and 23 are still accepted even though the comment marks them as invalid. If Wayland ever sends 22 or 23, this could cause undefined cursor behavior. Please tighten the condition to only accept 0–21, 24, and 25 (e.g. `if ((cursorShape >= 0 && cursorShape <= 21) || cursorShape == 24 || cursorShape == 25)`), or map any other value to a safe default.
</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.

@yixinshark
Copy link
Contributor Author

linuxdeepin/dde-tray-loader#424
这里修改协议,添加支持。

… protocol.

add support in plugin-manager-v1.xml

Log: Add support for modifying the plugin popup cursor shape via the protocol.
@deepin-ci-robot
Copy link

deepin pr auto review

这段代码主要实现了在 Wayland 协议下,插件弹窗(PluginPopup)支持动态设置鼠标光标形状的功能。整体来看,代码逻辑清晰,能够实现预期功能。但在代码质量、健壮性和安全性方面,仍有改进空间。

以下是详细的审查意见和改进建议:

1. 依赖版本控制 (debian/control)

审查意见

- dde-tray-loader-dev (>= 1.99.14),
+ dde-tray-loader-dev (> 2.0.24),

这里将依赖版本从 >= 1.99.14 修改为 > 2.0.24

改进建议

  • 语法与逻辑:使用 >(严格大于)通常是不推荐的,除非你非常确定 2.0.24 这个版本本身有严重问题。通常情况下,如果 2.0.24 修复了 bug 或引入了新接口,应该使用 >=。如果 2.0.24 是一个不稳定的测试版本,建议直接指定具体的稳定版本号(如 >= 2.0.25)。
  • 建议:改为 dde-tray-loader-dev (>= 2.0.24),除非明确排除 2.0.24

2. C++ 后端实现 (panels/dock/pluginmanagerextension.cpp..._p.h)

审查意见
pluginmanagerextension.cpp 中添加了 plugin_popup_set_cursor 函数,并在头文件中声明了对应的信号 cursorShapeRequested

void PluginPopup::plugin_popup_set_cursor(Resource *resource, int32_t cursor_shape)
{
    Q_UNUSED(resource);
    Q_EMIT cursorShapeRequested(cursor_shape);
}

改进建议

  • 参数校验(健壮性):虽然前端 QML 中做了边界检查,但在 C++ 层(协议入口处)对传入的 cursor_shape 进行校验更为安全。如果客户端发送了恶意或错误的数值,尽早拦截可以防止逻辑错误扩散。
  • 类型安全cursor_shapeint32_t,但 Qt 的 Qt::CursorShape 枚举值范围是有限的。建议在 C++ 层将其转换为枚举类型或至少进行范围断言。

改进代码示例

// 在 pluginmanagerextension.cpp 中
void PluginPopup::plugin_popup_set_cursor(Resource *resource, int32_t cursor_shape)
{
    Q_UNUSED(resource);
    
    // 基础范围校验,防止非法数值传播
    // 假设合法范围是 0-25,参考前端逻辑
    if (cursor_shape < 0 || cursor_shape > 25) {
        qWarning() << "Invalid cursor shape requested:" << cursor_shape << ", falling back to ArrowCursor";
        cursor_shape = Qt::ArrowCursor;
    }

    Q_EMIT cursorShapeRequested(static_cast<int>(cursor_shape));
}

3. QML 前端实现 (panels/dock/tray/ShellSurfaceItemProxy.qml)

审查意见
onCursorShapeRequested 函数中处理光标形状的更新,并添加了边界检查。

function onCursorShapeRequested(cursorShape)
{
    console.log("onCursorShapeRequested:", cursorShape)
    if (cursorShape < 0 || cursorShape > 25) {
        root.cursorShape = Qt.ArrowCursor
    } else {
        root.cursorShape = cursorShape
    }
}

改进建议

  • 代码质量与性能
    • 移除调试日志console.log 在正式版本中应当移除或通过 Qt.debug() 等机制控制,频繁的日志输出会影响性能,尤其是鼠标移动频繁触发时。
    • 硬编码数值025 的范围判断属于"魔术数字"。如果 Qt 未来更新了枚举值,这里容易出错。建议在 C++ 层定义常量并通过单例或上下文属性暴露给 QML,或者直接使用 Qt.ArrowCursor 等枚举值进行比较(如果 QML 支持该枚举的数值比较)。
  • 逻辑优化:目前的逻辑是如果越界则设为 Qt.ArrowCursor。这很合理,但建议保持与 C++ 层的校验逻辑一致。

改进代码示例

// 建议移除 console.log,或者仅在调试模式下输出
// function onCursorShapeRequested(cursorShape)
// {
//     if (typeof Qt.application !== 'undefined' && Qt.application.debug) {
//         console.log("onCursorShapeRequested:", cursorShape)
//     }
//     
//     // 使用常量或更明确的判断
//     // 假设我们无法从 C++ 传入常量,保留数值判断但需确保注释更新
//     if (cursorShape < Qt.ArrowCursor || cursorShape > 25) { 
//         root.cursorShape = Qt.ArrowCursor
//     } else {
//         root.cursorShape = cursorShape
//     }
// }

4. 综合安全与逻辑总结

  1. 协议安全:目前的实现直接将客户端传来的 int32_t 转发给 UI 层。虽然 QML 做了防御,但在 Wayland 协议处理函数(C++ 层)做第一道防线是更好的实践。
  2. 状态同步:确保 root.cursorShape 的初始值(Qt.ArrowCursor)与协议默认行为一致,避免初始化时的闪烁。
  3. 性能:鼠标光标的改变可能非常频繁,应确保 QML 的属性绑定和信号处理足够轻量。目前的实现是直接赋值,性能尚可。

5. 最终修改建议总结

  1. debian/control: 将 > 2.0.24 改为 >= 2.0.24
  2. pluginmanagerextension.cpp: 在 plugin_popup_set_cursor 中增加对 cursor_shape 的范围校验和日志输出(使用 qWarning 而非 console.log)。
  3. ShellSurfaceItemProxy.qml: 移除 console.log,或者加上条件判断;确保边界检查的数值与 Qt 文档严格对应。

这些修改将提高代码的健壮性、可维护性和安全性。

void yChanged();
void heightChanged();
void widthChanged();
void cursorShapeRequested(int cursorShape);
Copy link
Contributor

Choose a reason for hiding this comment

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

这里要不要再加个cursorShape属性,导出到qml中,

@deepin-ci-robot
Copy link

[APPROVALNOTIFIER] This PR is NOT APPROVED

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

@deepin-bot
Copy link

deepin-bot bot commented Feb 5, 2026

TAG Bot

New tag: 2.0.29
DISTRIBUTION: unstable
Suggest: synchronizing this PR through rebase #1436

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds support for plugin popups to request cursor shape changes via the Wayland protocol. The feature allows plugins to communicate their desired cursor shape to the compositor, which then updates the UI accordingly.

Changes:

  • Added protocol support for cursor shape requests in plugin popups
  • Implemented cursor shape handling in the QML UI layer with validation
  • Updated dependency version to require protocol support in dde-tray-loader-dev

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
panels/dock/tray/ShellSurfaceItemProxy.qml Added cursorShape property and signal handler to process cursor shape requests from plugins
panels/dock/pluginmanagerextension_p.h Declared new protocol method and signal for cursor shape requests
panels/dock/pluginmanagerextension.cpp Implemented plugin_popup_set_cursor to emit cursorShapeRequested signal
debian/control Updated dde-tray-loader-dev dependency to require version > 2.0.24 for protocol support

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +122 to +126
if (cursorShape < 0 || cursorShape > 25) {
root.cursorShape = Qt.ArrowCursor
} else {
root.cursorShape = cursorShape
}
Copy link

Copilot AI Feb 5, 2026

Choose a reason for hiding this comment

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

The validation logic allows cursor shape values 22 and 23, which are not valid Qt cursor shapes. According to the comment on line 120-121, Qt::CursorShape has values 0-21, then 24-25, with a gap at 22-23. The validation should explicitly exclude these invalid values to prevent potential rendering issues. Consider checking if the value is in the valid ranges: (cursorShape >= 0 && cursorShape <= 21) || cursorShape == 24 || cursorShape == 25.

Copilot uses AI. Check for mistakes.
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