Bug 1525101 - Make the XULPopupManager caller to GenerateChildFrames sound. r=mats
authorEmilio Cobos Álvarez <emilio@crisal.io>
Tue, 12 Feb 2019 18:53:22 +0000
changeset 458777 c405d8906d7c
parent 458776 c8e523ac7349
child 458778 a98671536694
push id35548
push useropoprus@mozilla.com
push dateWed, 13 Feb 2019 09:48:26 +0000
treeherdermozilla-central@93e37c529818 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmats
bugs1525101
milestone67.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 1525101 - Make the XULPopupManager caller to GenerateChildFrames sound. r=mats It only works basically by chance with XBL and doesn't handle any kind of dynamic insertion. See comment 4 in the bug for the diagnostic. Differential Revision: https://phabricator.services.mozilla.com/D19489
layout/xul/nsMenuPopupFrame.cpp
layout/xul/nsMenuPopupFrame.h
layout/xul/nsXULPopupManager.cpp
--- a/layout/xul/nsMenuPopupFrame.cpp
+++ b/layout/xul/nsMenuPopupFrame.cpp
@@ -52,16 +52,17 @@
 #include "mozilla/MouseEvents.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/Event.h"
 #include "mozilla/dom/KeyboardEvent.h"
 #include "mozilla/dom/KeyboardEventBinding.h"
 #include <algorithm>
 
 using namespace mozilla;
+using mozilla::dom::Document;
 using mozilla::dom::Event;
 using mozilla::dom::KeyboardEvent;
 
 int8_t nsMenuPopupFrame::sDefaultLevelIsTop = -1;
 
 DOMTimeStamp nsMenuPopupFrame::sLastKeyTime = 0;
 
 // XXX, kyle.yuan@sun.com, there are 4 definitions for the same purpose:
@@ -386,25 +387,16 @@ NS_IMETHODIMP nsXULPopupShownEvent::Hand
 void nsXULPopupShownEvent::CancelListener() {
   mPopup->RemoveSystemEventListener(NS_LITERAL_STRING("transitionend"), this,
                                     false);
 }
 
 NS_IMPL_ISUPPORTS_INHERITED(nsXULPopupShownEvent, Runnable,
                             nsIDOMEventListener);
 
-void nsMenuPopupFrame::SetInitialChildList(ChildListID aListID,
-                                           nsFrameList& aChildList) {
-  // unless the list is empty, indicate that children have been generated.
-  if (aListID == kPrincipalList && aChildList.NotEmpty()) {
-    mGeneratedChildren = true;
-  }
-  nsBoxFrame::SetInitialChildList(aListID, aChildList);
-}
-
 bool nsMenuPopupFrame::IsLeafDynamic() const {
   if (mGeneratedChildren) return false;
 
   if (mPopupType != ePopupTypeMenu) {
     // any panel with a type attribute, such as the autocomplete popup,
     // is always generated right away.
     return !mContent->AsElement()->HasAttr(kNameSpaceID_None, nsGkAtoms::type);
   }
@@ -448,17 +440,19 @@ void nsMenuPopupFrame::UpdateWidgetPrope
     widget->SetWindowOpacity(StyleUIReset()->mWindowOpacity);
     widget->SetWindowTransform(ComputeWidgetTransform());
   }
 }
 
 void nsMenuPopupFrame::LayoutPopup(nsBoxLayoutState& aState,
                                    nsIFrame* aParentMenu, nsIFrame* aAnchor,
                                    bool aSizedToPopup) {
-  if (!mGeneratedChildren) return;
+  if (IsLeaf()) {
+    return;
+  }
 
   SchedulePaint();
 
   bool shouldPosition = true;
   bool isOpen = IsOpen();
   if (!isOpen) {
     // if the popup is not open, only do layout while showing or if the menu
     // is sized to the popup
--- a/layout/xul/nsMenuPopupFrame.h
+++ b/layout/xul/nsMenuPopupFrame.h
@@ -242,19 +242,16 @@ class nsMenuPopupFrame final : public ns
   // Ensure that a widget has already been created for this view, and create
   // one if it hasn't. If aRecreate is true, destroys any existing widget and
   // creates a new one, regardless of whether one has already been created.
   void EnsureWidget(bool aRecreate = false);
 
   nsresult CreateWidgetForView(nsView* aView);
   uint8_t GetShadowStyle();
 
-  virtual void SetInitialChildList(ChildListID aListID,
-                                   nsFrameList& aChildList) override;
-
   virtual bool IsLeafDynamic() const override;
 
   virtual void UpdateWidgetProperties() override;
 
   // layout, position and display the popup as needed
   void LayoutPopup(nsBoxLayoutState& aState, nsIFrame* aParentMenu,
                    nsIFrame* aAnchor, bool aSizedToPopup);
 
--- a/layout/xul/nsXULPopupManager.cpp
+++ b/layout/xul/nsXULPopupManager.cpp
@@ -1279,18 +1279,21 @@ void nsXULPopupManager::FirePopupShowing
   nsMenuPopupFrame* popupFrame = do_QueryFrame(aPopup->GetPrimaryFrame());
   if (!popupFrame) return;
 
   nsPresContext* presContext = popupFrame->PresContext();
   nsCOMPtr<nsIPresShell> presShell = presContext->PresShell();
   nsPopupType popupType = popupFrame->PopupType();
 
   // generate the child frames if they have not already been generated
-  if (!popupFrame->HasGeneratedChildren()) {
-    popupFrame->SetGeneratedChildren();
+  const bool generateFrames = popupFrame->IsLeaf();
+  MOZ_ASSERT_IF(generateFrames, !popupFrame->HasGeneratedChildren());
+  popupFrame->SetGeneratedChildren();
+  if (generateFrames) {
+    MOZ_ASSERT(popupFrame->PrincipalChildList().IsEmpty());
     presShell->FrameConstructor()->GenerateChildFrames(popupFrame);
   }
 
   // get the frame again
   nsIFrame* frame = aPopup->GetPrimaryFrame();
   if (!frame) return;
 
   presShell->FrameNeedsReflow(frame, nsIPresShell::eTreeChange,