Bug 466379, add screen coordinates to dragend event, r=josh,sr=roc
authorNeil Deakin <neil@mozilla.com>
Mon, 13 Apr 2009 09:00:29 -0400
changeset 27257 63be60c2333bfab38c85d813cc4b4afadb9be407
parent 27256 66c661e575a9b891fa84bb1c6b85cda08a6d76a3
child 27258 273d8da211110754272ac11ad3c3cdf9e135f7a1
push idunknown
push userunknown
push dateunknown
reviewersjosh, roc
bugs466379
milestone1.9.2a1pre
Bug 466379, add screen coordinates to dragend event, r=josh,sr=roc
widget/src/cocoa/nsChildView.mm
widget/src/windows/nsDragService.cpp
widget/src/xpwidgets/nsBaseDragService.cpp
widget/src/xpwidgets/nsBaseDragService.h
--- a/widget/src/cocoa/nsChildView.mm
+++ b/widget/src/cocoa/nsChildView.mm
@@ -6223,16 +6223,22 @@ static BOOL keyUpAlreadySentKeyDown = NO
                         [currentEvent keyCode] == kEscapeKeyCode);
 
   if (!mDragService) {
     CallGetService(kDragServiceContractID, &mDragService);
     NS_ASSERTION(mDragService, "Couldn't get a drag service - big problem!");
   }
 
   if (mDragService) {
+    // set the dragend point from the current mouse location
+    nsDragService* dragService = static_cast<nsDragService *>(mDragService);
+    NSPoint pnt = [NSEvent mouseLocation];
+    FlipCocoaScreenCoordinate(pnt);
+    dragService->SetDragEndPoint(nsPoint(NSToIntRound(pnt.x), NSToIntRound(pnt.y)));
+
     mDragService->EndDragSession(PR_TRUE);
     NS_RELEASE(mDragService);
   }
 
   [globalDragPboard release];
   globalDragPboard = nil;
 
   NS_OBJC_END_TRY_ABORT_BLOCK;
--- a/widget/src/windows/nsDragService.cpp
+++ b/widget/src/windows/nsDragService.cpp
@@ -350,17 +350,20 @@ nsDragService::StartInvokingDragSession(
         dataTransfer->SetDropEffectInt(dropResult);
       else
         dataTransfer->SetDropEffectInt(DRAGDROP_ACTION_NONE);
     }
   }
 
   mUserCancelled = nativeDragSource->UserCancelled();
 
-  // We're done dragging
+  // We're done dragging, get the cursor position and end the drag
+  POINT pos;
+  GetCursorPos(&pos);
+  SetDragEndPoint(nsPoint(pos.x, pos.y));
   EndDragSession(PR_TRUE);
 
   // For some drag/drop interactions, IDataObject::SetData doesn't get
   // called with a CFSTR_PERFORMEDDROPEFFECT format and the
   // intermediate file (if it was created) isn't deleted.  See
   // http://bugzilla.mozilla.org/show_bug.cgi?id=203847#c4 for a
   // detailed description of the different cases.  Now that we know
   // that the drag/drop operation has ended, call SetData() so that
--- a/widget/src/xpwidgets/nsBaseDragService.cpp
+++ b/widget/src/xpwidgets/nsBaseDragService.cpp
@@ -219,16 +219,17 @@ nsBaseDragService::InvokeDragSession(nsI
                                      PRUint32 aActionType)
 {
   NS_ENSURE_TRUE(aDOMNode, NS_ERROR_INVALID_ARG);
   NS_ENSURE_TRUE(mSuppressLevel == 0, NS_ERROR_FAILURE);
 
   // stash the document of the dom node
   aDOMNode->GetOwnerDocument(getter_AddRefs(mSourceDocument));
   mSourceNode = aDOMNode;
+  mEndDragPoint = nsPoint(0, 0);
 
   // When the mouse goes down, the selection code starts a mouse
   // capture. However, this gets in the way of determining drag
   // feedback for things like trees because the event coordinates
   // are in the wrong coord system. Turn off mouse capture in
   // the associated view manager.
   nsCOMPtr<nsIContent> contentNode = do_QueryInterface(aDOMNode);
   if (contentNode) {
@@ -369,17 +370,21 @@ nsBaseDragService::FireDragEventAtSource
 {
   if (mSourceNode && !mSuppressLevel) {
     nsCOMPtr<nsIDocument> doc = do_QueryInterface(mSourceDocument);
     if (doc) {
       nsCOMPtr<nsIPresShell> presShell = doc->GetPrimaryShell();
       if (presShell) {
         nsEventStatus status = nsEventStatus_eIgnore;
         nsDragEvent event(PR_TRUE, aMsg, nsnull);
-        event.userCancelled = (aMsg == NS_DRAGDROP_END && mUserCancelled);
+        if (aMsg == NS_DRAGDROP_END) {
+          event.refPoint.x = mEndDragPoint.x;
+          event.refPoint.y = mEndDragPoint.y;
+          event.userCancelled = mUserCancelled;
+        }
 
         nsCOMPtr<nsIContent> content = do_QueryInterface(mSourceNode);
         return presShell->HandleDOMEventWithTarget(content, &event, &status);
       }
     }
   }
 
   return NS_OK;
--- a/widget/src/xpwidgets/nsBaseDragService.h
+++ b/widget/src/xpwidgets/nsBaseDragService.h
@@ -72,16 +72,18 @@ public:
 
   //nsISupports
   NS_DECL_ISUPPORTS
 
   //nsIDragSession and nsIDragService
   NS_DECL_NSIDRAGSERVICE
   NS_DECL_NSIDRAGSESSION
 
+  void SetDragEndPoint(nsPoint aEndDragPoint) { mEndDragPoint = aEndDragPoint; }
+
 protected:
 
   /**
    * Draw the drag image, if any, to a surface and return it. The drag image
    * is constructed from mImage if specified, or aDOMNode if mImage is null.
    *
    * aRegion may be used to draw only a subset of the element. This region
    * should be supplied using x and y coordinates measured in css pixels
@@ -149,12 +151,15 @@ protected:
   nsCOMPtr<nsISelection> mSelection;
 
   // the screen position where drag gesture occured, used for positioning the
   // drag image when no image is specified. If a value is -1, no event was
   // supplied so the screen position is not known
   PRInt32 mScreenX;
   PRInt32 mScreenY;
 
+  // the screen position where the drag ended
+  nsPoint mEndDragPoint;
+
   PRUint32 mSuppressLevel;
 };
 
 #endif // nsBaseDragService_h__