Bug 673080 - Dropping a link on Firefox from an external program has no effect. r=neil

This commit is contained in:
Brian R. Bondy 2011-09-01 09:48:48 -04:00
Родитель b2845a3c0d
Коммит 6ff418e50f
2 изменённых файлов: 33 добавлений и 26 удалений

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

@ -61,8 +61,8 @@ static POINTL gDragLastPoint;
* class nsNativeDragTarget * class nsNativeDragTarget
*/ */
nsNativeDragTarget::nsNativeDragTarget(nsIWidget * aWnd) nsNativeDragTarget::nsNativeDragTarget(nsIWidget * aWnd)
: m_cRef(0), mCanMove(PR_TRUE), mTookOwnRef(PR_FALSE), mWindow(aWnd), : m_cRef(0), mEffect(DROPEFFECT_MOVE | DROPEFFECT_COPY | DROPEFFECT_LINK),
mDropTargetHelper(nsnull) mTookOwnRef(PR_FALSE), mWindow(aWnd), mDropTargetHelper(nsnull)
{ {
mHWnd = (HWND)mWindow->GetNativeData(NS_NATIVE_WINDOW); mHWnd = (HWND)mWindow->GetNativeData(NS_NATIVE_WINDOW);
@ -123,23 +123,25 @@ STDMETHODIMP_(ULONG) nsNativeDragTarget::Release(void)
} }
void void
nsNativeDragTarget::GetGeckoDragAction(LPDATAOBJECT pData, DWORD grfKeyState, nsNativeDragTarget::GetGeckoDragAction(DWORD grfKeyState, LPDWORD pdwEffect,
LPDWORD pdwEffect,
PRUint32 * aGeckoAction) PRUint32 * aGeckoAction)
{ {
// Check if we can link from this data object as well.
PRBool canLink = PR_FALSE;
if (pData)
canLink = (S_OK == ::OleQueryLinkFromData(pData) ? PR_TRUE : PR_FALSE);
// Default is move if we can, in fact drop here, // Default is move if we can, in fact drop here,
// and if the drop source supports a move operation. // and if the drop source supports a move operation.
// If move is not preferred (mMovePreferred is false) // If move is not preferred (mMovePreferred is false)
// move only when the shift key is down. // move only when the shift key is down.
if (mCanMove && (mMovePreferred || (grfKeyState & MK_SHIFT))) { if ((mEffect & DROPEFFECT_MOVE) &&
(mMovePreferred || (grfKeyState & MK_SHIFT))) {
*aGeckoAction = nsIDragService::DRAGDROP_ACTION_MOVE; *aGeckoAction = nsIDragService::DRAGDROP_ACTION_MOVE;
*pdwEffect = DROPEFFECT_MOVE; *pdwEffect = DROPEFFECT_MOVE;
} else { }
else if (!(mEffect & DROPEFFECT_MOVE) &&
!(mEffect & DROPEFFECT_COPY) &&
(mEffect & DROPEFFECT_LINK)) {
*aGeckoAction = nsIDragService::DRAGDROP_ACTION_LINK;
*pdwEffect = DROPEFFECT_LINK;
}
else {
*aGeckoAction = nsIDragService::DRAGDROP_ACTION_COPY; *aGeckoAction = nsIDragService::DRAGDROP_ACTION_COPY;
*pdwEffect = DROPEFFECT_COPY; *pdwEffect = DROPEFFECT_COPY;
} }
@ -147,7 +149,7 @@ nsNativeDragTarget::GetGeckoDragAction(LPDATAOBJECT pData, DWORD grfKeyState,
// Given the key modifiers figure out what state we are in for both // Given the key modifiers figure out what state we are in for both
// the native system and Gecko // the native system and Gecko
if (grfKeyState & MK_CONTROL) { if (grfKeyState & MK_CONTROL) {
if (canLink && (grfKeyState & MK_SHIFT)) { if ((mEffect & DROPEFFECT_LINK) && (grfKeyState & MK_SHIFT)) {
*aGeckoAction = nsIDragService::DRAGDROP_ACTION_LINK; *aGeckoAction = nsIDragService::DRAGDROP_ACTION_LINK;
*pdwEffect = DROPEFFECT_LINK; *pdwEffect = DROPEFFECT_LINK;
} else { } else {
@ -196,15 +198,14 @@ nsNativeDragTarget::DispatchDragDropEvent(PRUint32 aEventType, POINTL aPT)
} }
void void
nsNativeDragTarget::ProcessDrag(LPDATAOBJECT pData, nsNativeDragTarget::ProcessDrag(PRUint32 aEventType,
PRUint32 aEventType,
DWORD grfKeyState, DWORD grfKeyState,
POINTL ptl, POINTL ptl,
DWORD* pdwEffect) DWORD* pdwEffect)
{ {
// Before dispatching the event make sure we have the correct drop action set // Before dispatching the event make sure we have the correct drop action set
PRUint32 geckoAction; PRUint32 geckoAction;
GetGeckoDragAction(pData, grfKeyState, pdwEffect, &geckoAction); GetGeckoDragAction(grfKeyState, pdwEffect, &geckoAction);
// Set the current action into the Gecko specific type // Set the current action into the Gecko specific type
nsCOMPtr<nsIDragSession> currSession; nsCOMPtr<nsIDragSession> currSession;
@ -256,8 +257,14 @@ nsNativeDragTarget::DragEnter(LPDATAOBJECT pIDataSource,
// outside app). // outside app).
mDragService->StartDragSession(); mDragService->StartDragSession();
// Remember if this operation allows a move. mEffect = *pdwEffect;
mCanMove = (*pdwEffect) & DROPEFFECT_MOVE; // If we don't have a link effect, but we can generate one, fix the
// drop effect to include it
if (!(mEffect & DROPEFFECT_LINK) && pIDataSource) {
if (S_OK == ::OleQueryLinkFromData(pIDataSource)) {
mEffect |= DROPEFFECT_LINK;
}
}
void* tempOutData = nsnull; void* tempOutData = nsnull;
PRUint32 tempDataLen = 0; PRUint32 tempDataLen = 0;
@ -271,7 +278,7 @@ nsNativeDragTarget::DragEnter(LPDATAOBJECT pIDataSource,
mMovePreferred = (preferredEffect & DROPEFFECT_MOVE) != 0; mMovePreferred = (preferredEffect & DROPEFFECT_MOVE) != 0;
} }
else else
mMovePreferred = mCanMove; mMovePreferred = (mEffect & DROPEFFECT_MOVE) != 0;
// Set the native data object into drag service // Set the native data object into drag service
// //
@ -283,7 +290,7 @@ nsNativeDragTarget::DragEnter(LPDATAOBJECT pIDataSource,
winDragService->SetIDataObject(pIDataSource); winDragService->SetIDataObject(pIDataSource);
// Now process the native drag state and then dispatch the event // Now process the native drag state and then dispatch the event
ProcessDrag(pIDataSource, NS_DRAGDROP_ENTER, grfKeyState, ptl, pdwEffect); ProcessDrag(NS_DRAGDROP_ENTER, grfKeyState, ptl, pdwEffect);
return S_OK; return S_OK;
} }
@ -314,7 +321,7 @@ nsNativeDragTarget::DragOver(DWORD grfKeyState,
mDragService->FireDragEventAtSource(NS_DRAGDROP_DRAG); mDragService->FireDragEventAtSource(NS_DRAGDROP_DRAG);
// Now process the native drag state and then dispatch the event // Now process the native drag state and then dispatch the event
ProcessDrag(nsnull, NS_DRAGDROP_OVER, grfKeyState, ptl, pdwEffect); ProcessDrag(NS_DRAGDROP_OVER, grfKeyState, ptl, pdwEffect);
this->Release(); this->Release();
@ -408,7 +415,7 @@ nsNativeDragTarget::Drop(LPDATAOBJECT pData,
nsCOMPtr<nsIDragService> serv = mDragService; nsCOMPtr<nsIDragService> serv = mDragService;
// Now process the native drag state and then dispatch the event // Now process the native drag state and then dispatch the event
ProcessDrag(pData, NS_DRAGDROP_DROP, grfKeyState, aPT, pdwEffect); ProcessDrag(NS_DRAGDROP_DROP, grfKeyState, aPT, pdwEffect);
nsCOMPtr<nsIDragSession> currentDragSession; nsCOMPtr<nsIDragSession> currentDragSession;
serv->GetCurrentSession(getter_AddRefs(currentDragSession)); serv->GetCurrentSession(getter_AddRefs(currentDragSession));

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

@ -102,16 +102,16 @@ public:
protected: protected:
void GetGeckoDragAction(LPDATAOBJECT pData, DWORD grfKeyState, void GetGeckoDragAction(DWORD grfKeyState, LPDWORD pdwEffect,
LPDWORD pdwEffect, PRUint32 * aGeckoAction); PRUint32 * aGeckoAction);
void ProcessDrag(LPDATAOBJECT pData, PRUint32 aEventType, DWORD grfKeyState, void ProcessDrag(PRUint32 aEventType, DWORD grfKeyState,
POINTL pt, DWORD* pdwEffect); POINTL pt, DWORD* pdwEffect);
void DispatchDragDropEvent(PRUint32 aType, POINTL pt); void DispatchDragDropEvent(PRUint32 aType, POINTL pt);
// Native Stuff // Native Stuff
ULONG m_cRef; // reference count ULONG m_cRef; // reference count
HWND mHWnd; HWND mHWnd;
PRBool mCanMove; DWORD mEffect;
PRBool mMovePreferred; PRBool mMovePreferred;
PRBool mTookOwnRef; PRBool mTookOwnRef;