Changeset 47243 in webkit


Ignore:
Timestamp:
Aug 13, 2009 3:38:12 PM (15 years ago)
Author:
eric@webkit.org
Message:

2009-08-13 Zan Dobersek <zandobersek@gmail.com>

Reviewed by Gustavo Noronha.

[GTK] Drag and drop support
https://bugs.webkit.org/show_bug.cgi?id=23642

Adds support for drag actions in WebKitWebView and DragClient.

Defines a support structure that can hold additional drag and drop data,
such as selection data or target IDs (infos) and can be passed through
clipboard requests.

Implements DragClient functions that gather start position of the drag
and start the GTK drag.

  • WebCoreSupport/DragClientGtk.cpp: (WebKit::DragClient::DragClient): (WebKit::DragClient::willPerformDragSourceAction): (WebKit::DragClient::startDrag): (WebKit::DragClient::createDragImageForLink): A small style fix.
  • WebCoreSupport/DragClientGtk.h:
  • webkit/webkitwebview.cpp: (webkit_web_view_drag_end): (clipboard_contents_received): GtkClipboard callback. (webkit_web_view_drag_data_get): (webkit_web_view_class_init): (webkit_web_view_init):
  • webkit/webkitwebview.h: Add GTK selection targets.
Location:
trunk/WebKit/gtk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebKit/gtk/ChangeLog

    r47149 r47243  
     12009-08-13  Zan Dobersek  <zandobersek@gmail.com>
     2
     3        Reviewed by Gustavo Noronha.
     4
     5        [GTK] Drag and drop support
     6        https://bugs.webkit.org/show_bug.cgi?id=23642
     7
     8        Adds support for drag actions in WebKitWebView and DragClient.
     9
     10        Defines a support structure that can hold additional drag and drop data,
     11        such as selection data or target IDs (infos) and can be passed through
     12        clipboard requests.
     13
     14        Implements DragClient functions that gather start position of the drag
     15        and start the GTK drag.
     16
     17        * WebCoreSupport/DragClientGtk.cpp:
     18        (WebKit::DragClient::DragClient):
     19        (WebKit::DragClient::willPerformDragSourceAction):
     20        (WebKit::DragClient::startDrag):
     21        (WebKit::DragClient::createDragImageForLink): A small style fix.
     22        * WebCoreSupport/DragClientGtk.h:
     23        * webkit/webkitwebview.cpp:
     24        (webkit_web_view_drag_end):
     25        (clipboard_contents_received): GtkClipboard callback.
     26        (webkit_web_view_drag_data_get):
     27        (webkit_web_view_class_init):
     28        (webkit_web_view_init):
     29        * webkit/webkitwebview.h: Add GTK selection targets.
     30
    1312009-08-12  Gustavo Noronha Silva  <gustavo.noronha@collabora.co.uk>
    232
  • trunk/WebKit/gtk/WebCoreSupport/DragClientGtk.cpp

    r29663 r47243  
    1818#include "DragClientGtk.h"
    1919
     20#include "Document.h"
     21#include "Element.h"
     22#include "Frame.h"
    2023#include "NotImplemented.h"
     24#include "RenderObject.h"
     25#include "webkitwebview.h"
     26
     27#include <gtk/gtk.h>
    2128
    2229using namespace WebCore;
    2330
    2431namespace WebKit {
     32
     33DragClient::DragClient(WebKitWebView* webView)
     34    : m_webView(webView)
     35    , m_startPos(0, 0)
     36{
     37}
    2538
    2639void DragClient::willPerformDragDestinationAction(DragDestinationAction, DragData*)
     
    2942}
    3043
    31 void DragClient::willPerformDragSourceAction(DragSourceAction, const IntPoint&, Clipboard*)
     44void DragClient::willPerformDragSourceAction(DragSourceAction, const IntPoint& startPos, Clipboard*)
    3245{
    33     notImplemented();
     46    m_startPos = startPos;
    3447}
    3548
     
    4659}
    4760
    48 void DragClient::startDrag(DragImageRef, const IntPoint&, const IntPoint&, Clipboard*, Frame*, bool)
     61void DragClient::startDrag(DragImageRef image, const IntPoint& dragImageOrigin, const IntPoint& eventPos, Clipboard*, Frame* frame, bool linkDrag)
    4962{
    50     notImplemented();
     63    Element* targetElement = frame->document()->elementFromPoint(m_startPos.x(), m_startPos.y());
     64    bool imageDrag = false;
     65
     66    if (targetElement)
     67        imageDrag = targetElement->renderer()->isImage();
     68
     69    GdkAtom textHtml = gdk_atom_intern_static_string("text/html");
     70    GdkAtom netscapeUrl = gdk_atom_intern_static_string("_NETSCAPE_URL");
     71
     72    GtkTargetList* targetList = gtk_target_list_new(NULL, 0);
     73    gtk_target_list_add(targetList, textHtml, 0, WEBKIT_WEB_VIEW_TARGET_INFO_HTML);
     74    gtk_target_list_add_text_targets(targetList, WEBKIT_WEB_VIEW_TARGET_INFO_TEXT);
     75
     76    if (linkDrag || imageDrag) {
     77        gtk_target_list_add(targetList, netscapeUrl, 0, WEBKIT_WEB_VIEW_TARGET_INFO_NETSCAPE_URL);
     78        gtk_target_list_add_uri_targets(targetList, WEBKIT_WEB_VIEW_TARGET_INFO_URI_LIST);
     79    }
     80
     81    if (imageDrag)
     82        gtk_target_list_add_image_targets(targetList, WEBKIT_WEB_VIEW_TARGET_INFO_IMAGE, false);
     83
     84    GdkDragAction dragAction = GDK_ACTION_COPY;
     85    if (linkDrag) {
     86        dragAction = GDK_ACTION_LINK;
     87        if (imageDrag)
     88            dragAction = (GdkDragAction)(dragAction | GDK_ACTION_COPY);
     89    }
     90
     91    GdkEvent* event = gdk_event_new(GDK_BUTTON_PRESS);
     92    reinterpret_cast<GdkEventButton*>(event)->window = gtk_widget_get_window(GTK_WIDGET(m_webView));
     93    reinterpret_cast<GdkEventButton*>(event)->time = GDK_CURRENT_TIME;
     94
     95    GdkDragContext* context = gtk_drag_begin(GTK_WIDGET(m_webView),
     96                                             targetList, dragAction, 1, event);
     97    g_object_ref(context);
     98
     99    if (image)
     100        gtk_drag_set_icon_pixbuf(context, image, eventPos.x() - dragImageOrigin.x(), eventPos.y() - dragImageOrigin.y());
     101    else
     102        gtk_drag_set_icon_default(context);
     103
     104    gtk_target_list_unref(targetList);
    51105}
    52106
    53 DragImageRef DragClient::createDragImageForLink(KURL&, const String& label, Frame*)
     107DragImageRef DragClient::createDragImageForLink(KURL&, const String&, Frame*)
    54108{
    55109    notImplemented();
  • trunk/WebKit/gtk/WebCoreSupport/DragClientGtk.h

    r29961 r47243  
    3333#include "DragClient.h"
    3434
     35typedef struct _WebKitWebView WebKitWebView;
     36
    3537namespace WebKit {
     38
    3639    class DragClient : public WebCore::DragClient {
    3740    public:
     41        DragClient(WebKitWebView*);
     42
    3843        virtual void willPerformDragDestinationAction(WebCore::DragDestinationAction, WebCore::DragData*);
    3944        virtual void willPerformDragSourceAction(WebCore::DragSourceAction, const WebCore::IntPoint&, WebCore::Clipboard*);
     
    4651
    4752        virtual void dragControllerDestroyed();
     53
     54        private:
     55            WebKitWebView* m_webView;
     56            WebCore::IntPoint m_startPos;
    4857    };
    4958}
  • trunk/WebKit/gtk/webkit/webkitwebview.cpp

    r46537 r47243  
    10821082}
    10831083
     1084static void webkit_web_view_drag_end(GtkWidget* widget, GdkDragContext* context)
     1085{
     1086    g_object_unref(context);
     1087}
     1088
     1089struct DNDContentsRequest
     1090{
     1091    gint info;
     1092    GtkSelectionData* dnd_selection_data;
     1093
     1094    gboolean is_url_label_request;
     1095    gchar* url;
     1096};
     1097
     1098void clipboard_contents_received(GtkClipboard* clipboard, GtkSelectionData* selection_data, gpointer data)
     1099{
     1100    DNDContentsRequest* contents_request = reinterpret_cast<DNDContentsRequest*>(data);
     1101
     1102    if (contents_request->is_url_label_request) {
     1103        // We have received contents of the label clipboard. Use them to form
     1104        // required structures. When formed, enhance the dnd's selection data
     1105        // with them and return.
     1106
     1107        // If the label is empty, use the url itself.
     1108        gchar* url_label = reinterpret_cast<gchar*>(gtk_selection_data_get_text(selection_data));
     1109        if (!url_label)
     1110            url_label = g_strdup(contents_request->url);
     1111
     1112        gchar* data;
     1113        switch (contents_request->info) {
     1114        case WEBKIT_WEB_VIEW_TARGET_INFO_URI_LIST:
     1115            data = g_strdup_printf("%s\r\n%s\r\n", contents_request->url, url_label);
     1116            break;
     1117        case WEBKIT_WEB_VIEW_TARGET_INFO_NETSCAPE_URL:
     1118            data = g_strdup_printf("%s\n%s", contents_request->url, url_label);
     1119            break;
     1120        }
     1121
     1122        gtk_selection_data_set(contents_request->dnd_selection_data,
     1123                               contents_request->dnd_selection_data->target, 8,
     1124                               reinterpret_cast<const guchar*>(data), strlen(data));
     1125
     1126        g_free(url_label);
     1127        g_free(data);
     1128        g_free(contents_request->url);
     1129        g_free(contents_request);
     1130
     1131        return;
     1132    }
     1133
     1134    switch (contents_request->info) {
     1135    case WEBKIT_WEB_VIEW_TARGET_INFO_HTML:
     1136    case WEBKIT_WEB_VIEW_TARGET_INFO_TEXT:
     1137        {
     1138        gchar* data = reinterpret_cast<gchar*>(gtk_selection_data_get_text(selection_data));
     1139        if (data) {
     1140            gtk_selection_data_set(contents_request->dnd_selection_data,
     1141                                   contents_request->dnd_selection_data->target, 8,
     1142                                   reinterpret_cast<const guchar*>(data),
     1143                                   strlen(data));
     1144            g_free(data);
     1145        }
     1146        break;
     1147        }
     1148    case WEBKIT_WEB_VIEW_TARGET_INFO_IMAGE:
     1149        {
     1150        GdkPixbuf* pixbuf = gtk_selection_data_get_pixbuf(selection_data);
     1151        if (pixbuf) {
     1152            gtk_selection_data_set_pixbuf(contents_request->dnd_selection_data, pixbuf);
     1153            g_object_unref(pixbuf);
     1154        }
     1155        break;
     1156        }
     1157    case WEBKIT_WEB_VIEW_TARGET_INFO_URI_LIST:
     1158    case WEBKIT_WEB_VIEW_TARGET_INFO_NETSCAPE_URL:
     1159        // URL's label is stored in another clipboard, so we store URL into
     1160        // contents request, mark the latter as an url label request
     1161        // and request for contents of the label clipboard.
     1162        contents_request->is_url_label_request = TRUE;
     1163        contents_request->url = reinterpret_cast<gchar*>(gtk_selection_data_get_text(selection_data));
     1164
     1165        gtk_clipboard_request_contents(gtk_clipboard_get(gdk_atom_intern_static_string("WebKitClipboardUrlLabel")),
     1166                                       selection_data->target, clipboard_contents_received, contents_request);
     1167        break;
     1168    }
     1169}
     1170
     1171static void webkit_web_view_drag_data_get(GtkWidget* widget, GdkDragContext* context, GtkSelectionData* selection_data, guint info, guint time_)
     1172{
     1173    GdkAtom selection_atom;
     1174    GdkAtom target_atom = selection_data->target;
     1175
     1176    switch (info) {
     1177        case WEBKIT_WEB_VIEW_TARGET_INFO_HTML:
     1178            selection_atom = gdk_atom_intern_static_string("WebKitClipboardHtml");
     1179            // HTML markup data is set as text, therefor, we need a text-like target atom
     1180            target_atom = gdk_atom_intern_static_string("UTF8_STRING");
     1181            break;
     1182        case WEBKIT_WEB_VIEW_TARGET_INFO_TEXT:
     1183            selection_atom = gdk_atom_intern_static_string("WebKitClipboardText");
     1184            break;
     1185        case WEBKIT_WEB_VIEW_TARGET_INFO_IMAGE:
     1186            selection_atom = gdk_atom_intern_static_string("WebKitClipboardImage");
     1187            break;
     1188        case WEBKIT_WEB_VIEW_TARGET_INFO_URI_LIST:
     1189        case WEBKIT_WEB_VIEW_TARGET_INFO_NETSCAPE_URL:
     1190            selection_atom = gdk_atom_intern_static_string("WebKitClipboardUrl");
     1191            // We require URL and label, which are both stored in text format
     1192            // and are needed to be retrieved as such.
     1193            target_atom = gdk_atom_intern_static_string("UTF8_STRING");
     1194            break;
     1195    }
     1196
     1197    DNDContentsRequest* contents_request = g_new(DNDContentsRequest, 1);
     1198    contents_request->info = info;
     1199    contents_request->is_url_label_request = FALSE;
     1200    contents_request->dnd_selection_data = selection_data;
     1201
     1202    gtk_clipboard_request_contents(gtk_clipboard_get(selection_atom), target_atom,
     1203                                   clipboard_contents_received, contents_request);
     1204}
     1205
    10841206static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass)
    10851207{
     
    18171939    widgetClass->get_accessible = webkit_web_view_get_accessible;
    18181940    widgetClass->screen_changed = webkit_web_view_screen_changed;
     1941    widgetClass->drag_end = webkit_web_view_drag_end;
     1942    widgetClass->drag_data_get = webkit_web_view_drag_data_get;
    18191943
    18201944    GtkContainerClass* containerClass = GTK_CONTAINER_CLASS(webViewClass);
     
    22572381
    22582382    WebKit::InspectorClient* inspectorClient = new WebKit::InspectorClient(webView);
    2259     priv->corePage = new Page(new WebKit::ChromeClient(webView), new WebKit::ContextMenuClient(webView), new WebKit::EditorClient(webView), new WebKit::DragClient, inspectorClient);
     2383    priv->corePage = new Page(new WebKit::ChromeClient(webView), new WebKit::ContextMenuClient(webView), new WebKit::EditorClient(webView), new WebKit::DragClient(webView), inspectorClient);
    22602384
    22612385    // We also add a simple wrapper class to provide the public
  • trunk/WebKit/gtk/webkit/webkitwebview.h

    r45801 r47243  
    5353{
    5454    WEBKIT_WEB_VIEW_TARGET_INFO_HTML,
    55     WEBKIT_WEB_VIEW_TARGET_INFO_TEXT
     55    WEBKIT_WEB_VIEW_TARGET_INFO_TEXT,
     56    WEBKIT_WEB_VIEW_TARGET_INFO_IMAGE,
     57    WEBKIT_WEB_VIEW_TARGET_INFO_URI_LIST,
     58    WEBKIT_WEB_VIEW_TARGET_INFO_NETSCAPE_URL
    5659} WebKitWebViewTargetInfo;
    5760
Note: See TracChangeset for help on using the changeset viewer.