2010-05-06 Martin Robinson <mrobinson@webkit.org>
authormrobinson@webkit.org <mrobinson@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 6 May 2010 16:32:42 +0000 (16:32 +0000)
committermrobinson@webkit.org <mrobinson@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 6 May 2010 16:32:42 +0000 (16:32 +0000)
        Reviewed by Gustavo Noronha Silva.

        [GTK] Enable DOM clipboard and drag-and-drop access
        https://bugs.webkit.org/show_bug.cgi?id=30623

        Convert dragging portion of drag-and-drop to use DataObjectGtk.

        * wtf/gobject/GRefPtr.h: Add forward declarations for GObject functions.
2010-05-06  Martin Robinson  <mrobinson@webkit.org>

        Reviewed by Gustavo Noronha Silva.

        [GTK] Enable DOM clipboard and drag-and-drop access
        https://bugs.webkit.org/show_bug.cgi?id=30623

        Convert dragging portion of drag-and-drop to use DataObjectGtk.

        No new tests, because functionality has not changed.

        * page/gtk/EventHandlerGtk.cpp:
        (WebCore::EventHandler::createDraggingClipboard): Pass the DataObjectGtk as a parameter here.
        * platform/gtk/ClipboardGtk.h:
        (WebCore::ClipboardGtk::create): Take the DataObject as a parameter instead of creating it here.
        (WebCore::ClipboardGtk::helper): Added.
        (WebCore::ClipboardGtk::dataObject): Added.
        * platform/gtk/PasteboardHelper.h: Make targetListForDataObject a public method.
2010-05-06  Martin Robinson  <mrobinson@webkit.org>

        Reviewed by Gustavo Noronha Silva.

        [GTK] Enable DOM clipboard and drag-and-drop access
        https://bugs.webkit.org/show_bug.cgi?id=30623

        Convert dragging portion of drag-and-drop to use DataObjectGtk.

        * WebCoreSupport/DragClientGtk.cpp:
        (WebKit::DragClient::willPerformDragDestinationAction): Remove the notImplemented. It is implemented, it's just a no-op.
        (WebKit::DragClient::startDrag): Start the drag context via the ClipboardGtk and PasteboardHelper now.
        * WebCoreSupport/DragClientGtk.h: Small style fix.
        * webkit/webkitprivate.h: Add a HashMap of contexts and DataObjects here to to represent all current drag operations.
        * webkit/webkitwebview.cpp:
        (webkit_web_view_dispose): Clear all data objects during disposal.
        (webkit_web_view_drag_end): When a drag is over, just remove it from the map.
        (webkit_web_view_drag_data_get): To get the drag data, just grab it from the DataObject.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@58885 268f45cc-cd09-0410-ab3c-d52691b4dbfc

JavaScriptCore/ChangeLog
JavaScriptCore/wtf/gobject/GRefPtr.h
WebCore/ChangeLog
WebCore/page/gtk/EventHandlerGtk.cpp
WebCore/platform/gtk/ClipboardGtk.h
WebCore/platform/gtk/PasteboardHelper.h
WebKit/gtk/ChangeLog
WebKit/gtk/WebCoreSupport/DragClientGtk.cpp
WebKit/gtk/WebCoreSupport/DragClientGtk.h
WebKit/gtk/webkit/webkitprivate.h
WebKit/gtk/webkit/webkitwebview.cpp

index 3f78f94..63555c2 100644 (file)
@@ -1,3 +1,14 @@
+2010-05-06  Martin Robinson  <mrobinson@webkit.org>
+
+        Reviewed by Gustavo Noronha Silva.
+
+        [GTK] Enable DOM clipboard and drag-and-drop access
+        https://bugs.webkit.org/show_bug.cgi?id=30623
+
+        Convert dragging portion of drag-and-drop to use DataObjectGtk.
+
+        * wtf/gobject/GRefPtr.h: Add forward declarations for GObject functions.
+
 2010-05-06  Steve Block  <steveblock@google.com>
 
         Reviewed by Eric Seidel.
index 66739ef..3a33605 100644 (file)
@@ -27,6 +27,9 @@
 #include <algorithm>
 
 typedef struct _GHashTable GHashTable;
