jnschulze / flutter-webview-windows

A WebView2-powered Flutter WebView implementation for the Windows platform.
BSD 3-Clause "New" or "Revised" License
203 stars 120 forks source link

The drag-and-drop actions within the web page are not functioning properly. #248

Open JucheDeng opened 1 year ago

JucheDeng commented 1 year ago

If the HTML5 drag-and-drop functionality is used on a web page, it will not function properly. The ondragstart event will be executed, but events such as ondragover and ondrop will not be responsive. It feels like after dragstart, the mouse is completely captured by webview2, but the mouse movement is actually happening within the Flutter UI window. Webview2 has no way of knowing this, and I haven't seen any forwarding or related handling of drag and drop in the C++ code.

Example:


<!DOCTYPE html>
<html>
<head>
  <style>
    #dragDiv {
      width: 100px;
      height: 100px;
      background-color: red;
      margin: 20px;
    }

    .dropDiv {
      width: 400px;
      height: 200px;
      background-color: blue;
      margin: 20px;
            display: inline-block;
    }
  </style>
</head>
<body>
  <div id="tip" style="height: 20px;background-color: salmon;"></div>
  <div id="tip2"  style="height: 20px;background-color: red;"></div>
  <div id="dragDiv" draggable="true" ondragstart="dragStart(event)" ondragend="dragEnd(event)">Drag me!</div>
  <div class="dropDiv" ondragover="dragOver(event)" ondrop="drop(event)" ondragEnter="dragEnter(event)" ondragleave="dragExit(event)">Drop here!</div>
  <div class="dropDiv" ondragover="dragOver(event)" ondrop="drop(event)">Drop here!</div>

  <script>    
    function dragStart(event) {      
      document.getElementById("tip").innerText = "dragStart";
      event.dataTransfer.setData("text", event.target.id);      
      console.log("dragStart")       
    }

    function dragOver(ev) {
      event.preventDefault();
      if (ev)  {
        document.getElementById("tip").innerText = "dragOver:" + ev.clientX + "," + ev.clientY
      }      
      console.log("dragOver") 
    }

    function dragEnter(event) {
      event.preventDefault();
      console.log("dragEnter") 
    }

    function dragExit(event) {
      event.preventDefault();
      console.log("dragExit") 
    }

    function dragEnd(event) {
      console.log("dragEnd")      
    }    

    function drop(event) {
      event.preventDefault();
      var data = event.dataTransfer.getData("text");
      var draggedElement = document.getElementById(data);
      event.target.appendChild(draggedElement);
      console.log("drop")  
    }

    window.addEventListener("mousemove", (ev)=> {
      document.getElementById("tip2").innerText = "MOVE:" + ev.clientX + "," + ev.clientY
    });
  </script>
</body>
</html>

If attempting to drag the dragDiv into the dropDiv, the action cannot be completed successfully, and the following content will be output. Additionally, dragend is immediately output after dragstart.

    dragStart
    dragEnd

ondragstart: The event will be triggered. ondragover: The event will not be triggered. (NG!!) ondrop: The event will not be triggered. (NG!!)

JucheDeng commented 1 year ago

I have directly uploaded the source code of the example Flutter project as an attachment. Please confirm it. Thank you! drag-example.zip