diff --git a/mozilla/layout/xul/base/src/nsMenuBarFrame.cpp b/mozilla/layout/xul/base/src/nsMenuBarFrame.cpp index 353c2f101e7..47ffaca9572 100644 --- a/mozilla/layout/xul/base/src/nsMenuBarFrame.cpp +++ b/mozilla/layout/xul/base/src/nsMenuBarFrame.cpp @@ -522,8 +522,8 @@ nsMenuBarFrame::Escape(PRBool& aHandledFlag) // designation. mCurrentMenu->OpenMenu(PR_FALSE); } - if (nsMenuFrame::mDismissalListener) - nsMenuFrame::mDismissalListener->Unregister(); + if (nsMenuFrame::sDismissalListener) + nsMenuFrame::sDismissalListener->Unregister(); return NS_OK; } @@ -537,8 +537,8 @@ nsMenuBarFrame::Escape(PRBool& aHandledFlag) RemoveKeyboardNavigator(); // Clear out our dismissal listener - if (nsMenuFrame::mDismissalListener) - nsMenuFrame::mDismissalListener->Unregister(); + if (nsMenuFrame::sDismissalListener) + nsMenuFrame::sDismissalListener->Unregister(); return NS_OK; } @@ -571,8 +571,8 @@ nsMenuBarFrame::HideChain() // Stop capturing rollups // (must do this during Hide, which happens before the menu item is executed, // since this reinstates normal event handling.) - if (nsMenuFrame::mDismissalListener) - nsMenuFrame::mDismissalListener->Unregister(); + if (nsMenuFrame::sDismissalListener) + nsMenuFrame::sDismissalListener->Unregister(); if (mCurrentMenu) { mCurrentMenu->ActivateMenu(PR_FALSE); @@ -585,8 +585,8 @@ NS_IMETHODIMP nsMenuBarFrame::DismissChain() { // Stop capturing rollups - if (nsMenuFrame::mDismissalListener) - nsMenuFrame::mDismissalListener->Unregister(); + if (nsMenuFrame::sDismissalListener) + nsMenuFrame::sDismissalListener->Unregister(); SetCurrentMenuItem(nsnull); SetActive(PR_FALSE); @@ -629,7 +629,7 @@ nsMenuBarFrame::GetWidget(nsIWidget **aWidget) NS_IMETHODIMP nsMenuBarFrame::CreateDismissalListener() { - NS_ADDREF(nsMenuFrame::mDismissalListener = new nsMenuDismissalListener()); + NS_ADDREF(nsMenuFrame::sDismissalListener = new nsMenuDismissalListener()); return NS_OK; } diff --git a/mozilla/layout/xul/base/src/nsMenuDismissalListener.cpp b/mozilla/layout/xul/base/src/nsMenuDismissalListener.cpp index 3fc6643a861..18e5d05b910 100644 --- a/mozilla/layout/xul/base/src/nsMenuDismissalListener.cpp +++ b/mozilla/layout/xul/base/src/nsMenuDismissalListener.cpp @@ -77,7 +77,7 @@ nsMenuDismissalListener::SetCurrentMenuParent(nsIMenuParent* aMenuParent) widget->CaptureRollupEvents(this, PR_TRUE, PR_TRUE); mWidget = widget; - NS_ADDREF(nsMenuFrame::mDismissalListener = this); + NS_ADDREF(nsMenuFrame::sDismissalListener = this); } NS_IMETHODIMP @@ -172,7 +172,7 @@ nsMenuDismissalListener::Unregister() mWidget = nsnull; } - NS_RELEASE(nsMenuFrame::mDismissalListener); + NS_RELEASE(nsMenuFrame::sDismissalListener); return NS_OK; } diff --git a/mozilla/layout/xul/base/src/nsMenuFrame.cpp b/mozilla/layout/xul/base/src/nsMenuFrame.cpp index 2667812f1ad..0f67124d467 100644 --- a/mozilla/layout/xul/base/src/nsMenuFrame.cpp +++ b/mozilla/layout/xul/base/src/nsMenuFrame.cpp @@ -77,7 +77,7 @@ static PRInt32 gEatMouseMove = PR_FALSE; -nsMenuDismissalListener* nsMenuFrame::mDismissalListener = nsnull; +nsMenuDismissalListener* nsMenuFrame::sDismissalListener = nsnull; static NS_DEFINE_IID(kLookAndFeelCID, NS_LOOKANDFEEL_CID); @@ -691,8 +691,8 @@ nsMenuFrame::OpenMenuInternal(PRBool aActivateFlag) mCreateHandlerSucceeded = PR_TRUE; // Set the focus back to our view's widget. - if (nsMenuFrame::mDismissalListener) - nsMenuFrame::mDismissalListener->EnableListener(PR_FALSE); + if (nsMenuFrame::sDismissalListener) + nsMenuFrame::sDismissalListener->EnableListener(PR_FALSE); // XXX Only have this here because of RDF-generated content. MarkAsGenerated(); @@ -788,8 +788,8 @@ nsMenuFrame::OpenMenuInternal(PRBool aActivateFlag) } // Set the focus back to our view's widget. - if (nsMenuFrame::mDismissalListener) - nsMenuFrame::mDismissalListener->EnableListener(PR_TRUE); + if (nsMenuFrame::sDismissalListener) + nsMenuFrame::sDismissalListener->EnableListener(PR_TRUE); } else { @@ -802,9 +802,9 @@ nsMenuFrame::OpenMenuInternal(PRBool aActivateFlag) mMenuOpen = PR_FALSE; // Set the focus back to our view's widget. - if (nsMenuFrame::mDismissalListener) { - nsMenuFrame::mDismissalListener->EnableListener(PR_FALSE); - nsMenuFrame::mDismissalListener->SetCurrentMenuParent(mMenuParent); + if (nsMenuFrame::sDismissalListener) { + nsMenuFrame::sDismissalListener->EnableListener(PR_FALSE); + nsMenuFrame::sDismissalListener->SetCurrentMenuParent(mMenuParent); } nsIFrame* frame = mPopupFrames.FirstChild(); @@ -830,8 +830,8 @@ nsMenuFrame::OpenMenuInternal(PRBool aActivateFlag) OnDestroyed(); - if (nsMenuFrame::mDismissalListener) - nsMenuFrame::mDismissalListener->EnableListener(PR_TRUE); + if (nsMenuFrame::sDismissalListener) + nsMenuFrame::sDismissalListener->EnableListener(PR_TRUE); } } @@ -1486,8 +1486,8 @@ nsMenuFrame::Execute() // Temporarily disable rollup events on this menu. This is // to suppress this menu getting removed in the case where // the oncommand handler opens a dialog, etc. - if ( nsMenuFrame::mDismissalListener ) { - nsMenuFrame::mDismissalListener->EnableListener(PR_FALSE); + if ( nsMenuFrame::sDismissalListener ) { + nsMenuFrame::sDismissalListener->EnableListener(PR_FALSE); } // Get our own content node and hold on to it to keep it from going away. @@ -1555,8 +1555,8 @@ nsMenuFrame::Execute() // END HACK // Re-enable rollup events on this menu. - if ( nsMenuFrame::mDismissalListener ) { - nsMenuFrame::mDismissalListener->EnableListener(PR_TRUE); + if ( nsMenuFrame::sDismissalListener ) { + nsMenuFrame::sDismissalListener->EnableListener(PR_TRUE); } } @@ -1841,7 +1841,7 @@ nsMenuFrame::AppendFrames(nsIPresContext* aPresContext, void nsMenuFrame::UpdateDismissalListener(nsIMenuParent* aMenuParent) { - if (!nsMenuFrame::mDismissalListener) { + if (!nsMenuFrame::sDismissalListener) { if (!aMenuParent) return; // Create the listener and attach it to the outermost window. @@ -1850,7 +1850,7 @@ nsMenuFrame::UpdateDismissalListener(nsIMenuParent* aMenuParent) // Make sure the menu dismissal listener knows what the current // innermost menu popup frame is. - nsMenuFrame::mDismissalListener->SetCurrentMenuParent(aMenuParent); + nsMenuFrame::sDismissalListener->SetCurrentMenuParent(aMenuParent); } NS_IMETHODIMP diff --git a/mozilla/layout/xul/base/src/nsMenuFrame.h b/mozilla/layout/xul/base/src/nsMenuFrame.h index be13165a4d2..7b5020ea30c 100644 --- a/mozilla/layout/xul/base/src/nsMenuFrame.h +++ b/mozilla/layout/xul/base/src/nsMenuFrame.h @@ -236,7 +236,7 @@ protected: static nsString *gModifierSeparator; public: - static nsMenuDismissalListener* mDismissalListener; // The listener that dismisses menus. + static nsMenuDismissalListener* sDismissalListener; // The listener that dismisses menus. private: nsCSSFrameConstructor* mFrameConstructor; }; // class nsMenuFrame diff --git a/mozilla/layout/xul/base/src/nsMenuPopupFrame.cpp b/mozilla/layout/xul/base/src/nsMenuPopupFrame.cpp index cfe52acbd33..51aefffea7d 100644 --- a/mozilla/layout/xul/base/src/nsMenuPopupFrame.cpp +++ b/mozilla/layout/xul/base/src/nsMenuPopupFrame.cpp @@ -133,7 +133,7 @@ NS_INTERFACE_MAP_END_INHERITING(nsBoxFrame) // nsMenuPopupFrame::nsMenuPopupFrame(nsIPresShell* aShell) :nsBoxFrame(aShell), mCurrentMenu(nsnull), mTimerMenu(nsnull), mCloseTimer(nsnull), - mMenuCanOverlapOSBar(PR_FALSE) + mMenuCanOverlapOSBar(PR_FALSE), mShouldAutoPosition(PR_TRUE), mShouldRollup(PR_TRUE) { SetIsContextMenu(PR_FALSE); // we're not a context menu by default // Don't allow container frames to automatically position @@ -216,6 +216,8 @@ nsMenuPopupFrame::Init(nsIPresContext* aPresContext, ourView->CreateWidget(kCChildCID, &widgetData, nsnull); #endif + MoveToAttributePosition(); + return rv; } @@ -529,7 +531,7 @@ void GetWidgetForView(nsIView *aView, nsIWidget *&aWidget) // this document. // void -nsMenuPopupFrame :: AdjustClientXYForNestedDocuments ( nsIDOMXULDocument* inPopupDoc, nsIPresShell* inPopupShell, +nsMenuPopupFrame::AdjustClientXYForNestedDocuments ( nsIDOMXULDocument* inPopupDoc, nsIPresShell* inPopupShell, PRInt32 inClientX, PRInt32 inClientY, PRInt32* outAdjX, PRInt32* outAdjY ) { @@ -607,7 +609,7 @@ nsMenuPopupFrame :: AdjustClientXYForNestedDocuments ( nsIDOMXULDocument* inPopu // the parent. // void -nsMenuPopupFrame :: AdjustPositionForAnchorAlign ( PRInt32* ioXPos, PRInt32* ioYPos, const nsRect & inParentRect, +nsMenuPopupFrame::AdjustPositionForAnchorAlign ( PRInt32* ioXPos, PRInt32* ioYPos, const nsRect & inParentRect, const nsString& aPopupAnchor, const nsString& aPopupAlign, PRBool* outFlushWithTopBottom ) { @@ -684,7 +686,7 @@ nsMenuPopupFrame :: AdjustPositionForAnchorAlign ( PRInt32* ioXPos, PRInt32* ioY // flush against the bottom, is there more room if its bottom edge were flush against the top) // PRBool -nsMenuPopupFrame :: IsMoreRoomOnOtherSideOfParent ( PRBool inFlushAboveBelow, PRInt32 inScreenViewLocX, PRInt32 inScreenViewLocY, +nsMenuPopupFrame::IsMoreRoomOnOtherSideOfParent ( PRBool inFlushAboveBelow, PRInt32 inScreenViewLocX, PRInt32 inScreenViewLocY, const nsRect & inScreenParentFrameRect, PRInt32 inScreenTopTwips, PRInt32 inScreenLeftTwips, PRInt32 inScreenBottomTwips, PRInt32 inScreenRightTwips ) { @@ -722,10 +724,10 @@ nsMenuPopupFrame :: IsMoreRoomOnOtherSideOfParent ( PRBool inFlushAboveBelow, PR // have the side effect of touching |mRect|. // void -nsMenuPopupFrame :: MovePopupToOtherSideOfParent ( PRBool inFlushAboveBelow, PRInt32* ioXPos, PRInt32* ioYPos, - PRInt32* ioScreenViewLocX, PRInt32* ioScreenViewLocY, - const nsRect & inScreenParentFrameRect, PRInt32 inScreenTopTwips, PRInt32 inScreenLeftTwips, - PRInt32 inScreenBottomTwips, PRInt32 inScreenRightTwips ) +nsMenuPopupFrame::MovePopupToOtherSideOfParent ( PRBool inFlushAboveBelow, PRInt32* ioXPos, PRInt32* ioYPos, + PRInt32* ioScreenViewLocX, PRInt32* ioScreenViewLocY, + const nsRect & inScreenParentFrameRect, PRInt32 inScreenTopTwips, PRInt32 inScreenLeftTwips, + PRInt32 inScreenBottomTwips, PRInt32 inScreenRightTwips ) { if ( inFlushAboveBelow ) { if ( *ioScreenViewLocY > inScreenParentFrameRect.y ) { // view is currently below parent @@ -784,6 +786,9 @@ nsMenuPopupFrame::SyncViewWithFrame(nsIPresContext* aPresContext, NS_ENSURE_ARG(aPresContext); NS_ENSURE_ARG(aFrame); + if (!mShouldAutoPosition) + return NS_OK; + // |containingView| // The view that contains the frame that is invoking this popup. This is // the canvas view inside the scrollport view. It can have negative bounds @@ -1541,11 +1546,14 @@ nsMenuPopupFrame::GetParentPopup(nsIMenuParent** aMenuParent) NS_IMETHODIMP nsMenuPopupFrame::HideChain() { + if (!mShouldRollup) + return NS_OK; + // Stop capturing rollups // (must do this during Hide, which happens before the menu item is executed, // since this reinstates normal event handling.) - if (nsMenuFrame::mDismissalListener) - nsMenuFrame::mDismissalListener->Unregister(); + if (nsMenuFrame::sDismissalListener) + nsMenuFrame::sDismissalListener->Unregister(); nsIFrame* frame; GetParent(&frame); @@ -1575,9 +1583,12 @@ nsMenuPopupFrame::HideChain() NS_IMETHODIMP nsMenuPopupFrame::DismissChain() { + if (!mShouldRollup) + return NS_OK; + // Stop capturing rollups - if (nsMenuFrame::mDismissalListener) - nsMenuFrame::mDismissalListener->Unregister(); + if (nsMenuFrame::sDismissalListener) + nsMenuFrame::sDismissalListener->Unregister(); // Get our menu parent. nsIFrame* frame; @@ -1622,7 +1633,7 @@ nsMenuPopupFrame::CreateDismissalListener() { nsMenuDismissalListener *listener = new nsMenuDismissalListener(); if (!listener) return NS_ERROR_OUT_OF_MEMORY; - nsMenuFrame::mDismissalListener = listener; + nsMenuFrame::sDismissalListener = listener; NS_ADDREF(listener); return NS_OK; } @@ -1687,6 +1698,43 @@ nsMenuPopupFrame::IsDisabled(nsIContent* aContent) return PR_FALSE; } +NS_IMETHODIMP +nsMenuPopupFrame::AttributeChanged(nsIPresContext* aPresContext, + nsIContent* aChild, + PRInt32 aNameSpaceID, + nsIAtom* aAttribute, + PRInt32 aModType, + PRInt32 aHint) + +{ + nsresult rv = nsBoxFrame::AttributeChanged(aPresContext, aChild, + aNameSpaceID, aAttribute, aModType, aHint); + + if (aAttribute == nsXULAtoms::left || aAttribute == nsXULAtoms::top) + MoveToAttributePosition(); + + return NS_OK; +} + +void +nsMenuPopupFrame::MoveToAttributePosition() +{ + // Move the widget around when the user sets the |left| and |top| attributes. + // Note that this is not the best way to move the widget, as it results in lots + // of FE notifications and is likely to be slow as molasses. Use |moveTo| on + // nsIPopupBoxObject if possible. + nsAutoString left, top; + mContent->GetAttr(kNameSpaceID_None, nsXULAtoms::left, left); + mContent->GetAttr(kNameSpaceID_None, nsXULAtoms::top, top); + PRInt32 err1, err2, xPos, yPos; + xPos = left.ToInteger(&err1); + yPos = top.ToInteger(&err2); + + if (NS_SUCCEEDED(err1) && NS_SUCCEEDED(err2)) + MoveTo(xPos, yPos); +} + + NS_IMETHODIMP nsMenuPopupFrame::HandleEvent(nsIPresContext* aPresContext, nsGUIEvent* aEvent, @@ -1829,9 +1877,92 @@ nsMenuPopupFrame::KillCloseTimer() NS_IMETHODIMP -nsMenuPopupFrame :: KillPendingTimers ( ) +nsMenuPopupFrame::KillPendingTimers ( ) { return KillCloseTimer(); } // KillPendingTimers +void +nsMenuPopupFrame::MoveTo(PRInt32 aLeft, PRInt32 aTop) +{ + // Set the 'left' and 'top' attributes + nsAutoString left, top; + left.AppendInt(aLeft); + top.AppendInt(aTop); + + mContent->SetAttr(kNameSpaceID_None, nsXULAtoms::left, left, PR_FALSE); + mContent->SetAttr(kNameSpaceID_None, nsXULAtoms::top, top, PR_FALSE); + + nsIView* view = nsnull; + GetView(mPresContext, &view); + + // Retrieve screen position of parent view + nsIView* parentView = nsnull; + view->GetParent(parentView); + nsPoint screenPos; + GetScreenPosition(parentView, screenPos); + + // Move the widget + nsCOMPtr widget; + view->GetWidget(*getter_AddRefs(widget)); + widget->Move(aLeft - screenPos.x, aTop - screenPos.y); +} + +void +nsMenuPopupFrame::GetScreenPosition(nsIView* aView, nsPoint& aScreenPosition) +{ + nsPoint screenPos(0,0); + nscoord x, y; + + nsIView* currView = aView; + nsIView* nextView = nsnull; + + while (1) { + currView->GetPosition(&x, &y); + screenPos.x += x; + screenPos.y += y; + + currView->GetParent(nextView); + if (!nextView) + break; + else + currView = nextView; + } + + nsCOMPtr rootWidget; + currView->GetWidget(*getter_AddRefs(rootWidget)); + nsRect bounds, screenBounds; + rootWidget->GetScreenBounds(bounds); + rootWidget->WidgetToScreen(bounds, screenBounds); + + float t2p; + mPresContext->GetTwipsToPixels(&t2p); + + aScreenPosition.x = NSTwipsToIntPixels(screenPos.x, t2p) + screenBounds.x; + aScreenPosition.y = NSTwipsToIntPixels(screenPos.y, t2p) + screenBounds.y; +} + +void +nsMenuPopupFrame::GetAutoPosition(PRBool* aShouldAutoPosition) +{ + *aShouldAutoPosition = mShouldAutoPosition; +} + +void +nsMenuPopupFrame::SetAutoPosition(PRBool aShouldAutoPosition) +{ + mShouldAutoPosition = aShouldAutoPosition; +} + +void +nsMenuPopupFrame::EnableRollup(PRBool aShouldRollup) +{ + if (!aShouldRollup) { + if (nsMenuFrame::sDismissalListener) + nsMenuFrame::sDismissalListener->Unregister(); + } + else + CreateDismissalListener(); +} + diff --git a/mozilla/layout/xul/base/src/nsMenuPopupFrame.h b/mozilla/layout/xul/base/src/nsMenuPopupFrame.h index 8476dbc59c4..9e317fff21d 100644 --- a/mozilla/layout/xul/base/src/nsMenuPopupFrame.h +++ b/mozilla/layout/xul/base/src/nsMenuPopupFrame.h @@ -94,10 +94,17 @@ public: // Overridden methods NS_IMETHOD Init(nsIPresContext* aPresContext, - nsIContent* aContent, - nsIFrame* aParent, - nsIStyleContext* aContext, - nsIFrame* aPrevInFlow); + nsIContent* aContent, + nsIFrame* aParent, + nsIStyleContext* aContext, + nsIFrame* aPrevInFlow); + + NS_IMETHOD AttributeChanged(nsIPresContext* aPresContext, + nsIContent* aChild, + PRInt32 aNameSpaceID, + nsIAtom* aAttribute, + PRInt32 aModType, + PRInt32 aHint); NS_IMETHOD HandleEvent(nsIPresContext* aPresContext, nsGUIEvent* aEvent, @@ -142,6 +149,13 @@ public: void EnsureMenuItemIsVisible(nsIMenuFrame* aMenuFrame); + void MoveTo(PRInt32 aLeft, PRInt32 aTop); + void GetScreenPosition(nsIView* aView, nsPoint& aScreenPosition); + + void GetAutoPosition(PRBool* aShouldAutoPosition); + void SetAutoPosition(PRBool aShouldAutoPosition); + void EnableRollup(PRBool aShouldRollup); + nsIScrollableView* GetScrollableView(nsIFrame* aStart); protected: @@ -167,6 +181,10 @@ protected: const nsRect & inScreenParentFrameRect, PRInt32 inScreenTopTwips, PRInt32 inScreenLeftTwips, PRInt32 inScreenBottomTwips, PRInt32 inScreenRightTwips ) ; + // Move the popup to the position specified in its |left| and |top| attributes. + void MoveToAttributePosition(); + + nsIMenuFrame* mCurrentMenu; // The current menu that is active. PRBool mIsCapturingMouseEvents; // Whether or not we're grabbing the mouse events. // XXX Hack @@ -182,6 +200,9 @@ protected: PRBool mMenuCanOverlapOSBar; // can we appear over the taskbar/menubar? + PRBool mShouldAutoPosition; // Should SyncViewWithFrame be allowed to auto position popup? + PRBool mShouldRollup; // Should this menupopup be allowed to dismiss automatically? + }; // class nsMenuPopupFrame #endif diff --git a/mozilla/layout/xul/base/src/nsPopupBoxObject.cpp b/mozilla/layout/xul/base/src/nsPopupBoxObject.cpp index 7abeef64d4c..38c7954e16b 100644 --- a/mozilla/layout/xul/base/src/nsPopupBoxObject.cpp +++ b/mozilla/layout/xul/base/src/nsPopupBoxObject.cpp @@ -17,7 +17,9 @@ * Copyright (C) 1998 Netscape Communications Corporation. All * Rights Reserved. * - * Original Author: David W. Hyatt (hyatt@netscape.com) + * Original Authors: + * David W. Hyatt + * Ben Goodger * * Contributor(s): */ @@ -32,6 +34,13 @@ #include "nsIDOMDocument.h" #include "nsIDOMElement.h" #include "nsIFrame.h" +#include "nsINameSpaceManager.h" +#include "nsHTMLAtoms.h" +#include "nsXULAtoms.h" +#include "nsMenuPopupFrame.h" +#include "nsIViewManager.h" +#include "nsIWidget.h" + class nsPopupBoxObject : public nsIPopupBoxObject, public nsBoxObject { @@ -41,8 +50,7 @@ public: nsPopupBoxObject(); virtual ~nsPopupBoxObject(); - -protected: + }; /* Implementation file */ @@ -151,8 +159,112 @@ nsPopupBoxObject::ShowPopup(nsIDOMElement* aSrcContent, nsAutoString anchorAlign(anAnchorAlignment); nsAutoString popupAlign(aPopupAlignment); - return popupSet->ShowPopup(srcContent, popupContent, aXPos, aYPos, popupType, anchorAlign, - popupAlign); + // Use |left| and |top| dimension attributes to position the popup if + // present, as they may have been persisted. + nsAutoString left, top; + popupContent->GetAttr(kNameSpaceID_None, nsXULAtoms::left, left); + popupContent->GetAttr(kNameSpaceID_None, nsXULAtoms::top, top); + + PRInt32 err; + if (!left.IsEmpty()) { + aXPos = left.ToInteger(&err); + if (NS_FAILED(err)) + return err; + } + if (!top.IsEmpty()) { + aYPos = top.ToInteger(&err); + if (NS_FAILED(err)) + return err; + } + + return popupSet->ShowPopup(srcContent, popupContent, aXPos, aYPos, + popupType, anchorAlign, popupAlign); +} + +NS_IMETHODIMP +nsPopupBoxObject::MoveTo(PRInt32 aLeft, PRInt32 aTop) +{ + nsIFrame* frame = GetFrame(); + if (!frame) return NS_OK; + + nsMenuPopupFrame* menuPopupFrame = NS_STATIC_CAST(nsMenuPopupFrame*, frame); + if (!menuPopupFrame) return NS_OK; + + menuPopupFrame->MoveTo(aLeft, aTop); + + return NS_OK; +} + +NS_IMETHODIMP +nsPopupBoxObject::SizeTo(PRInt32 aWidth, PRInt32 aHeight) +{ + nsAutoString width, height; + width.AppendInt(aWidth); + height.AppendInt(aHeight); + + mContent->SetAttr(kNameSpaceID_None, nsHTMLAtoms::width, width, PR_FALSE); + mContent->SetAttr(kNameSpaceID_None, nsHTMLAtoms::height, height, PR_TRUE); + + return NS_OK; +} + +NS_IMETHODIMP +nsPopupBoxObject::GetAutoPosition(PRBool* aShouldAutoPosition) +{ + nsIFrame* frame = GetFrame(); + if (!frame) return NS_OK; + + nsMenuPopupFrame* menuPopupFrame = NS_STATIC_CAST(nsMenuPopupFrame*, frame); + if (!menuPopupFrame) return NS_OK; + + menuPopupFrame->GetAutoPosition(aShouldAutoPosition); + + return NS_OK; +} + +NS_IMETHODIMP +nsPopupBoxObject::SetAutoPosition(PRBool aShouldAutoPosition) +{ + nsIFrame* frame = GetFrame(); + if (!frame) return NS_OK; + + nsMenuPopupFrame* menuPopupFrame = NS_STATIC_CAST(nsMenuPopupFrame*, frame); + if (!menuPopupFrame) return NS_OK; + + menuPopupFrame->SetAutoPosition(aShouldAutoPosition); + + return NS_OK; +} + +NS_IMETHODIMP +nsPopupBoxObject::EnableRollup(PRBool aShouldRollup) +{ + nsIFrame* frame = GetFrame(); + if (!frame) return NS_OK; + + nsMenuPopupFrame* menuPopupFrame = NS_STATIC_CAST(nsMenuPopupFrame*, frame); + if (!menuPopupFrame) return NS_OK; + + menuPopupFrame->EnableRollup(aShouldRollup); + + return NS_OK; +} + +NS_IMETHODIMP +nsPopupBoxObject::EnableKeyboardNavigator(PRBool aEnableKeyboardNavigator) +{ + nsIFrame* frame = GetFrame(); + if (!frame) return NS_OK; + + nsMenuPopupFrame* menuPopupFrame = NS_STATIC_CAST(nsMenuPopupFrame*, frame); + if (!menuPopupFrame) return NS_OK; + + if (aEnableKeyboardNavigator) + menuPopupFrame->InstallKeyboardNavigator(); + else + menuPopupFrame->RemoveKeyboardNavigator(); + + return NS_OK; } // Creation Routine /////////////////////////////////////////////////////////////////////// diff --git a/mozilla/layout/xul/base/src/nsPopupSetFrame.cpp b/mozilla/layout/xul/base/src/nsPopupSetFrame.cpp index 9f6c3ad66e6..9c26f512c3a 100644 --- a/mozilla/layout/xul/base/src/nsPopupSetFrame.cpp +++ b/mozilla/layout/xul/base/src/nsPopupSetFrame.cpp @@ -444,8 +444,8 @@ nsPopupSetFrame::OpenPopup(nsPopupFrameList* aEntry, PRBool aActivateFlag) // Unregister, but not if we're a tooltip if (aEntry->mPopupType != NS_LITERAL_STRING("tooltip") ) { - if (nsMenuFrame::mDismissalListener) - nsMenuFrame::mDismissalListener->Unregister(); + if (nsMenuFrame::sDismissalListener) + nsMenuFrame::sDismissalListener->Unregister(); } // Remove any keyboard navigators @@ -470,6 +470,7 @@ nsPopupSetFrame::ActivatePopup(nsPopupFrameList* aEntry, PRBool aActivateFlag) // is set by setting the |menuactive| attribute. This used to trip css into showing the menu // but now we do it ourselves. if (aActivateFlag) + // XXXben hook in |width| and |height| usage here? aEntry->mPopupContent->SetAttr(kNameSpaceID_None, nsXULAtoms::menutobedisplayed, NS_LITERAL_STRING("true"), PR_TRUE); else { aEntry->mPopupContent->UnsetAttr(kNameSpaceID_None, nsXULAtoms::menuactive, PR_TRUE); @@ -665,7 +666,7 @@ nsPopupSetFrame::OnDestroyed(nsIContent* aPopupContent) void nsPopupSetFrame::UpdateDismissalListener(nsIMenuParent* aMenuParent) { - if (!nsMenuFrame::mDismissalListener) { + if (!nsMenuFrame::sDismissalListener) { if (!aMenuParent) return; // Create the listener and attach it to the outermost window. @@ -674,7 +675,7 @@ nsPopupSetFrame::UpdateDismissalListener(nsIMenuParent* aMenuParent) // Make sure the menu dismissal listener knows what the current // innermost menu popup frame is. - nsMenuFrame::mDismissalListener->SetCurrentMenuParent(aMenuParent); + nsMenuFrame::sDismissalListener->SetCurrentMenuParent(aMenuParent); } NS_IMETHODIMP