Bug 698266. Go back to using views when clearing mouse capture in views instead of trying to use frames. r=roc
authorTimothy Nikkel <tnikkel@gmail.com>
Wed, 02 Nov 2011 12:58:44 -0500
changeset 80270 961921808d93431291c20010a020d06a3149ce7b
parent 80269 e672c96a4fe4755006d822e126ac06c2535fab75
child 80271 c9a39f3b26e1a5b030e1517d0c11bf7f505df769
push idunknown
push userunknown
push dateunknown
reviewersroc
bugs698266
milestone10.0a1
Bug 698266. Go back to using views when clearing mouse capture in views instead of trying to use frames. r=roc
layout/base/nsPresShell.cpp
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -3651,31 +3651,50 @@ PresShell::DispatchSynthMouseMove(nsGUIE
     // can suppress any synthesized mouse moves caused by that reflow.
     FlushPendingNotifications(Flush_Layout);
   }
 }
 
 NS_IMETHODIMP_(void)
 PresShell::ClearMouseCapture(nsIView* aView)
 {
-  if (!aView) {
-    nsIPresShell::ClearMouseCapture(static_cast<nsIFrame*>(nsnull));
-    return;
-  }
-
-  nsIFrame* frame = nsnull;
-  nsIView* view = aView;
-  while (!frame && view) {
-    frame = static_cast<nsIFrame*>(view->GetClientData());
-    view = view->GetParent();
-  }
-
-  if (frame) {
-    nsIPresShell::ClearMouseCapture(frame);
-  }
+  if (gCaptureInfo.mContent) {
+    if (aView) {
+      // if a view was specified, ensure that the captured content is within
+      // this view.
+      nsIFrame* frame = gCaptureInfo.mContent->GetPrimaryFrame();
+      if (frame) {
+        nsIView* view = frame->GetClosestView();
+        // if there is no view, capturing won't be handled any more, so
+        // just release the capture.
+        if (view) {
+          do {
+            if (view == aView) {
+              NS_RELEASE(gCaptureInfo.mContent);
+              // the view containing the captured content likely disappeared so
+              // disable capture for now.
+              gCaptureInfo.mAllowed = false;
+              break;
+            }
+
+            view = view->GetParent();
+          } while (view);
+          // return if the view wasn't found
+          return;
+        }
+      }
+    }
+
+    NS_RELEASE(gCaptureInfo.mContent);
+  }
+
+  // disable mouse capture until the next mousedown as a dialog has opened
+  // or a drag has started. Otherwise, someone could start capture during
+  // the modal dialog or drag.
+  gCaptureInfo.mAllowed = false;
 }
 
 void
 nsIPresShell::ClearMouseCapture(nsIFrame* aFrame)
 {
   if (!gCaptureInfo.mContent) {
     gCaptureInfo.mAllowed = false;
     return;