Bug 489127 - nodesFromRect required for better usability on mobile devices (part 3) [r=roc]
authorFelipe Gomes <felipc@gmail.com>
Wed, 07 Apr 2010 20:31:26 -0400
changeset 40569 c417a4e9347861c0c6eabe203caf5c349e6ef8dd
parent 40568 d39c927497e2667710d1ed0c29133fae4f5fe7eb
child 40570 a1d1e59ac1de9028a9d9b6ac2117692858b4f090
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs489127
milestone1.9.3a5pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
Bug 489127 - nodesFromRect required for better usability on mobile devices (part 3) [r=roc]
layout/base/nsLayoutUtils.cpp
layout/base/nsLayoutUtils.h
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -1008,50 +1008,65 @@ static PRBool gDumpEventList = PR_FALSE;
 static PRBool gDumpRepaintRegionForCopy = PR_FALSE;
 #endif
 
 nsIFrame*
 nsLayoutUtils::GetFrameForPoint(nsIFrame* aFrame, nsPoint aPt,
                                 PRBool aShouldIgnoreSuppression,
                                 PRBool aIgnoreRootScrollFrame)
 {
+  nsresult rv;
+  nsTArray<nsIFrame*> outFrames;
+  rv = GetFramesForArea(aFrame, nsRect(aPt, nsSize(1, 1)), outFrames,
+                        aShouldIgnoreSuppression, aIgnoreRootScrollFrame);
+  NS_ENSURE_SUCCESS(rv, nsnull);
+  return outFrames.Length() ? outFrames.ElementAt(0) : nsnull;
+}
+
+nsresult
+nsLayoutUtils::GetFramesForArea(nsIFrame* aFrame, const nsRect& aRect,
+                                nsTArray<nsIFrame*> &aOutFrames,
+                                PRBool aShouldIgnoreSuppression,
+                                PRBool aIgnoreRootScrollFrame)
+{
   nsDisplayListBuilder builder(aFrame, PR_TRUE, PR_FALSE);
   nsDisplayList list;
-  nsRect target(aPt, nsSize(1, 1));
-
-  if (aShouldIgnoreSuppression)
+  nsRect target(aRect);
+
+  if (aShouldIgnoreSuppression) {
     builder.IgnorePaintSuppression();
+  }
 
   if (aIgnoreRootScrollFrame) {
     nsIFrame* rootScrollFrame =
       aFrame->PresContext()->PresShell()->GetRootScrollFrame();
     if (rootScrollFrame) {
       builder.SetIgnoreScrollFrame(rootScrollFrame);
     }
   }
 
   builder.EnterPresShell(aFrame, target);
 
   nsresult rv =
     aFrame->BuildDisplayListForStackingContext(&builder, target, &list);
 
   builder.LeavePresShell(aFrame, target);
-  NS_ENSURE_SUCCESS(rv, nsnull);
+  NS_ENSURE_SUCCESS(rv, rv);
 
 #ifdef DEBUG
   if (gDumpEventList) {
-    fprintf(stderr, "Event handling --- (%d,%d):\n", aPt.x, aPt.y);
+    fprintf(stderr, "Event handling --- (%d,%d):\n", aRect.x, aRect.y);
     nsFrame::PrintDisplayList(&builder, list);
   }
 #endif
 
   nsDisplayItem::HitTestState hitTestState;
-  nsIFrame* result = list.HitTest(&builder, aPt, &hitTestState);
+  list.HitTest(&builder, target, &hitTestState, &aOutFrames);
   list.DeleteAll();
-  return result;
+  return NS_OK;
 }
 
 /**
  * Remove all leaf display items that are not for descendants of
  * aBuilder->GetReferenceFrame() from aList, and move all nsDisplayClip
  * wrappers to their correct locations.
  * @param aExtraPage the page we constructed aList for
  * @param aY the Y-coordinate where aPage would be positioned relative
--- a/layout/base/nsLayoutUtils.h
+++ b/layout/base/nsLayoutUtils.h
@@ -431,16 +431,32 @@ public:
    * @param aIgnoreRootScrollFrame whether or not the display list builder
    * should ignore the root scroll frame.
    */
   static nsIFrame* GetFrameForPoint(nsIFrame* aFrame, nsPoint aPt,
                                     PRBool aShouldIgnoreSuppression = PR_FALSE,
                                     PRBool aIgnoreRootScrollFrame = PR_FALSE);
 
   /**
+   * Given aFrame, the root frame of a stacking context, find all descendant
+   * frames under the area of a rectangle that receives a mouse event,
+   * or nsnull if there is no such frame.
+   * @param aRect the rect, relative to the frame origin
+   * @param aOutFrames an array to add all the frames found
+   * @param aShouldIgnoreSuppression a boolean to control if the display
+   * list builder should ignore paint suppression or not
+   * @param aIgnoreRootScrollFrame whether or not the display list builder
+   * should ignore the root scroll frame.
+   */
+  static nsresult GetFramesForArea(nsIFrame* aFrame, const nsRect& aRect,
+                                   nsTArray<nsIFrame*> &aOutFrames,
+                                   PRBool aShouldIgnoreSuppression = PR_FALSE,
+                                   PRBool aIgnoreRootScrollFrame = PR_FALSE);
+
+  /**
    * Given a point in the global coordinate space, returns that point expressed
    * in the coordinate system of aFrame.  This effectively inverts all transforms
    * between this point and the root frame.
    *
    * @param aFrame The frame that acts as the coordinate space container.
    * @param aPoint The point, in the global space, to get in the frame-local space.
    * @return aPoint, expressed in aFrame's canonical coordinate space.
    */