Title: [96299] trunk/Source
Revision
96299
Author
mrobin...@webkit.org
Date
2011-09-28 23:02:57 -0700 (Wed, 28 Sep 2011)

Log Message

[GTK] Move drag-and-drop code which can be shared with WebKit2 to WebCore
https://bugs.webkit.org/show_bug.cgi?id=66890

Source/WebCore:

Added a GtkDragAndDropHelper class to hold all the logic that is common
between WebKit1 and WebKit2. This will allow greater code sharing between
the two ports.

Reviewed by Philippe Normand.

No new tests. This patch should not change behavior.

* GNUmakefile.list.am: Added the GtkDragAndDropHelper to the sources list.
* platform/gtk/GtkDragAndDropHelper.cpp: Added.
* platform/gtk/GtkDragAndDropHelper.h: Added.

Source/WebKit/gtk:

Use the new GtkWidgetDragAndDropGlue class to hold the logic that will be
common between WebKit1 and WebKit2. Modify WebKitWebView to use this class.

Reviewed by Philippe Normand.

* WebCoreSupport/DragClientGtk.cpp:
(WebKit::DragClient::startDrag): Inform the drag-and-drop glue about the drag.
* webkit/webkitwebview.cpp: Use GtkWidgetDragAndDropGlue wherever this class was
maintaining drag-and-drop state itself.
* webkit/webkitwebviewprivate.h: Swap out the drag-and-drop state for an instance
of the glue class.

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (96298 => 96299)


--- trunk/Source/WebCore/ChangeLog	2011-09-29 06:01:34 UTC (rev 96298)
+++ trunk/Source/WebCore/ChangeLog	2011-09-29 06:02:57 UTC (rev 96299)
@@ -1,3 +1,20 @@
+2011-09-28  Martin Robinson  <mrobin...@igalia.com>
+
+        [GTK] Move drag-and-drop code which can be shared with WebKit2 to WebCore
+        https://bugs.webkit.org/show_bug.cgi?id=66890
+
+        Added a GtkDragAndDropHelper class to hold all the logic that is common
+        between WebKit1 and WebKit2. This will allow greater code sharing between
+        the two ports.
+
+        Reviewed by Philippe Normand.
+
+        No new tests. This patch should not change behavior.
+
+        * GNUmakefile.list.am: Added the GtkDragAndDropHelper to the sources list.
+        * platform/gtk/GtkDragAndDropHelper.cpp: Added.
+        * platform/gtk/GtkDragAndDropHelper.h: Added.
+
 2011-09-28  Dan Bernstein  <m...@apple.com>
 
         <rdar://problem/10196497> first-letter after list marker not updated correctly

Modified: trunk/Source/WebCore/GNUmakefile.list.am (96298 => 96299)


--- trunk/Source/WebCore/GNUmakefile.list.am	2011-09-29 06:01:34 UTC (rev 96298)
+++ trunk/Source/WebCore/GNUmakefile.list.am	2011-09-29 06:02:57 UTC (rev 96299)
@@ -3998,6 +3998,8 @@
 	Source/WebCore/platform/gtk/FileSystemGtk.cpp \
 	Source/WebCore/platform/gtk/GtkClickCounter.cpp \
 	Source/WebCore/platform/gtk/GtkClickCounter.h \
+	Source/WebCore/platform/gtk/GtkDragAndDropHelper.cpp \
+	Source/WebCore/platform/gtk/GtkDragAndDropHelper.h \
 	Source/WebCore/platform/gtk/GtkUtilities.cpp \
 	Source/WebCore/platform/gtk/GtkUtilities.h \
 	Source/WebCore/platform/gtk/GeolocationServiceGtk.cpp \

Added: trunk/Source/WebCore/platform/gtk/GtkDragAndDropHelper.cpp (0 => 96299)


