Title: [261570] trunk/Source
Revision
261570
Author
[email protected]
Date
2020-05-12 12:27:48 -0700 (Tue, 12 May 2020)

Log Message

[GTK] Rework drag and drop handling in preparation for GTK4
https://bugs.webkit.org/show_bug.cgi?id=211723

Reviewed by Adrian Perez de Castro.

Source/WebCore:

Remove PasteboardHelper that is no longer used and add conversion functions to GtkUtilities.

* PlatformGTK.cmake:
* SourcesGTK.txt:
* platform/gtk/GtkUtilities.cpp:
(WebCore::gdkDragActionToDragOperation):
(WebCore::dragOperationToGdkDragActions):
(WebCore::dragOperationToSingleGdkDragAction):
* platform/gtk/GtkUtilities.h:
* platform/gtk/PasteboardHelper.cpp: Removed.
* platform/gtk/PasteboardHelper.h: Removed.

Source/WebKit:

Split DragAndDropHelper class into DragSource and DropTarget classes. This separates the source and destination
parts making it easier to follow. This patch also adds PageClient::didPerformDragControllerAction() to notify
back the view when an operation is done to update the result.

* SourcesGTK.txt:
* UIProcess/API/gtk/DragSource.h: Added.
* UIProcess/API/gtk/DragSourceGtk3.cpp: Added.
(WebKit::DragSource::DragSource):
(WebKit::DragSource::~DragSource):
(WebKit::DragSource::begin):
* UIProcess/API/gtk/DropTarget.h: Added.
* UIProcess/API/gtk/DropTargetGtk3.cpp: Added.
(WebKit::DropTarget::DropTarget):
(WebKit::DropTarget::~DropTarget):
(WebKit::DropTarget::accept):
(WebKit::DropTarget::enter):
(WebKit::DropTarget::update):
(WebKit::DropTarget::dataReceived):
(WebKit::DropTarget::didPerformAction):
(WebKit::DropTarget::leaveTimerFired):
(WebKit::DropTarget::leave):
(WebKit::DropTarget::drop):
* UIProcess/API/gtk/PageClientImpl.cpp:
(WebKit::PageClientImpl::startDrag):
(WebKit::PageClientImpl::didPerformDragControllerAction):
* UIProcess/API/gtk/PageClientImpl.h:
* UIProcess/API/gtk/WebKitWebViewBase.cpp:
(webkitWebViewBaseConstructed):
(webkit_web_view_base_class_init):
(webkitWebViewBaseStartDrag):
(webkitWebViewBaseDidPerformDragControllerAction):
* UIProcess/API/gtk/WebKitWebViewBasePrivate.h:
* UIProcess/PageClient.h:
(WebKit::PageClient::didPerformDragControllerAction):
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::didPerformDragControllerAction):
* UIProcess/gtk/DragAndDropHandler.cpp: Removed.
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::performDragControllerAction):
* WebProcess/WebPage/gtk/WebPageGtk.cpp:

Modified Paths

Added Paths

Removed Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (261569 => 261570)


--- trunk/Source/WebCore/ChangeLog	2020-05-12 19:13:18 UTC (rev 261569)
+++ trunk/Source/WebCore/ChangeLog	2020-05-12 19:27:48 UTC (rev 261570)
@@ -1,3 +1,22 @@
+2020-05-12  Carlos Garcia Campos  <[email protected]>
+
+        [GTK] Rework drag and drop handling in preparation for GTK4
+        https://bugs.webkit.org/show_bug.cgi?id=211723
+
+        Reviewed by Adrian Perez de Castro.
+
+        Remove PasteboardHelper that is no longer used and add conversion functions to GtkUtilities.
+
+        * PlatformGTK.cmake:
+        * SourcesGTK.txt:
+        * platform/gtk/GtkUtilities.cpp:
+        (WebCore::gdkDragActionToDragOperation):
+        (WebCore::dragOperationToGdkDragActions):
+        (WebCore::dragOperationToSingleGdkDragAction):
+        * platform/gtk/GtkUtilities.h:
+        * platform/gtk/PasteboardHelper.cpp: Removed.
+        * platform/gtk/PasteboardHelper.h: Removed.
+
 2020-05-12  Jacob Uphoff  <[email protected]>
 
         Unreviewed, reverting r261557.

Modified: trunk/Source/WebCore/PlatformGTK.cmake (261569 => 261570)


--- trunk/Source/WebCore/PlatformGTK.cmake	2020-05-12 19:13:18 UTC (rev 261569)
+++ trunk/Source/WebCore/PlatformGTK.cmake	2020-05-12 19:27:48 UTC (rev 261570)
@@ -61,7 +61,6 @@
     platform/gtk/GUniquePtrGtk.h
     platform/gtk/GtkUtilities.h
     platform/gtk/GtkVersioning.h
-    platform/gtk/PasteboardHelper.h
     platform/gtk/ScrollbarThemeGtk.h
     platform/gtk/SelectionData.h
 

Modified: trunk/Source/WebCore/SourcesGTK.txt (261569 => 261570)


--- trunk/Source/WebCore/SourcesGTK.txt	2020-05-12 19:13:18 UTC (rev 261569)
+++ trunk/Source/WebCore/SourcesGTK.txt	2020-05-12 19:27:48 UTC (rev 261570)
@@ -107,7 +107,6 @@
 platform/gtk/GtkUtilities.cpp
 platform/gtk/LocalizedStringsGtk.cpp
 platform/gtk/PasteboardGtk.cpp
-platform/gtk/PasteboardHelper.cpp
 platform/gtk/PlatformKeyboardEventGtk.cpp
 platform/gtk/PlatformScreenGtk.cpp
 platform/gtk/PlatformWheelEventGtk.cpp

Modified: trunk/Source/WebCore/platform/gtk/GtkUtilities.cpp (261569 => 261570)


--- trunk/Source/WebCore/platform/gtk/GtkUtilities.cpp	2020-05-12 19:13:18 UTC (rev 261569)
+++ trunk/Source/WebCore/platform/gtk/GtkUtilities.cpp	2020-05-12 19:27:48 UTC (rev 261570)
@@ -102,4 +102,51 @@
     return 1 << (8 + button - 1);
 }
 
+DragOperation gdkDragActionToDragOperation(GdkDragAction gdkAction)
+{
+    // We have no good way to detect DragOperationEvery other than
+    // to use it when all applicable flags are on.
+    if (gdkAction & GDK_ACTION_COPY
+        && gdkAction & GDK_ACTION_MOVE
+        && gdkAction & GDK_ACTION_LINK)
+        return DragOperationEvery;
+
+    unsigned action = ""
+    if (gdkAction & GDK_ACTION_COPY)
+        action |= DragOperationCopy;
+    if (gdkAction & GDK_ACTION_MOVE)
+        action |= DragOperationMove;
+    if (gdkAction & GDK_ACTION_LINK)
+        action |= DragOperationLink;
+
+    return static_cast<DragOperation>(action);
+}
+
+GdkDragAction dragOperationToGdkDragActions(DragOperation coreAction)
+{
+    unsigned gdkAction = 0;
+    if (coreAction == DragOperationNone)
+        return static_cast<GdkDragAction>(gdkAction);
+
+    if (coreAction & DragOperationCopy)
+        gdkAction |= GDK_ACTION_COPY;
+    if (coreAction & DragOperationMove)
+        gdkAction |= GDK_ACTION_MOVE;
+    if (coreAction & DragOperationLink)
+        gdkAction |= GDK_ACTION_LINK;
+
+    return static_cast<GdkDragAction>(gdkAction);
+}
+
+GdkDragAction dragOperationToSingleGdkDragAction(DragOperation coreAction)
+{
+    if (coreAction == DragOperationEvery || coreAction & DragOperationCopy)
+        return GDK_ACTION_COPY;
+    if (coreAction & DragOperationMove)
+        return GDK_ACTION_MOVE;
+    if (coreAction & DragOperationLink)
+        return GDK_ACTION_LINK;
+    return static_cast<GdkDragAction>(0);
+}
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/platform/gtk/GtkUtilities.h (261569 => 261570)


--- trunk/Source/WebCore/platform/gtk/GtkUtilities.h	2020-05-12 19:13:18 UTC (rev 261569)
+++ trunk/Source/WebCore/platform/gtk/GtkUtilities.h	2020-05-12 19:27:48 UTC (rev 261570)
@@ -18,6 +18,7 @@
 
 #pragma once
 
+#include "DragActions.h"
 #include <gtk/gtk.h>
 #include <wtf/MonotonicTime.h>
 #include <wtf/WallTime.h>
@@ -47,4 +48,8 @@
 
 WEBCORE_EXPORT unsigned stateModifierForGdkButton(unsigned button);
 
+WEBCORE_EXPORT DragOperation gdkDragActionToDragOperation(GdkDragAction);
+WEBCORE_EXPORT GdkDragAction dragOperationToGdkDragActions(DragOperation);
+WEBCORE_EXPORT GdkDragAction dragOperationToSingleGdkDragAction(DragOperation);
+
 } // namespace WebCore

Deleted: trunk/Source/WebCore/platform/gtk/PasteboardHelper.cpp (261569 => 261570)


