Bug 1370034 - Implement UpdateWidgetProperties for top level windows and for popups, and call nsIWidget::SetWindowShadow. r?dbaron draft
authorMarkus Stange <mstange@themasta.com>
Fri, 16 Jun 2017 15:08:30 -0400
changeset 596313 9a1c79a11ad6ceeb30fb53c08accb3769e3a147e
parent 596312 014c89d42ff0a91cf56626ed7d537134ad63246a
child 596314 96a9b4e7fc8020966994df345b8b584ffe9c1aa0
child 596345 a8b292491888ede3a5d75a5f19aa775b5697e8ca
push id64577
push userbmo:mstange@themasta.com
push dateMon, 19 Jun 2017 04:31:30 +0000
reviewersdbaron
bugs1370034
milestone56.0a1
Bug 1370034 - Implement UpdateWidgetProperties for top level windows and for popups, and call nsIWidget::SetWindowShadow. r?dbaron MozReview-Commit-ID: 9ooCdDRLOSq
layout/generic/nsFrame.cpp
layout/generic/nsIFrame.h
layout/xul/nsMenuPopupFrame.cpp
layout/xul/nsMenuPopupFrame.h
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -10474,16 +10474,54 @@ IsFrameScrolledOutOfView(nsIFrame *aFram
 }
 
 bool
 nsIFrame::IsScrolledOutOfView()
 {
   return IsFrameScrolledOutOfView(this);
 }
 
+static already_AddRefed<nsIWidget>
+GetWindowWidget(nsPresContext* aPresContext)
+{
+  // We want to obtain the widget for the window. We can't use any of these
+  // methods: nsPresContext::GetRootWidget, nsPresContext::GetNearestWidget,
+  // nsIFrame::GetNearestWidget because those deal with child widgets and
+  // there is no parent widget connection between child widgets and the
+  // window widget that contains them.
+  nsCOMPtr<nsISupports> container = aPresContext->Document()->GetContainer();
+  nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(container);
+  if (!baseWindow) {
+    return nullptr;
+  }
+
+  nsCOMPtr<nsIWidget> mainWidget;
+  baseWindow->GetMainWidget(getter_AddRefs(mainWidget));
+  return mainWidget.forget();
+}
+
+void
+nsIFrame::UpdateWidgetProperties()
+{
+  nsPresContext* presContext = PresContext();
+  if (presContext->IsRoot() || !presContext->IsChrome()) {
+    // Don't do anything for documents that aren't the root chrome document.
+    return;
+  }
+  nsIFrame* rootFrame =
+    presContext->FrameConstructor()->GetRootElementStyleFrame();
+  if (this != rootFrame) {
+    // Only the window's root style frame is relevant for widget properties.
+    return;
+  }
+  if (nsCOMPtr<nsIWidget> widget = GetWindowWidget(presContext)) {
+    widget->SetWindowOpacity(StyleUIReset()->mWindowOpacity);
+  }
+}
+
 void
 nsIFrame::DoUpdateStyleOfOwnedAnonBoxes(ServoStyleSet& aStyleSet,
                                         nsStyleChangeList& aChangeList,
                                         nsChangeHint aHintForThisFrame)
 {
   // As a special case, we check for {ib}-split block frames here, rather
   // than have an nsInlineFrame::AppendDirectlyOwnedAnonBoxes implementation
   // that returns them.
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -3929,17 +3929,20 @@ public:
     return StyleDisplay()->BackfaceIsHidden();
   }
 
   /**
    * Returns true if the frame is scrolled out of view.
    */
   bool IsScrolledOutOfView();
 
-  virtual void UpdateWidgetProperties() {}
+  /**
+   * Applies the values from the -moz-window-* properties to the widget.
+   */
+  virtual void UpdateWidgetProperties();
 
   /**
    * @return true iff this frame has one or more associated image requests.
    * @see mozilla::css::ImageLoader.
    */
   bool HasImageRequest() const { return mHasImageRequest; }
 
   /**
--- a/layout/xul/nsMenuPopupFrame.cpp
+++ b/layout/xul/nsMenuPopupFrame.cpp
@@ -452,16 +452,24 @@ nsMenuPopupFrame::IsLeafDynamic() const
   // the parent menu is dependent on the size of the popup, so the frames
   // need to exist in order to calculate this size.
   nsIContent* parentContent = mContent->GetParent();
   return (parentContent &&
           !parentContent->HasAttr(kNameSpaceID_None, nsGkAtoms::sizetopopup));
 }
 
 void
+nsMenuPopupFrame::UpdateWidgetProperties()
+{
+  if (nsIWidget* widget = GetWidget()) {
+    widget->SetWindowOpacity(StyleUIReset()->mWindowOpacity);
+  }
+}
+
+void
 nsMenuPopupFrame::LayoutPopup(nsBoxLayoutState& aState, nsIFrame* aParentMenu,
                               nsIFrame* aAnchor, bool aSizedToPopup)
 {
   if (!mGeneratedChildren)
     return;
 
   SchedulePaint();
 
--- a/layout/xul/nsMenuPopupFrame.h
+++ b/layout/xul/nsMenuPopupFrame.h
@@ -243,16 +243,18 @@ public:
   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);
 
   nsView* GetRootViewForPopup(nsIFrame* aStartFrame);
 
   // Set the position of the popup either relative to the anchor aAnchorFrame
   // (or the frame for mAnchorContent if aAnchorFrame is null), anchored at a