Skip to content

fix: use dummy drag target on Wayland to prevent layout breakage#756

Merged
wjyrich merged 1 commit into
linuxdeepin:masterfrom
wjyrich:fix-bug-346739
May 7, 2026
Merged

fix: use dummy drag target on Wayland to prevent layout breakage#756
wjyrich merged 1 commit into
linuxdeepin:masterfrom
wjyrich:fix-bug-346739

Conversation

@wjyrich
Copy link
Copy Markdown
Contributor

@wjyrich wjyrich commented May 6, 2026

Add a dummy Item as drag.target instead of directly using the ItemDelegate to avoid layout issues in Wayland drag-and-drop. The original implementation caused the ItemDelegate's layout to break when used as a drag target under Wayland compositors, leading to visual glitches and incorrect positioning.

Log: Fix layout breakage during drag-and-drop on Wayland

Influence:

  1. Test drag-and-drop functionality in both AppListView and FreeSortListView
  2. Verify that item layout remains stable during and after drag operations on Wayland
  3. Ensure no regression on X11 sessions
  4. Test drag-and-drop behavior with multiple items and across different view sections
  5. Verify that right-click context menu still works correctly

fix: 在 Wayland 上使用虚拟拖拽目标以防止布局损坏

添加一个虚拟的 Item 作为 drag.target,而不是直接使用 ItemDelegate,以 避免 Wayland 拖放操作中的布局问题。原实现方式在 Wayland 合成器下直接使
用 ItemDelegate 作为拖拽目标会导致其布局损坏,出现视觉错乱和位置不正确的
问题。

Log: 修复 Wayland 下拖拽时布局损坏问题

Influence:

  1. 测试 AppListView 和 FreeSortListView 中的拖拽功能
  2. 验证 Wayland 下拖拽操作期间和之后项目布局保持稳定
  3. 确保在 X11 会话中没有回归问题
  4. 测试多个项目和不同视图区间的拖拽行为
  5. 验证右键菜单功能仍然正常工作

此问题修复,自由排序时, 交换应用位置会出现的图标重叠问题.

Summary by Sourcery

Prevent Wayland drag-and-drop from breaking item layouts by decoupling drag targets from visual delegates in app list views.

Bug Fixes:

  • Avoid layout corruption on Wayland by using a dummy drag target instead of the visual ItemDelegate in AppListView and FreeSortListView.

Enhancements:

  • Align drag-and-drop behavior in AppListView and FreeSortListView so item layout remains stable across Wayland and X11 sessions.

@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented May 6, 2026

Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

This PR updates drag-and-drop handling in AppListView and FreeSortListView by introducing a dummy QML Item as the MouseArea.drag.target instead of the ItemDelegate itself, preventing layout breakage under Wayland while preserving existing behavior elsewhere.

Sequence diagram for the new drag-and-drop dummy target on Wayland

sequenceDiagram
    actor User
    participant MouseArea
    participant dndTarget
    participant ItemDelegate
    participant WaylandCompositor

    User->>MouseArea: press(Qt.LeftButton)
    MouseArea->>MouseArea: set drag.target to dndTarget
    User->>MouseArea: move mouse with button pressed
    MouseArea->>dndTarget: update position during drag
    MouseArea->>WaylandCompositor: initiate drag using dndTarget
    WaylandCompositor-->>MouseArea: drag events bound to dndTarget
    ItemDelegate-->>ItemDelegate: layout and position remain unchanged
    User->>MouseArea: release button
    MouseArea->>WaylandCompositor: finish drag operation
    dndTarget-->>MouseArea: final position used for drop handling
    ItemDelegate-->>User: visual layout stable after drag
Loading

Flow diagram for MouseArea drag.target wiring with dummy Item