--- trunk/Source/WebCore/platform/gtk/PasteboardHelper.cpp	2020-05-12 19:13:18 UTC (rev 261569)
+++ trunk/Source/WebCore/platform/gtk/PasteboardHelper.cpp	2020-05-12 19:27:48 UTC (rev 261570)
@@ -1,235 +0,0 @@
-/*
- * Copyright (C) 2010 Martin Robinson <[email protected]>
- * Copyright (C) Igalia S.L.
- * Copyright (C) 2013 Collabora Ltd.
- * All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-#include "config.h"
-#include "PasteboardHelper.h"
-
-#if !USE(GTK4)
-
-#include "BitmapImage.h"
-#include "SelectionData.h"
-#include <gtk/gtk.h>
-#include <wtf/glib/GUniquePtr.h>
-#include <wtf/text/CString.h>
-
-namespace WebCore {
-
-static GdkAtom textPlainAtom;
-static GdkAtom markupAtom;
-static GdkAtom netscapeURLAtom;
-static GdkAtom uriListAtom;
-static GdkAtom smartPasteAtom;
-static GdkAtom unknownAtom;
-
-static const String& markupPrefix()
-{
-    static NeverDestroyed<const String> prefix(MAKE_STATIC_STRING_IMPL("<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">"));
-    return prefix.get();
-}
-
-static void removeMarkupPrefix(String& markup)
-{
-    // The markup prefix is not harmful, but we remove it from the string anyway, so that
-    // we can have consistent results with other ports during the layout tests.
-    if (markup.startsWith(markupPrefix()))
-        markup.remove(0, markupPrefix().length());
-}
-
-PasteboardHelper& PasteboardHelper::singleton()
-{
-    static PasteboardHelper helper;
-    return helper;
-}
-
-PasteboardHelper::PasteboardHelper()
-    : m_targetList(adoptGRef(gtk_target_list_new(nullptr, 0)))
-{
-    textPlainAtom = gdk_atom_intern_static_string("text/plain;charset=utf-8");
-    markupAtom = gdk_atom_intern_static_string("text/html");
-    netscapeURLAtom = gdk_atom_intern_static_string("_NETSCAPE_URL");
-    uriListAtom = gdk_atom_intern_static_string("text/uri-list");
-    smartPasteAtom = gdk_atom_intern_static_string("application/vnd.webkitgtk.smartpaste");
-    unknownAtom = gdk_atom_intern_static_string("application/vnd.webkitgtk.unknown");
-
-    gtk_target_list_add_text_targets(m_targetList.get(), PasteboardHelper::TargetTypeText);
-    gtk_target_list_add(m_targetList.get(), markupAtom, 0, PasteboardHelper::TargetTypeMarkup);
-    gtk_target_list_add_uri_targets(m_targetList.get(), PasteboardHelper::TargetTypeURIList);
-    gtk_target_list_add(m_targetList.get(), netscapeURLAtom, 0, PasteboardHelper::TargetTypeNetscapeURL);
-    gtk_target_list_add_image_targets(m_targetList.get(), PasteboardHelper::TargetTypeImage, TRUE);
-    gtk_target_list_add(m_targetList.get(), unknownAtom, 0, PasteboardHelper::TargetTypeUnknown);
-}
-
-PasteboardHelper::~PasteboardHelper() = default;
-
-GtkTargetList* PasteboardHelper::targetList() const
-{
-    return m_targetList.get();
-}
-
-static String selectionDataToUTF8String(GtkSelectionData* data)
-{
-    if (!gtk_selection_data_get_length(data))
-        return String();
-
-    // g_strndup guards against selection data that is not null-terminated.
-    GUniquePtr<gchar> markupString(g_strndup(reinterpret_cast<const char*>(gtk_selection_data_get_data(data)), gtk_selection_data_get_length(data)));
-    return String::fromUTF8(markupString.get());
-}
-
-GRefPtr<GtkTargetList> PasteboardHelper::targetListForSelectionData(const SelectionData& selection)
-{
-    GRefPtr<GtkTargetList> list = adoptGRef(gtk_target_list_new(nullptr, 0));
-
-    if (selection.hasText())
-        gtk_target_list_add_text_targets(list.get(), TargetTypeText);
-
-    if (selection.hasMarkup())
-        gtk_target_list_add(list.get(), markupAtom, 0, TargetTypeMarkup);
-
-    if (selection.hasURIList()) {
-        gtk_target_list_add_uri_targets(list.get(), TargetTypeURIList);
-        gtk_target_list_add(list.get(), netscapeURLAtom, 0, TargetTypeNetscapeURL);
-    }
-
-    if (selection.hasImage())
-        gtk_target_list_add_image_targets(list.get(), TargetTypeImage, TRUE);
-
-    if (selection.hasUnknownTypeData())
-        gtk_target_list_add(list.get(), unknownAtom, 0, TargetTypeUnknown);
-
-    if (selection.canSmartReplace())
-        gtk_target_list_add(list.get(), smartPasteAtom, 0, TargetTypeSmartPaste);
-
-    return list;
-}
-
-void PasteboardHelper::fillSelectionData(const SelectionData& selection, unsigned info, GtkSelectionData* selectionData)
-{
-    if (info == TargetTypeText)
-        gtk_selection_data_set_text(selectionData, selection.text().utf8().data(), -1);
-
-    else if (info == TargetTypeMarkup) {
-        // Some Linux applications refuse to accept pasted markup unless it is
-        // prefixed by a content-type meta tag.
-        CString markup = makeString(markupPrefix(), selection.markup()).utf8();
-        gtk_selection_data_set(selectionData, markupAtom, 8, reinterpret_cast<const guchar*>(markup.data()), markup.length());
-
-    } else if (info == TargetTypeURIList) {
-        CString uriList = selection.uriList().utf8();
-        gtk_selection_data_set(selectionData, uriListAtom, 8, reinterpret_cast<const guchar*>(uriList.data()), uriList.length());
-
-    } else if (info == TargetTypeNetscapeURL && selection.hasURL()) {
-        String url(selection.url());
-        String result(url);
-        result.append("\n");
-
-        if (selection.hasText())
-            result.append(selection.text());
-        else
-            result.append(url);
-
-        GUniquePtr<gchar> resultData(g_strdup(result.utf8().data()));
-        gtk_selection_data_set(selectionData, netscapeURLAtom, 8, reinterpret_cast<const guchar*>(resultData.get()), strlen(resultData.get()));
-
-    } else if (info == TargetTypeImage && selection.hasImage()) {
-        GRefPtr<GdkPixbuf> pixbuf = adoptGRef(selection.image()->getGdkPixbuf());
-        gtk_selection_data_set_pixbuf(selectionData, pixbuf.get());
-
-    } else if (info == TargetTypeSmartPaste)
-        gtk_selection_data_set_text(selectionData, "", -1);
-
-    else if (info == TargetTypeUnknown) {
-        GVariantBuilder builder;
-        g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
-
-        for (auto& it : selection.unknownTypes()) {
-            GUniquePtr<gchar> dictItem(g_strdup_printf("{'%s', '%s'}", it.key.utf8().data(), it.value.utf8().data()));
-            g_variant_builder_add_parsed(&builder, dictItem.get());
-        }
-
-        GRefPtr<GVariant> variant = g_variant_builder_end(&builder);
-        GUniquePtr<gchar> serializedVariant(g_variant_print(variant.get(), TRUE));
-        gtk_selection_data_set(selectionData, unknownAtom, 1, reinterpret_cast<const guchar*>(serializedVariant.get()), strlen(serializedVariant.get()));
-    }
-}
-
-void PasteboardHelper::fillSelectionData(GtkSelectionData* data, unsigned /* info */, SelectionData& selection)
-{
-    if (gtk_selection_data_get_length(data) < 0)
-        return;
-
-    GdkAtom target = gtk_selection_data_get_target(data);
-    if (target == textPlainAtom)
-        selection.setText(selectionDataToUTF8String(data));
-    else if (target == markupAtom) {
-        String markup(selectionDataToUTF8String(data));
-        removeMarkupPrefix(markup);
-        selection.setMarkup(markup);
-    } else if (target == uriListAtom) {
-        selection.setURIList(selectionDataToUTF8String(data));
-    } else if (target == netscapeURLAtom) {
-        String urlWithLabel(selectionDataToUTF8String(data));
-        Vector<String> pieces = urlWithLabel.split('\n');
-
-        // Give preference to text/uri-list here, as it can hold more
-        // than one URI but still take  the label if there is one.
-        if (!selection.hasURIList() && !pieces.isEmpty())
-            selection.setURIList(pieces[0]);
-        if (pieces.size() > 1)
-            selection.setText(pieces[1]);
-    } else if (target == unknownAtom && gtk_selection_data_get_length(data)) {
-        GRefPtr<GVariant> variant = g_variant_new_parsed(reinterpret_cast<const char*>(gtk_selection_data_get_data(data)));
-
-        GUniqueOutPtr<gchar> key;
-        GUniqueOutPtr<gchar> value;
-        GVariantIter iter;
-
-        g_variant_iter_init(&iter, variant.get());
-        while (g_variant_iter_next(&iter, "{ss}", &key.outPtr(), &value.outPtr()))
-            selection.setUnknownTypeData(key.get(), value.get());
-    }
-}
-
-Vector<GdkAtom> PasteboardHelper::dropAtomsForContext(GtkWidget* widget, GdkDragContext* context)
-{
-    // Always search for these common atoms.
-    Vector<GdkAtom> dropAtoms;
-    dropAtoms.append(textPlainAtom);
-    dropAtoms.append(markupAtom);
-    dropAtoms.append(uriListAtom);
-    dropAtoms.append(netscapeURLAtom);
-    dropAtoms.append(unknownAtom);
-
-    // For images, try to find the most applicable image type.
-    GRefPtr<GtkTargetList> list = adoptGRef(gtk_target_list_new(0, 0));
-    gtk_target_list_add_image_targets(list.get(), TargetTypeImage, TRUE);
-    GdkAtom atom = gtk_drag_dest_find_target(widget, context, list.get());
-    if (atom != GDK_NONE)
-        dropAtoms.append(atom);
-
-    return dropAtoms;
-}
-
-} // namespace WebCore
-
-#endif // !USE(GTK4)
-