+typedef void* gpointer;
+extern "C" void g_object_unref(gpointer object);
+extern "C" gpointer  g_object_ref_sink(gpointer object);
 
 namespace WTF {
 
index 12629d0..271f71f 100644 (file)
@@ -1,3 +1,22 @@
+2010-05-06  Martin Robinson  <mrobinson@webkit.org>
+
+        Reviewed by Gustavo Noronha Silva.
+
+        [GTK] Enable DOM clipboard and drag-and-drop access
+        https://bugs.webkit.org/show_bug.cgi?id=30623
+
+        Convert dragging portion of drag-and-drop to use DataObjectGtk.
+
+        No new tests, because functionality has not changed.
+
+        * page/gtk/EventHandlerGtk.cpp:
+        (WebCore::EventHandler::createDraggingClipboard): Pass the DataObjectGtk as a parameter here.
+        * platform/gtk/ClipboardGtk.h:
+        (WebCore::ClipboardGtk::create): Take the DataObject as a parameter instead of creating it here.
+        (WebCore::ClipboardGtk::helper): Added.
+        (WebCore::ClipboardGtk::dataObject): Added.
+        * platform/gtk/PasteboardHelper.h: Make targetListForDataObject a public method.
+
 2010-05-06  Pavel Feldman  <pfeldman@chromium.org>
 
         Reviewed by Timothy Hatcher.
index 7051391..0ff67d2 100644 (file)
@@ -96,7 +96,7 @@ bool EventHandler::passWheelEventToWidget(PlatformWheelEvent& event, Widget* wid
 
 PassRefPtr<Clipboard> EventHandler::createDraggingClipboard() const
 {
-    return ClipboardGtk::create(ClipboardWritable, true);
+    return ClipboardGtk::create(ClipboardWritable, DataObjectGtk::create(), true);
 }
 
 bool EventHandler::passMousePressEventToSubframe(MouseEventWithHitTestResults& mev, Frame* subframe)
index fd31d1e..c3438c4 100644 (file)
@@ -45,9 +45,9 @@ namespace WebCore {
             return adoptRef(new ClipboardGtk(policy, clipboard));
         }
 
-        static PassRefPtr<ClipboardGtk> create(ClipboardAccessPolicy policy, bool isForDragging)
+        static PassRefPtr<ClipboardGtk> create(ClipboardAccessPolicy policy, PassRefPtr<DataObjectGtk> dataObject, bool isForDragging)
         {
-            return adoptRef(new ClipboardGtk(policy, DataObjectGtk::create(), isForDragging));
+            return adoptRef(new ClipboardGtk(policy, dataObject, isForDragging));
         }
         virtual ~ClipboardGtk();
 
@@ -73,6 +73,9 @@ namespace WebCore {
 
         virtual bool hasData();
 
+        PasteboardHelper* helper() { return m_helper; }
+        PassRefPtr<DataObjectGtk> dataObject() { return m_dataObject; }
+
     private:
         ClipboardGtk(ClipboardAccessPolicy, GtkClipboard*);
         ClipboardGtk(ClipboardAccessPolicy, PassRefPtr<DataObjectGtk>, bool);
index 1aeb9b7..2d46adc 100644 (file)
@@ -2,6 +2,7 @@
  * Copyright (C) 2007 Luca Bruno <lethalman88@gmail.com>
  * Copyright (C) 2009 Holger Hans Peter Freyther
  * Copyright (C) 2010 Martin Robinson <mrobinson@webkit.org>
+ * Copyright (C) 2010 Igalia S.L.
  * All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
@@ -49,6 +50,7 @@ public:
     GtkClipboard* getClipboard(Frame*) const;
     GtkClipboard* getPrimarySelectionClipboard(Frame*) const;
     GtkTargetList* targetList() const;
+    GtkTargetList* targetListForDataObject(DataObjectGtk*);
     void fillSelectionData(GtkSelectionData*, guint, DataObjectGtk*);
     void writeClipboardContents(GtkClipboard*, GClosure* closure = 0);
     void getClipboardContents(GtkClipboard*);
@@ -62,7 +64,6 @@ protected:
 
 private:
     GtkTargetList* m_targetList;
-    GtkTargetList* targetListForDataObject(DataObjectGtk*);
 };
 
 }
index a4170d2..448503b 100644 (file)
@@ -1,3 +1,22 @@
+2010-05-06  Martin Robinson  <mrobinson@webkit.org>
+
+        Reviewed by Gustavo Noronha Silva.
+
+        [GTK] Enable DOM clipboard and drag-and-drop access
+        https://bugs.webkit.org/show_bug.cgi?id=30623
+
+        Convert dragging portion of drag-and-drop to use DataObjectGtk.
+
+        * WebCoreSupport/DragClientGtk.cpp:
+        (WebKit::DragClient::willPerformDragDestinationAction): Remove the notImplemented. It is implemented, it's just a no-op.
+        (WebKit::DragClient::startDrag): Start the drag context via the ClipboardGtk and PasteboardHelper now.
+        * WebCoreSupport/DragClientGtk.h: Small style fix.
+        * webkit/webkitprivate.h: Add a HashMap of contexts and DataObjects here to to represent all current drag operations.
+        * webkit/webkitwebview.cpp: 
+        (webkit_web_view_dispose): Clear all data objects during disposal.
+        (webkit_web_view_drag_end): When a drag is over, just remove it from the map.
+        (webkit_web_view_drag_data_get): To get the drag data, just grab it from the DataObject.
+
 2010-05-03  Abhishek Arya  <inferno@chromium.org>
 
         Reviewed by Adam Barth.
index f4b0df1..900fb61 100644 (file)
@@ -1,4 +1,6 @@
 /*
+ * Copyright (C) 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
 #include "config.h"
 #include "DragClientGtk.h"
 
+#include "ClipboardGtk.h"
+#include "DataObjectGtk.h"
 #include "Document.h"
 #include "Element.h"
 #include "Frame.h"
+#include "GRefPtrGtk.h"
 #include "NotImplemented.h"
+#include "PasteboardHelper.h"
 #include "RenderObject.h"
+#include "webkitprivate.h"
 #include "webkitwebview.h"
 
 #include <gtk/gtk.h>
@@ -41,7 +48,6 @@ DragClient::DragClient(WebKitWebView* webView)
 
 void DragClient::willPerformDragDestinationAction(DragDestinationAction, DragData*)
 {
-    notImplemented();
 }
 
 void DragClient::willPerformDragSourceAction(DragSourceAction, const IntPoint& startPos, Clipboard*)
@@ -61,50 +67,29 @@ DragSourceAction DragClient::dragSourceActionMaskForPoint(const IntPoint&)
     return DragSourceActionAny;
 }
 
-void DragClient::startDrag(DragImageRef image, const IntPoint& dragImageOrigin, const IntPoint& eventPos, Clipboard*, Frame* frame, bool linkDrag)
+void DragClient::startDrag(DragImageRef image, const IntPoint& dragImageOrigin, const IntPoint& eventPos, Clipboard* clipboard, Frame* frame, bool linkDrag)
 {
-    Element* targetElement = frame->document()->elementFromPoint(m_startPos.x(), m_startPos.y());
-    bool imageDrag = false;
-
-    if (targetElement)
-        imageDrag = targetElement->renderer()->isImage();
-
-    GdkAtom textHtml = gdk_atom_intern_static_string("text/html");
-    GdkAtom netscapeUrl = gdk_atom_intern_static_string("_NETSCAPE_URL");
-
-    GtkTargetList* targetList = gtk_target_list_new(NULL, 0);
-    gtk_target_list_add(targetList, textHtml, 0, WEBKIT_WEB_VIEW_TARGET_INFO_HTML);
-    gtk_target_list_add_text_targets(targetList, WEBKIT_WEB_VIEW_TARGET_INFO_TEXT);
-
-    if (linkDrag || imageDrag) {
-        gtk_target_list_add(targetList, netscapeUrl, 0, WEBKIT_WEB_VIEW_TARGET_INFO_NETSCAPE_URL);
-        gtk_target_list_add_uri_targets(targetList, WEBKIT_WEB_VIEW_TARGET_INFO_URI_LIST);
-    }
-
-    if (imageDrag)
-        gtk_target_list_add_image_targets(targetList, WEBKIT_WEB_VIEW_TARGET_INFO_IMAGE, false);
+    ClipboardGtk* clipboardGtk = reinterpret_cast<ClipboardGtk*>(clipboard);
 
     GdkDragAction dragAction = GDK_ACTION_COPY;
-    if (linkDrag) {
-        dragAction = GDK_ACTION_LINK;
-        if (imageDrag)
-            dragAction = (GdkDragAction)(dragAction | GDK_ACTION_COPY);
-    }
+    if (linkDrag)
+        dragAction = (GdkDragAction) (dragAction | GDK_ACTION_LINK);
 
+    WebKitWebView* webView = webkit_web_frame_get_web_view(kit(frame));
+    RefPtr<DataObjectGtk> dataObject = clipboardGtk->dataObject();
+
+    GRefPtr<GtkTargetList> targetList(clipboardGtk->helper()->targetListForDataObject(dataObject.get()));
     GdkEvent* event = gdk_event_new(GDK_BUTTON_PRESS);
     reinterpret_cast<GdkEventButton*>(event)->window = gtk_widget_get_window(GTK_WIDGET(m_webView));
     reinterpret_cast<GdkEventButton*>(event)->time = GDK_CURRENT_TIME;
 
-    GdkDragContext* context = gtk_drag_begin(GTK_WIDGET(m_webView),
-                                             targetList, dragAction, 1, event);
-    g_object_ref(context);
+    GdkDragContext* context = gtk_drag_begin(GTK_WIDGET(m_webView), targetList.get(), dragAction, 1, event);
+    webView->priv->draggingDataObjects.set(context, dataObject);
 
     if (image)
         gtk_drag_set_icon_pixbuf(context, image, eventPos.x() - dragImageOrigin.x(), eventPos.y() - dragImageOrigin.y());
     else
         gtk_drag_set_icon_default(context);
-
-    gtk_target_list_unref(targetList);
 }
 
 DragImageRef DragClient::createDragImageForLink(KURL&, const String&, Frame*)
index 97ea72a..6604940 100644 (file)
@@ -51,9 +51,9 @@ namespace WebKit {
 
         virtual void dragControllerDestroyed();
 
-        private:
-            WebKitWebView* m_webView;
-            WebCore::IntPoint m_startPos;
+    private:
+        WebKitWebView* m_webView;
+        WebCore::IntPoint m_startPos;
     };
 }
 
index 2642d50..034eb88 100644 (file)
@@ -2,6 +2,7 @@
  * Copyright (C) 2007, 2008, 2009 Holger Hans Peter Freyther
  * Copyright (C) 2008 Jan Michael C. Alonzo
  * Copyright (C) 2008 Collabora Ltd.
+ * Copyright (C) 2010 Igalia S.L.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -46,6 +47,7 @@
 
 #include "ArchiveResource.h"
 #include "BackForwardList.h"
+#include "DataObjectGtk.h"
 #include <enchant.h>
 #include "GOwnPtr.h"
 #include "Geolocation.h"
@@ -149,6 +151,8 @@ extern "C" {
         char* mainResourceIdentifier;
         GHashTable* subResources;
         char* tooltipText;
+
+        HashMap<GdkDragContext*, RefPtr<WebCore::DataObjectGtk> > draggingDataObjects;
     };
 
     #define WEBKIT_WEB_FRAME_GET_PRIVATE(obj)    (G_TYPE_INSTANCE_GET_PRIVATE((obj), WEBKIT_TYPE_WEB_FRAME, WebKitWebFramePrivate))
index 6536961..10a082c 100644 (file)
@@ -1124,6 +1124,8 @@ static void webkit_web_view_dispose(GObject* object)
         priv->subResources = NULL;
     }
 
+    priv->draggingDataObjects.clear();
+
     G_OBJECT_CLASS(webkit_web_view_parent_class)->dispose(object);
 }
 
@@ -1234,126 +1236,26 @@ static void webkit_web_view_screen_changed(GtkWidget* widget, GdkScreen* previou
 
 static void webkit_web_view_drag_end(GtkWidget* widget, GdkDragContext* context)
 {
-    g_object_unref(context);
-}
-
-struct DNDContentsRequest
-{
-    gint info;
-    GtkSelectionData* dnd_selection_data;
-
-    gboolean is_url_label_request;
-    gchar* url;
-};
-
-void clipboard_contents_received(GtkClipboard* clipboard, GtkSelectionData* selection_data, gpointer data)
-{
-    DNDContentsRequest* contents_request = reinterpret_cast<DNDContentsRequest*>(data);
-
-    if (contents_request->is_url_label_request) {
-        // We have received contents of the label clipboard. Use them to form
-        // required structures. When formed, enhance the dnd's selection data
-        // with them and return.
-
-        // If the label is empty, use the url itself.
-        gchar* url_label = reinterpret_cast<gchar*>(gtk_selection_data_get_text(selection_data));
-        if (!url_label)
-            url_label = g_strdup(contents_request->url);
-
-        gchar* data = 0;
-        switch (contents_request->info) {
-        case WEBKIT_WEB_VIEW_TARGET_INFO_URI_LIST:
-            data = g_strdup_printf("%s\r\n%s\r\n", contents_request->url, url_label);
-            break;
-        case WEBKIT_WEB_VIEW_TARGET_INFO_NETSCAPE_URL:
-            data = g_strdup_printf("%s\n%s", contents_request->url, url_label);
-            break;
-        }
-
-        if (data) {
-            gtk_selection_data_set(contents_request->dnd_selection_data,
-                                   contents_request->dnd_selection_data->target, 8,
-                                   reinterpret_cast<const guchar*>(data), strlen(data));
-            g_free(data);
-        }
-
-        g_free(url_label);
-        g_free(contents_request->url);
-        g_free(contents_request);
+    WebKitWebViewPrivate* priv = WEBKIT_WEB_VIEW_GET_PRIVATE(WEBKIT_WEB_VIEW(widget));
 
+    // 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;
-    }
 
-    switch (contents_request->info) {
-    case WEBKIT_WEB_VIEW_TARGET_INFO_HTML:
-    case WEBKIT_WEB_VIEW_TARGET_INFO_TEXT:
-        {
-        gchar* data = reinterpret_cast<gchar*>(gtk_selection_data_get_text(selection_data));
-        if (data) {
-            gtk_selection_data_set(contents_request->dnd_selection_data,
-                                   contents_request->dnd_selection_data->target, 8,
-                                   reinterpret_cast<const guchar*>(data),
-                                   strlen(data));
-            g_free(data);
-        }
-        break;
-        }
-    case WEBKIT_WEB_VIEW_TARGET_INFO_IMAGE:
-        {
-        GdkPixbuf* pixbuf = gtk_selection_data_get_pixbuf(selection_data);
-        if (pixbuf) {
-            gtk_selection_data_set_pixbuf(contents_request->dnd_selection_data, pixbuf);
-            g_object_unref(pixbuf);
-        }
-        break;
-        }
-    case WEBKIT_WEB_VIEW_TARGET_INFO_URI_LIST:
-    case WEBKIT_WEB_VIEW_TARGET_INFO_NETSCAPE_URL:
-        // URL's label is stored in another clipboard, so we store URL into
-        // contents request, mark the latter as an url label request
-        // and request for contents of the label clipboard.
-        contents_request->is_url_label_request = TRUE;
-        contents_request->url = reinterpret_cast<gchar*>(gtk_selection_data_get_text(selection_data));
-
-        gtk_clipboard_request_contents(gtk_clipboard_get(gdk_atom_intern_static_string("WebKitClipboardUrlLabel")),
-                                       selection_data->target, clipboard_contents_received, contents_request);
-        break;
-    }
+    priv->draggingDataObjects.remove(context);
 }
 
-static void webkit_web_view_drag_data_get(GtkWidget* widget, GdkDragContext* context, GtkSelectionData* selection_data, guint info, guint time_)
-{
-    GdkAtom selection_atom = GDK_NONE;
-    GdkAtom target_atom = selection_data->target;
-
-    switch (info) {
-        case WEBKIT_WEB_VIEW_TARGET_INFO_HTML:
-            selection_atom = gdk_atom_intern_static_string("WebKitClipboardHtml");
-            // HTML markup data is set as text, therefor, we need a text-like target atom
-            target_atom = gdk_atom_intern_static_string("UTF8_STRING");
-            break;
-        case WEBKIT_WEB_VIEW_TARGET_INFO_TEXT:
-            selection_atom = gdk_atom_intern_static_string("WebKitClipboardText");
-            break;
-        case WEBKIT_WEB_VIEW_TARGET_INFO_IMAGE:
-            selection_atom = gdk_atom_intern_static_string("WebKitClipboardImage");
-            break;
-        case WEBKIT_WEB_VIEW_TARGET_INFO_URI_LIST:
-        case WEBKIT_WEB_VIEW_TARGET_INFO_NETSCAPE_URL:
-            selection_atom = gdk_atom_intern_static_string("WebKitClipboardUrl");
-            // We require URL and label, which are both stored in text format
-            // and are needed to be retrieved as such.
-            target_atom = gdk_atom_intern_static_string("UTF8_STRING");
-            break;
-    }
+static void webkit_web_view_drag_data_get(GtkWidget* widget, GdkDragContext* context, GtkSelectionData* selectionData, guint info, guint)
+{
+    WebKitWebViewPrivate* priv = WEBKIT_WEB_VIEW_GET_PRIVATE(WEBKIT_WEB_VIEW(widget));
 
-    DNDContentsRequest* contents_request = g_new(DNDContentsRequest, 1);
-    contents_request->info = info;
-    contents_request->is_url_label_request = FALSE;
-    contents_request->dnd_selection_data = selection_data;
+    // 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;
 
-    gtk_clipboard_request_contents(gtk_clipboard_get(selection_atom), target_atom,
-                                   clipboard_contents_received, contents_request);
+    pasteboardHelperInstance()->fillSelectionData(selectionData, info, priv->draggingDataObjects.get(context).get());
 }
 
 #if GTK_CHECK_VERSION(2, 12, 0)