Skip to content

fix: enable page-turn drag in full app folder rows - #808

Open
mhduiy wants to merge 1 commit into
linuxdeepin:masterfrom
mhduiy:agent/pms-bug-bot/0bbe9a17db39
Open

mhduiy wants to merge 1 commit into
linuxdeepin:masterfrom
mhduiy:agent/pms-bug-bot/0bbe9a17db39

Conversation

@mhduiy

@mhduiy mhduiy commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

Root Cause Analysis

In the app folder popup of dde-launchpad, the DelegateDropArea (on each app icon delegate) sits above folderPageDropArea in the QML event hierarchy. When a row is full (4 apps), dragging across that row always stays on a delegate's DropArea, so folderPageDropArea never receives onPositionChanged — its checkDragMove() is never called, and page-turn detection fails. When a row is partially filled, the empty space has no delegate, so folderPageDropArea receives events normally and page-turn works.

Key evidence: folderPageDropArea covers the full content area and checks drag X against the left/right 30% zone; DelegateDropArea instances are children of SwipeView placed after folderPageDropArea, making them event-level occluders.

Fix

Added page-turn detection to DelegateDropArea: in onEntered and onPositionChanged, the drag position is mapped to folderPageDropArea coordinates. If it falls within the page-turn zone (left/right 30%), the sort timer is stopped and checkDragMove(mappedX) is called to trigger page-turn; otherwise pageIntent is reset and normal sort logic proceeds. checkDragMove() now accepts an optional dragX parameter (defaults to drag.x). onExited resets pageIntent.

Change Safety Assessment

Code Safety

  • Risk Level: Low
  • The page-turn drag feature was introduced by commit 190355ca5 and refined by subsequent commits; this change is purely additive and does not revert any historical fix.
  • DelegateDropArea is only used within FolderGridViewPopup.qml (no external references), so the blast radius is limited to the folder popup.

Business Impact Scope

Affected module: App folder popup (both fullscreen and windowed modes share DelegateDropArea). User scenario: dragging an app icon to the left/right edge of the folder popup to switch pages. After the fix, page-turn works consistently regardless of how many apps are in the dragged-over row. Drag-to-sort and drag-out-to-close behaviors are unchanged for non-edge positions.

Verification Suggestion

  1. Test page-turn drag with a full first row (4 apps) — dragging to the right/left edge should switch pages.
  2. Test page-turn drag with a partially filled row — should work as before.
  3. Test drag-to-sort and drag-out-to-close to confirm no regression.

根因分析

在 dde-launchpad 的应用文件夹弹窗中,DelegateDropArea(每个应用图标 delegate 的 DropArea)在 QML 事件层级上位于 folderPageDropArea 之上。当某排已满(4 个应用)时,拖拽经过该排始终停留在某个 delegate 的 DropArea 上,folderPageDropArea 无法收到 onPositionChangedcheckDragMove() 不被调用,翻页检测失效。当某排未满时,空白区域无 delegate 遮挡,folderPageDropArea 正常收到事件,翻页正常工作。

关键证据:folderPageDropArea 覆盖整个内容区域,检测拖拽 X 坐标是否在左/右 30% 区域内;DelegateDropArea 实例是 SwipeView 的子节点,排在 folderPageDropArea 之后,构成事件层级遮挡。

修复方案

DelegateDropArea 增加翻页检测:在 onEnteredonPositionChanged 中,将拖拽位置映射到 folderPageDropArea 坐标系,若落在翻页区域(左/右 30%)则停止排序 timer 并调用 checkDragMove(mappedX) 触发翻页,否则重置 pageIntent 并正常进行排序。checkDragMove() 增加可选参数 dragX(默认回退到 drag.x)。onExited 中重置 pageIntent

改动安全评估

代码安全评估

  • 风险等级: 低风险
  • 翻页拖拽功能最初由 commit 190355ca5 引入,后续多次修复完善;本次改动为纯增量,不撤销任何历史修复。
  • DelegateDropArea 仅在 FolderGridViewPopup.qml 内部使用(无外部引用),影响范围仅限文件夹弹窗。

业务影响范围

受影响模块:应用文件夹弹窗(全屏模式和窗口模式共用 DelegateDropArea)。用户场景:拖拽应用图标到文件夹弹窗左/右边缘进行翻页。修复后,无论拖拽经过的排是否已满,翻页功能均正常工作。非边缘位置的拖拽排序和拖拽出文件夹关闭弹窗行为不变。

