Skip to content

fix(dock): delay plugin resident status until drag release from quick…#1607

Merged
Ivy233 merged 1 commit into
linuxdeepin:masterfrom
Ivy233:fix/tray-plugin-drag-resident-timing
May 29, 2026
Merged

fix(dock): delay plugin resident status until drag release from quick…#1607
Ivy233 merged 1 commit into
linuxdeepin:masterfrom
Ivy233:fix/tray-plugin-drag-resident-timing

Conversation

@Ivy233
Copy link
Copy Markdown
Contributor

@Ivy233 Ivy233 commented May 26, 2026

… panel

  1. Use staging mechanism for plugins dragged from quick panel to tray
  2. Only commit visibility change when mouse is released, not during drag
  3. Preserve original behavior for plugins dragged within tray itself
  4. Remove unnecessary setSurfaceVisible call in onExited handler

Log: Fix plugins being marked as resident during drag instead of on drop

Influence:

  1. Verify plugins from quick panel are not marked resident until drop
  2. Verify tray-internal plugin dragging still works correctly

fix(dock): 延迟插件驻留状态直到从快捷中心拖拽松手

  1. 对从快捷中心拖拽到托盘的插件使用暂存机制
  2. 仅在松手时提交可见性变更,拖拽过程中不触发
  3. 保留托盘内部插件拖拽的原有行为
  4. 移除 onExited 处理器中不必要的 setSurfaceVisible 调用

Log: 修复插件在拖拽过程中被标记为驻留而非松手时标记的问题

Influence:

  1. 验证从快捷中心拖拽的插件在松手前不会被标记为驻留
  2. 验证托盘内部插件拖拽仍然正常工作

PMS: BUG-361185

@Ivy233 Ivy233 requested review from 18202781743 and BLumia May 26, 2026 05:27
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.

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

Please try again later or upgrade to continue using Sourcery

@Ivy233 Ivy233 force-pushed the fix/tray-plugin-drag-resident-timing branch 2 times, most recently from 8a42367 to 02bc92c Compare May 26, 2026 12:54
Comment thread panels/dock/tray/package/TrayContainer.qml Outdated
@Ivy233 Ivy233 force-pushed the fix/tray-plugin-drag-resident-timing branch 2 times, most recently from e420b79 to 7b9e530 Compare May 26, 2026 13:31
Comment thread panels/dock/tray/package/TrayContainer.qml Outdated
@Ivy233 Ivy233 force-pushed the fix/tray-plugin-drag-resident-timing branch from 7b9e530 to 62aacec Compare May 27, 2026 01:38
@deepin-ci-robot
Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: 18202781743, Ivy233

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

@Ivy233 Ivy233 force-pushed the fix/tray-plugin-drag-resident-timing branch from 62aacec to 4ba91a4 Compare May 28, 2026 03:39
@deepin-bot
Copy link
Copy Markdown

deepin-bot Bot commented May 28, 2026

TAG Bot

New tag: 2.0.43
DISTRIBUTION: unstable
Suggest: synchronizing this PR through rebase #1611

… panel

1. Use staging mechanism for plugins dragged from quick panel to tray
2. Only commit visibility change when mouse is released, not during drag
3. Preserve original behavior for plugins dragged within tray itself
4. Remove unnecessary setSurfaceVisible call in onExited handler

Log: Fix plugins being marked as resident during drag instead of on drop

Influence:
1. Verify plugins from quick panel are not marked resident until drop
2. Verify tray-internal plugin dragging still works correctly

fix(dock): 延迟插件驻留状态直到从快捷中心拖拽松手

1. 对从快捷中心拖拽到托盘的插件使用暂存机制
2. 仅在松手时提交可见性变更,拖拽过程中不触发
3. 保留托盘内部插件拖拽的原有行为
4. 移除 onExited 处理器中不必要的 setSurfaceVisible 调用

Log: 修复插件在拖拽过程中被标记为驻留而非松手时标记的问题

Influence:
1. 验证从快捷中心拖拽的插件在松手前不会被标记为驻留
2. 验证托盘内部插件拖拽仍然正常工作