graph TD
    subgraph AppListView
        ALV_ItemDelegate[ItemDelegate]
        ALV_MouseArea[MouseArea]
        ALV_dndTarget[dndTarget Item]
        ALV_MouseArea --> ALV_dndTarget
        ALV_MouseArea --> ALV_ItemDelegate
        ALV_MouseArea -- drag.target --> ALV_dndTarget
        ALV_ItemDelegate -- visual layout --> ALV_ItemDelegate
    end

    subgraph FreeSortListView
        FSLV_ItemDelegate[ItemDelegate]
        FSLV_MouseArea[MouseArea]
        FSLV_dndTarget[dndTarget Item]
        FSLV_MouseArea --> FSLV_dndTarget
        FSLV_MouseArea --> FSLV_ItemDelegate
        FSLV_MouseArea -- drag.target --> FSLV_dndTarget
        FSLV_ItemDelegate -- visual layout --> FSLV_ItemDelegate
    end

    ALV_MouseArea -. same pattern .- FSLV_MouseArea
Loading

File-Level Changes

Change Details Files
Route drag-and-drop through a dummy QML Item instead of the visible ItemDelegate to avoid layout breakage on Wayland compositors.
  • Add a child Item inside each MouseArea to serve as the drag.target.
  • Change MouseArea.drag.target from the ItemDelegate to the new dummy Item while keeping mouse handling and buttons unchanged.
  • Ensure the solution is applied consistently in both AppListView and FreeSortListView drag-enabled delegates.
qml/windowed/AppListView.qml
qml/windowed/FreeSortListView.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

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 left some high level feedback:

  • The new dndTarget Items have no size or position bindings; consider anchoring them to the itemDelegate (e.g., anchors.fill: parent or explicit x/y/width/height bindings) to ensure the drag hotspot and geometry match the visual item consistently across platforms.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The new `dndTarget` Items have no size or position bindings; consider anchoring them to the `itemDelegate` (e.g., `anchors.fill: parent` or explicit `x/y/width/height` bindings) to ensure the drag hotspot and geometry match the visual item consistently across platforms.

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.

Copy link
Copy Markdown
Member

@BLumia BLumia left a comment

Choose a reason for hiding this comment

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

总觉得这个改法怪怪的,按理说这个问题本身不应该和显示协议相关。目前改动不大,能接受,不过有条件的话可以写最小复现例子丢给 Qt 那边。

@deepin-ci-robot
Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

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

Add a dummy Item as drag.target instead of directly using the
ItemDelegate to avoid layout issues in Wayland drag-and-drop. The
original implementation caused the ItemDelegate's layout to break when
used as a drag target under Wayland compositors, leading to visual
glitches and incorrect positioning.

Log: Fix layout breakage during drag-and-drop on Wayland

Influence:
1. Test drag-and-drop functionality in both AppListView and
FreeSortListView
2. Verify that item layout remains stable during and after drag
operations on Wayland
3. Ensure no regression on X11 sessions
4. Test drag-and-drop behavior with multiple items and across different
view sections
5. Verify that right-click context menu still works correctly

fix: 在 Wayland 上使用虚拟拖拽目标以防止布局损坏

添加一个虚拟的 Item 作为 drag.target,而不是直接使用 ItemDelegate,以
避免 Wayland 拖放操作中的布局问题。原实现方式在 Wayland 合成器下直接使
用 ItemDelegate 作为拖拽目标会导致其布局损坏,出现视觉错乱和位置不正确的
问题。

Log: 修复 Wayland 下拖拽时布局损坏问题

Influence:
1. 测试 AppListView 和 FreeSortListView 中的拖拽功能
2. 验证 Wayland 下拖拽操作期间和之后项目布局保持稳定
3. 确保在 X11 会话中没有回归问题
4. 测试多个项目和不同视图区间的拖拽行为
5. 验证右键菜单功能仍然正常工作

此问题修复,自由排序时, 交换应用位置会出现的图标重叠问题.
@deepin-ci-robot
Copy link
Copy Markdown

deepin pr auto review

