Bug 100180 - Modal dialogs should try to cancel any drag sessions in progress. r=roc.
authorMike Conley <mconley@mozilla.com>
Wed, 23 Apr 2014 12:35:00 -0400
changeset 180241 0aab0a3738cf076dafcbc31fd95b0d6f9c8ff1e0
parent 180240 671620466491e7e02bae8cb58e88e936c6c7c746
child 180242 6ea4ce828d069fa99f3e1526f40eaeb193de17a3
push id272
push userpvanderbeken@mozilla.com
push dateMon, 05 May 2014 16:31:18 +0000
reviewersroc
bugs100180
milestone31.0a1
Bug 100180 - Modal dialogs should try to cancel any drag sessions in progress. r=roc.
dom/base/nsGlobalWindow.cpp
widget/windows/nsDragService.cpp
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -8425,16 +8425,23 @@ nsGlobalWindow::EnterModalState()
 
       if (activeShell) {
         nsRefPtr<nsFrameSelection> frameSelection = activeShell->FrameSelection();
         frameSelection->SetMouseDownState(false);
       }
     }
   }
 
+  // If there are any drag and drop operations in flight, try to end them.
+  nsCOMPtr<nsIDragService> ds =
+    do_GetService("@mozilla.org/widget/dragservice;1");
+  if (ds) {
+    ds->EndDragSession(true);
+  }
+
   // Clear the capturing content if it is under topDoc.
   // Usually the activeESM check above does that, but there are cases when
   // we don't have activeESM, or it is for different document.
   nsIDocument* topDoc = topWin->GetExtantDoc();
   nsIContent* capturingContent = nsIPresShell::GetCapturingContent();
   if (capturingContent && topDoc &&
       nsContentUtils::ContentIsCrossDocDescendantOf(capturingContent, topDoc)) {
     nsIPresShell::SetCapturingContent(nullptr, 0);
--- a/widget/windows/nsDragService.cpp
+++ b/widget/windows/nsDragService.cpp
@@ -586,13 +586,20 @@ nsDragService::IsCollectionObject(IDataO
 //
 // Override the default to make sure that we release the data object
 // when the drag ends. It seems that OLE doesn't like to let apps quit
 // w/out crashing when we're still holding onto their data
 //
 NS_IMETHODIMP
 nsDragService::EndDragSession(bool aDoneDrag)
 {
+  // Bug 100180: If we've got mouse events captured, make sure we release it -
+  // that way, if we happen to call EndDragSession before diving into a nested
+  // event loop, we can still respond to mouse events.
+  if (::GetCapture()) {
+    ::ReleaseCapture();
+  }
+
   nsBaseDragService::EndDragSession(aDoneDrag);
   NS_IF_RELEASE(mDataObject);
 
   return NS_OK;
 }