Changeset 76824 in webkit


Ignore:
Timestamp:
Jan 27, 2011 11:51:14 AM (13 years ago)
Author:
enrica@apple.com
Message:

Source/WebCore: WebKit2: add support for drag and drop on Windows
https://bugs.webkit.org/show_bug.cgi?id=52775
<rdar://problem/8514409>

Reviewed by Darin Adler and Adam Roben.

On Windows the access to the content being dragged is
provided via the IDataObject interface that is made available
to the window that registers itself as drop target.
Since this interface cannot be accessed from the WebProcess,
in every call to one of the methods of the IDropTarget interface
we serialize the content of the drag clipboard and send it over to
the WebProcess.
The bulk of this patch consists in the refactoring needed in DragData
and ClipboardWin classes to extract the data from the serialized object.

  • platform/DragData.cpp:
  • platform/DragData.h:
  • platform/win/ClipboardUtilitiesWin.cpp:

(WebCore::getWebLocData):
(WebCore::getURL):
(WebCore::getPlainText):
(WebCore::getTextHTML):
(WebCore::getCFHTML):
(WebCore::fragmentFromFilenames):
(WebCore::containsFilenames):
(WebCore::fragmentFromHTML):
(WebCore::containsHTML):
(WebCore::getClipboardData):

  • platform/win/ClipboardUtilitiesWin.h:
  • platform/win/ClipboardWin.cpp:

(WebCore::Clipboard::create):
(WebCore::ClipboardWin::ClipboardWin):
(WebCore::ClipboardWin::getData):
(WebCore::ClipboardWin::types):
(WebCore::ClipboardWin::files):
(WebCore::ClipboardWin::hasData):

  • platform/win/ClipboardWin.h:

(WebCore::ClipboardWin::create):

  • platform/win/DragDataWin.cpp:

(WebCore::DragData::DragData):
(WebCore::DragData::containsURL):
(WebCore::DragData::dragDataMap):
(WebCore::DragData::asURL):
(WebCore::DragData::containsFiles):
(WebCore::DragData::asFilenames):
(WebCore::DragData::containsPlainText):
(WebCore::DragData::asPlainText):
(WebCore::DragData::canSmartReplace):
(WebCore::DragData::containsCompatibleContent):
(WebCore::DragData::asFragment):

Source/WebKit2: WebKit2: add support for drag and drop on Windows
https://bugs.webkit.org/show_bug.cgi?id=52775
<rdar://problem/8514409>

Reviewed by Darin Adler and Adam Roben.

On Windows the access to the content being dragged is
provided via the IDataObject interface that is made available
to the window that registers itself as drop target.
Since this interface cannot be accessed from the WebProcess,
in every call to one of the methods of the IDropTarget interface
we serialize the content of the drag clipboard and send it over to
the WebProcess. The implementation uses the same messages as the
Mac one, with slightly different parameters to pass the serialized
clipboard.

  • UIProcess/WebPageProxy.cpp:

(WebKit::WebPageProxy::performDragControllerAction): Added Windows
specific implementation.

  • UIProcess/WebPageProxy.h:
  • UIProcess/win/WebView.cpp:

(WebKit::WebView::WebView): Added dropTargetHelper object creation.
(WebKit::WebView::initialize): Added to register for drag/drop with out
refcount issues.
(WebKit::WebView::close):
(WebKit::WebView::windowReceivedMessage):
(WebKit::WebView::QueryInterface):
(WebKit::WebView::AddRef):
(WebKit::WebView::Release):
(WebKit::dragOperationToDragCursor):
(WebKit::WebView::keyStateToDragOperation):
(WebKit::WebView::DragEnter):
(WebKit::WebView::DragOver):
(WebKit::WebView::DragLeave):
(WebKit::WebView::Drop):

  • UIProcess/win/WebView.h:

(WebKit::WebView::create):

  • WebProcess/WebPage/WebPage.cpp:

(WebKit::WebPage::performDragControllerAction):

  • WebProcess/WebPage/WebPage.h:
  • WebProcess/WebPage/WebPage.messages.in:
