Bug 638430. Fix finding the display root of a view when a floating view is inside a floating view. r=roc

This commit is contained in:
Timothy Nikkel 2011-05-29 22:15:00 -05:00
parent f7a686456c
commit c70fc900c3
3 changed files with 28 additions and 21 deletions

View File

@ -6203,21 +6203,6 @@ nsContentUtils::PlatformToDOMLineBreaks(nsString &aString)
}
}
static nsIView* GetDisplayRootFor(nsIView* aView)
{
nsIView *displayRoot = aView;
for (;;) {
nsIView *displayParent = displayRoot->GetParent();
if (!displayParent)
return displayRoot;
if (displayRoot->GetFloating() && !displayParent->GetFloating())
return displayRoot;
displayRoot = displayParent;
}
return nsnull;
}
static already_AddRefed<LayerManager>
LayerManagerForDocumentInternal(nsIDocument *aDoc, bool aRequirePersistent,
bool* aAllowRetaining)
@ -6253,7 +6238,7 @@ LayerManagerForDocumentInternal(nsIDocument *aDoc, bool aRequirePersistent,
if (VM) {
nsIView* rootView = VM->GetRootView();
if (rootView) {
nsIView* displayRoot = GetDisplayRootFor(rootView);
nsIView* displayRoot = nsIViewManager::GetDisplayRootFor(rootView);
if (displayRoot) {
nsIWidget* widget = displayRoot->GetNearestWidget(nsnull);
if (widget) {

View File

@ -378,6 +378,12 @@ public:
* @param aTime Last user event time in microseconds
*/
NS_IMETHOD GetLastUserEventTime(PRUint32& aTime)=0;
/**
* Find the nearest display root view for the view aView. This is the view for
* the nearest enclosing popup or the root view for the root document.
*/
static nsIView* GetDisplayRootFor(nsIView* aView);
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsIViewManager, NS_IVIEWMANAGER_IID)

View File

@ -344,16 +344,32 @@ static nsRegion ConvertRegionBetweenViews(const nsRegion& aIn,
return out;
}
static nsView* GetDisplayRootFor(nsView* aView)
nsIView* nsIViewManager::GetDisplayRootFor(nsIView* aView)
{
nsView *displayRoot = aView;
nsIView *displayRoot = aView;
for (;;) {
nsView *displayParent = displayRoot->GetParent();
nsIView *displayParent = displayRoot->GetParent();
if (!displayParent)
return displayRoot;
if (displayRoot->GetFloating() && !displayParent->GetFloating())
return displayRoot;
// If we have a combobox dropdown popup within a panel popup, both the view
// for the dropdown popup and its parent will be floating, so we need to
// distinguish this situation. We do this by looking for a widget. Any view
// with a widget is a display root, except for plugins.
nsIWidget* widget = displayRoot->GetWidget();
if (widget) {
nsWindowType type;
widget->GetWindowType(type);
if (type == eWindowType_popup) {
NS_ASSERTION(displayRoot->GetFloating() && displayParent->GetFloating(),
"this should only happen with floating views that have floating parents");
return displayRoot;
}
}
displayRoot = displayParent;
}
}
@ -658,7 +674,7 @@ NS_IMETHODIMP nsViewManager::UpdateViewNoSuppression(nsIView *aView,
return NS_OK;
}
nsView* displayRoot = GetDisplayRootFor(view);
nsView* displayRoot = static_cast<nsView*>(GetDisplayRootFor(view));
nsViewManager* displayRootVM = displayRoot->GetViewManager();
// Propagate the update to the displayRoot, since iframes, for example,
// can overlap each other and be translucent. So we have to possibly
@ -1011,7 +1027,7 @@ NS_IMETHODIMP nsViewManager::DispatchEvent(nsGUIEvent *aEvent,
if (NS_IsEventUsingCoordinates(aEvent)) {
// will dispatch using coordinates. Pretty bogus but it's consistent
// with what presshell does.
view = GetDisplayRootFor(baseView);
view = static_cast<nsView*>(GetDisplayRootFor(baseView));
}
if (nsnull != view) {