--- trunk/Source/WebCore/platform/gtk/GtkDragAndDropHelper.cpp	                        (rev 0)
+++ trunk/Source/WebCore/platform/gtk/GtkDragAndDropHelper.cpp	2011-09-29 06:02:57 UTC (rev 96299)
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2011, Igalia S.L.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser 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
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "config.h"
+#include "GtkDragAndDropHelper.h"
+
+#include "ClipboardUtilitiesGtk.h"
+#include "DragData.h"
+#include "GtkUtilities.h"
+#include "PasteboardHelper.h"
+#include <gtk/gtk.h>
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+struct DroppingContext {
+    DroppingContext(GdkDragContext* gdkContext, const IntPoint& position)
+        : gdkContext(gdkContext)
+        , dataObject(DataObjectGtk::create())
+        , lastMotionPosition(position)
+        , dropHappened(false)
+        , exitedCallback(0)
+    {
+    }
+
+    GdkDragContext* gdkContext;
+    RefPtr<WebCore::DataObjectGtk> dataObject;
+    WebCore::IntPoint lastMotionPosition;
+    int pendingDataRequests;
+    bool dropHappened;
+    DragExitedCallback exitedCallback;
+};
+
+typedef HashMap<GdkDragContext*, DroppingContext*> DroppingContextMap;
+typedef HashMap<GdkDragContext*, RefPtr<DataObjectGtk> > DraggingDataObjectsMap;
+
+GtkDragAndDropHelper::~GtkDragAndDropHelper()
+{
+    deleteAllValues(m_droppingContexts);
+}
+
+bool GtkDragAndDropHelper::handleDragEnd(GdkDragContext* dragContext)
+{
+    DraggingDataObjectsMap::iterator iterator = m_draggingDataObjects.find(dragContext);
+    if (iterator == m_draggingDataObjects.end())
+        return false;
+
+    m_draggingDataObjects.remove(iterator);
+    return true;
+}
+
+void GtkDragAndDropHelper::handleGetDragData(GdkDragContext* context, GtkSelectionData* selectionData, guint info)
+{
+    DraggingDataObjectsMap::iterator iterator = m_draggingDataObjects.find(context);
+    if (iterator == m_draggingDataObjects.end())
+        return;
+    PasteboardHelper::defaultPasteboardHelper()->fillSelectionData(selectionData, info, iterator->second.get());
+}
+
+struct HandleDragLaterData {
+    DroppingContext* context;
+    GtkDragAndDropHelper* glue;
+};
+
+static gboolean handleDragLeaveLaterCallback(HandleDragLaterData* data)
+{
+    data->glue->handleDragLeaveLater(data->context);
+    delete data;
+    return FALSE;
+}
+
+void GtkDragAndDropHelper::handleDragLeaveLater(DroppingContext* context)
+{
+    DroppingContextMap::iterator iterator = m_droppingContexts.find(context->gdkContext);
+    if (iterator == 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 (context->pendingDataRequests)
+        return;
+
+    const IntPoint& position = context->lastMotionPosition;
+    DragData dragData(context->dataObject.get(), position,
+                      convertWidgetPointToScreenPoint(m_widget, position),
+                      DragOperationNone);
+    context->exitedCallback(m_widget, &dragData, context->dropHappened);
+
+    m_droppingContexts.remove(iterator);
+    delete context;
+}
+
+void GtkDragAndDropHelper::handleDragLeave(GdkDragContext* gdkContext, DragExitedCallback exitedCallback)
+{
+    DroppingContextMap::iterator iterator = m_droppingContexts.find(gdkContext);
+    if (iterator == m_droppingContexts.end())
+        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.
+    HandleDragLaterData* data = "" HandleDragLaterData;
+    data->context = iterator->second;
+    data->context->exitedCallback = exitedCallback;
+    data->glue = this;
+    g_timeout_add(0, reinterpret_cast<GSourceFunc>(handleDragLeaveLaterCallback), data);
+}
+
+static void queryNewDropContextData(DroppingContext* dropContext, GtkWidget* widget, guint time)
+{
+    GdkDragContext* gdkContext = dropContext->gdkContext;
+    Vector<GdkAtom> acceptableTargets(PasteboardHelper::defaultPasteboardHelper()->dropAtomsForContext(widget, gdkContext));
+    dropContext->pendingDataRequests = acceptableTargets.size();
+    for (size_t i = 0; i < acceptableTargets.size(); i++)
+        gtk_drag_get_data(widget, gdkContext, acceptableTargets.at(i), time);
+}
+
+PassOwnPtr<DragData> GtkDragAndDropHelper::handleDragMotion(GdkDragContext* context, const IntPoint& position, unsigned time)
+{
+    DroppingContext* droppingContext = 0;
+    DroppingContextMap::iterator iterator = m_droppingContexts.find(context);
+    if (iterator == m_droppingContexts.end()) {
+        droppingContext = new DroppingContext(context, position);
+        m_droppingContexts.set(context, droppingContext);
+        queryNewDropContextData(droppingContext, m_widget, time);
+    } else {
+        droppingContext = iterator->second;
+        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.
+    ASSERT(droppingContext);
+    if (droppingContext->pendingDataRequests > 0)
+        return adoptPtr(static_cast<DragData*>(0));
+
+    return adoptPtr(new DragData(droppingContext->dataObject.get(), position,
+                                 convertWidgetPointToScreenPoint(m_widget, position),
+                                 gdkDragActionToDragOperation(gdk_drag_context_get_actions(context))));
+}
+
+PassOwnPtr<DragData> GtkDragAndDropHelper::handleDragDataReceived(GdkDragContext* context, GtkSelectionData* selectionData, guint info)
+{
+    DroppingContextMap::iterator iterator = m_droppingContexts.find(context);
+    if (iterator == m_droppingContexts.end())
+        return adoptPtr(static_cast<DragData*>(0));
+
+    DroppingContext* droppingContext = iterator->second;
+    droppingContext->pendingDataRequests--;
+    PasteboardHelper::defaultPasteboardHelper()->fillDataObjectFromDropData(selectionData, info, droppingContext->dataObject.get());
+
+    if (droppingContext->pendingDataRequests)
+        return adoptPtr(static_cast<DragData*>(0));
+
+    // The coordinates passed to drag-data-received signal are sometimes
+    // inaccurate in DRT, so use the coordinates of the last motion event.
+    const IntPoint& position = droppingContext->lastMotionPosition;
+
+    // If there are no more pending requests, start sending dragging data to WebCore.
+    return adoptPtr(new DragData(droppingContext->dataObject.get(), position, 
+                                 convertWidgetPointToScreenPoint(m_widget, position),
+                                 gdkDragActionToDragOperation(gdk_drag_context_get_actions(context))));
+}
+
+PassOwnPtr<DragData> GtkDragAndDropHelper::handleDragDrop(GdkDragContext* context, const IntPoint& position)
+{
+    DroppingContextMap::iterator iterator = m_droppingContexts.find(context);
+    if (iterator == m_droppingContexts.end())
+        return adoptPtr(static_cast<DragData*>(0));
+
+    DroppingContext* droppingContext = iterator->second;
+    droppingContext->dropHappened = true;
+
+    return adoptPtr(new DragData(droppingContext->dataObject.get(), position, 
+                                 convertWidgetPointToScreenPoint(m_widget, position),
+                                 gdkDragActionToDragOperation(gdk_drag_context_get_actions(context))));
+}
+
+void GtkDragAndDropHelper::startedDrag(GdkDragContext* context, DataObjectGtk* dataObject)
+{
+    m_draggingDataObjects.set(context, dataObject);
+}
+
+} // namespace WebCore
Property changes on: trunk/Source/WebCore/platform/gtk/GtkDragAndDropHelper.cpp
___________________________________________________________________

Added: svn:eol-style

Added: trunk/Source/WebCore/platform/gtk/GtkDragAndDropHelper.h (0 => 96299)


--- trunk/Source/WebCore/platform/gtk/GtkDragAndDropHelper.h	                        (rev 0)
+++ trunk/Source/WebCore/platform/gtk/GtkDragAndDropHelper.h	2011-09-29 06:02:57 UTC (rev 96299)
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2011, Igalia S.L.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser 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
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef GtkDragAndDropHelper_h
+#define GtkDragAndDropHelper_h
+
+#include "DataObjectGtk.h"
+#include <wtf/FastAllocBase.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/text/CString.h>
+
+namespace WebCore {
+
+struct DroppingContext;
+class DragData;
+
+typedef void (*DragExitedCallback)(GtkWidget*, DragData*, bool dropHappened);
+
+class GtkDragAndDropHelper {
+    WTF_MAKE_NONCOPYABLE(GtkDragAndDropHelper);
+    WTF_MAKE_FAST_ALLOCATED;
+
+public:
+    GtkDragAndDropHelper()
+        : m_widget(0)
+    {
+    }
+    ~GtkDragAndDropHelper();
+
+    void setWidget(GtkWidget* widget) { m_widget = widget; }
+    bool handleDragEnd(GdkDragContext*);
+    void handleGetDragData(GdkDragContext*, GtkSelectionData*, guint info);
+    void handleDragLeave(GdkDragContext*, DragExitedCallback);
+    void handleDragLeaveLater(DroppingContext*);
+    PassOwnPtr<DragData> handleDragMotion(GdkDragContext*, const IntPoint&, unsigned time);
+    PassOwnPtr<DragData> handleDragDataReceived(GdkDragContext*, GtkSelectionData*, guint info);
+    PassOwnPtr<DragData> handleDragDrop(GdkDragContext*, const IntPoint&);
+    void startedDrag(GdkDragContext*, DataObjectGtk*);
+
+private:
+    GtkWidget* m_widget;
+    HashMap<GdkDragContext*, DroppingContext*> m_droppingContexts;
+    HashMap<GdkDragContext*, RefPtr<DataObjectGtk> > m_draggingDataObjects;
+};
+
+}
+
+#endif // DataObjectGtk_h
Property changes on: trunk/Source/WebCore/platform/gtk/GtkDragAndDropHelper.h
___________________________________________________________________

Added: svn:eol-style

Modified: trunk/Source/WebKit/gtk/ChangeLog (96298 => 96299)


--- trunk/Source/WebKit/gtk/ChangeLog	2011-09-29 06:01:34 UTC (rev 96298)
+++ trunk/Source/WebKit/gtk/ChangeLog	2011-09-29 06:02:57 UTC (rev 96299)
@@ -1,3 +1,20 @@
+2011-09-28  Martin Robinson  <mrobin...@igalia.com>
+
+        [GTK] Move drag-and-drop code which can be shared with WebKit2 to WebCore
+        https://bugs.webkit.org/show_bug.cgi?id=66890
+
+        Use the new GtkWidgetDragAndDropGlue class to hold the logic that will be
+        common between WebKit1 and WebKit2. Modify WebKitWebView to use this class.
+
+        Reviewed by Philippe Normand.
+
+        * WebCoreSupport/DragClientGtk.cpp:
+        (WebKit::DragClient::startDrag): Inform the drag-and-drop glue about the drag.
+        * webkit/webkitwebview.cpp: Use GtkWidgetDragAndDropGlue wherever this class was
+        maintaining drag-and-drop state itself.
+        * webkit/webkitwebviewprivate.h: Swap out the drag-and-drop state for an instance
+        of the glue class.
+
 2011-09-28  Kaustubh Atrawalkar  <kaust...@motorola.com>
 
         [Gtk] Implement textInputController.doCommand

Modified: trunk/Source/WebKit/gtk/WebCoreSupport/DragClientGtk.cpp (96298 => 96299)


--- trunk/Source/WebKit/gtk/WebCoreSupport/DragClientGtk.cpp	2011-09-29 06:01:34 UTC (rev 96298)
+++ trunk/Source/WebKit/gtk/WebCoreSupport/DragClientGtk.cpp	2011-09-29 06:02:57 UTC (rev 96299)
@@ -107,7 +107,7 @@
     GOwnPtr<GdkEvent> currentEvent(gtk_get_current_event());
 
     GdkDragContext* context = gtk_drag_begin(GTK_WIDGET(m_webView), targetList.get(), dragOperationToGdkDragActions(clipboard->sourceOperation()), 1, currentEvent.get());
-    webView->priv->draggingDataObjects.set(context, dataObject);
+    webView->priv->dragAndDropHelper.startedDrag(context, dataObject.get());
 
     // 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 DRT).

Modified: trunk/Source/WebKit/gtk/webkit/webkitwebview.cpp (96298 => 96299)


--- trunk/Source/WebKit/gtk/webkit/webkitwebview.cpp	2011-09-29 06:01:34 UTC (rev 96298)
+++ trunk/Source/WebKit/gtk/webkit/webkitwebview.cpp	2011-09-29 06:02:57 UTC (rev 96299)
@@ -779,7 +779,8 @@
         return TRUE;
 
     PlatformMouseEvent platformEvent(event);
-    platformEvent.setClickCount(priv->clickCounter.clickCountForGdkButtonEvent(widget, event));
+    int count = priv->clickCounter.clickCountForGdkButtonEvent(widget, event);
+    platformEvent.setClickCount(count);
 
     if (event->button == 3)
         return webkit_web_view_forward_context_menu_event(webView, PlatformMouseEvent(event));
@@ -1333,11 +1334,6 @@
     priv->mainResource.clear();
     priv->subResources.clear();
 
-    HashMap<GdkDragContext*, DroppingContext*>::iterator endDroppingContexts = priv->droppingContexts.end();
-    for (HashMap<GdkDragContext*, DroppingContext*>::iterator iter = priv->droppingContexts.begin(); iter != endDroppingContexts; ++iter)
-        delete (iter->second);
-    priv->droppingContexts.clear();
-
     G_OBJECT_CLASS(webkit_web_view_parent_class)->dispose(object);
 }
 