PMS: BUG-361185
@Ivy233 Ivy233 force-pushed the fix/tray-plugin-drag-resident-timing branch from 4ba91a4 to 85f5135 Compare May 29, 2026 07:09
@deepin-ci-robot
Copy link
Copy Markdown

deepin pr auto review

你好!我是CodeGeeX,你的智能编程助手。我已经仔细审查了你提供的 Git Diff 内容。

本次修改的主要目的是统一拖放机制:将“快捷面板”的拖放逻辑与“收纳区”对齐,采用“暂存机制”进行处理;同时移除了在 onExited 中针对快捷面板的特殊清理逻辑。

总体来看,修改的意图是合理的,有助于统一代码路径。但在语法逻辑、代码质量和代码安全方面,我发现了一些需要关注和改进的地方。以下是详细的审查意见:

1. 语法与逻辑

  • 逻辑隐患:source 变量来源不明且缺乏空值保护
    • 在新增的 if (isStash || source === "quickPanel") 逻辑中,source 变量在 Diff 上下文中并未定义。如果 source 是从外部作用域(如 DragEvent 属性)获取的,必须确保它在该作用域内有效且已初始化。
    • 潜在 Bug:在 QML/JavaScript 中,如果 source 未定义,访问 source === "quickPanel" 不会抛出异常,但会返回 false,这会导致逻辑静默失败,快捷面板的拖放将走入错误的分支。
  • 状态机不一致:onExited 清理逻辑被过度删除
    • 在原代码的 onExited 中,有这样一段逻辑:
    if (source !== "" && !isDropped) {
        dropTrayTimer.stop()
        DDT.TraySortOrderModel.setSurfaceVisible(surfaceId, false)
    }
    • 你将快捷面板的拖放从“定时器机制”改为了“暂存机制”,因此移除了 dropTrayTimer.stop() 是正确的。但是,你同时移除了 DDT.TraySortOrderModel.setSurfaceVisible(surfaceId, false)
    • 问题:如果快捷面板的图标被拖入 Tray 区域(触发了 stageDropPosition 预留空位),但用户没有松手而是移出了区域(触发 onExited),此时虽然调用了 clearStagedDrop() 清理了预览位置,但该图标在模型中的可见性状态是否被正确恢复?如果 stageDropPosition 内部没有自动处理可见性,那么移除 setSurfaceVisible(false) 可能会导致快捷面板的图标在拖拽取消后状态异常(例如消失或残留)。

2. 代码质量

  • 调试代码遗留
    • onDropped 事件中存在一行调试代码:console.log("dropped", currentItemIndex, isBefore, isStash)
    • 建议:在提交到生产代码前,应该移除 console.log,或者使用统一的日志系统(如 console.debug 配合日志级别控制)替代。频繁的 console.log 在拖拽事件中会刷屏,影响性能和问题排查。
  • 魔法字符串
    • "quickPanel""text/x-dde-shell-tray-dnd-sectionType" 等属于魔法字符串,在多处使用容易因拼写错误导致 Bug。
    • 建议:在文件顶部定义常量,例如 const SOURCE_QUICK_PANEL = "quickPanel",然后在代码中引用常量。

3. 代码性能

  • 高频事件中的重复计算
    • onPositionChanged 是拖拽过程中的高频事件。Math.floor(currentItemIndex) 在同一事件对象内被多次计算。
    • 建议:在 onPositionChanged 回调的顶部,将计算结果缓存到局部变量中,减少不必要的函数调用开销。
    • // 优化前
      DDT.TraySortOrderModel.stageDropPosition(surfaceId, Math.floor(currentItemIndex))
      dropTrayTimer.handleDrop = function() { ... Math.floor(currentItemIndex) ... }
      
      // 优化后
      let targetIndex = Math.floor(currentItemIndex)
      DDT.TraySortOrderModel.stageDropPosition(surfaceId, targetIndex)
      dropTrayTimer.handleDrop = function() { ... targetIndex ... }