验证建议

  1. 测试满排(4 个应用)时拖拽应用到右/左边缘翻页——应正常切换页面。
  2. 测试不满排时拖拽翻页——应与修复前行为一致。
  3. 验证拖拽排序和拖拽出文件夹关闭弹窗无回归。

Summary by Sourcery

Fix app folder drag handling so dragging icons to the popup edges turns pages consistently regardless of row occupancy.

Bug Fixes:

  • Restore reliable drag-to-turn page navigation in app folder popups when dragging over fully populated rows.

Enhancements:

  • Preserve drag sorting behavior outside page-turn zones while coordinating page-turn state across delegate and folder drop areas.

1. Root cause: DelegateDropArea on app icons occluded
   folderPageDropArea drag events, preventing page-turn detection
   when a row was full of apps
2. Fix: DelegateDropArea maps drag position to folderPageDropArea
   coordinates and triggers page-turn in the edge zone (30 percent
   width), otherwise delegates to normal sort logic
3. Impact: page-turn drag works consistently regardless of row
   fullness, no change to sort behavior or page-turn zone size

Log: Fix page-turn drag not working when app folder rows are full

Influence:
1. Test dragging apps to page-turn zone with full rows
2. Test dragging apps to page-turn zone with partial rows
3. Test drag-to-sort and drag-out-to-close still work normally

fix: 修复满排时应用文件夹弹窗翻页拖拽失效

1. 根因:应用图标 DelegateDropArea 在事件层级上遮挡了
   folderPageDropArea,满排时拖拽事件无法传递到翻页检测区域
2. 方案:DelegateDropArea 将拖拽位置映射到 folderPageDropArea
   坐标系,在翻页区域内触发翻页,否则正常进行重排序
3. 影响:满排与不满排时翻页行为一致,排序和翻页区域大小不变

Log: 修复应用文件夹满排时翻页拖拽失效问题

Influence:
1. 测试满排时拖拽应用到边缘翻页区域
2. 测试不满排时拖拽应用到边缘翻页区域
3. 验证拖拽排序和拖拽出文件夹关闭弹窗无回归

PMS: BUG-375231
@deepin-ci-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: mhduiy

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 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 @mhduiy, you've used your own review budget of 250,000 diff characters for the last 7 days.

You can request another review in 5 hours and 27 minutes by commenting @sourcery-ai review. Upgrade to get a review now.

@sourcery-ai

sourcery-ai Bot commented Sep 14, 2026

Copy link
Copy Markdown

Reviewer's Guide

Fix page-turn dragging over fully populated rows by handling edge-zone detection inside each delegate drop area, mapping coordinates to the folder-level area, and keeping sorting behavior unchanged away from the edges.

Sequence diagram for edge-zone page-turn drag handling

sequenceDiagram
    actor User
    participant DelegateDropArea
    participant folderPageDropArea
    participant folderDragApplyTimer
    participant folderPagesView

    User->>DelegateDropArea: onEntered or onPositionChanged
    DelegateDropArea->>DelegateDropArea: mapToItem(folderPageDropArea, drag.x, 0)
    alt mappedX is in edge zone
        DelegateDropArea->>folderDragApplyTimer: stop()
        DelegateDropArea->>folderPageDropArea: checkDragMove(mappedX)
        folderPageDropArea->>folderPagesView: change page intent or turn page
    else mappedX is outside edge zone
        DelegateDropArea->>folderPageDropArea: pageIntent = 0
        DelegateDropArea->>folderDragApplyTimer: restart()
    end
    User->>DelegateDropArea: onExited
    DelegateDropArea->>folderPageDropArea: pageIntent = 0
Loading

Flow diagram for drag event routing in full folder rows

flowchart LR
    Drag[Drag over app icon] --> Delegate[DelegateDropArea receives event]
    Delegate --> Map[mapToItem to folderPageDropArea coordinates]
    Map --> Edge{Within left or right edge zone?}
    Edge -->|Yes| Page["stop folderDragApplyTimer and call checkDragMove(mappedX)"]
    Edge -->|No| Sort[reset pageIntent and continue sorting timer]
    Empty[Drag over empty row space] --> Folder[folderPageDropArea receives event]
    Folder --> Page
Loading

File-Level Changes

Change Details Files
Route page-turn detection through delegate drop areas that otherwise occlude the folder-level drop area.
  • Map delegate drag coordinates into the folder page drop area coordinate system.
  • Detect edge-zone drags during both drag entry and movement, stopping sort handling and invoking page-turn logic.
  • Reset page intent and preserve normal sorting behavior outside edge zones.
  • Reset page intent when delegates are exited.
