Bug 265857 - [GTK] Drag and drop is broken unless DataTransfer.setData() is called
Summary: [GTK] Drag and drop is broken unless DataTransfer.setData() is called
Status: NEW
Alias: None
Product: WebKit
Classification: Unclassified
Component: WebKitGTK (show other bugs)
Version: WebKit Local Build
Hardware: PC Linux
: P2 Normal
Assignee: Nobody
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2023-12-05 01:33 PST by toterddd
Modified: 2024-08-05 06:50 PDT (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description toterddd 2023-12-05 01:33:32 PST
Most of the HTML5 native drag-and-drop events do not fire. Most notably ondrop does not work, fully preventing typical usage of the api.
The issue occurs both on Epiphany as well as with tauri. It does not occur on macOS.

Initial debugging info:
https://github.com/DioxusLabs/dioxus/issues/1504
https://github.com/tauri-apps/tauri/issues/6695
https://discord.com/channels/616186924390023171/1181215497451208714 (public tauri discord)


To test this, the following link may be used:
https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/drop_event

Platform:
Gentoo Linux (broken for other ppl as well)
Epiphany 44.6 built against WebKitGTK 2.42.1, GStreamer 1.20.6
Comment 1 toterddd 2023-12-07 08:32:30 PST
I believe I may have found the culprit.

In the DropTargetGtk3 implementation it says:
```c++
// WebCore needs the selection data to decide, so we need to preload the
    // data of targets we support. Once all data requests are done we start
    // notifying the web process about the DND events.
    auto* list = gdk_drag_context_list_targets(m_drop.get());
    static const char* const supportedTargets[] = {
        "text/plain;charset=utf-8",
        "text/html",
        "_NETSCAPE_URL",
        "text/uri-list",
        "application/vnd.webkitgtk.smartpaste",
        "org.webkitgtk.WebKit.custom-pasteboard-data"
    };
```

I have tried modifying Mozillas provided example and added a line like
```js
event.dataTransfer.setData("text/plain", "vier");
```
and the drop worked afterwards.
Full code:
```html
<div class="dropzone">
  <div id="draggable" draggable="true">This div is draggable</div>
</div>
<div class="dropzone" id="droptarget"></div>

```

```css
body {
  /* Prevent the user from selecting text in the example */
  user-select: none;
}

#draggable {
  text-align: center;
  background: white;
}

.dropzone {
  width: 200px;
  height: 20px;
  background: blueviolet;
  margin: 10px;
  padding: 10px;
}

```

```js
let dragged = null;

const source = document.getElementById("draggable");
source.addEventListener("dragstart", (event) => {
  // store a ref. on the dragged elem
  dragged = event.target;

  event.dataTransfer.setData("text/plain", "vier");
});

const target = document.getElementById("droptarget");
target.addEventListener("dragover", (event) => {
  // prevent default to allow drop
  event.preventDefault();
});

target.addEventListener("drop", (event) => {
  // prevent default action (open as a link for some elements)
  event.preventDefault();

  console.log(event.dataTransfer.getData("text/plain"));
  // move dragged element to the selected drop target
  if (event.target.className === "dropzone") {
    dragged.parentNode.removeChild(dragged);
    event.target.appendChild(dragged);
  }
});

```

Disclaimer: I have absolutely no knowledge of WebKit and just looked at the code for the first time so I have no idea if this will cause issues.

I think a default target should be set for those events that do not explicitly set it since the html specification does not mention requiring this property to be set.
Comment 2 Michael Catanzaro 2023-12-07 10:00:48 PST
The GTK 3 code you're looking at isn't used by Epiphany 44, which is a GTK 4 app. But I can reproduce the behavior you've described.
Comment 3 Michael Catanzaro 2023-12-07 10:22:30 PST
(In reply to toterddd from comment #1)
> I think a default target should be set for those events that do not
> explicitly set it since the html specification does not mention requiring
> this property to be set.

Well you were able to fix the problem by calling event.dataTransfer.setData(), so we know nothing is wrong with the drop target.

Isn't the problem that the paragraph element with draggable attribute enabled has no default drag data? Presumably it should default to the text of the paragraph element.
Comment 4 toterddd 2023-12-07 12:07:24 PST
I don't know how this is usually handled in WebKit but the specification (https://html.spec.whatwg.org/multipage/dnd.html#the-datatransfer-interface) says to intialize an empty list for the datatransfer.
Comment 5 toterddd 2023-12-07 12:25:02 PST
The Gtk4 implementation straight up quits when no data is loaded:
webkitgtk-2.42.2/Source/WebKit/UIProcess/API/gtk/DropTargetGtk4:149-152
 if (!data) {
                didloaddata();
                return;
            }