Deleted: trunk/Source/WebCore/platform/gtk/PasteboardHelper.h (261569 => 261570)


--- trunk/Source/WebCore/platform/gtk/PasteboardHelper.h	2020-05-12 19:13:18 UTC (rev 261569)
+++ trunk/Source/WebCore/platform/gtk/PasteboardHelper.h	2020-05-12 19:27:48 UTC (rev 261570)
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2007 Luca Bruno <[email protected]>
- * Copyright (C) 2009 Holger Hans Peter Freyther
- * Copyright (C) 2010 Martin Robinson <[email protected]>
- * Copyright (C) 2010 Igalia S.L.
- * All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#pragma once
-
-#if !USE(GTK4)
-
-#include "GRefPtrGtk.h"
-#include <wtf/Function.h>
-#include <wtf/Noncopyable.h>
-#include <wtf/Vector.h>
-
-namespace WebCore {
-
-class SelectionData;
-
-class PasteboardHelper {
-    WTF_MAKE_NONCOPYABLE(PasteboardHelper);
-public:
-    static PasteboardHelper& singleton();
-
-    GtkTargetList* targetList() const;
-    GRefPtr<GtkTargetList> targetListForSelectionData(const SelectionData&);
-    void fillSelectionData(const SelectionData&, unsigned, GtkSelectionData*);
-    void fillSelectionData(GtkSelectionData*, unsigned, SelectionData&);
-    Vector<GdkAtom> dropAtomsForContext(GtkWidget*, GdkDragContext*);
-
-    enum PasteboardTargetType { TargetTypeMarkup, TargetTypeText, TargetTypeImage, TargetTypeURIList, TargetTypeNetscapeURL, TargetTypeSmartPaste, TargetTypeUnknown };
-
-private:
-    PasteboardHelper();
-    ~PasteboardHelper();
-
-    GRefPtr<GtkTargetList> m_targetList;
-};
-
-} // namespace WebCore
-
-#endif // !USE(GTK4)

Modified: trunk/Source/WebKit/ChangeLog (261569 => 261570)


--- trunk/Source/WebKit/ChangeLog	2020-05-12 19:13:18 UTC (rev 261569)
+++ trunk/Source/WebKit/ChangeLog	2020-05-12 19:27:48 UTC (rev 261570)
@@ -1,3 +1,51 @@
+2020-05-12  Carlos Garcia Campos  <[email protected]>
+
+        [GTK] Rework drag and drop handling in preparation for GTK4
+        https://bugs.webkit.org/show_bug.cgi?id=211723
+
+        Reviewed by Adrian Perez de Castro.
+
+        Split DragAndDropHelper class into DragSource and DropTarget classes. This separates the source and destination
+        parts making it easier to follow. This patch also adds PageClient::didPerformDragControllerAction() to notify
+        back the view when an operation is done to update the result.
+
+        * SourcesGTK.txt:
+        * UIProcess/API/gtk/DragSource.h: Added.
+        * UIProcess/API/gtk/DragSourceGtk3.cpp: Added.
+        (WebKit::DragSource::DragSource):
+        (WebKit::DragSource::~DragSource):
+        (WebKit::DragSource::begin):
+        * UIProcess/API/gtk/DropTarget.h: Added.
+        * UIProcess/API/gtk/DropTargetGtk3.cpp: Added.
+        (WebKit::DropTarget::DropTarget):
+        (WebKit::DropTarget::~DropTarget):
+        (WebKit::DropTarget::accept):
+        (WebKit::DropTarget::enter):
+        (WebKit::DropTarget::update):
+        (WebKit::DropTarget::dataReceived):
+        (WebKit::DropTarget::didPerformAction):
+        (WebKit::DropTarget::leaveTimerFired):
+        (WebKit::DropTarget::leave):
+        (WebKit::DropTarget::drop):
+        * UIProcess/API/gtk/PageClientImpl.cpp:
+        (WebKit::PageClientImpl::startDrag):
+        (WebKit::PageClientImpl::didPerformDragControllerAction):
+        * UIProcess/API/gtk/PageClientImpl.h:
+        * UIProcess/API/gtk/WebKitWebViewBase.cpp:
+        (webkitWebViewBaseConstructed):
+        (webkit_web_view_base_class_init):
+        (webkitWebViewBaseStartDrag):
+        (webkitWebViewBaseDidPerformDragControllerAction):
+        * UIProcess/API/gtk/WebKitWebViewBasePrivate.h:
+        * UIProcess/PageClient.h:
+        (WebKit::PageClient::didPerformDragControllerAction):
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::didPerformDragControllerAction):
+        * UIProcess/gtk/DragAndDropHandler.cpp: Removed.
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::performDragControllerAction):
+        * WebProcess/WebPage/gtk/WebPageGtk.cpp:
+
 2020-05-12  Jacob Uphoff  <[email protected]>
 
         Unreviewed, reverting r261557.

Modified: trunk/Source/WebKit/SourcesGTK.txt (261569 => 261570)


--- trunk/Source/WebKit/SourcesGTK.txt	2020-05-12 19:13:18 UTC (rev 261569)
+++ trunk/Source/WebKit/SourcesGTK.txt	2020-05-12 19:27:48 UTC (rev 261570)
@@ -194,6 +194,10 @@
 UIProcess/API/glib/WebKitWebsiteDataManager.cpp @no-unify
 UIProcess/API/glib/WebKitWindowProperties.cpp @no-unify
 
+UIProcess/API/gtk/DragSourceGtk3.cpp @no-unify
+UIProcess/API/gtk/DragSourceGtk4.cpp @no-unify
+UIProcess/API/gtk/DropTargetGtk3.cpp @no-unify
+UIProcess/API/gtk/DropTargetGtk4.cpp @no-unify
 UIProcess/API/gtk/InputMethodFilterGtk.cpp @no-unify
 UIProcess/API/gtk/PageClientImpl.cpp @no-unify
 UIProcess/API/gtk/WebKitAuthenticationDialog.cpp @no-unify
@@ -256,7 +260,6 @@
 UIProcess/gtk/Clipboard.cpp
 UIProcess/gtk/ClipboardGtk3.cpp @no-unify
 UIProcess/gtk/ClipboardGtk4.cpp @no-unify
-UIProcess/gtk/DragAndDropHandler.cpp
 UIProcess/gtk/GestureController.cpp
 UIProcess/gtk/HardwareAccelerationManager.cpp
 UIProcess/gtk/KeyBindingTranslator.cpp

Added: trunk/Source/WebKit/UIProcess/API/gtk/DragSource.h (0 => 261570)


--- trunk/Source/WebKit/UIProcess/API/gtk/DragSource.h	                        (rev 0)
+++ trunk/Source/WebKit/UIProcess/API/gtk/DragSource.h	2020-05-12 19:27:48 UTC (rev 261570)
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2020 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(DRAG_SUPPORT)
+
+#include <WebCore/DragActions.h>
+#include <wtf/Forward.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/glib/GRefPtr.h>
+
+typedef struct _GtkWidget GtkWidget;
+
+#if !USE(GTK4)
+typedef struct _GdkDragContext GdkDragContext;
+#endif
+
+namespace WebCore {
+class SelectionData;
+}
+
+namespace WebKit {
+
+class ShareableBitmap;
+
+class DragSource {
+    WTF_MAKE_NONCOPYABLE(DragSource); WTF_MAKE_FAST_ALLOCATED;
+public:
+
+    explicit DragSource(GtkWidget*);
+    ~DragSource();
+
+    void begin(Ref<WebCore::SelectionData>&&, WebCore::DragOperation, RefPtr<ShareableBitmap>&&);
+
+private:
+    GtkWidget* m_webView { nullptr };
+#if !USE(GTK4)
+    GRefPtr<GdkDragContext> m_drag;
+#endif
+    RefPtr<WebCore::SelectionData> m_selectionData;
+};
+
+} // namespace WebKit
+
+#endif // ENABLE(DRAG_SUPPORT)

Added: trunk/Source/WebKit/UIProcess/API/gtk/DragSourceGtk3.cpp (0 => 261570)