Location:
trunk/Source
Files:
15 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r76822 r76824  
     12011-01-26  Enrica Casucci  <enrica@apple.com>
     2
     3        Reviewed by Darin Adler and Adam Roben.
     4
     5        WebKit2: add support for drag and drop on Windows
     6        https://bugs.webkit.org/show_bug.cgi?id=52775
     7        <rdar://problem/8514409>
     8       
     9        On Windows the access to the content being dragged is
     10        provided via the IDataObject interface that is made available
     11        to the window that registers itself as drop target.
     12        Since this interface cannot be accessed from the WebProcess,
     13        in every call to one of the methods of the IDropTarget interface
     14        we serialize the content of the drag clipboard and send it over to
     15        the WebProcess.
     16        The bulk of this patch consists in the refactoring needed in DragData
     17        and ClipboardWin classes to extract the data from the serialized object.
     18       
     19        * platform/DragData.cpp:
     20        * platform/DragData.h:
     21        * platform/win/ClipboardUtilitiesWin.cpp:
     22        (WebCore::getWebLocData):
     23        (WebCore::getURL):
     24        (WebCore::getPlainText):
     25        (WebCore::getTextHTML):
     26        (WebCore::getCFHTML):
     27        (WebCore::fragmentFromFilenames):
     28        (WebCore::containsFilenames):
     29        (WebCore::fragmentFromHTML):
     30        (WebCore::containsHTML):
     31        (WebCore::getClipboardData):
     32        * platform/win/ClipboardUtilitiesWin.h:
     33        * platform/win/ClipboardWin.cpp:
     34        (WebCore::Clipboard::create):
     35        (WebCore::ClipboardWin::ClipboardWin):
     36        (WebCore::ClipboardWin::getData):
     37        (WebCore::ClipboardWin::types):
     38        (WebCore::ClipboardWin::files):
     39        (WebCore::ClipboardWin::hasData):
     40        * platform/win/ClipboardWin.h:
     41        (WebCore::ClipboardWin::create):
     42        * platform/win/DragDataWin.cpp:
     43        (WebCore::DragData::DragData):
     44        (WebCore::DragData::containsURL):
     45        (WebCore::DragData::dragDataMap):
     46        (WebCore::DragData::asURL):
     47        (WebCore::DragData::containsFiles):
     48        (WebCore::DragData::asFilenames):
     49        (WebCore::DragData::containsPlainText):
     50        (WebCore::DragData::asPlainText):
     51        (WebCore::DragData::canSmartReplace):
     52        (WebCore::DragData::containsCompatibleContent):
     53        (WebCore::DragData::asFragment):
     54
    1552011-01-27  Mario Sanchez Prada  <msanchez@igalia.com>
    256
  • trunk/Source/WebCore/platform/DragData.h

    r75743 r76824  
    3232
    3333#include <wtf/Forward.h>
     34#include <wtf/HashMap.h>
    3435#include <wtf/Vector.h>
    3536
     
    5253#elif PLATFORM(WIN)
    5354typedef struct IDataObject* DragDataRef;
     55#include <wtf/text/WTFString.h>
    5456#elif PLATFORM(WX)
    5557typedef class wxDataObject* DragDataRef;
     
    8385    DragApplicationIsCopyKeyDown = 8
    8486};
    85    
     87
     88#if PLATFORM(WIN)
     89typedef HashMap<UINT, Vector<String> > DragDataMap;
     90#endif
     91
    8692class DragData {
    8793public:
     
    9197    DragData(DragDataRef, const IntPoint& clientPosition, const IntPoint& globalPosition, DragOperation, DragApplicationFlags = DragApplicationNone);
    9298    DragData(const String& dragStorageName, const IntPoint& clientPosition, const IntPoint& globalPosition, DragOperation, DragApplicationFlags = DragApplicationNone);
    93 
     99#if PLATFORM(WIN)
     100    DragData(const DragDataMap&, const IntPoint& clientPosition, const IntPoint& globalPosition, DragOperation sourceOperationMask, DragApplicationFlags = DragApplicationNone);
     101    const DragDataMap& dragDataMap();
     102#endif
    94103    const IntPoint& clientPosition() const { return m_clientPosition; }
    95104    const IntPoint& globalPosition() const { return m_globalPosition; }
     
    118127    RetainPtr<NSPasteboard> m_pasteboard;
    119128#endif
     129#if PLATFORM(WIN)
     130    DragDataMap m_dragDataMap;
     131#endif
    120132};
    121133   
  • trunk/Source/WebCore/platform/win/ClipboardUtilitiesWin.cpp

    r71401 r76824  
    7171#endif
    7272
     73static bool getDataMapItem(const DragDataMap* dataObject, FORMATETC* format, String& item)
     74{
     75    DragDataMap::const_iterator found = dataObject->find(format->cfFormat);
     76    if (found == dataObject->end())
     77        return false;
     78    item = found->second[0];
     79    return true;
     80}
     81
    7382static bool getWebLocData(IDataObject* dataObject, String& url, String* title)
    7483{
     
    110119#endif
    111120    return succeeded;
     121}
     122
     123static bool getWebLocData(const DragDataMap* dataObject, String& url, String* title)
     124{
     125#if PLATFORM(CF)
     126    WCHAR filename[MAX_PATH];
     127    WCHAR urlBuffer[INTERNET_MAX_URL_LENGTH];
     128
     129    if (!dataObject->contains(cfHDropFormat()->cfFormat))
     130        return false;
     131
     132    wcscpy(filename, dataObject->get(cfHDropFormat()->cfFormat)[0].characters());
     133    if (_wcsicmp(PathFindExtensionW(filename), L".url"))
     134        return false;   
     135
     136    if (!GetPrivateProfileStringW(L"InternetShortcut", L"url", 0, urlBuffer, WTF_ARRAY_LENGTH(urlBuffer), filename))
     137        return false;
     138
     139    if (title) {
     140        PathRemoveExtension(filename);
     141        *title = filename;
     142    }
     143   
     144    url = urlBuffer;
     145    return true;
     146#else
     147    return false;
     148#endif
    112149}
    113150
     
    387424}
    388425
     426String getURL(const DragDataMap* data, DragData::FilenameConversionPolicy filenamePolicy, String* title)
     427{
     428    String url;
     429
     430    if (getWebLocData(data, url, title))
     431        return url;
     432    if (getDataMapItem(data, urlWFormat(), url))
     433        return extractURL(url, title);
     434    if (getDataMapItem(data, urlFormat(), url))
     435        return extractURL(url, title);
     436#if PLATFORM(CF)
     437    if (filenamePolicy != DragData::ConvertFilenames)
     438        return url;
     439
     440    String stringData;
     441    if (!getDataMapItem(data, filenameWFormat(), stringData))
     442        getDataMapItem(data, filenameFormat(), stringData);
     443
     444    if (stringData.isEmpty() || (!PathFileExists(stringData.charactersWithNullTermination()) && !PathIsUNC(stringData.charactersWithNullTermination())))
     445        return url;
     446    RetainPtr<CFStringRef> pathAsCFString(AdoptCF, CFStringCreateWithCharacters(kCFAllocatorDefault, (const UniChar *)stringData.charactersWithNullTermination(), stringData.length()));
     447    if (urlFromPath(pathAsCFString.get(), url) && title)
     448        *title = url;
     449#endif
     450    return url;
     451}
     452
    389453String getPlainText(IDataObject* dataObject, bool& success)
    390454{
     
    416480}
    417481
     482String getPlainText(const DragDataMap* data)
     483{
     484    String text;
     485   
     486    if (getDataMapItem(data, plainTextWFormat(), text))
     487        return text;
     488    if (getDataMapItem(data, plainTextFormat(), text))
     489        return text;
     490    return getURL(data, DragData::DoNotConvertFilenames);
     491}
     492
    418493String getTextHTML(IDataObject* data, bool& success)
    419494{
     
    431506}
    432507
     508String getTextHTML(const DragDataMap* data)
     509{
     510    String text;
     511    getDataMapItem(data, texthtmlFormat(), text);
     512    return text;
     513}
     514
    433515String getCFHTML(IDataObject* data, bool& success)
    434516{
     
    439521}
    440522
     523String getCFHTML(const DragDataMap* dataMap)
     524{
     525    String cfhtml;
     526    getDataMapItem(dataMap, htmlFormat(), cfhtml);
     527    return extractMarkupFromCFHTML(cfhtml);
     528}
     529
    441530PassRefPtr<DocumentFragment> fragmentFromFilenames(Document*, const IDataObject*)
    442531{
     
    445534}
    446535
     536PassRefPtr<DocumentFragment> fragmentFromFilenames(Document*, const DragDataMap*)
     537{
     538    // FIXME: We should be able to create fragments from files
     539    return 0;
     540}
     541
    447542bool containsFilenames(const IDataObject*)
     543{
     544    // FIXME: We'll want to update this once we can produce fragments from files
     545    return false;
     546}
     547
     548bool containsFilenames(const DragDataMap*)
    448549{
    449550    // FIXME: We'll want to update this once we can produce fragments from files
     
    478579    String cfhtml = getFullCFHTML(data, success);
    479580    if (success) {
    480         if (PassRefPtr<DocumentFragment> fragment = fragmentFromCFHTML(doc, cfhtml))
    481             return fragment;
     581        if (RefPtr<DocumentFragment> fragment = fragmentFromCFHTML(doc, cfhtml))
     582            return fragment.release();
    482583    }
    483584
     
    490591}
    491592
     593PassRefPtr<DocumentFragment> fragmentFromHTML(Document* document, const DragDataMap* data)
     594{
     595    if (!document || !data || data->isEmpty())
     596        return 0;
     597
     598    String stringData;
     599    if (getDataMapItem(data, htmlFormat(), stringData)) {
     600        if (RefPtr<DocumentFragment> fragment = fragmentFromCFHTML(document, stringData))
     601            return fragment.release();
     602    }
     603
     604    String srcURL;
     605    if (getDataMapItem(data, texthtmlFormat(), stringData))
     606        return createFragmentFromMarkup(document, stringData, srcURL, FragmentScriptingNotAllowed);
     607
     608    return 0;
     609}
     610
    492611bool containsHTML(IDataObject* data)
    493612{
     
    495614}
    496615
     616bool containsHTML(const DragDataMap* data)
     617{
     618    return data->contains(texthtmlFormat()->cfFormat) || data->contains(htmlFormat()->cfFormat);
     619}
     620
     621typedef void (*GetStringFunction)(IDataObject*, FORMATETC*, Vector<String>&);
     622typedef HashMap<UINT, GetStringFunction> ClipboardFormatMap;
     623
     624template<typename T> void getStringData(IDataObject* data, FORMATETC* format, Vector<String>& dataStrings)
     625{
     626    STGMEDIUM store;
     627    if (FAILED(data->GetData(format, &store)))
     628        return;
     629    dataStrings.append(String(static_cast<T*>(GlobalLock(store.hGlobal)), ::GlobalSize(store.hGlobal) / sizeof(T)));
     630    GlobalUnlock(store.hGlobal);
     631    ReleaseStgMedium(&store);
     632}
     633
     634void getUtf8Data(IDataObject* data, FORMATETC* format, Vector<String>& dataStrings)
     635{
     636    STGMEDIUM store;
     637    if (FAILED(data->GetData(format, &store)))
     638        return;
     639    dataStrings.append(String(UTF8Encoding().decode(static_cast<char*>(GlobalLock(store.hGlobal)), GlobalSize(store.hGlobal))));
     640    GlobalUnlock(store.hGlobal);
     641    ReleaseStgMedium(&store);
     642}
     643
     644#if PLATFORM(CF)
     645void getCfData(IDataObject* data, FORMATETC* format, Vector<String>& dataStrings)
     646{
     647    STGMEDIUM store;
     648    if (FAILED(data->GetData(format, &store)))
     649        return;
     650
     651    HDROP hdrop = reinterpret_cast<HDROP>(GlobalLock(store.hGlobal));
     652    if (!hdrop)
     653        return;
     654
     655    WCHAR filename[MAX_PATH];
     656    UINT fileCount = DragQueryFileW(hdrop, 0xFFFFFFFF, 0, 0);
     657    for (UINT i = 0; i < fileCount; i++) {
     658        if (!DragQueryFileW(hdrop, i, filename, WTF_ARRAY_LENGTH(filename)))
     659            continue;
     660        dataStrings.append(static_cast<UChar*>(filename));
     661    }
     662
     663    GlobalUnlock(store.hGlobal);
     664    ReleaseStgMedium(&store);
     665}
     666#endif
     667
     668void getClipboardData(IDataObject *dataObject, FORMATETC* format, Vector<String>& dataStrings)
     669{
     670    static ClipboardFormatMap formatMap;
     671    if (formatMap.isEmpty()) {
     672        formatMap.add(htmlFormat()->cfFormat, getUtf8Data);
     673        formatMap.add(texthtmlFormat()->cfFormat, getStringData<UChar>);
     674        formatMap.add(plainTextFormat()->cfFormat, getStringData<char>);
     675        formatMap.add(plainTextWFormat()->cfFormat, getStringData<UChar>);
     676#if PLATFORM(CF)
     677        formatMap.add(cfHDropFormat()->cfFormat, getCfData);
     678#endif
     679        formatMap.add(filenameFormat()->cfFormat, getStringData<char>);
     680        formatMap.add(filenameWFormat()->cfFormat, getStringData<UChar>);
     681        formatMap.add(urlFormat()->cfFormat, getStringData<char>);
     682        formatMap.add(urlWFormat()->cfFormat, getStringData<UChar>);
     683    }
     684    ClipboardFormatMap::iterator found = formatMap.find(format->cfFormat);
     685    if (found == formatMap.end())
     686        return;
     687    found->second(dataObject, format, dataStrings);
     688}
     689
    497690} // namespace WebCore
  • trunk/Source/WebCore/platform/win/ClipboardUtilitiesWin.h

    r65021 r76824  
    5656
    5757bool containsFilenames(const IDataObject*);
     58bool containsFilenames(const DragDataMap*);
    5859bool containsHTML(IDataObject*);
     60bool containsHTML(const DragDataMap*);
    5961
    6062PassRefPtr<DocumentFragment> fragmentFromFilenames(Document*, const IDataObject*);
     63PassRefPtr<DocumentFragment> fragmentFromFilenames(Document*, const DragDataMap*);
    6164PassRefPtr<DocumentFragment> fragmentFromHTML(Document*, IDataObject*);
     65PassRefPtr<DocumentFragment> fragmentFromHTML(Document*, const DragDataMap*);
    6266PassRefPtr<DocumentFragment> fragmentFromCFHTML(Document*, const String& cfhtml);
    6367
    6468String getURL(IDataObject*, DragData::FilenameConversionPolicy, bool& success, String* title = 0);
     69String getURL(const DragDataMap*, DragData::FilenameConversionPolicy, String* title = 0);
    6570String getPlainText(IDataObject*, bool& success);
     71String getPlainText(const DragDataMap*);
    6672String getTextHTML(IDataObject*, bool& success);
     73String getTextHTML(const DragDataMap*);
    6774String getCFHTML(IDataObject*, bool& success);
     75String getCFHTML(const DragDataMap*);
     76
     77void getClipboardData(IDataObject*, FORMATETC* fetc, Vector<String>& dataStrings);
    6878
    6979} // namespace WebCore
  • trunk/Source/WebCore/platform/win/ClipboardWin.cpp

    r71401 r76824  
    341341PassRefPtr<Clipboard> Clipboard::create(ClipboardAccessPolicy policy, DragData* dragData, Frame* frame)
    342342{
    343     return ClipboardWin::create(DragAndDrop, dragData->platformData(), policy, frame);
     343    if (dragData->platformData())
     344        return ClipboardWin::create(DragAndDrop, dragData->platformData(), policy, frame);
     345    return ClipboardWin::create(DragAndDrop, dragData->dragDataMap(), policy, frame);
    344346}
    345347
     
    357359    , m_writableDataObject(dataObject)
    358360    , m_frame(frame)
     361{
     362}
     363
     364ClipboardWin::ClipboardWin(ClipboardType clipboardType, const DragDataMap& dataMap, ClipboardAccessPolicy policy, Frame* frame)
     365    : Clipboard(policy, clipboardType)
     366    , m_dataObject(0)
     367    , m_writableDataObject(0)
     368    , m_frame(frame)
     369    , m_dragDataMap(dataMap)
    359370{
    360371}
     
    443454{     
    444455    success = false;
    445     if (policy() != ClipboardReadable || !m_dataObject)
     456    if (policy() != ClipboardReadable || !m_dataObject || m_dragDataMap.isEmpty())
    446457        return "";
    447458
    448459    ClipboardDataType dataType = clipboardTypeFromMIMEType(type);
    449460    if (dataType == ClipboardDataTypeText)
    450         return getPlainText(m_dataObject.get(), success);
     461        return m_dataObject ? getPlainText(m_dataObject.get(), success) : getPlainText(&m_dragDataMap);
    451462    if (dataType == ClipboardDataTypeURL)
    452         return getURL(m_dataObject.get(), DragData::DoNotConvertFilenames, success);
     463        return m_dataObject ? getURL(m_dataObject.get(), DragData::DoNotConvertFilenames, success) : getURL(&m_dragDataMap, DragData::DoNotConvertFilenames);
    453464    else if (dataType == ClipboardDataTypeTextHTML) {
    454         String data = getTextHTML(m_dataObject.get(), success);
     465        String data = m_dataObject ? getTextHTML(m_dataObject.get(), success) : getTextHTML(&m_dragDataMap);
    455466        if (success)
    456467            return data;
    457         return getCFHTML(m_dataObject.get(), success);
     468        return m_dataObject ? getCFHTML(m_dataObject.get(), success) : getCFHTML(&m_dragDataMap);
    458469    }
    459470   
     
    511522        return results;
    512523
    513     if (!m_dataObject)
     524    if (!m_dataObject || m_dragDataMap.isEmpty())
    514525        return results;
    515526
    516     COMPtr<IEnumFORMATETC> itr;
    517 
    518     if (FAILED(m_dataObject->EnumFormatEtc(DATADIR_GET, &itr)))
    519         return results;
    520 
    521     if (!itr)
    522         return results;
    523 
    524     FORMATETC data;
    525 
    526     // IEnumFORMATETC::Next returns S_FALSE if there are no more items.
    527     while (itr->Next(1, &data, 0) == S_OK)
    528         addMimeTypesForFormat(results, data);
     527    if (m_dataObject) {
     528        COMPtr<IEnumFORMATETC> itr;
     529
     530        if (FAILED(m_dataObject->EnumFormatEtc(DATADIR_GET, &itr)))
     531            return results;
     532
     533        if (!itr)
     534            return results;
     535
     536        FORMATETC data;
     537
     538        // IEnumFORMATETC::Next returns S_FALSE if there are no more items.
     539        while (itr->Next(1, &data, 0) == S_OK)
     540            addMimeTypesForFormat(results, data);
     541    } else {
     542        for (DragDataMap::const_iterator it = m_dragDataMap.begin(); it != m_dragDataMap.end(); ++it) {
     543            FORMATETC data;
     544            data.cfFormat = (*it).first;
     545            addMimeTypesForFormat(results, data);
     546        }
     547    }
    529548
    530549    return results;
     
    541560        return files.release();
    542561
    543     if (!m_dataObject)
     562    if (!m_dataObject || m_dragDataMap.isEmpty())
    544563        return files.release();
    545564
    546     STGMEDIUM medium;
    547     if (FAILED(m_dataObject->GetData(cfHDropFormat(), &medium)))
     565    if (m_dataObject) {
     566        STGMEDIUM medium;
     567        if (FAILED(m_dataObject->GetData(cfHDropFormat(), &medium)))
     568            return files.release();
     569
     570        HDROP hdrop = reinterpret_cast<HDROP>(GlobalLock(medium.hGlobal));
     571        if (!hdrop)
     572            return files.release();
     573
     574        WCHAR filename[MAX_PATH];
     575        UINT fileCount = DragQueryFileW(hdrop, 0xFFFFFFFF, 0, 0);
     576        for (UINT i = 0; i < fileCount; i++) {
     577            if (!DragQueryFileW(hdrop, i, filename, WTF_ARRAY_LENGTH(filename)))
     578                continue;
     579            files->append(File::create(reinterpret_cast<UChar*>(filename)));
     580        }
     581
     582        GlobalUnlock(medium.hGlobal);
     583        ReleaseStgMedium(&medium);
    548584        return files.release();
    549 
    550     HDROP hdrop = reinterpret_cast<HDROP>(GlobalLock(medium.hGlobal));
    551     if (!hdrop)
     585    }
     586    if (!m_dragDataMap.contains(cfHDropFormat()->cfFormat))
    552587        return files.release();
    553 
    554     WCHAR filename[MAX_PATH];
    555     UINT fileCount = DragQueryFileW(hdrop, 0xFFFFFFFF, 0, 0);
    556     for (UINT i = 0; i < fileCount; i++) {
    557         if (!DragQueryFileW(hdrop, i, filename, WTF_ARRAY_LENGTH(filename)))
    558             continue;
    559         files->append(File::create(reinterpret_cast<UChar*>(filename)));
    560     }
    561 
    562     GlobalUnlock(medium.hGlobal);
    563     ReleaseStgMedium(&medium);
     588    Vector<String> filesVector = m_dragDataMap.get(cfHDropFormat()->cfFormat);
     589    for (Vector<String>::iterator it = filesVector.begin(); it != filesVector.end(); ++it)
     590        files->append(File::create((*it).characters()));
    564591    return files.release();
    565592#endif
     
    779806bool ClipboardWin::hasData()
    780807{
    781     if (!m_dataObject)
     808    if (!m_dataObject && m_dragDataMap.isEmpty())
    782809        return false;
    783810
    784     COMPtr<IEnumFORMATETC> itr;
    785     if (FAILED(m_dataObject->EnumFormatEtc(DATADIR_GET, &itr)))
     811    if (m_dataObject) {
     812        COMPtr<IEnumFORMATETC> itr;
     813        if (FAILED(m_dataObject->EnumFormatEtc(DATADIR_GET, &itr)))
     814            return false;
     815
     816        if (!itr)
     817            return false;
     818
     819        FORMATETC data;
     820
     821        // IEnumFORMATETC::Next returns S_FALSE if there are no more items.
     822        if (itr->Next(1, &data, 0) == S_OK) {
     823            // There is at least one item in the IDataObject
     824            return true;
     825        }
     826
    786827        return false;
    787 
    788     if (!itr)
    789         return false;
    790 
    791     FORMATETC data;
    792 
    793     // IEnumFORMATETC::Next returns S_FALSE if there are no more items.
    794     if (itr->Next(1, &data, 0) == S_OK) {
    795         // There is at least one item in the IDataObject
    796         return true;
    797     }
    798 
    799     return false;
     828    }
     829    return !m_dragDataMap.isEmpty();
    800830}
    801831
  • trunk/Source/WebCore/platform/win/ClipboardWin.h

    r76248 r76824  
    3030#include "CachedResourceClient.h"
    3131#include "Clipboard.h"
     32#include "DragData.h"
    3233
    3334struct IDataObject;
     
    5152    {
    5253        return adoptRef(new ClipboardWin(clipboardType, dataObject, policy, frame));
     54    }
     55    static PassRefPtr<ClipboardWin> create(ClipboardType clipboardType, const DragDataMap& dataMap, ClipboardAccessPolicy policy, Frame* frame)
     56    {
     57        return adoptRef(new ClipboardWin(clipboardType, dataMap, policy, frame));
    5358    }
    5459    ~ClipboardWin();
     
    8186    ClipboardWin(ClipboardType, IDataObject*, ClipboardAccessPolicy, Frame*);
    8287    ClipboardWin(ClipboardType, WCDataObject*, ClipboardAccessPolicy, Frame*);
     88    ClipboardWin(ClipboardType, const DragDataMap&, ClipboardAccessPolicy, Frame*);
    8389
    8490    void resetFromClipboard();
     
    8793    COMPtr<IDataObject> m_dataObject;
    8894    COMPtr<WCDataObject> m_writableDataObject;
     95    DragDataMap m_dragDataMap;
    8996    Frame* m_frame;
    9097};
  • trunk/Source/WebCore/platform/win/DragDataWin.cpp

    r75523 r76824  
    2727#include "DragData.h"
    2828
     29#include "COMPtr.h"
    2930#include "ClipboardUtilitiesWin.h"
    3031#include "Frame.h"
     
    3637#include <shlwapi.h>
    3738#include <wininet.h>
     39#include <wtf/Forward.h>
     40#include <wtf/Hashmap.h>
     41#include <wtf/PassRefPtr.h>
     42#include <wtf/RefPtr.h>
    3843
    3944namespace WebCore {
    4045
     46DragData::DragData(const DragDataMap& data, const IntPoint& clientPosition, const IntPoint& globalPosition,
     47    DragOperation sourceOperationMask, DragApplicationFlags flags)
     48    : m_clientPosition(clientPosition)
     49    , m_globalPosition(globalPosition)
     50    , m_platformDragData(0)
     51    , m_draggingSourceOperationMask(sourceOperationMask)
     52    , m_applicationFlags(flags)
     53    , m_dragDataMap(data)
     54{
     55}
     56
    4157bool DragData::containsURL(Frame*, FilenameConversionPolicy filenamePolicy) const
    4258{
    43     return SUCCEEDED(m_platformDragData->QueryGetData(urlWFormat()))
    44         || SUCCEEDED(m_platformDragData->QueryGetData(urlFormat()))
    45         || (filenamePolicy == ConvertFilenames
    46             && (SUCCEEDED(m_platformDragData->QueryGetData(filenameWFormat()))
    47                 || SUCCEEDED(m_platformDragData->QueryGetData(filenameFormat()))));
     59    if (m_platformDragData)
     60        return SUCCEEDED(m_platformDragData->QueryGetData(urlWFormat()))
     61            || SUCCEEDED(m_platformDragData->QueryGetData(urlFormat()))
     62            || (filenamePolicy == ConvertFilenames
     63                && (SUCCEEDED(m_platformDragData->QueryGetData(filenameWFormat()))
     64                    || SUCCEEDED(m_platformDragData->QueryGetData(filenameFormat()))));
     65    return m_dragDataMap.contains(urlWFormat()->cfFormat) || m_dragDataMap.contains(urlFormat()->cfFormat)
     66        || (filenamePolicy == ConvertFilenames && (m_dragDataMap.contains(filenameWFormat()->cfFormat) || m_dragDataMap.contains(filenameFormat()->cfFormat)));
     67}
     68
     69const DragDataMap& DragData::dragDataMap()
     70{
     71    if (!m_dragDataMap.isEmpty() || !m_platformDragData)
     72        return m_dragDataMap;
     73    // Enumerate clipboard content and load it in the map.
     74    COMPtr<IEnumFORMATETC> itr;
     75
     76    if (FAILED(m_platformDragData->EnumFormatEtc(DATADIR_GET, &itr)) || !itr)
     77        return m_dragDataMap;
     78
     79    FORMATETC dataFormat;
     80    while (itr->Next(1, &dataFormat, 0) == S_OK) {
     81        Vector<String> dataStrings;
     82        getClipboardData(m_platformDragData, &dataFormat, dataStrings);
     83        if (!dataStrings.isEmpty())
     84            m_dragDataMap.set(dataFormat.cfFormat, dataStrings);
     85    }
     86    return m_dragDataMap;
    4887}
    4988
     
    5190{
    5291    bool success;
    53     return getURL(m_platformDragData, filenamePolicy, success, title);
     92    return (m_platformDragData) ? getURL(m_platformDragData, filenamePolicy, success, title) : getURL(&m_dragDataMap, filenamePolicy, title);
    5493}
    5594
    5695bool DragData::containsFiles() const
    5796{
    58     return SUCCEEDED(m_platformDragData->QueryGetData(cfHDropFormat()));
     97    return (m_platformDragData) ? SUCCEEDED(m_platformDragData->QueryGetData(cfHDropFormat())) : m_dragDataMap.contains(cfHDropFormat()->cfFormat);
    5998}
    6099
    61100void DragData::asFilenames(Vector<String>& result) const
    62101{
    63     WCHAR filename[MAX_PATH];
    64    
    65     STGMEDIUM medium;
    66     if (FAILED(m_platformDragData->GetData(cfHDropFormat(), &medium)))
     102    if (m_platformDragData) {
     103        WCHAR filename[MAX_PATH];
     104       
     105        STGMEDIUM medium;
     106        if (FAILED(m_platformDragData->GetData(cfHDropFormat(), &medium)))
     107            return;
     108       
     109        HDROP hdrop = (HDROP)GlobalLock(medium.hGlobal);
     110       
     111        if (!hdrop)
     112            return;
     113
     114        const unsigned numFiles = DragQueryFileW(hdrop, 0xFFFFFFFF, 0, 0);
     115        for (unsigned i = 0; i < numFiles; i++) {
     116            if (!DragQueryFileW(hdrop, 0, filename, WTF_ARRAY_LENGTH(filename)))
     117                continue;
     118            result.append((UChar*)filename);
     119        }
     120
     121        // Free up memory from drag
     122        DragFinish(hdrop);
     123
     124        GlobalUnlock(medium.hGlobal);
    67125        return;
    68    
    69     HDROP hdrop = (HDROP)GlobalLock(medium.hGlobal);
    70    
    71     if (!hdrop)
    72         return;
    73 
    74     const unsigned numFiles = DragQueryFileW(hdrop, 0xFFFFFFFF, 0, 0);
    75     for (unsigned i = 0; i < numFiles; i++) {
    76         if (!DragQueryFileW(hdrop, 0, filename, WTF_ARRAY_LENGTH(filename)))
    77             continue;
    78         result.append((UChar*)filename);
    79126    }
    80 
    81     // Free up memory from drag
    82     DragFinish(hdrop);
    83 
    84     GlobalUnlock(medium.hGlobal);
     127    result = m_dragDataMap.get(cfHDropFormat()->cfFormat);
    85128}
    86129
    87130bool DragData::containsPlainText() const
    88131{
    89     return SUCCEEDED(m_platformDragData->QueryGetData(plainTextWFormat()))
    90         || SUCCEEDED(m_platformDragData->QueryGetData(plainTextFormat()));
     132    if (m_platformDragData)
     133        return SUCCEEDED(m_platformDragData->QueryGetData(plainTextWFormat()))
     134            || SUCCEEDED(m_platformDragData->QueryGetData(plainTextFormat()));
     135    return m_dragDataMap.contains(plainTextWFormat()->cfFormat) || m_dragDataMap.contains(plainTextFormat()->cfFormat);
    91136}
    92137
     
    94139{
    95140    bool success;
    96     return getPlainText(m_platformDragData, success);
     141    return (m_platformDragData) ? getPlainText(m_platformDragData, success) : getPlainText(&m_dragDataMap);
    97142}
    98143
     
    104149bool DragData::canSmartReplace() const
    105150{
    106     return SUCCEEDED(m_platformDragData->QueryGetData(smartPasteFormat()));
     151    if (m_platformDragData)
     152        return SUCCEEDED(m_platformDragData->QueryGetData(smartPasteFormat()));
     153    return m_dragDataMap.contains(smartPasteFormat()->cfFormat);
    107154}
    108155
     
    110157{
    111158    return containsPlainText() || containsURL(0)
    112         || containsHTML(m_platformDragData)
    113         || containsFilenames(m_platformDragData)
     159        || ((m_platformDragData) ? (containsHTML(m_platformDragData) || containsFilenames(m_platformDragData))
     160            : (containsHTML(&m_dragDataMap) || containsFilenames(&m_dragDataMap)))
    114161        || containsColor();
    115162}
     
    126173     * * PICT
    127174     */
    128        
    129      if (containsFilenames(m_platformDragData))
    130          if (PassRefPtr<DocumentFragment> fragment = fragmentFromFilenames(frame->document(), m_platformDragData))
    131              return fragment;
    132 
    133      if (containsHTML(m_platformDragData))
    134          if (PassRefPtr<DocumentFragment> fragment = fragmentFromHTML(frame->document(), m_platformDragData))
    135              return fragment;
    136 
    137      return 0;
     175     
     176    if (m_platformDragData) {
     177        if (containsFilenames(m_platformDragData)) {
     178            if (PassRefPtr<DocumentFragment> fragment = fragmentFromFilenames(frame->document(), m_platformDragData))
     179                return fragment;
     180        }
     181
     182        if (containsHTML(m_platformDragData)) {
     183            if (PassRefPtr<DocumentFragment> fragment = fragmentFromHTML(frame->document(), m_platformDragData))
     184                return fragment;
     185        }
     186    } else {
     187        if (containsFilenames(&m_dragDataMap)) {
     188            if (PassRefPtr<DocumentFragment> fragment = fragmentFromFilenames(frame->document(), &m_dragDataMap))
     189                return fragment;
     190        }
     191
     192        if (containsHTML(&m_dragDataMap)) {
     193            if (PassRefPtr<DocumentFragment> fragment = fragmentFromHTML(frame->document(), &m_dragDataMap))
     194                return fragment;
     195        }
     196    }
     197    return 0;
    138198}
    139199
     
    144204
    145205}
    146 
  • trunk/Source/WebKit2/ChangeLog

    r76821 r76824  
     12011-01-26  Enrica Casucci  <enrica@apple.com>
     2
     3        Reviewed by Darin Adler and Adam Roben.
     4
     5        WebKit2: add support for drag and drop on Windows
     6        https://bugs.webkit.org/show_bug.cgi?id=52775
     7        <rdar://problem/8514409>
     8
     9        On Windows the access to the content being dragged is
     10        provided via the IDataObject interface that is made available
     11        to the window that registers itself as drop target.
     12        Since this interface cannot be accessed from the WebProcess,
     13        in every call to one of the methods of the IDropTarget interface
     14        we serialize the content of the drag clipboard and send it over to
     15        the WebProcess. The implementation uses the same messages as the
     16        Mac one, with slightly different parameters to pass the serialized
     17        clipboard.
     18
     19        * UIProcess/WebPageProxy.cpp:
     20        (WebKit::WebPageProxy::performDragControllerAction): Added Windows
     21        specific implementation.
     22        * UIProcess/WebPageProxy.h:
     23        * UIProcess/win/WebView.cpp:
     24        (WebKit::WebView::WebView): Added dropTargetHelper object creation.
     25        (WebKit::WebView::initialize): Added to register for drag/drop with out
     26        refcount issues.
     27        (WebKit::WebView::close):
     28        (WebKit::WebView::windowReceivedMessage):
     29        (WebKit::WebView::QueryInterface):
     30        (WebKit::WebView::AddRef):
     31        (WebKit::WebView::Release):
     32        (WebKit::dragOperationToDragCursor):
     33        (WebKit::WebView::keyStateToDragOperation):
     34        (WebKit::WebView::DragEnter):
     35        (WebKit::WebView::DragOver):
     36        (WebKit::WebView::DragLeave):
     37        (WebKit::WebView::Drop):
     38        * UIProcess/win/WebView.h:
     39        (WebKit::WebView::create):
     40        * WebProcess/WebPage/WebPage.cpp:
     41        (WebKit::WebPage::performDragControllerAction):
     42        * WebProcess/WebPage/WebPage.h:
     43        * WebProcess/WebPage/WebPage.messages.in:
     44
    1452011-01-26  Alexey Proskuryakov  <ap@apple.com>
    246
  • trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp

    r76821 r76824  
    613613    if (!isValid())
    614614        return;
     615#if PLATFORM(WIN)
     616    // FIXME: We should pass the drag data map only on DragEnter.
     617    process()->send(Messages::WebPage::PerformDragControllerAction(action, dragData->clientPosition(), dragData->globalPosition(),
     618        dragData->draggingSourceOperationMask(), dragData->dragDataMap(), dragData->flags()), m_pageID);
     619#else
    615620    process()->send(Messages::WebPage::PerformDragControllerAction(action, dragData->clientPosition(), dragData->globalPosition(), dragData->draggingSourceOperationMask(), dragStorageName, dragData->flags()), m_pageID);
     621#endif
    616622}
    617623
  • trunk/Source/WebKit2/UIProcess/WebPageProxy.h

    r76821 r76824  
    295295
    296296    // Drag and drop support.
    297     void performDragControllerAction(DragControllerAction, WebCore::DragData*, const String&);
     297    void performDragControllerAction(DragControllerAction, WebCore::DragData*, const String& = String());
    298298    void didPerformDragControllerAction(uint64_t resultOperation);
    299299    void dragEnded(const WebCore::IntPoint& clientPosition, const WebCore::IntPoint& globalPosition, uint64_t operation);
  • trunk/Source/WebKit2/UIProcess/win/WebView.cpp

    r76657 r76824  
    244244    m_page->initializeWebPage();
    245245
     246    CoCreateInstance(CLSID_DragDropHelper, 0, CLSCTX_INPROC_SERVER, IID_IDropTargetHelper, (void**)&m_dropTargetHelper);
     247
    246248    ::ShowWindow(m_window, SW_SHOW);
    247249
     
    259261    if (::IsWindow(m_toolTipWindow))
    260262        ::DestroyWindow(m_toolTipWindow);
     263}
     264
     265void WebView::initialize()
     266{
     267    ::RegisterDragDrop(m_window, this);
    261268}
    262269
     
    570577void WebView::close()
    571578{
     579    ::RevokeDragDrop(m_window);
    572580    setParentWindow(0);
    573581    m_page->close();
     
    10931101}
    10941102
     1103HRESULT STDMETHODCALLTYPE WebView::QueryInterface(REFIID riid, void** ppvObject)
     1104{
     1105    *ppvObject = 0;
     1106    if (IsEqualGUID(riid, IID_IUnknown))
     1107        *ppvObject = static_cast<IUnknown*>(this);
     1108    else if (IsEqualGUID(riid, IID_IDropTarget))
     1109        *ppvObject = static_cast<IDropTarget*>(this);
     1110    else
     1111        return E_NOINTERFACE;
     1112
     1113    AddRef();
     1114    return S_OK;
     1115}
     1116
     1117ULONG STDMETHODCALLTYPE WebView::AddRef(void)
     1118{
     1119    ref();
     1120    return refCount();
     1121}
     1122
     1123ULONG STDMETHODCALLTYPE WebView::Release(void)
     1124{
     1125    deref();
     1126    return refCount();
     1127}
     1128
     1129static DWORD dragOperationToDragCursor(DragOperation op)
     1130{
     1131    DWORD res = DROPEFFECT_NONE;
     1132    if (op & DragOperationCopy)
     1133        res = DROPEFFECT_COPY;
     1134    else if (op & DragOperationLink)
     1135        res = DROPEFFECT_LINK;
     1136    else if (op & DragOperationMove)
     1137        res = DROPEFFECT_MOVE;
     1138    else if (op & DragOperationGeneric)
     1139        res = DROPEFFECT_MOVE; // This appears to be the Firefox behaviour
     1140    return res;
     1141}
     1142
     1143WebCore::DragOperation WebView::keyStateToDragOperation(DWORD grfKeyState) const
     1144{
     1145    if (!m_page)
     1146        return DragOperationNone;
     1147
     1148    // Conforms to Microsoft's key combinations as documented for
     1149    // IDropTarget::DragOver. Note, grfKeyState is the current
     1150    // state of the keyboard modifier keys on the keyboard. See:
     1151    // <http://msdn.microsoft.com/en-us/library/ms680129(VS.85).aspx>.
     1152    DragOperation operation = m_page->dragOperation();
     1153
     1154    if ((grfKeyState & (MK_CONTROL | MK_SHIFT)) == (MK_CONTROL | MK_SHIFT))
     1155        operation = DragOperationLink;
     1156    else if ((grfKeyState & MK_CONTROL) == MK_CONTROL)
     1157        operation = DragOperationCopy;
     1158    else if ((grfKeyState & MK_SHIFT) == MK_SHIFT)
     1159        operation = DragOperationGeneric;
     1160
     1161    return operation;
     1162}
     1163
     1164HRESULT STDMETHODCALLTYPE WebView::DragEnter(IDataObject* pDataObject, DWORD grfKeyState, POINTL pt, DWORD* pdwEffect)
     1165{
     1166    m_dragData = 0;
     1167    m_page->resetDragOperation();
     1168
     1169    if (m_dropTargetHelper)
     1170        m_dropTargetHelper->DragEnter(m_window, pDataObject, (POINT*)&pt, *pdwEffect);
     1171
     1172    POINTL localpt = pt;
     1173    ::ScreenToClient(m_window, (LPPOINT)&localpt);
     1174    DragData data(pDataObject, IntPoint(localpt.x, localpt.y), IntPoint(pt.x, pt.y), keyStateToDragOperation(grfKeyState));
     1175    m_page->performDragControllerAction(DragControllerActionEntered, &data);
     1176    *pdwEffect = dragOperationToDragCursor(m_page->dragOperation());
     1177
     1178    m_lastDropEffect = *pdwEffect;
     1179    m_dragData = pDataObject;
     1180
     1181    return S_OK;
     1182}
     1183
     1184HRESULT STDMETHODCALLTYPE WebView::DragOver(DWORD grfKeyState, POINTL pt, DWORD* pdwEffect)
     1185{
     1186    if (m_dropTargetHelper)
     1187        m_dropTargetHelper->DragOver((POINT*)&pt, *pdwEffect);
     1188
     1189    if (m_dragData) {
     1190        POINTL localpt = pt;
     1191        ::ScreenToClient(m_window, (LPPOINT)&localpt);
     1192        DragData data(m_dragData.get(), IntPoint(localpt.x, localpt.y), IntPoint(pt.x, pt.y), keyStateToDragOperation(grfKeyState));
     1193        m_page->performDragControllerAction(DragControllerActionUpdated, &data);
     1194        *pdwEffect = dragOperationToDragCursor(m_page->dragOperation());
     1195    } else
     1196        *pdwEffect = DROPEFFECT_NONE;
     1197
     1198    m_lastDropEffect = *pdwEffect;
     1199    return S_OK;
     1200}
     1201
     1202HRESULT STDMETHODCALLTYPE WebView::DragLeave()
     1203{
     1204    if (m_dropTargetHelper)
     1205        m_dropTargetHelper->DragLeave();
     1206
     1207    if (m_dragData) {
     1208        DragData data(m_dragData.get(), IntPoint(), IntPoint(), DragOperationNone);
     1209        m_page->performDragControllerAction(DragControllerActionExited, &data);
     1210        m_dragData = 0;
     1211        m_page->resetDragOperation();
     1212    }
     1213    return S_OK;
     1214}
     1215
     1216HRESULT STDMETHODCALLTYPE WebView::Drop(IDataObject* pDataObject, DWORD grfKeyState, POINTL pt, DWORD* pdwEffect)
     1217{
     1218    if (m_dropTargetHelper)
     1219        m_dropTargetHelper->Drop(pDataObject, (POINT*)&pt, *pdwEffect);
     1220
     1221    m_dragData = 0;
     1222    *pdwEffect = m_lastDropEffect;
     1223    POINTL localpt = pt;
     1224    ::ScreenToClient(m_window, (LPPOINT)&localpt);
     1225    DragData data(pDataObject, IntPoint(localpt.x, localpt.y), IntPoint(pt.x, pt.y), keyStateToDragOperation(grfKeyState));
     1226    m_page->performDragControllerAction(DragControllerActionPerformDrag, &data);
     1227    return S_OK;
     1228}
     1229
    10951230} // namespace WebKit
  • trunk/Source/WebKit2/UIProcess/win/WebView.h

    r76657 r76824  
    3030#include "PageClient.h"
    3131#include "WebPageProxy.h"
     32#include <WebCore/COMPtr.h>
     33#include <WebCore/DragActions.h>
     34#include <WebCore/DragData.h>
    3235#include <WebCore/WindowMessageListener.h>
    3336#include <wtf/Forward.h>
    3437#include <wtf/PassRefPtr.h>
    3538#include <wtf/RefPtr.h>
     39#include <ShlObj.h>
     40
     41interface IDropTargetHelper;
    3642
    3743namespace WebKit {
     
    3945class DrawingAreaProxy;
    4046
    41 class WebView : public APIObject, public PageClient, WebCore::WindowMessageListener {
     47class WebView : public APIObject, public PageClient, WebCore::WindowMessageListener, public IDropTarget {
    4248public:
    4349    static PassRefPtr<WebView> create(RECT rect, WebContext* context, WebPageGroup* pageGroup, HWND parentWindow)
    4450    {
    45         return adoptRef(new WebView(rect, context, pageGroup, parentWindow));
     51        RefPtr<WebView> webView = adoptRef(new WebView(rect, context, pageGroup, parentWindow));
     52        webView->initialize();
     53        return webView;
    4654    }
    4755    ~WebView();
     
    5361    void setOverrideCursor(HCURSOR overrideCursor);
    5462    void setInitialFocus(bool forward);
     63    void initialize();
     64
     65    // IUnknown
     66    virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject);
     67    virtual ULONG STDMETHODCALLTYPE AddRef(void);
     68    virtual ULONG STDMETHODCALLTYPE Release(void);
     69
     70    // IDropTarget
     71    virtual HRESULT STDMETHODCALLTYPE DragEnter(IDataObject* pDataObject, DWORD grfKeyState, POINTL pt, DWORD* pdwEffect);
     72    virtual HRESULT STDMETHODCALLTYPE DragOver(DWORD grfKeyState, POINTL pt, DWORD* pdwEffect);
     73    virtual HRESULT STDMETHODCALLTYPE DragLeave();
     74    virtual HRESULT STDMETHODCALLTYPE Drop(IDataObject* pDataObject, DWORD grfKeyState, POINTL pt, DWORD* pdwEffect);
    5575
    5676    WebPageProxy* page() const { return m_page.get(); }
     
    143163    virtual double customRepresentationZoomFactor();
    144164    virtual void setCustomRepresentationZoomFactor(double);
     165    WebCore::DragOperation keyStateToDragOperation(DWORD grfKeyState) const;
    145166
    146167    virtual HWND nativeWindow();
     
    166187
    167188    unsigned m_inIMEComposition;
     189    COMPtr<IDataObject> m_dragData;
     190    COMPtr<IDropTargetHelper> m_dropTargetHelper;
     191    // FIXME: This variable is part of a workaround. The drop effect (pdwEffect) passed to Drop is incorrect.
     192    // We set this variable in DragEnter and DragOver so that it can be used in Drop to set the correct drop effect.
     193    // Thus, on return from DoDragDrop we have the correct pdwEffect for the drag-and-drop operation.
     194    // (see https://bugs.webkit.org/show_bug.cgi?id=29264)
     195    DWORD m_lastDropEffect;
    168196};
    169197
  • trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp

    r76821 r76824  
    13321332#endif
    13331333
    1334 void WebPage::performDragControllerAction(uint64_t action, WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t draggingSourceOperationMask, const String& dragStorageName, uint32_t flags)
     1334#if PLATFORM(WIN)
     1335void WebPage::performDragControllerAction(uint64_t action, WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t draggingSourceOperationMask, const WebCore::DragDataMap& dataMap, uint32_t flags)
    13351336{
    13361337    if (!m_page) {
     
    13391340    }
    13401341
    1341     DragData dragData(dragStorageName, clientPosition, globalPosition, static_cast<DragOperation>(draggingSourceOperationMask), static_cast<DragApplicationFlags>(flags));
     1342    DragData dragData(dataMap, clientPosition, globalPosition, static_cast<DragOperation>(draggingSourceOperationMask), static_cast<DragApplicationFlags>(flags));
    13421343    switch (action) {
    13431344    case DragControllerActionEntered:
     
    13611362    }
    13621363}
     1364#else
     1365void WebPage::performDragControllerAction(uint64_t action, WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t draggingSourceOperationMask, const String& dragStorageName, uint32_t flags)
     1366{
     1367    if (!m_page) {
     1368        send(Messages::WebPageProxy::DidPerformDragControllerAction(DragOperationNone));
     1369        return;
     1370    }
     1371
     1372    DragData dragData(dragStorageName, clientPosition, globalPosition, static_cast<DragOperation>(draggingSourceOperationMask), static_cast<DragApplicationFlags>(flags));
     1373    switch (action) {
     1374    case DragControllerActionEntered:
     1375        send(Messages::WebPageProxy::DidPerformDragControllerAction(m_page->dragController()->dragEntered(&dragData)));
     1376        break;
     1377
     1378    case DragControllerActionUpdated:
     1379        send(Messages::WebPageProxy::DidPerformDragControllerAction(m_page->dragController()->dragUpdated(&dragData)));
     1380        break;
     1381       
     1382    case DragControllerActionExited:
     1383        m_page->dragController()->dragExited(&dragData);
     1384        break;
     1385       
     1386    case DragControllerActionPerformDrag:
     1387        m_page->dragController()->performDrag(&dragData);
     1388        break;
     1389       
     1390    default:
     1391        ASSERT_NOT_REACHED();
     1392    }
     1393}
     1394#endif
    13631395
    13641396void WebPage::dragEnded(WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t operation)
  • trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h

    r76821 r76824  
    4141#include "SandboxExtension.h"
    4242#include "WebEditCommand.h"
     43#include <WebCore/DragData.h>
    4344#include <WebCore/Editor.h>
    4445#include <WebCore/FrameLoaderTypes.h>
     
    305306
    306307    void replaceSelectionWithText(WebCore::Frame*, const String&);
     308#if PLATFORM(WIN)
     309    void performDragControllerAction(uint64_t action, WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t draggingSourceOperationMask, const WebCore::DragDataMap&, uint32_t flags);
     310#else
    307311    void performDragControllerAction(uint64_t action, WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t draggingSourceOperationMask, const WTF::String& dragStorageName, uint32_t flags);
     312#endif
    308313    void dragEnded(WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t operation);
    309314
  • trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in

    r76821 r76824  
    107107
    108108    # Drag and drop.
     109#if PLATFORM(WIN)
     110    PerformDragControllerAction(uint64_t action, WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t draggingSourceOperationMask, HashMap<UINT,Vector<String>> dataMap, uint32_t flags)
     111#endif
     112#if !PLATFORM(WIN)
    109113    PerformDragControllerAction(uint64_t action, WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t draggingSourceOperationMask, WTF::String dragStorageName, uint32_t flags)
     114#endif
    110115    DragEnded(WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t operation)
    111116
Note: See TracChangeset for help on using the changeset viewer.