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 79583 961921808d93431291c20010a020d06a3149ce7b
parent 79582 e672c96a4fe4755006d822e126ac06c2535fab75
child 79584 c9a39f3b26e1a5b030e1517d0c11bf7f505df769
push id3064
push usertnikkel@gmail.com
push dateWed, 02 Nov 2011 17:59:17 +0000
treeherdermozilla-inbound@961921808d93 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs698266
milestone10.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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;