--- trunk/Source/WebKit/UIProcess/API/gtk/DragSourceGtk3.cpp	                        (rev 0)
+++ trunk/Source/WebKit/UIProcess/API/gtk/DragSourceGtk3.cpp	2020-05-12 19:27:48 UTC (rev 261570)
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2020 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "DragSource.h"
+
+#if ENABLE(DRAG_SUPPORT) && !USE(GTK4)
+
+#include "WebKitWebViewBasePrivate.h"
+#include <WebCore/GRefPtrGtk.h>
+#include <WebCore/GtkUtilities.h>
+#include <gtk/gtk.h>
+
+namespace WebKit {
+using namespace WebCore;
+
+enum DragTargetType { Markup, Text, Image, URIList, NetscapeURL, SmartPaste };
+
+DragSource::DragSource(GtkWidget* webView)
+    : m_webView(webView)
+{
+    g_signal_connect(m_webView, "drag-data-get", G_CALLBACK(+[](GtkWidget*, GdkDragContext* context, GtkSelectionData* data, guint info, guint, gpointer userData) {
+        auto& drag = *static_cast<DragSource*>(userData);
+        if (drag.m_drag.get() != context)
+            return;
+
+        switch (info) {
+        case DragTargetType::Text:
+            gtk_selection_data_set_text(data, drag.m_selectionData->text().utf8().data(), -1);
+            break;
+        case DragTargetType::Markup: {
+            CString markup = drag.m_selectionData->markup().utf8();
+            gtk_selection_data_set(data, gdk_atom_intern_static_string("text/html"), 8, reinterpret_cast<const guchar*>(markup.data()), markup.length());
+            break;
+        }
+        case DragTargetType::URIList: {
+            CString uriList = drag.m_selectionData->uriList().utf8();
+            gtk_selection_data_set(data, gdk_atom_intern_static_string("text/uri-list"), 8, reinterpret_cast<const guchar*>(uriList.data()), uriList.length());
+            break;
+        }
+        case DragTargetType::NetscapeURL: {
+            CString urlString = drag.m_selectionData->url().string().utf8();
+            GUniquePtr<gchar> url(g_strdup_printf("%s\n%s", urlString.data(), drag.m_selectionData->hasText() ? drag.m_selectionData->text().utf8().data() : urlString.data()));
+            gtk_selection_data_set(data, gdk_atom_intern_static_string("_NETSCAPE_URL"), 8, reinterpret_cast<const guchar*>(url.get()), strlen(url.get()));
+            break;
+        }
+        case DragTargetType::Image: {
+            GRefPtr<GdkPixbuf> pixbuf = adoptGRef(drag.m_selectionData->image()->getGdkPixbuf());
+            gtk_selection_data_set_pixbuf(data, pixbuf.get());
+            break;
+        }
+        case DragTargetType::SmartPaste:
+            gtk_selection_data_set_text(data, "", -1);
+            break;
+        }
+    }), this);
+
+    g_signal_connect(m_webView, "drag-end", G_CALLBACK(+[](GtkWidget*, GdkDragContext* context, gpointer userData) {
+        auto& drag = *static_cast<DragSource*>(userData);
+        if (drag.m_drag.get() != context)
+            return;
+        if (!drag.m_selectionData)
+            return;
+
+        drag.m_selectionData = nullptr;
+        drag.m_drag = nullptr;
+
+        GdkDevice* device = gdk_drag_context_get_device(context);
+        int x = 0;
+        int y = 0;
+        gdk_device_get_window_at_position(device, &x, &y);
+        int xRoot = 0;
+        int yRoot = 0;
+        gdk_device_get_position(device, nullptr, &xRoot, &yRoot);
+
+        auto* page = webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(drag.m_webView));
+        ASSERT(page);
+        page->dragEnded({ x, y }, { xRoot, yRoot }, gdkDragActionToDragOperation(gdk_drag_context_get_selected_action(context)));
+    }), this);
+}
+
+DragSource::~DragSource()
+{
+    g_signal_handlers_disconnect_by_data(m_webView, this);
+}
+
+void DragSource::begin(Ref<SelectionData>&& selectionData, DragOperation operation, RefPtr<ShareableBitmap>&& image)
+{
+    if (m_drag) {
+        gtk_drag_cancel(m_drag.get());
+        m_drag = nullptr;
+    }
+
+    m_selectionData = WTFMove(selectionData);
+
+    GRefPtr<GtkTargetList> list = adoptGRef(gtk_target_list_new(nullptr, 0));
+    if (m_selectionData->hasText())
+        gtk_target_list_add_text_targets(list.get(), DragTargetType::Text);
+    if (m_selectionData->hasMarkup())
+        gtk_target_list_add(list.get(), gdk_atom_intern_static_string("text/html"), 0, DragTargetType::Markup);
+    if (m_selectionData->hasURIList())
+        gtk_target_list_add_uri_targets(list.get(), DragTargetType::URIList);
+    if (m_selectionData->hasURL())
+        gtk_target_list_add(list.get(), gdk_atom_intern_static_string("_NETSCAPE_URL"), 0, DragTargetType::NetscapeURL);
+    if (m_selectionData->hasImage())
+        gtk_target_list_add_image_targets(list.get(), DragTargetType::Image, TRUE);
+    if (m_selectionData->canSmartReplace())
+        gtk_target_list_add(list.get(), gdk_atom_intern_static_string("application/vnd.webkitgtk.smartpaste"), 0, DragTargetType::SmartPaste);
+
+    m_drag = gtk_drag_begin_with_coordinates(m_webView, list.get(), dragOperationToGdkDragActions(operation), GDK_BUTTON_PRIMARY, nullptr, -1, -1);
+    if (image) {
+        RefPtr<cairo_surface_t> imageSurface(image->createCairoSurface());
+        // Use the center of the drag image as hotspot.
+        cairo_surface_set_device_offset(imageSurface.get(), -cairo_image_surface_get_width(imageSurface.get()) / 2, -cairo_image_surface_get_height(imageSurface.get()) / 2);
+        gtk_drag_set_icon_surface(m_drag.get(), imageSurface.get());
+    } else
+        gtk_drag_set_icon_default(m_drag.get());
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(DRAG_SUPPORT) && !USE(GTK4)

Added: trunk/Source/WebKit/UIProcess/API/gtk/DragSourceGtk4.cpp (0 => 261570)


--- trunk/Source/WebKit/UIProcess/API/gtk/DragSourceGtk4.cpp	                        (rev 0)
+++ trunk/Source/WebKit/UIProcess/API/gtk/DragSourceGtk4.cpp	2020-05-12 19:27:48 UTC (rev 261570)
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2020 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "DragSource.h"
+
+#if ENABLE(DRAG_SUPPORT) && USE(GTK4)
+
+#include "WebKitWebViewBasePrivate.h"
+#include <WebCore/GtkUtilities.h>
+#include <gtk/gtk.h>
+
+namespace WebKit {
+using namespace WebCore;
+
+DragSource::DragSource(GtkWidget* webView)
+    : m_webView(webView)
+{
+}
+
+DragSource::~DragSource()
+{
+}
+
+void DragSource::begin(Ref<SelectionData>&&, DragOperation, RefPtr<ShareableBitmap>&&)
+{
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(DRAG_SUPPORT) && USE(GTK4)

Added: trunk/Source/WebKit/UIProcess/API/gtk/DropTarget.h (0 => 261570)


--- trunk/Source/WebKit/UIProcess/API/gtk/DropTarget.h	                        (rev 0)
+++ trunk/Source/WebKit/UIProcess/API/gtk/DropTarget.h	2020-05-12 19:27:48 UTC (rev 261570)
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2020 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(DRAG_SUPPORT)
+
+#include <WebCore/DragActions.h>
+#include <WebCore/IntPoint.h>
+#include <wtf/Forward.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/RunLoop.h>
+#include <wtf/glib/GRefPtr.h>
+
+typedef struct _GtkWidget GtkWidget;
+
+#if !USE(GTK4)
+typedef struct _GdkDragContext GdkDragContext;
+typedef struct _GtkSelectionData GtkSelectionData;
+#endif
+
+namespace WebCore {
+class SelectionData;
+}
+
+namespace WebKit {
+
+class ShareableBitmap;
+
+class DropTarget {
+    WTF_MAKE_NONCOPYABLE(DropTarget); WTF_MAKE_FAST_ALLOCATED;
+public:
+    explicit DropTarget(GtkWidget*);
+    ~DropTarget();
+
+    void didPerformAction();
+
+private:
+    void accept(unsigned = 0);
+    void enter(WebCore::IntPoint&&, unsigned = 0);
+    void update(WebCore::IntPoint&&, unsigned = 0);
+    void leave();
+    void drop(WebCore::IntPoint&&, unsigned = 0);
+
+#if !USE(GTK4)
+    void dataReceived(WebCore::IntPoint&&, GtkSelectionData*, unsigned, unsigned);
+    void leaveTimerFired();
+#endif
+
+    GtkWidget* m_webView { nullptr };
+#if !USE(GTK4)
+    GRefPtr<GdkDragContext> m_drop;
+#endif
+    Optional<WebCore::IntPoint> m_position;
+    unsigned m_dataRequestCount { 0 };
+    RefPtr<WebCore::SelectionData> m_selectionData;
+    WebCore::DragOperation m_operation { WebCore::DragOperationNone };
+#if !USE(GTK4)
+    RunLoop::Timer<DropTarget> m_leaveTimer;
+#endif
+};
+
+} // namespace WebKit
+
+#endif // ENABLE(DRAG_SUPPORT)

Added: trunk/Source/WebKit/UIProcess/API/gtk/DropTargetGtk3.cpp (0 => 261570)


--- trunk/Source/WebKit/UIProcess/API/gtk/DropTargetGtk3.cpp	                        (rev 0)
+++ trunk/Source/WebKit/UIProcess/API/gtk/DropTargetGtk3.cpp	2020-05-12 19:27:48 UTC (rev 261570)
@@ -0,0 +1,270 @@
+/*
+ * Copyright (C) 2020 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "DropTarget.h"
+
+#if ENABLE(DRAG_SUPPORT) && !USE(GTK4)
+
+#include "WebKitWebViewBasePrivate.h"
+#include <WebCore/DragData.h>
+#include <WebCore/GRefPtrGtk.h>
+#include <WebCore/GtkUtilities.h>
+#include <gtk/gtk.h>
+#include <wtf/glib/GUniquePtr.h>
+
+namespace WebKit {
+using namespace WebCore;
+
+enum DropTargetType { Markup, Text, URIList, NetscapeURL, SmartPaste };
+
+DropTarget::DropTarget(GtkWidget* webView)
+    : m_webView(webView)
+    , m_leaveTimer(RunLoop::main(), this, &DropTarget::leaveTimerFired)
+{
+    GRefPtr<GtkTargetList> list = adoptGRef(gtk_target_list_new(nullptr, 0));
+    gtk_target_list_add_text_targets(list.get(), DropTargetType::Text);
+    gtk_target_list_add(list.get(), gdk_atom_intern_static_string("text/html"), 0, DropTargetType::Markup);
+    gtk_target_list_add_uri_targets(list.get(), DropTargetType::URIList);
+    gtk_target_list_add(list.get(), gdk_atom_intern_static_string("_NETSCAPE_URL"), 0, DropTargetType::NetscapeURL);
+    gtk_target_list_add(list.get(), gdk_atom_intern_static_string("application/vnd.webkitgtk.smartpaste"), 0, DropTargetType::SmartPaste);
+    gtk_drag_dest_set(m_webView, static_cast<GtkDestDefaults>(0), nullptr, 0,
+        static_cast<GdkDragAction>(GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK));
+    gtk_drag_dest_set_target_list(m_webView, list.get());
+
+    g_signal_connect(m_webView, "drag-motion", G_CALLBACK(+[](GtkWidget*, GdkDragContext* context, gint x, gint y, guint time, gpointer userData) -> gboolean {
+        auto& drop = *static_cast<DropTarget*>(userData);
+        if (!drop.m_drop) {
+            drop.m_drop = context;
+            drop.m_position = IntPoint(x, y);
+            drop.accept(time);
+        } else if (drop.m_drop == context)
+            drop.update({ x, y }, time);
+        return TRUE;
+    }), this);
+
+    g_signal_connect(m_webView, "drag-leave", G_CALLBACK(+[](GtkWidget*, GdkDragContext* context, guint time, gpointer userData) {
+        auto& drop = *static_cast<DropTarget*>(userData);
+        if (drop.m_drop != context)
+            return;
+        drop.leave();
+    }), this);
+
+    g_signal_connect(m_webView, "drag-drop", G_CALLBACK(+[](GtkWidget*, GdkDragContext* context, gint x, gint y, guint time, gpointer userData) -> gboolean {
+        auto& drop = *static_cast<DropTarget*>(userData);
+        if (drop.m_drop != context) {
+            gtk_drag_finish(context, FALSE, FALSE, time);
+            return TRUE;
+        }
+        drop.drop({ x, y }, time);
+        return TRUE;
+    }), this);
+
+    g_signal_connect(m_webView, "drag-data-received", G_CALLBACK(+[](GtkWidget*, GdkDragContext* context, gint x, gint y, GtkSelectionData* data, guint info, guint time, gpointer userData) {
+        auto& drop = *static_cast<DropTarget*>(userData);
+        if (drop.m_drop != context)
+            return;
+        drop.dataReceived({ x, y }, data, info, time);
+    }), this);
+}
+
+DropTarget::~DropTarget()
+{
+    g_signal_handlers_disconnect_by_data(m_webView, this);
+}
+
+void DropTarget::accept(unsigned time)
+{
+    if (m_leaveTimer.isActive()) {
+        m_leaveTimer.stop();
+        leaveTimerFired();
+    }
+
+    m_dataRequestCount = 0;
+    m_selectionData = SelectionData::create();
+
+    // 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"
+    };
+    Vector<GdkAtom, 4> targets;
+    for (unsigned i = 0; i < G_N_ELEMENTS(supportedTargets); ++i) {
+        GdkAtom atom = gdk_atom_intern_static_string(supportedTargets[i]);
+        if (g_list_find(list, atom))
+            targets.append(atom);
+        else if (!i) {
+            atom = gdk_atom_intern_static_string("text/plain");
+            if (g_list_find(list, atom))
+                targets.append(atom);
+        }
+    }
+
+    m_dataRequestCount = targets.size();
+    for (auto* atom : targets)
+        gtk_drag_get_data(m_webView, m_drop.get(), atom, time);
+}
+
+void DropTarget::enter(IntPoint&& position, unsigned time)
+{
+    m_position = WTFMove(position);
+
+    auto* page = webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(m_webView));
+    ASSERT(page);
+    page->resetCurrentDragInformation();
+
+    DragData dragData(m_selectionData.get(), *m_position, convertWidgetPointToScreenPoint(m_webView, *m_position), gdkDragActionToDragOperation(gdk_drag_context_get_actions(m_drop.get())));
+    page->dragEntered(dragData);
+}
+
+void DropTarget::update(IntPoint&& position, unsigned time)
+{
+    if (m_dataRequestCount || !m_selectionData)
+        return;
+
+    m_position = WTFMove(position);
+
+    auto* page = webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(m_webView));
+    ASSERT(page);
+
+    DragData dragData(m_selectionData.get(), *m_position, convertWidgetPointToScreenPoint(m_webView, *m_position), gdkDragActionToDragOperation(gdk_drag_context_get_actions(m_drop.get())));
+    page->dragUpdated(dragData);
+}
+
+void DropTarget::dataReceived(IntPoint&& position, GtkSelectionData* data, unsigned info, unsigned time)
+{
+    switch (info) {
+    case DropTargetType::Text: {
+        GUniquePtr<char> text(reinterpret_cast<char*>(gtk_selection_data_get_text(data)));
+        m_selectionData->setText(String::fromUTF8(text.get()));
+        break;
+    }
+    case DropTargetType::Markup: {
+        gint length;
+        const auto* markupData = gtk_selection_data_get_data_with_length(data, &length);
+        if (length) {
+            // If data starts with UTF-16 BOM assume it's UTF-16, otherwise assume UTF-8.
+            if (length >= 2 && reinterpret_cast<const UChar*>(markupData)[0] == 0xFEFF)
+                m_selectionData->setMarkup(String(reinterpret_cast<const UChar*>(markupData) + 1, (length / 2) - 1));
+            else
+                m_selectionData->setMarkup(String::fromUTF8(markupData, length));
+        }
+        break;
+    }
+    case DropTargetType::URIList: {
+        gint length;
+        const auto* uriListData = gtk_selection_data_get_data_with_length(data, &length);
+        if (length)
+            m_selectionData->setURIList(String::fromUTF8(uriListData, length));
+        break;
+    }
+    case DropTargetType::NetscapeURL: {
+        gint length;
+        const auto* urlData = gtk_selection_data_get_data_with_length(data, &length);
+        if (length) {
+            Vector<String> tokens = String::fromUTF8(urlData, length).split('\n');
+            URL url({ }, tokens[0]);
+            if (url.isValid())
+                m_selectionData->setURL(url, tokens.size() > 1 ? tokens[1] : String());
+        }
+        break;
+    }
+    case DropTargetType::SmartPaste:
+        m_selectionData->setCanSmartReplace(true);
+        break;
+    }
+
+    if (--m_dataRequestCount)
+        return;
+
+    enter(WTFMove(position), time);
+}
+
+void DropTarget::didPerformAction()
+{
+    if (!m_drop)
+        return;
+
+    auto* page = webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(m_webView));
+    ASSERT(page);
+
+    auto operation = page->currentDragOperation();
+    if (operation == m_operation)
+        return;
+
+    m_operation = operation;
+    gdk_drag_status(m_drop.get(), dragOperationToSingleGdkDragAction(m_operation), GDK_CURRENT_TIME);
+}
+
+void DropTarget::leaveTimerFired()
+{
+    auto* page = webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(m_webView));
+    ASSERT(page);
+
+    DragData dragData(m_selectionData.get(), *m_position, convertWidgetPointToScreenPoint(m_webView, *m_position), DragOperationNone);
+    page->dragExited(dragData);
+    page->resetCurrentDragInformation();
+
+    m_drop = nullptr;
+    m_position = WTF::nullopt;
+    m_selectionData = nullptr;
+}
+
+void DropTarget::leave()
+{
+    // GTK emits drag-leave before drag-drop, but we need to know whether a drop
+    // happened to notify the web process about the drag exit.
+    m_leaveTimer.startOneShot(0_s);
+}
+
+void DropTarget::drop(IntPoint&& position, unsigned time)
+{
+    if (m_leaveTimer.isActive())
+        m_leaveTimer.stop();
+
+    auto* page = webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(m_webView));
+    ASSERT(page);
+
+    uint32_t flags = 0;
+    if (gdk_drag_context_get_selected_action(m_drop.get()) == GDK_ACTION_COPY)
+        flags |= DragApplicationIsCopyKeyDown;
+    DragData dragData(m_selectionData.get(), position, convertWidgetPointToScreenPoint(m_webView, position), gdkDragActionToDragOperation(gdk_drag_context_get_actions(m_drop.get())), static_cast<DragApplicationFlags>(flags));
+    page->performDragOperation(dragData, { }, { }, { });
+    gtk_drag_finish(m_drop.get(), TRUE, FALSE, time);
+
+    m_drop = nullptr;
+    m_position = WTF::nullopt;
+    m_selectionData = nullptr;
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(DRAG_SUPPORT) && !USE(GTK4)

Added: trunk/Source/WebKit/UIProcess/API/gtk/DropTargetGtk4.cpp (0 => 261570)


--- trunk/Source/WebKit/UIProcess/API/gtk/DropTargetGtk4.cpp	                        (rev 0)
+++ trunk/Source/WebKit/UIProcess/API/gtk/DropTargetGtk4.cpp	2020-05-12 19:27:48 UTC (rev 261570)
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2020 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "DropTarget.h"
+
+#if ENABLE(DRAG_SUPPORT) && USE(GTK4)
+
+#include "WebKitWebViewBasePrivate.h"
+#include <WebCore/DragData.h>
+#include <WebCore/GtkUtilities.h>
+#include <gtk/gtk.h>
+#include <wtf/glib/GUniquePtr.h>
+
+namespace WebKit {
+using namespace WebCore;
+
+DropTarget::DropTarget(GtkWidget* webView)
+    : m_webView(webView)
+{
+}
+
+DropTarget::~DropTarget()
+{
+}
+
+void DropTarget::accept(unsigned)
+{
+}
+
+void DropTarget::loadData(const char*, CompletionHandler<void(GRefPtr<GBytes>&&)>&&)
+{
+}
+
+void DropTarget::didLoadData()
+{
+}
+
+void DropTarget::enter(IntPoint&&, unsigned)
+{
+}
+
+void DropTarget::update(IntPoint&&, unsigned)
+{
+}
+
+void DropTarget::didPerformAction()
+{
+}
+
+void DropTarget::leave()
+{
+}
+
+void DropTarget::drop(IntPoint&&, unsigned)
+{
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(DRAG_SUPPORT) && USE(GTK4)

Modified: trunk/Source/WebKit/UIProcess/API/gtk/PageClientImpl.cpp (261569 => 261570)


--- trunk/Source/WebKit/UIProcess/API/gtk/PageClientImpl.cpp	2020-05-12 19:13:18 UTC (rev 261569)
+++ trunk/Source/WebKit/UIProcess/API/gtk/PageClientImpl.cpp	2020-05-12 19:27:48 UTC (rev 261570)
@@ -330,14 +330,12 @@
 #if ENABLE(DRAG_SUPPORT)
 void PageClientImpl::startDrag(Ref<SelectionData>&& selection, DragOperation dragOperation, RefPtr<ShareableBitmap>&& dragImage)
 {
-#if !USE(GTK4)
-    WebKitWebViewBase* webView = WEBKIT_WEB_VIEW_BASE(m_viewWidget);
-    webkitWebViewBaseDragAndDropHandler(webView).startDrag(WTFMove(selection), dragOperation, WTFMove(dragImage));
+    webkitWebViewBaseStartDrag(WEBKIT_WEB_VIEW_BASE(m_viewWidget), WTFMove(selection), dragOperation, WTFMove(dragImage));
+}
 
-    // A drag starting should prevent a double-click from happening. This might
-    // happen if a drag is followed very quickly by another click (like in the WTR).
-    webkitWebViewBaseResetClickCounter(webView);
-#endif
+void PageClientImpl::didPerformDragControllerAction()
+{
+    webkitWebViewBaseDidPerformDragControllerAction(WEBKIT_WEB_VIEW_BASE(m_viewWidget));
 }
 #endif
 

Modified: trunk/Source/WebKit/UIProcess/API/gtk/PageClientImpl.h (261569 => 261570)


--- trunk/Source/WebKit/UIProcess/API/gtk/PageClientImpl.h	2020-05-12 19:13:18 UTC (rev 261569)
+++ trunk/Source/WebKit/UIProcess/API/gtk/PageClientImpl.h	2020-05-12 19:27:48 UTC (rev 261570)
@@ -101,6 +101,7 @@
     RefPtr<ViewSnapshot> takeViewSnapshot(Optional<WebCore::IntRect>&&) override;
 #if ENABLE(DRAG_SUPPORT)
     void startDrag(Ref<WebCore::SelectionData>&&, WebCore::DragOperation, RefPtr<ShareableBitmap>&& dragImage) override;
+    void didPerformDragControllerAction() override;
 #endif
 
     void enterAcceleratedCompositingMode(const LayerTreeContext&) override;

Modified: trunk/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBase.cpp (261569 => 261570)


--- trunk/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBase.cpp	2020-05-12 19:13:18 UTC (rev 261569)
+++ trunk/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBase.cpp	2020-05-12 19:27:48 UTC (rev 261570)
@@ -31,7 +31,9 @@
 
 #include "APIPageConfiguration.h"
 #include "AcceleratedBackingStore.h"
+#include "DragSource.h"
 #include "DrawingAreaProxyCoordinatedGraphics.h"
+#include "DropTarget.h"
 #include "InputMethodFilter.h"
 #include "KeyBindingTranslator.h"
 #include "NativeWebKeyboardEvent.h"
@@ -58,7 +60,6 @@
 #include <WebCore/GtkUtilities.h>
 #include <WebCore/GtkVersioning.h>
 #include <WebCore/NotImplemented.h>
-#include <WebCore/PasteboardHelper.h>
 #include <WebCore/PlatformDisplay.h>
 #include <WebCore/RefPtrCairo.h>
 #include <WebCore/Region.h>
@@ -219,8 +220,9 @@
 
     std::unique_ptr<AcceleratedBackingStore> acceleratedBackingStore;
 
-#if ENABLE(DRAG_SUPPORT) && !USE(GTK4)
-    std::unique_ptr<DragAndDropHandler> dragAndDropHandler;
+#if ENABLE(DRAG_SUPPORT)
+    std::unique_ptr<DragSource> dragSource;
+    std::unique_ptr<DropTarget> dropTarget;
 #endif
 
 #if !USE(GTK4)
@@ -1554,27 +1556,6 @@
     return TRUE;
 }
 
-#if ENABLE(DRAG_SUPPORT) && !USE(GTK4)
-static void webkitWebViewBaseDragDataGet(GtkWidget* widget, GdkDragContext* context, GtkSelectionData* selectionData, guint info, guint /* time */)
-{
-    WebKitWebViewBasePrivate* priv = WEBKIT_WEB_VIEW_BASE(widget)->priv;
-    ASSERT(priv->dragAndDropHandler);
-    priv->dragAndDropHandler->fillDragData(context, selectionData, info);
-}
-
-static void webkitWebViewBaseDragEnd(GtkWidget* widget, GdkDragContext* context)
-{
-    WebKitWebViewBasePrivate* priv = WEBKIT_WEB_VIEW_BASE(widget)->priv;
-    ASSERT(priv->dragAndDropHandler);
-    priv->dragAndDropHandler->finishDrag(context);
-}
-
-static void webkitWebViewBaseDragDataReceived(GtkWidget* widget, GdkDragContext* context, gint /* x */, gint /* y */, GtkSelectionData* selectionData, guint info, guint time)
-{
-    webkitWebViewBaseDragAndDropHandler(WEBKIT_WEB_VIEW_BASE(widget)).dragEntered(context, selectionData, info, time);
-}
-#endif // ENABLE(DRAG_SUPPORT)
-
 #if !USE(GTK4)
 static gboolean webkitWebViewBaseEvent(GtkWidget* widget, GdkEvent* event)
 {
@@ -1601,28 +1582,6 @@
     return priv->accessible.get();
 }
 
-#if ENABLE(DRAG_SUPPORT) && !USE(GTK4)
-static gboolean webkitWebViewBaseDragMotion(GtkWidget* widget, GdkDragContext* context, gint x, gint y, guint time)
-{
-    webkitWebViewBaseDragAndDropHandler(WEBKIT_WEB_VIEW_BASE(widget)).dragMotion(context, IntPoint(x, y), time);
-    return TRUE;
-}
-
-static void webkitWebViewBaseDragLeave(GtkWidget* widget, GdkDragContext* context, guint /* time */)
-{
-    WebKitWebViewBasePrivate* priv = WEBKIT_WEB_VIEW_BASE(widget)->priv;
-    ASSERT(priv->dragAndDropHandler);
-    priv->dragAndDropHandler->dragLeave(context);
-}
-
-static gboolean webkitWebViewBaseDragDrop(GtkWidget* widget, GdkDragContext* context, gint x, gint y, guint time)
-{
-    WebKitWebViewBasePrivate* priv = WEBKIT_WEB_VIEW_BASE(widget)->priv;
-    ASSERT(priv->dragAndDropHandler);
-    return priv->dragAndDropHandler->drop(context, IntPoint(x, y), time);
-}
-#endif // ENABLE(DRAG_SUPPORT)
-
 #if !USE(GTK4)
 static void webkitWebViewBaseHierarchyChanged(GtkWidget* widget, GtkWidget* oldToplevel)
 {
@@ -1673,10 +1632,8 @@
     priv->pageClient = makeUnique<PageClientImpl>(viewWidget);
     gtk_container_add(GTK_CONTAINER(viewWidget), priv->keyBindingTranslator.widget());
 
-#if !USE(GTK4)
-    gtk_drag_dest_set(viewWidget, static_cast<GtkDestDefaults>(0), nullptr, 0,
-        static_cast<GdkDragAction>(GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK | GDK_ACTION_PRIVATE));
-    gtk_drag_dest_set_target_list(viewWidget, PasteboardHelper::singleton().targetList());
+#if ENABLE(DRAG_SUPPORT)
+    priv->dropTarget = makeUnique<DropTarget>(viewWidget);
 #endif
 
 #if USE(GTK4)
@@ -1747,14 +1704,6 @@
     widgetClass->touch_event = webkitWebViewBaseTouchEvent;
 #endif
     widgetClass->query_tooltip = webkitWebViewBaseQueryTooltip;
-#if ENABLE(DRAG_SUPPORT) && !USE(GTK4)
-    widgetClass->drag_end = webkitWebViewBaseDragEnd;
-    widgetClass->drag_data_get = webkitWebViewBaseDragDataGet;
-    widgetClass->drag_motion = webkitWebViewBaseDragMotion;
-    widgetClass->drag_leave = webkitWebViewBaseDragLeave;
-    widgetClass->drag_drop = webkitWebViewBaseDragDrop;
-    widgetClass->drag_data_received = webkitWebViewBaseDragDataReceived;
-#endif // ENABLE(DRAG_SUPPORT)
 #if !USE(GTK4)
     widgetClass->event = webkitWebViewBaseEvent;
 #endif
@@ -1829,14 +1778,26 @@
     webViewBase->priv->tooltipArea = tooltipArea;
 }
 
-#if ENABLE(DRAG_SUPPORT) && !USE(GTK4)
-DragAndDropHandler& webkitWebViewBaseDragAndDropHandler(WebKitWebViewBase* webViewBase)
+#if ENABLE(DRAG_SUPPORT)
+void webkitWebViewBaseStartDrag(WebKitWebViewBase* webViewBase, Ref<SelectionData>&& selectionData, DragOperation dragOperation, RefPtr<ShareableBitmap>&& image)
 {
     WebKitWebViewBasePrivate* priv = webViewBase->priv;
-    if (!priv->dragAndDropHandler)
-        priv->dragAndDropHandler = makeUnique<DragAndDropHandler>(*priv->pageProxy);
-    return *priv->dragAndDropHandler;
+    if (!priv->dragSource)
+        priv->dragSource = makeUnique<DragSource>(GTK_WIDGET(webViewBase));
+
+    priv->dragSource->begin(WTFMove(selectionData), dragOperation, WTFMove(image));
+
+#if !USE(GTK4)
+    // A drag starting should prevent a double-click from happening. This might
+    // happen if a drag is followed very quickly by another click (like in the WTR).
+    priv->clickCounter.reset();
+#endif
 }
+
+void webkitWebViewBaseDidPerformDragControllerAction(WebKitWebViewBase* webViewBase)
+{
+    webViewBase->priv->dropTarget->didPerformAction();
+}
 #endif // ENABLE(DRAG_SUPPORT)
 
 void webkitWebViewBaseForwardNextKeyEvent(WebKitWebViewBase* webkitWebViewBase)

Modified: trunk/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBasePrivate.h (261569 => 261570)


--- trunk/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBasePrivate.h	2020-05-12 19:13:18 UTC (rev 261569)
+++ trunk/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBasePrivate.h	2020-05-12 19:27:48 UTC (rev 261570)
@@ -32,6 +32,7 @@
 #include "GestureController.h"
 #include "InputMethodState.h"
 #include "SameDocumentNavigationType.h"
+#include "ShareableBitmap.h"
 #include "ViewGestureController.h"
 #include "ViewSnapshotStore.h"
 #include "WebContextMenuProxyGtk.h"
@@ -39,6 +40,8 @@
 #include "WebKitInputMethodContext.h"
 #include "WebKitWebViewBase.h"
 #include "WebPageProxy.h"
+#include <WebCore/DragActions.h>
+#include <WebCore/SelectionData.h>
 #include <wtf/Optional.h>
 
 WebKitWebViewBase* webkitWebViewBaseCreate(const API::PageConfiguration&);
@@ -78,8 +81,9 @@
 void webkitWebViewBaseDidRelaunchWebProcess(WebKitWebViewBase*);
 void webkitWebViewBasePageClosed(WebKitWebViewBase*);
 
-#if ENABLE(DRAG_SUPPORT) && !USE(GTK4)
-WebKit::DragAndDropHandler& webkitWebViewBaseDragAndDropHandler(WebKitWebViewBase*);
+#if ENABLE(DRAG_SUPPORT)
+void webkitWebViewBaseStartDrag(WebKitWebViewBase*, Ref<WebCore::SelectionData>&&, WebCore::DragOperation, RefPtr<WebKit::ShareableBitmap>&&);
+void webkitWebViewBaseDidPerformDragControllerAction(WebKitWebViewBase*);
 #endif
 
 #if !USE(GTK4)

Modified: trunk/Source/WebKit/UIProcess/PageClient.h (261569 => 261570)


--- trunk/Source/WebKit/UIProcess/PageClient.h	2020-05-12 19:13:18 UTC (rev 261569)
+++ trunk/Source/WebKit/UIProcess/PageClient.h	2020-05-12 19:27:48 UTC (rev 261570)
@@ -250,6 +250,7 @@
     virtual void startDrag(const WebCore::DragItem&, const ShareableBitmap::Handle&) { }
 #endif
     virtual void didPerformDragOperation(bool) { }
+    virtual void didPerformDragControllerAction() { }
 #endif // ENABLE(DRAG_SUPPORT)
 
     virtual void setCursor(const WebCore::Cursor&) = 0;

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (261569 => 261570)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp	2020-05-12 19:13:18 UTC (rev 261569)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp	2020-05-12 19:27:48 UTC (rev 261570)
@@ -2424,6 +2424,7 @@
     m_currentDragNumberOfFilesToBeAccepted = numberOfItemsToBeAccepted;
     m_currentDragCaretEditableElementRect = editableElementRect;
     setDragCaretRect(insertionRect);
+    pageClient().didPerformDragControllerAction();
 }
 
 #if PLATFORM(GTK)

Deleted: trunk/Source/WebKit/UIProcess/gtk/DragAndDropHandler.cpp (261569 => 261570)


--- trunk/Source/WebKit/UIProcess/gtk/DragAndDropHandler.cpp	2020-05-12 19:13:18 UTC (rev 261569)
+++ trunk/Source/WebKit/UIProcess/gtk/DragAndDropHandler.cpp	2020-05-12 19:27:48 UTC (rev 261570)
@@ -1,284 +0,0 @@
-/*
- * Copyright (C) 2014 Igalia S.L.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "DragAndDropHandler.h"
-
-#if ENABLE(DRAG_SUPPORT) && !USE(GTK4)
-
-#include "WebPageProxy.h"
-#include <WebCore/DragData.h>
-#include <WebCore/GRefPtrGtk.h>
-#include <WebCore/GUniquePtrGtk.h>
-#include <WebCore/GtkUtilities.h>
-#include <WebCore/PasteboardHelper.h>
-#include <wtf/RunLoop.h>
-
-namespace WebKit {
-using namespace WebCore;
-
-DragAndDropHandler::DragAndDropHandler(WebPageProxy& page)
-    : m_page(page)
-{
-}
-
-DragAndDropHandler::DroppingContext::DroppingContext(GdkDragContext* gdkContext, const IntPoint& position)
-    : gdkContext(gdkContext)
-    , lastMotionPosition(position)
-    , selectionData(SelectionData::create())
-{
-}
-
-static inline GdkDragAction dragOperationToGdkDragActions(DragOperation coreAction)
-{
-    GdkDragAction gdkAction = static_cast<GdkDragAction>(0);
-    if (coreAction == DragOperationNone)
-        return gdkAction;
-
-    if (coreAction & DragOperationCopy)
-        gdkAction = static_cast<GdkDragAction>(GDK_ACTION_COPY | gdkAction);
-    if (coreAction & DragOperationMove)
-        gdkAction = static_cast<GdkDragAction>(GDK_ACTION_MOVE | gdkAction);
-    if (coreAction & DragOperationLink)
-        gdkAction = static_cast<GdkDragAction>(GDK_ACTION_LINK | gdkAction);
-    if (coreAction & DragOperationPrivate)
-        gdkAction = static_cast<GdkDragAction>(GDK_ACTION_PRIVATE | gdkAction);
-
-    return gdkAction;
-}
-
-static inline GdkDragAction dragOperationToSingleGdkDragAction(DragOperation coreAction)
-{
-    if (coreAction == DragOperationEvery || coreAction & DragOperationCopy)
-        return GDK_ACTION_COPY;
-    if (coreAction & DragOperationMove)
-        return GDK_ACTION_MOVE;
-    if (coreAction & DragOperationLink)
-        return GDK_ACTION_LINK;
-    if (coreAction & DragOperationPrivate)
-        return GDK_ACTION_PRIVATE;
-    return static_cast<GdkDragAction>(0);
-}
-
-static inline DragOperation gdkDragActionToDragOperation(GdkDragAction gdkAction)
-{
-    // We have no good way to detect DragOperationEvery other than
-    // to use it when all applicable flags are on.
-    if (gdkAction & GDK_ACTION_COPY
-        && gdkAction & GDK_ACTION_MOVE
-        && gdkAction & GDK_ACTION_LINK
-        && gdkAction & GDK_ACTION_PRIVATE)
-        return DragOperationEvery;
-
-    unsigned action = ""
-    if (gdkAction & GDK_ACTION_COPY)
-        action |= DragOperationCopy;
-    if (gdkAction & GDK_ACTION_MOVE)
-        action |= DragOperationMove;
-    if (gdkAction & GDK_ACTION_LINK)
-        action |= DragOperationLink;
-    if (gdkAction & GDK_ACTION_PRIVATE)
-        action |= DragOperationPrivate;
-    return static_cast<DragOperation>(action);
-}
-
-void DragAndDropHandler::startDrag(Ref<SelectionData>&& selection, DragOperation dragOperation, RefPtr<ShareableBitmap>&& dragImage)
-{
-    // WebCore::EventHandler does not support more than one DnD operation at the same time for
-    // a given page, so we should cancel any previous operation whose context we might have
-    // stored, should we receive a new startDrag event before finishing a previous DnD operation.
-    if (m_dragContext) {
-        gtk_drag_cancel(m_dragContext.get());
-        m_dragContext = nullptr;
-    }
-
-    m_draggingSelectionData = WTFMove(selection);
-    GRefPtr<GtkTargetList> targetList = PasteboardHelper::singleton().targetListForSelectionData(*m_draggingSelectionData);
-
-    GUniquePtr<GdkEvent> currentEvent(gtk_get_current_event());
-    GdkDragContext* context = gtk_drag_begin_with_coordinates(m_page.viewWidget(), targetList.get(), dragOperationToGdkDragActions(dragOperation),
-        GDK_BUTTON_PRIMARY, currentEvent.get(), -1, -1);
-
-    m_dragContext = context;
-
-    if (dragImage) {
-        RefPtr<cairo_surface_t> image(dragImage->createCairoSurface());
-        // Use the center of the drag image as hotspot.
-        cairo_surface_set_device_offset(image.get(), -cairo_image_surface_get_width(image.get()) / 2, -cairo_image_surface_get_height(image.get()) / 2);
-        gtk_drag_set_icon_surface(context, image.get());
-    } else
-        gtk_drag_set_icon_default(context);
-}
-
-void DragAndDropHandler::fillDragData(GdkDragContext* context, GtkSelectionData* selectionData, unsigned info)
-{
-    // This can happen when attempting to call finish drag from webkitWebViewBaseDragDataGet()
-    // for a obsolete DnD operation that got previously cancelled in startDrag().
-    if (m_dragContext.get() != context)
-        return;
-
-    ASSERT(m_draggingSelectionData);
-    PasteboardHelper::singleton().fillSelectionData(*m_draggingSelectionData, info, selectionData);
-}
-
-void DragAndDropHandler::finishDrag(GdkDragContext* context)
-{
-    // This can happen when attempting to call finish drag from webkitWebViewBaseDragEnd()
-    // for a obsolete DnD operation that got previously cancelled in startDrag().
-    if (m_dragContext.get() != context)
-        return;
-
-    if (!m_draggingSelectionData)
-        return;
-
-    m_dragContext = nullptr;
-    m_draggingSelectionData = nullptr;
-
-    GdkDevice* device = gdk_drag_context_get_device(context);
-    int x = 0, y = 0;
-    gdk_device_get_window_at_position(device, &x, &y);
-    int xRoot = 0, yRoot = 0;
-    gdk_device_get_position(device, nullptr, &xRoot, &yRoot);
-    m_page.dragEnded(IntPoint(x, y), IntPoint(xRoot, yRoot), gdkDragActionToDragOperation(gdk_drag_context_get_selected_action(context)));
-}
-
-SelectionData* DragAndDropHandler::dropDataSelection(GdkDragContext* context, GtkSelectionData* selectionData, unsigned info, IntPoint& position)
-{
-    DroppingContext* droppingContext = m_droppingContexts.get(context);
-    if (!droppingContext)
-        return nullptr;
-
-    droppingContext->pendingDataRequests--;
-    PasteboardHelper::singleton().fillSelectionData(selectionData, info, droppingContext->selectionData);
-    if (droppingContext->pendingDataRequests)
-        return nullptr;
-
-    // The coordinates passed to drag-data-received signal are sometimes
-    // inaccurate in WTR, so use the coordinates of the last motion event.
-    position = droppingContext->lastMotionPosition;
-
-    // If there are no more pending requests, start sending dragging data to WebCore.
-    return droppingContext->selectionData.ptr();
-}
-
-void DragAndDropHandler::dragEntered(GdkDragContext* context, GtkSelectionData* selectionData, unsigned info, unsigned time)
-{
-    IntPoint position;
-    auto* selection = dropDataSelection(context, selectionData, info, position);
-    if (!selection)
-        return;
-
-    DragData dragData(selection, position, convertWidgetPointToScreenPoint(m_page.viewWidget(), position), gdkDragActionToDragOperation(gdk_drag_context_get_actions(context)));
-    m_page.resetCurrentDragInformation();
-    m_page.dragEntered(dragData);
-    DragOperation operation = m_page.currentDragOperation();
-    gdk_drag_status(context, dragOperationToSingleGdkDragAction(operation), time);
-}
-
-SelectionData* DragAndDropHandler::dragDataSelection(GdkDragContext* context, const IntPoint& position, unsigned time)
-{
-    std::unique_ptr<DroppingContext>& droppingContext = m_droppingContexts.add(context, nullptr).iterator->value;
-    if (!droppingContext) {
-        GtkWidget* widget = m_page.viewWidget();
-        droppingContext = makeUnique<DroppingContext>(context, position);
-        Vector<GdkAtom> acceptableTargets(PasteboardHelper::singleton().dropAtomsForContext(widget, droppingContext->gdkContext));
-        droppingContext->pendingDataRequests = acceptableTargets.size();
-        for (auto& target : acceptableTargets)
-            gtk_drag_get_data(widget, droppingContext->gdkContext, target, time);
-    } else
-        droppingContext->lastMotionPosition = position;
-
-    // Don't send any drag information to WebCore until we've retrieved all the data for this drag operation.
-    // Otherwise we'd have to block to wait for the drag's data.
-    if (droppingContext->pendingDataRequests > 0)
-        return nullptr;
-
-    return droppingContext->selectionData.ptr();
-}
-
-void DragAndDropHandler::dragMotion(GdkDragContext* context, const IntPoint& position, unsigned time)
-{
-    auto* selection = dragDataSelection(context, position, time);
-    if (!selection)
-        return;
-
-    DragData dragData(selection, position, convertWidgetPointToScreenPoint(m_page.viewWidget(), position), gdkDragActionToDragOperation(gdk_drag_context_get_actions(context)));
-    m_page.dragUpdated(dragData);
-    DragOperation operation = m_page.currentDragOperation();
-    gdk_drag_status(context, dragOperationToSingleGdkDragAction(operation), time);
-}
-
-void DragAndDropHandler::dragLeave(GdkDragContext* context)
-{
-    DroppingContext* droppingContext = m_droppingContexts.get(context);
-    if (!droppingContext)
-        return;
-
-    // During a drop GTK+ will fire a drag-leave signal right before firing
-    // the drag-drop signal. We want the actions for drag-leave to happen after
-    // those for drag-drop, so schedule them to happen asynchronously here.
-    RunLoop::main().dispatch([this, context, droppingContext]() {
-        auto it = m_droppingContexts.find(context);
-        if (it == m_droppingContexts.end())
-            return;
-
-        // If the view doesn't know about the drag yet (there are still pending data requests),
-        // don't update it with information about the drag.
-        if (droppingContext->pendingDataRequests)
-            return;
-
-        if (!droppingContext->dropHappened) {
-            // Don't call dragExited if we have just received a drag-drop signal. This
-            // happens in the case of a successful drop onto the view.
-            const IntPoint& position = droppingContext->lastMotionPosition;
-            DragData dragData(droppingContext->selectionData.ptr(), position, convertWidgetPointToScreenPoint(m_page.viewWidget(), position), DragOperationNone);
-            m_page.dragExited(dragData);
-            m_page.resetCurrentDragInformation();
-        }
-
-        m_droppingContexts.remove(it);
-    });
-}
-
-bool DragAndDropHandler::drop(GdkDragContext* context, const IntPoint& position, unsigned time)
-{
-    DroppingContext* droppingContext = m_droppingContexts.get(context);
-    if (!droppingContext)
-        return false;
-
-    droppingContext->dropHappened = true;
-
-    uint32_t flags = 0;
-    if (gdk_drag_context_get_selected_action(context) == GDK_ACTION_COPY)
-        flags |= WebCore::DragApplicationIsCopyKeyDown;
-    DragData dragData(droppingContext->selectionData.ptr(), position, convertWidgetPointToScreenPoint(m_page.viewWidget(), position), gdkDragActionToDragOperation(gdk_drag_context_get_actions(context)), static_cast<WebCore::DragApplicationFlags>(flags));
-    m_page.performDragOperation(dragData, String(), { }, { });
-    gtk_drag_finish(context, TRUE, FALSE, time);
-    return true;
-}
-
-} // namespace WebKit
-
-#endif // ENABLE(DRAG_SUPPORT)

Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp (261569 => 261570)


--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp	2020-05-12 19:13:18 UTC (rev 261569)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp	2020-05-12 19:27:48 UTC (rev 261570)
@@ -3943,7 +3943,7 @@
         return;
     }
     case DragControllerAction::Updated: {
-        DragOperation resolvedDragOperation = m_page->dragController().dragEntered(dragData);
+        DragOperation resolvedDragOperation = m_page->dragController().dragUpdated(dragData);
         send(Messages::WebPageProxy::DidPerformDragControllerAction(resolvedDragOperation, m_page->dragController().dragHandlingMethod(), m_page->dragController().mouseIsOverFileInput(), m_page->dragController().numberOfItemsToBeAccepted(), { }, { }));
         return;
     }

Modified: trunk/Source/WebKit/WebProcess/WebPage/gtk/WebPageGtk.cpp (261569 => 261570)


--- trunk/Source/WebKit/WebProcess/WebPage/gtk/WebPageGtk.cpp	2020-05-12 19:13:18 UTC (rev 261569)
+++ trunk/Source/WebKit/WebProcess/WebPage/gtk/WebPageGtk.cpp	2020-05-12 19:27:48 UTC (rev 261570)
@@ -42,7 +42,6 @@
 #include <WebCore/KeyboardEvent.h>
 #include <WebCore/NotImplemented.h>
 #include <WebCore/Page.h>
-#include <WebCore/PasteboardHelper.h>
 #include <WebCore/PlatformKeyboardEvent.h>
 #include <WebCore/RenderTheme.h>
 #include <WebCore/Settings.h>
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to