Bug 668437. Part 2. When placing popup widgets check if the client offset of the window has changed in addition to the top left of the window. r=enndeakin

This commit is contained in:
Timothy Nikkel 2011-12-01 13:56:41 -06:00
parent 0e3f3865eb
commit e5d288b5ae
3 changed files with 18 additions and 5 deletions

View File

@ -115,6 +115,7 @@ nsMenuPopupFrame::nsMenuPopupFrame(nsIPresShell* aShell, nsStyleContext* aContex
:nsBoxFrame(aShell, aContext),
mCurrentMenu(nsnull),
mPrefSize(-1, -1),
mLastClientOffset(0, 0),
mPopupType(ePopupTypePanel),
mPopupState(ePopupClosed),
mPopupAlignment(POPUPALIGNMENT_NONE),
@ -1327,9 +1328,9 @@ nsMenuPopupFrame::SetPopupPosition(nsIFrame* aAnchorFrame, bool aIsMove)
// to save time since they will never have a titlebar.
nsIWidget* widget = view->GetWidget();
if (mPopupType == ePopupTypePanel && widget) {
nsIntPoint offset = widget->GetClientOffset();
viewPoint.x += presContext->DevPixelsToAppUnits(offset.x);
viewPoint.y += presContext->DevPixelsToAppUnits(offset.y);
mLastClientOffset = widget->GetClientOffset();
viewPoint.x += presContext->DevPixelsToAppUnits(mLastClientOffset.x);
viewPoint.y += presContext->DevPixelsToAppUnits(mLastClientOffset.y);
}
// Now that we've positioned the view, sync up the frame's origin.
@ -1869,8 +1870,11 @@ nsMenuPopupFrame::DestroyFrom(nsIFrame* aDestructRoot)
void
nsMenuPopupFrame::MoveTo(PRInt32 aLeft, PRInt32 aTop, bool aUpdateAttrs)
{
if (mScreenXPos == aLeft && mScreenYPos == aTop)
nsIWidget* widget = GetWidget();
if ((mScreenXPos == aLeft && mScreenYPos == aTop) &&
(!widget || widget->GetClientOffset() == mLastClientOffset)) {
return;
}
// reposition the popup at the specified coordinates. Don't clear the anchor
// and position, because the popup can be reset to its anchor position by

View File

@ -352,6 +352,9 @@ public:
NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder,
const nsRect& aDirtyRect,
const nsDisplayListSet& aLists);
nsIntPoint GetLastClientOffset() const { return mLastClientOffset; }
protected:
// returns the popup's level.
@ -435,6 +438,10 @@ protected:
PRInt32 mYPos;
PRInt32 mScreenXPos;
PRInt32 mScreenYPos;
// The value of the client offset of our widget the last time we positioned
// ourselves. We store this so that we can detect when it changes but the
// position of our widget didn't change.
nsIntPoint mLastClientOffset;
nsPopupType mPopupType; // type of popup
nsPopupState mPopupState; // open state of the popup

View File

@ -358,7 +358,9 @@ nsXULPopupManager::PopupMoved(nsIFrame* aFrame, nsIntPoint aPnt)
// Don't do anything if the popup is already at the specified location. This
// prevents recursive calls when a popup is positioned.
nsIntPoint currentPnt = menuPopupFrame->ScreenPosition();
if (aPnt.x != currentPnt.x || aPnt.y != currentPnt.y) {
nsIWidget* widget = menuPopupFrame->GetWidget();
if ((aPnt.x != currentPnt.x || aPnt.y != currentPnt.y) || (widget &&
widget->GetClientOffset() != menuPopupFrame->GetLastClientOffset())) {
// Update the popup's position using SetPopupPosition if the popup is
// anchored and at the parent level as these maintain their position
// relative to the parent window. Otherwise, just update the popup to