这段代码的修改主要涉及QML中拖拽功能的实现,特别是在Wayland显示服务器协议下的兼容性处理。以下是对这段diff的详细审查意见:

1. 语法逻辑

  • 正确性:语法上是完全正确的。引入了一个临时的 Item (dndTarget) 并将其作为 drag.target,这是QML中处理拖拽的标准写法。
  • 逻辑分析
    • 原代码直接将 itemDelegate 设置为拖拽目标。在Wayland协议下,系统级拖拽可能会接管窗口内的拖拽行为,或者直接操作代理项的坐标会导致布局重排或视觉闪烁。
    • 新代码创建了一个不可见的空 Item 作为拖拽目标。这样做的好处是解耦了"拖拽手势"与"视觉表现"。虽然 dndTarget 本身没有内容,但它成为了拖拽事件的载体,从而保护了 itemDelegate 的原始布局不被拖拽操作破坏。

2. 代码质量

  • 可读性:添加的注释 // Use a dummy Item... 非常清晰,解释了为什么要引入这个看似无用的 Item。这对于维护代码的人来说非常重要。
  • 可维护性:通过引入中间层 dndTarget,隔离了特定平台(Wayland)的副作用,使得代码的意图更加明确,且易于后续调试。

3. 代码性能

  • 对象创建:引入了一个额外的 QML 对象 dndTarget。由于这是一个轻量级的 Item(没有子元素,没有复杂的绘制),其内存开销和初始化开销极小,几乎可以忽略不计。
  • 布局计算:由于 dndTarget 没有设置 anchors 或尺寸,且不参与父布局的约束,它不会触发父容器的重排或重绘,性能影响极小。

4. 代码安全

  • 空指针/状态安全dndTarget 是一个静态定义的 ID,不存在运行时创建失败或为空的风险,比动态创建对象更安全。
  • 副作用隔离:这是一个很好的安全实践。将拖拽的目标对象与实际显示的 UI 元素分离,防止了底层窗口系统(Wayland)直接修改 UI 元素的属性(如 x, y, z, opacity 等),从而避免了 UI 状态混乱或崩溃的风险。

5. 潜在改进建议

虽然这段修改解决了 Wayland 下的布局破坏问题,但引入了一个"哑"(dummy)目标后,通常需要配合其他逻辑来实现视觉上的拖拽反馈(即用户看到东西在动)。

建议检查以下逻辑是否存在或需要补充:

  1. 视觉反馈
    由于 dndTarget 是不可见的,如果代码中没有其他逻辑(例如在 onDragChanged 中手动移动 itemDelegate 或显示一个拖拽图标),用户在拖拽时可能看不到任何东西在移动。

    • 检查点:确认代码中是否有逻辑在拖拽发生时,同步更新 itemDelegate 的位置或显示一个拖拽中的快照。
  2. 坐标映射
    如果使用了 dndTarget,鼠标/触摸点的坐标需要正确映射。通常需要处理 drag.target.x/y 与实际数据模型索引的关系。

    • 检查点:确认 drag 事件处理函数(如 onDrop, onPositionChanged)中是否正确计算了基于 dndTarget 位置的插入索引。
  3. 平台兼容性
    注释中提到了 Wayland。建议确认这个修改是否会影响 X11 或 Windows/macOS 下的行为。

    • 建议:如果 X11 下直接拖拽 itemDelegate 表现更好,可以考虑通过 Qt.platform.pluginName 进行条件判断,针对不同平台使用不同的策略(虽然通常统一使用 dummy target 也是可行的,但需要测试)。

总结
这是一个针对特定平台(Wayland)Bug 的有效且安全的修复方案。它以极小的性能代价换取了稳定性和兼容性。只要确保后续的拖拽视觉反馈逻辑(让用户看到东西在动)已经正确实现,这就是一段高质量的代码。

@wjyrich wjyrich merged commit 2f9b210 into linuxdeepin:master May 7, 2026
11 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