Skip to content

[Bug]: Repeat File Manager → Terminal DnD fails after first drop under native Wayland #1255

Description

@svan71

Summary

On Treeland native Wayland, a File Manager → Terminal drag works once after a fresh login, then later drag attempts fail until the next logout/login.

This is not a Terminal or File Manager payload problem: the same source/target sequence fails with a minimal Qt URI-list drag source and a generic Qt drop target.

Possibly related: #1174 (Chromium native-Wayland DnD cannot start), but this issue is specifically a repeat-drag hover/drop failure after a successfully accepted start_drag.

Environment

  • Treeland 0.8.17 (Arch Linux / DDE Wayland)
  • waylib and vendored wlroots from Treeland 0.8.17
  • Qt 6.11.1
  • deepin-file-manager 1:6.5.152-6
  • deepin-terminal 6.5.40-1

A real Deepin reference system completes three repeated File Manager → Terminal drops, so this does not appear to be a general Deepin File Manager limitation.

Reproduction

  1. Start a fresh DDE Wayland session.
  2. Open Deepin File Manager and Deepin Terminal.
  3. Drag a file from File Manager into Terminal; it inserts the path.
  4. Repeat the same drag.

Expected

Every drag reaches the target and inserts the path.

Actual

The first drop works. Later attempts do not reach target drop handling. Restarting File Manager or dde-shell does not recover it; logout/login does.

Cut/paste continues to insert the file path, confirming the URI payload and Terminal insertion code remain healthy.

Protocol / compositor evidence

A minimal Qt source (QDrag, text/uri-list) and generic Qt target reproduce the same first-success / later-failure behavior. On the failing attempt:

  • the client sends a fresh wl_data_device.start_drag serial;
  • Treeland accepts the request: instrumentation shows buttonCount = 1, grabSerial = request serial, and originMatchesFocus = true;
  • the target then receives no successful DnD enter/drop, and the source is later cancelled.

This rules out rejected serial validation, File Manager, and Terminal as the immediate fault.

Suspected area

In waylib/src/server/kernel/wseat.cpp, WSeatPrivate::doEnter() calls pointer_notify_enter() and then considers the enter failed whenever normal pointer_state.focused_surface is null.

During an active pointer DnD, wlroots intentionally clears normal pointer focus and stores the current destination in wlr_drag::focus. Thus a valid drag enter can update drag->focus while pointerFocusSurface() remains null. Waylib then returns false and repeatedly re-enters the target; I observed heavy repeated enter/leave churn during one drag.

A minimal candidate is to accept the matching drag focus as success:

handle()->pointer_notify_enter(surface->handle()->handle(), position.x(), position.y());

const auto *drag = nativeHandle()->drag;
const bool dragFocusMatches = drag && drag->focus == surface->handle()->handle();
if (!pointerFocusSurface() && !dragFocusMatches) {
    // existing popup-focus handling
    return false;
}

This preserves the existing popup case while recognizing wlroots' expected DnD focus model. I am testing this locally; posting now so maintainers can assess the correct upstream form.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions