Bug 1156401 - Fix ContextMenu handling when building Fennec with C++ APZ. r=kats, r=botond
authorDanilo Cesar Lemes de Paula <danilo.cesar@collabora.co.uk>
Thu, 30 Apr 2015 06:09:00 -0400
changeset 273367 d4b430ab9d27aaff59b75aec4d52a947736c62e6
parent 273366 cbc880a746c6fde122c8c66bb8ab6bc91129a65d
child 273368 35408d0b3835f884edd14e0f90ae2ee4ceb9dedf
push id863
push userraliiev@mozilla.com
push dateMon, 03 Aug 2015 13:22:43 +0000
treeherdermozilla-release@f6321b14228d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskats, botond
bugs1156401
milestone40.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 1156401 - Fix ContextMenu handling when building Fennec with C++ APZ. r=kats, r=botond This commit deals with the situation where there's no scrollable element on a fennec's page. It uses the Top Most root element (Xul viewport) instead. So this fixes the situation when the tap/click was not being send to the correct dom element.
gfx/layers/apz/util/APZCCallbackHelper.cpp
layout/base/nsDisplayList.cpp
--- a/gfx/layers/apz/util/APZCCallbackHelper.cpp
+++ b/gfx/layers/apz/util/APZCCallbackHelper.cpp
@@ -13,16 +13,17 @@
 #include "nsIScrollableFrame.h"
 #include "nsLayoutUtils.h"
 #include "nsIDOMElement.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsIContent.h"
 #include "nsIDocument.h"
 #include "nsIDOMWindow.h"
 #include "nsRefreshDriver.h"
+#include "nsView.h"
 
 #define APZCCH_LOG(...)
 // #define APZCCH_LOG(...) printf_stderr("APZCCH: " __VA_ARGS__)
 
 namespace mozilla {
 namespace layers {
 
 using dom::TabParent;
@@ -494,33 +495,52 @@ GetDisplayportElementFor(nsIScrollableFr
   // nearest ancestor scrollable frame. The element corresponding to this
   // frame should be the one with the displayport set on it, so find that
   // element and return it.
   nsIContent* content = scrolledFrame->GetContent();
   MOZ_ASSERT(content->IsElement()); // roc says this must be true
   return content->AsElement();
 }
 
+
+static dom::Element*
+GetRootDocumentElementFor(nsIWidget* aWidget)
+{
+  // This returns the root element that ChromeProcessController sets the
+  // displayport on during initialization.
+  if (nsView* view = nsView::GetViewFor(aWidget)) {
+    if (nsIPresShell* shell = view->GetPresShell()) {
+      MOZ_ASSERT(shell->GetDocument());
+      return shell->GetDocument()->GetDocumentElement();
+    }
+  }
+  return nullptr;
+}
+
 // Determine the scrollable target frame for the given point and add it to
 // the target list. If the frame doesn't have a displayport, set one.
 // Return whether or not a displayport was set.
 static bool
 PrepareForSetTargetAPZCNotification(nsIWidget* aWidget,
                                     const ScrollableLayerGuid& aGuid,
                                     nsIFrame* aRootFrame,
                                     const LayoutDeviceIntPoint& aRefPoint,
                                     nsTArray<ScrollableLayerGuid>* aTargets)
 {
   ScrollableLayerGuid guid(aGuid.mLayersId, 0, FrameMetrics::NULL_SCROLL_ID);
   nsPoint point =
     nsLayoutUtils::GetEventCoordinatesRelativeTo(aWidget, aRefPoint, aRootFrame);
   nsIFrame* target =
     nsLayoutUtils::GetFrameForPoint(aRootFrame, point, nsLayoutUtils::IGNORE_ROOT_SCROLL_FRAME);
   nsIScrollableFrame* scrollAncestor = GetScrollableAncestorFrame(target);
-  nsCOMPtr<dom::Element> dpElement = GetDisplayportElementFor(scrollAncestor);
+
+  // Assuming that if there's no scrollAncestor, there's already a displayPort.
+  nsCOMPtr<dom::Element> dpElement = scrollAncestor
+    ? GetDisplayportElementFor(scrollAncestor)
+    : GetRootDocumentElementFor(aWidget);
 
   nsAutoString dpElementDesc;
   if (dpElement) {
     dpElement->Describe(dpElementDesc);
   }
   APZCCH_LOG("For event at %s found scrollable element %p (%s)\n",
       Stringify(aRefPoint).c_str(), dpElement.get(),
       NS_LossyConvertUTF16toASCII(dpElementDesc).get());
@@ -529,16 +549,17 @@ PrepareForSetTargetAPZCNotification(nsIW
     dpElement, &(guid.mPresShellId), &(guid.mScrollId));
   aTargets->AppendElement(guid);
 
   if (!guidIsValid || nsLayoutUtils::GetDisplayPort(dpElement, nullptr)) {
     return false;
   }
 
   APZCCH_LOG("%p didn't have a displayport, so setting one...\n", dpElement.get());
+  MOZ_ASSERT(scrollAncestor);
   return nsLayoutUtils::CalculateAndSetDisplayPortMargins(
       scrollAncestor, nsLayoutUtils::RepaintMode::Repaint);
 }
 
 static void
 SendLayersDependentApzcTargetConfirmation(nsIPresShell* aShell, uint64_t aInputBlockId,
                                           const nsTArray<ScrollableLayerGuid>& aTargets)
 {
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -1476,22 +1476,22 @@ already_AddRefed<LayerManager> nsDisplay
     bool isRoot = presContext->IsRootContentDocument();
 
     nsRect viewport(aBuilder->ToReferenceFrame(frame), frame->GetSize());
 
     nsIFrame* scrollFrame = presShell->GetRootScrollFrame();
     nsIContent* content = nullptr;
     if (scrollFrame) {
       content = scrollFrame->GetContent();
-    } else if (!gfxPrefs::LayoutUseContainersForRootFrames()) {
-      // If there is no root scroll frame, and we're using containerless
-      // scrolling, pick the document element instead.
-      // On Android we want the root xul document to get a null scroll id
-      // so that the root content document gets the first non-null scroll id.
-#ifndef MOZ_WIDGET_ANDROID
+    } else {
+      // If there is no root scroll frame, pick the document element instead.
+      // The only case we don't want to do this is in non-APZ fennec, where
+      // we want the root xul document to get a null scroll id so that the root
+      // content document gets the first non-null scroll id.
+#if !defined(MOZ_WIDGET_ANDROID) || defined(MOZ_ANDROID_APZ)
       content = document->GetDocumentElement();
 #endif
     }
 
     root->SetFrameMetrics(
       nsLayoutUtils::ComputeFrameMetrics(frame,
                          presShell->GetRootScrollFrame(),
                          content,