From 6f1c81015c0562febb8f9bb4812871031ebf5da3 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Tue, 12 Jan 2010 10:45:18 +1300 Subject: [PATCH] Bug 526394. Part 29: Create new nsLayoutUtils methods and remove useless code from nsListControlFrame::CaptureMouseEvents. r=mats --- layout/base/nsLayoutUtils.cpp | 33 +++++++++++++++++++++++++++++ layout/base/nsLayoutUtils.h | 12 +++++++++++ layout/forms/nsListControlFrame.cpp | 6 ------ layout/generic/nsFrame.cpp | 2 +- 4 files changed, 46 insertions(+), 7 deletions(-) diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index 7e8e8ea88de..90d073b83e3 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -89,6 +89,7 @@ #include "imgIContainer.h" #include "nsIImageLoadingContent.h" #include "nsCOMPtr.h" +#include "nsListControlFrame.h" #ifdef MOZ_SVG #include "nsSVGUtils.h" @@ -3233,6 +3234,38 @@ nsLayoutUtils::GetFrameTransparency(nsIFrame* aBackgroundFrame, return eTransparencyOpaque; } +/* static */ PRBool +nsLayoutUtils::IsPopup(nsIFrame* aFrame) +{ + nsIAtom* frameType = aFrame->GetType(); + + // We're a popup if we're the list control frame dropdown for a combobox. + if (frameType == nsGkAtoms::listControlFrame) { + nsListControlFrame* listControlFrame = static_cast(aFrame); + + if (listControlFrame) { + return listControlFrame->IsInDropDownMode(); + } + } + + // ... or if we're a XUL menupopup frame. + return (frameType == nsGkAtoms::menuPopupFrame); +} + +/* static */ nsIFrame* +nsLayoutUtils::GetDisplayRootFrame(nsIFrame* aFrame) +{ + nsIFrame* f = aFrame; + for (;;) { + if (IsPopup(f)) + return f; + nsIFrame* parent = GetCrossDocParentFrame(f); + if (!parent) + return f; + f = parent; + } +} + static PRBool IsNonzeroCoord(const nsStyleCoord& aCoord) { diff --git a/layout/base/nsLayoutUtils.h b/layout/base/nsLayoutUtils.h index 90dafda63ab..cea1328f953 100644 --- a/layout/base/nsLayoutUtils.h +++ b/layout/base/nsLayoutUtils.h @@ -1019,6 +1019,18 @@ public: static nsTransparencyMode GetFrameTransparency(nsIFrame* aBackgroundFrame, nsIFrame* aCSSRootFrame); + /** + * A frame is a popup if it has its own floating window. Menus, panels + * and combobox dropdowns are popups. + */ + static PRBool IsPopup(nsIFrame* aFrame); + + /** + * Find the nearest "display root". This is the nearest enclosing + * popup frame or the root prescontext's root frame. + */ + static nsIFrame* GetDisplayRootFrame(nsIFrame* aFrame); + /** * Get textrun construction flags determined by a given style; in particular * some combination of: diff --git a/layout/forms/nsListControlFrame.cpp b/layout/forms/nsListControlFrame.cpp index 9de54442c35..c9ea5369cb1 100644 --- a/layout/forms/nsListControlFrame.cpp +++ b/layout/forms/nsListControlFrame.cpp @@ -1020,12 +1020,6 @@ nsListControlFrame::CaptureMouseEvents(PRBool aGrabMouseEvents) // code paths, if any exist). if (aGrabMouseEvents && IsInDropDownMode() && nsComboboxControlFrame::ToolkitHasNativePopup()) return; - - nsIView* view = GetScrolledFrame()->GetView(); - - NS_ASSERTION(view, "no view???"); - if (NS_UNLIKELY(!view)) - return; if (aGrabMouseEvents) { nsIPresShell::SetCapturingContent(mContent, CAPTURE_IGNOREALLOWED); diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index 6f83a7e2a70..1fb3d03bfe6 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -1422,7 +1422,7 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder, nsPlaceholderFrame* placeholder = static_cast(aChild); aChild = placeholder->GetOutOfFlowFrame(); NS_ASSERTION(aChild, "No out of flow frame?"); - if (!aChild || aChild->GetType() == nsGkAtoms::menuPopupFrame) + if (!aChild || nsLayoutUtils::IsPopup(aChild)) return NS_OK; // update for the new child disp = aChild->GetStyleDisplay();