Bug 455884 - nsIDOMDataTransfer's dropEffect not updated after drag operation completes; r=enndeakin sr=roc

This commit is contained in:
Jim Mathies 2008-09-28 22:57:33 +02:00
Родитель 7fd66d0307
Коммит 6c95c0a009
3 изменённых файлов: 48 добавлений и 3 удалений

Просмотреть файл

@ -80,7 +80,7 @@
//
//-------------------------------------------------------------------------
nsDragService::nsDragService()
: mNativeDragSrc(nsnull), mNativeDragTarget(nsnull), mDataObject(nsnull)
: mNativeDragSrc(nsnull), mNativeDragTarget(nsnull), mDataObject(nsnull), mSentLocalDropEvent(PR_FALSE)
{
}
@ -278,7 +278,7 @@ nsDragService::StartInvokingDragSession(IDataObject * aDataObj,
mNativeDragSrc->AddRef();
// Now figure out what the native drag effect should be
DWORD dropRes;
DWORD winDropRes;
DWORD effects = DROPEFFECT_SCROLL;
if (aActionType & DRAGDROP_ACTION_COPY) {
effects |= DROPEFFECT_COPY;
@ -294,6 +294,7 @@ nsDragService::StartInvokingDragSession(IDataObject * aDataObj,
// the drag
mDragAction = aActionType;
mDoingDrag = PR_TRUE;
mSentLocalDropEvent = PR_FALSE;
// Start dragging
StartDragSession();
@ -311,7 +312,7 @@ nsDragService::StartInvokingDragSession(IDataObject * aDataObj,
}
// Call the native D&D method
HRESULT res = ::DoDragDrop(aDataObj, mNativeDragSrc, effects, &dropRes);
HRESULT res = ::DoDragDrop(aDataObj, mNativeDragSrc, effects, &winDropRes);
if (isAsyncAvailable)
{
@ -326,6 +327,31 @@ nsDragService::StartInvokingDragSession(IDataObject * aDataObj,
}
}
// In cases where the drop operation completed outside the application, update
// the source node's nsIDOMNSDataTransfer dropEffect value so it is up to date.
if (!mSentLocalDropEvent) {
PRUint32 dropResult;
// Order is important, since multiple flags can be returned.
if (winDropRes & DROPEFFECT_COPY)
dropResult = DRAGDROP_ACTION_COPY;
else if (winDropRes & DROPEFFECT_LINK)
dropResult = DRAGDROP_ACTION_LINK;
else if (winDropRes & DROPEFFECT_MOVE)
dropResult = DRAGDROP_ACTION_MOVE;
else
dropResult = DRAGDROP_ACTION_NONE;
nsCOMPtr<nsIDOMNSDataTransfer> dataTransfer =
do_QueryInterface(mDataTransfer);
if (dataTransfer) {
if (res == DRAGDROP_S_DROP) // Success
dataTransfer->SetDropEffectInt(dropResult);
else
dataTransfer->SetDropEffectInt(DRAGDROP_ACTION_NONE);
}
}
// We're done dragging
EndDragSession(PR_TRUE);
@ -468,6 +494,16 @@ nsDragService::SetIDataObject(IDataObject * aDataObj)
return NS_OK;
}
//---------------------------------------------------------
void
nsDragService::SetDroppedLocal()
{
// Sent from the native drag handler, letting us know
// a drop occured within the application vs. outside of it.
mSentLocalDropEvent = PR_TRUE;
return;
}
//-------------------------------------------------------------------------
NS_IMETHODIMP
nsDragService::IsDataFlavorSupported(const char *aDataFlavor, PRBool *_retval)

Просмотреть файл

@ -75,6 +75,9 @@ public:
NS_IMETHOD StartInvokingDragSession(IDataObject * aDataObj,
PRUint32 aActionType);
// A drop occured within the application vs. outside of it.
void SetDroppedLocal();
protected:
nsDataObjCollection* GetDataObjCollection(IDataObject * aDataObj);
@ -93,6 +96,7 @@ protected:
IDropSource * mNativeDragSrc;
nsNativeDragTarget * mNativeDragTarget;
IDataObject * mDataObject;
PRPackedBool mSentLocalDropEvent;
};
#endif // nsDragService_h__

Просмотреть файл

@ -421,6 +421,11 @@ nsNativeDragTarget::Drop(LPDATAOBJECT pData,
// Now process the native drag state and then dispatch the event
ProcessDrag(pData, NS_DRAGDROP_DROP, grfKeyState, aPT, pdwEffect);
// Let the win drag service know whether this session experienced
// a drop event within the application. Drop will not oocur if the
// drop landed outside the app. (used in tab tear off, bug 455884)
winDragService->SetDroppedLocal();
// tell the drag service we're done with the session
serv->EndDragSession(PR_TRUE);
return S_OK;