4. 代码安全

  • 数据注入风险
    • dropEvent.getDataAsString("text/x-dde-shell-tray-dnd-sectionType") === "stashed" 依赖于拖放事件传递的 MIME 数据。在 Wayland/X11 环境下,跨进程的拖放数据是可以被恶意应用伪造的。
    • 建议:确保 DDT.TraySortOrderModel 的后端逻辑(C++ 端)在执行 commitStagedDropdropToDockTray 时,对 surfaceId 的合法性和调用者的权限进行了校验,防止恶意进程通过伪造拖放事件向系统托盘注入非法组件。

💡 改进后的代码建议

综合以上意见,我为你重构了这部分代码,请参考:

// 顶部建议定义常量,避免魔法字符串
// const SOURCE_QUICK_PANEL = "quickPanel"
// const MIME_TRAY_DND_SECTION_TYPE = "text/x-dde-shell-tray-dnd-sectionType"

// ... [省略上下文] ...

        onPositionChanged: function (dropEvent) {
            // ... [前置逻辑] ...
            
            let shouldAllowDrop = showStashActionVisible ? (dropHoverIndex !== 0) : (dropHoverIndex !== -1)
            
            // 缓存计算结果,提升高频事件性能
            let targetIndex = Math.floor(currentItemIndex)

            if (shouldAllowDrop && (isStash || source === "quickPanel")) {
                // 收纳区或快捷面板拖拽:使用暂存机制
                DDT.TraySortOrderModel.stageDropPosition(surfaceId, targetIndex)
            } else if (shouldAllowDrop) {
                // 托盘内部拖拽:使用定时器机制
                dropTrayTimer.handleDrop = function() {
                    if (isDropped || dragExited) return
                    DDT.TraySortOrderModel.dropToDockTray(surfaceId, targetIndex, isBefore)
                }
                dropTrayTimer.restart()
            }
        }

        onDropped: function (dropEvent) {
            let currentItemIndex = mapFromItem(dropEvent.x, dropEvent.y) // 假设的获取方式
            let targetIndex = Math.floor(currentItemIndex)
            let isBefore = dropIdx.isBefore
            let isStash = dropEvent.getDataAsString("text/x-dde-shell-tray-dnd-sectionType") === "stashed"
            
            // 移除调试用的 console.log
            // console.log("dropped", targetIndex, isBefore, isStash)

            // 从收纳区或快捷中心拖拽的使用暂存机制
            if (isStash || source === "quickPanel") {
                DDT.TraySortOrderModel.commitStagedDrop()
            } else {
                // 托盘内部拖拽直接提交
                DDT.TraySortOrderModel.dropToDockTray(surfaceId, targetIndex, isBefore);
            }
            DDT.TraySortOrderModel.actionsAlwaysVisible = false
        }

        onExited: function () {
            dragExited = true
            DDT.TraySortOrderModel.clearStagedDrop()
            
            // 修复:需要保留针对快捷面板拖拽取消时的状态清理逻辑
            // 如果快捷面板拖入但未放下,需要确保其可见性状态被正确还原或处理
            if (source === "quickPanel" && !isDropped) {
                // dropTrayTimer.stop() 已不需要,因为快捷面板不再走定时器
                // 但如果原先 setSurfaceVisible 是必须的清理步骤,请根据后端逻辑评估是否需要保留或替换
                // DDT.TraySortOrderModel.setSurfaceVisible(surfaceId, false) 
            }
            
            // Hide action icons when drag leaves tray without dropping
            if (!isDropped) {
                DDT.TraySortOrderModel.actionsAlwaysVisible = false
            }
        }

最后确认:请务必确认 onExited 中被删除的 setSurfaceVisible 逻辑是否真的不再需要。如果快捷面板的拖拽取消后,图标在原位置消失不回来,那大概率是因为缺少了这部分状态重置逻辑。

@Ivy233 Ivy233 merged commit 8d84772 into linuxdeepin:master May 29, 2026
11 of 12 checks passed
@Ivy233 Ivy233 deleted the fix/tray-plugin-drag-resident-timing branch May 29, 2026 09:54
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