@@ -1450,19 +1446,14 @@
 static void webkit_web_view_drag_end(GtkWidget* widget, GdkDragContext* context)
 {
     WebKitWebView* webView = WEBKIT_WEB_VIEW(widget);
-    WebKitWebViewPrivate* priv = webView->priv;
-
-    // This might happen if a drag is still in progress after a WebKitWebView
-    // is disposed and before it is finalized.
-    if (!priv->draggingDataObjects.contains(context))
+    if (!webView->priv->dragAndDropHelper.handleDragEnd(context))
         return;
 
-    priv->draggingDataObjects.remove(context);
-
     Frame* frame = core(webView)->focusController()->focusedOrMainFrame();
     if (!frame)
         return;
 
+    // Synthesize a button release event to send with the drag end action.
     GOwnPtr<GdkEvent> event(gdk_event_new(GDK_BUTTON_RELEASE));
     int x, y, xRoot, yRoot;
     GdkModifierType modifiers = static_cast<GdkModifierType>(0);
@@ -1490,136 +1481,54 @@
 
 static void webkit_web_view_drag_data_get(GtkWidget* widget, GdkDragContext* context, GtkSelectionData* selectionData, guint info, guint)
 {
-    WebKitWebViewPrivate* priv = WEBKIT_WEB_VIEW(widget)->priv;
-
-    // This might happen if a drag is still in progress after a WebKitWebView
-    // is diposed and before it is finalized.
-    if (!priv->draggingDataObjects.contains(context))
-        return;
-
-    PasteboardHelper::defaultPasteboardHelper()->fillSelectionData(selectionData, info, priv->draggingDataObjects.get(context).get());
+    WEBKIT_WEB_VIEW(widget)->priv->dragAndDropHelper.handleGetDragData(context, selectionData, info);
 }
 
-static gboolean doDragLeaveLater(DroppingContext* context)
+static void dragExitedCallback(GtkWidget* widget, DragData* dragData, bool dropHappened)
 {
-    WebKitWebView* webView = context->webView;
-    WebKitWebViewPrivate* priv = webView->priv;
-
-    if (!priv->droppingContexts.contains(context->gdkContext))
-        return FALSE;
-
-    // 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 (context->pendingDataRequests)
-        return FALSE;
-
     // 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.
-    if (!context->dropHappened) {
-        const IntPoint& position = context->lastMotionPosition;
-        DragData dragData(context->dataObject.get(), position, convertWidgetPointToScreenPoint(GTK_WIDGET(webView), position), DragOperationNone);
-        core(webView)->dragController()->dragExited(&dragData);
-    }
-
-    core(webView)->dragController()->dragEnded();
-    priv->droppingContexts.remove(context->gdkContext);
-    delete context;
-    return FALSE;
+    if (!dropHappened)
+        core(WEBKIT_WEB_VIEW(widget))->dragController()->dragExited(dragData);
+    core(WEBKIT_WEB_VIEW(widget))->dragController()->dragEnded();
 }
 
 static void webkit_web_view_drag_leave(GtkWidget* widget, GdkDragContext* context, guint time)
 {
-    WebKitWebView* webView = WEBKIT_WEB_VIEW(widget);
-    WebKitWebViewPrivate* priv = webView->priv;
-
-    if (!priv->droppingContexts.contains(context))
-        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.
-    g_timeout_add(0, reinterpret_cast<GSourceFunc>(doDragLeaveLater), priv->droppingContexts.get(context));
+    WEBKIT_WEB_VIEW(widget)->priv->dragAndDropHelper.handleDragLeave(context, dragExitedCallback);
 }
 
 static gboolean webkit_web_view_drag_motion(GtkWidget* widget, GdkDragContext* context, gint x, gint y, guint time)
 {
     WebKitWebView* webView = WEBKIT_WEB_VIEW(widget);
-    WebKitWebViewPrivate* priv = webView->priv;
-
-    DroppingContext* droppingContext = 0;
-    IntPoint position = IntPoint(x, y);
-    if (!priv->droppingContexts.contains(context)) {
-        droppingContext = new DroppingContext;
-        droppingContext->webView = webView;
-        droppingContext->gdkContext = context;
-        droppingContext->dataObject = WebCore::DataObjectGtk::create();
-        droppingContext->dropHappened = false;
-        droppingContext->lastMotionPosition = position;
-        priv->droppingContexts.set(context, droppingContext);
-
-        Vector<GdkAtom> acceptableTargets(PasteboardHelper::defaultPasteboardHelper()->dropAtomsForContext(widget, context));
-        droppingContext->pendingDataRequests = acceptableTargets.size();
-        for (size_t i = 0; i < acceptableTargets.size(); i++)
-            gtk_drag_get_data(widget, context, acceptableTargets.at(i), time);
-    } else {
-        droppingContext = priv->droppingContexts.get(context);
-        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.
-    ASSERT(droppingContext);
-    if (droppingContext->pendingDataRequests > 0)
+    OwnPtr<DragData> dragData(webView->priv->dragAndDropHelper.handleDragMotion(context, IntPoint(x, y), time));
+    if (!dragData)
         return TRUE;
 
-    DragData dragData(droppingContext->dataObject.get(), position, convertWidgetPointToScreenPoint(widget, position), gdkDragActionToDragOperation(gdk_drag_context_get_actions(context)));
-    DragOperation operation = core(webView)->dragController()->dragUpdated(&dragData);
+    DragOperation operation = core(webView)->dragController()->dragUpdated(dragData.get());
     gdk_drag_status(context, dragOperationToSingleGdkDragAction(operation), time);
-
     return TRUE;
 }
 
 static void webkit_web_view_drag_data_received(GtkWidget* widget, GdkDragContext* context, gint x, gint y, GtkSelectionData* selectionData, guint info, guint time)
 {
     WebKitWebView* webView = WEBKIT_WEB_VIEW(widget);
-    WebKitWebViewPrivate* priv = webView->priv;
-
-    if (!priv->droppingContexts.contains(context))
+    OwnPtr<DragData> dragData(webView->priv->dragAndDropHelper.handleDragDataReceived(context, selectionData, info));
+    if (!dragData)
         return;
 
-    DroppingContext* droppingContext = priv->droppingContexts.get(context);
-    droppingContext->pendingDataRequests--;
-    PasteboardHelper::defaultPasteboardHelper()->fillDataObjectFromDropData(selectionData, info, droppingContext->dataObject.get());
-
-    if (droppingContext->pendingDataRequests)
-        return;
-
-    // The coordinates passed to drag-data-received signal are sometimes
-    // inaccurate in DRT, so use the coordinates of the last motion event.
-    const IntPoint& position = droppingContext->lastMotionPosition;
-
-    // If there are no more pending requests, start sending dragging data to WebCore.
-    DragData dragData(droppingContext->dataObject.get(), position, convertWidgetPointToScreenPoint(widget, position), gdkDragActionToDragOperation(gdk_drag_context_get_actions(context)));
-    DragOperation operation = core(webView)->dragController()->dragEntered(&dragData);
+    DragOperation operation = core(webView)->dragController()->dragEntered(dragData.get());
     gdk_drag_status(context, dragOperationToSingleGdkDragAction(operation), time);
 }
 
 static gboolean webkit_web_view_drag_drop(GtkWidget* widget, GdkDragContext* context, gint x, gint y, guint time)
 {
     WebKitWebView* webView = WEBKIT_WEB_VIEW(widget);
-    WebKitWebViewPrivate* priv = webView->priv;
-
-    if (!priv->droppingContexts.contains(context))
+    OwnPtr<DragData> dragData(webView->priv->dragAndDropHelper.handleDragDrop(context, IntPoint(x, y)));
+    if (!dragData)
         return FALSE;
 
-    DroppingContext* droppingContext = priv->droppingContexts.get(context);
-    droppingContext->dropHappened = true;
-
-    IntPoint position(x, y);
-    DragData dragData(droppingContext->dataObject.get(), position, convertWidgetPointToScreenPoint(widget, position), gdkDragActionToDragOperation(gdk_drag_context_get_actions(context)));
-    core(webView)->dragController()->performDrag(&dragData);
-
+    core(webView)->dragController()->performDrag(dragData.get());
     gtk_drag_finish(context, TRUE, FALSE, time);
     return TRUE;
 }
@@ -3438,6 +3347,7 @@
 
     priv->subResources = adoptGRef(g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_object_unref));
 
+    priv->dragAndDropHelper.setWidget(GTK_WIDGET(webView));
     gtk_drag_dest_set(GTK_WIDGET(webView), static_cast<GtkDestDefaults>(0), 0, 0, static_cast<GdkDragAction>(GDK_ACTION_COPY | GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK | GDK_ACTION_PRIVATE));
     gtk_drag_dest_set_target_list(GTK_WIDGET(webView), PasteboardHelper::defaultPasteboardHelper()->targetList());
 

Modified: trunk/Source/WebKit/gtk/webkit/webkitwebviewprivate.h (96298 => 96299)


--- trunk/Source/WebKit/gtk/webkit/webkitwebviewprivate.h	2011-09-29 06:01:34 UTC (rev 96298)
+++ trunk/Source/WebKit/gtk/webkit/webkitwebviewprivate.h	2011-09-29 06:02:57 UTC (rev 96299)
@@ -23,29 +23,17 @@
 #ifndef webkitwebviewprivate_h
 #define webkitwebviewprivate_h
 
-#include "DataObjectGtk.h"
 #include "FullscreenVideoController.h"
 #include "GtkClickCounter.h"
+#include "GtkDragAndDropHelper.h"
 #include "GOwnPtr.h"
 #include "Page.h"
 #include "ResourceHandle.h"
 #include <webkit/webkitwebview.h>
 
 namespace WebKit {
-
 WebCore::Page* core(WebKitWebView*);
 WebKitWebView* kit(WebCore::Page*);
-
-
-typedef struct DroppingContext_ {
-    WebKitWebView* webView;
-    GdkDragContext* gdkContext;
-    RefPtr<WebCore::DataObjectGtk> dataObject;
-    WebCore::IntPoint lastMotionPosition;
-    int pendingDataRequests;
-    bool dropHappened;
-} DroppingContext;
-
 }
 
 extern "C" {
@@ -100,9 +88,7 @@
     WebCore::IntRect tooltipArea;
 
     WebCore::GtkClickCounter clickCounter;
-    HashMap<GdkDragContext*, RefPtr<WebCore::DataObjectGtk> > draggingDataObjects;
-    HashMap<GdkDragContext*, WebKit::DroppingContext*> droppingContexts;
-
+    WebCore::GtkDragAndDropHelper dragAndDropHelper;
     bool selfScrolling;
 };
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to