qml/FolderGridViewPopup.qml
Make page-turn detection reusable with explicitly mapped drag coordinates.
  • Allow checkDragMove() to accept an optional X coordinate while retaining drag.x as the default.
  • Track the latest drag X coordinate for subsequent page transitions.
qml/FolderGridViewPopup.qml

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

@deepin-ci-robot

Copy link
Copy Markdown

deepin pr auto review

🤖 AI 代码审查报告

总体评分: 93 分 (通过阈值: 70分)

Pass


📊 总体评价

项目 结果
审查结论 代码审查通过
评分详情 总体评分 93 分,大于 70 分通过阈值,代码质量符合要求。本次修改为修复应用文件夹弹窗中满排时翻页拖拽失效的问题,通过在 DelegateDropArea 中增加翻页区域检测和坐标映射,正确解决了 QML 事件层级遮挡导致的翻页检测失效问题。存在少量代码重复和注释缺失,建议优化但不影响整体质量。

🔍 详细分析

1. 语法逻辑 ✅

评价: 优秀 ✅ 通过

潜在问题:
✅ 未发现明显问题

建议: 语法正确,逻辑清晰。可考虑使用 QML 默认参数语法简化 checkDragMove 函数的可选参数处理


2. 代码质量 ✅

评价: 良好 ✅ 通过

潜在问题:

  1. qml/FolderGridViewPopup.qml:575 - onEntered 和 onPositionChanged 中存在6行完全相同的翻页检测逻辑,属于代码重复,建议提取为独立函数
  2. qml/FolderGridViewPopup.qml:575 - 新增的翻页检测逻辑缺少注释说明,mapToItem 坐标映射原因和翻页区域判定逻辑未加注释

建议: 将重复的翻页检测逻辑提取为独立函数 checkPageTurnZone(dragX),在 onEntered 和 onPositionChanged 中复用;为新增的关键逻辑添加注释,说明坐标映射的原因和翻页区域判定规则


3. 代码性能 ✅

评价: 优秀 ✅ 通过

潜在问题:

  1. qml/FolderGridViewPopup.qml:575 - mapToItem 坐标转换在 onEntered 和 onPositionChanged 中重复执行,可提取为公共函数优化

建议: 性能良好,资源使用合理。可将翻页检测逻辑提取为公共函数减少重复调用,或缓存 mapToItem 结果


4. 代码安全 🔒

评价: 优秀 ✅ 通过

🔐 发现 0 个安全漏洞

安全漏洞详情:
✅ 未发现安全漏洞

建议: 存在0个安全漏洞。本次修改为 UI 层 QML 代码,无用户输入处理、无网络操作、无文件系统访问、无硬编码凭证,无注入风险。保持现有安全编码实践


💡 改进建议代码示例

// 在 DelegateDropArea 中提取翻页检测逻辑为独立函数
function checkPageTurnZone(dragX) {
    // 将拖拽位置映射到 folderPageDropArea 坐标系
    // 解决 DelegateDropArea 事件层级遮挡导致 folderPageDropArea
 // 无法接收拖拽事件的问题
    let mappedX = mapToItem(folderPageDropArea, dragX, 0).x
    // 检测是否在翻页区域(左/右 30%)
    if (mappedX < folderPageDropArea.horizontalPadding || 
        mappedX > (folderPageDropArea.width - folderPageDropArea.horizontalPadding)) {
        folderDragApplyTimer.stop()
        folderPageDropArea.checkDragMove(mappedX)
        return true  // 在翻页区域,已处理
    }
    folderPageDropArea.pageIntent = 0
    return false  // 不在翻页区域,继续排序逻辑
}

// onEntered 中复用
onEntered: {
    if (dragId !== model.desktopId) {
        isDragHover = true
    }
    if (checkPageTurnZone(drag.x)) return
    folderDragApplyTimer.dragId = dragId
    folderDragApplyTimer.restart()
}

// onPositionChanged 中复用
onPositionChanged: {
    if (dragId === model.desktopId) {
        return
    }
    if (checkPageTurnZone(drag.x)) return
    folderDragApplyTimer.dragId = dragId
    folderDragApplyTimer.currentDropX = drag.x
    if (!folderDragApplyTimer.running) {
        folderDragApplyTimer.restart()
    }
}

本报告由 AI 代码审查工具自动生成

@deepin-bot

deepin-bot Bot commented Sep 22, 2026

Copy link
Copy Markdown

TAG Bot

New tag: 2.0.48
DISTRIBUTION: unstable
Suggest: synchronizing this PR through rebase #816

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.

2 participants