Bug 696745, remove nsIMenuRollup and xul-popup-manager component, r=mats,sr=roc
authorNeil Deakin <neil@mozilla.com>
Tue, 08 Nov 2011 14:59:07 -0500
changeset 80043 e3461cc0b174ce72e95079241a427c73e0dc623f
parent 80042 31328657b6d65a0d1d5b7090a921542d78d7f9f3
child 80044 53a4a92228f850e2d387e75a873c17a60f65eb50
push id21460
push usermak77@bonardo.net
push dateWed, 09 Nov 2011 13:03:50 +0000
treeherdermozilla-central@4fb61ebbf8ff [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmats, roc
bugs696745
milestone10.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 696745, remove nsIMenuRollup and xul-popup-manager component, r=mats,sr=roc
layout/build/nsLayoutCID.h
layout/build/nsLayoutModule.cpp
layout/forms/nsComboboxControlFrame.cpp
layout/forms/nsComboboxControlFrame.h
layout/xul/base/public/nsXULPopupManager.h
layout/xul/base/src/nsXULPopupManager.cpp
widget/public/Makefile.in
widget/public/nsIMenuRollup.h
widget/public/nsIRollupListener.h
widget/public/nsIWidget.h
widget/src/android/nsWindow.h
widget/src/cocoa/nsAppShell.mm
widget/src/cocoa/nsChildView.h
widget/src/cocoa/nsChildView.mm
widget/src/cocoa/nsCocoaWindow.h
widget/src/cocoa/nsCocoaWindow.mm
widget/src/cocoa/nsMenuX.mm
widget/src/cocoa/nsToolkit.mm
widget/src/gtk2/nsWindow.cpp
widget/src/gtk2/nsWindow.h
widget/src/os2/nsWindow.cpp
widget/src/os2/nsWindow.h
widget/src/os2/os2FrameWindow.cpp
widget/src/qt/nsWindow.cpp
widget/src/qt/nsWindow.h
widget/src/windows/nsWindow.cpp
widget/src/windows/nsWindow.h
widget/src/xpwidgets/PuppetWidget.h
xpfe/appshell/src/nsWebShellWindow.cpp
--- a/layout/build/nsLayoutCID.h
+++ b/layout/build/nsLayoutCID.h
@@ -110,20 +110,16 @@
 // {27AECC62-7777-428e-B34C-5973A47B8298}
 #define NS_DOMSTORAGE2_CID \
 { 0x27aecc62, 0x7777, 0x428e, { 0xb3, 0x4c, 0x59, 0x73, 0xa4, 0x7b, 0x82, 0x98 } }
 
 // {b88a4712-eb52-4c10-9b85-bf5894b510f0}
 #define NS_DOMSTORAGEMANAGER_CID               \
 { 0xb88a4712, 0xeb52, 0x4c10, { 0x9b, 0x85, 0xbf, 0x58, 0x94, 0xb5, 0x10, 0xf0 } }
 
-// {14632191-AC21-4BDF-83E7-2363AD17E838}
-#define NS_XULPOPUPMANAGER_CID \
-{ 0x14632191, 0xac21, 0x4bdf, { 0x83, 0xe7, 0x23, 0x63, 0xad, 0x17, 0xe8, 0x38 } }
-
 // {93ad72a6-02cd-4716-9626-d47d5ec275ec}
 #define NS_DOMJSON_CID \
 { 0x93ad72a6, 0x02cd, 0x4716, { 0x96, 0x26, 0xd4, 0x7d, 0x5e, 0xc2, 0x75, 0xec } }
 
 // {CF7FD51F-ABA2-44C1-9FF0-11F7508EFCD4}
 #define NS_FOCUSMANAGER_CID \
 { 0xcf7fd51f, 0xaba2, 0x44c1, { 0x9f, 0xf0, 0x11, 0xf7, 0x50, 0x8e, 0xfc, 0xd4 } }
 
--- a/layout/build/nsLayoutModule.cpp
+++ b/layout/build/nsLayoutModule.cpp
@@ -81,17 +81,16 @@
 #include "nsXHTMLContentSerializer.h"
 #include "nsRuleNode.h"
 #include "nsContentAreaDragDrop.h"
 #include "nsContentList.h"
 #include "nsBox.h"
 #include "nsIFrameTraversal.h"
 #include "nsLayoutCID.h"
 #include "nsStyleSheetService.h"
-#include "nsXULPopupManager.h"
 #include "nsFocusManager.h"
 #include "ThirdPartyUtil.h"
 #include "mozilla/Services.h"
 #include "nsStructuredCloneContainer.h"
 
 #include "nsIEventListenerService.h"
 #include "nsIFrameMessageManager.h"
 
@@ -529,17 +528,16 @@ MAKE_CTOR(CreateSanitizingHTMLSerializer
 MAKE_CTOR(CreateXBLService,               nsIXBLService,               NS_NewXBLService)
 MAKE_CTOR(CreateContentPolicy,            nsIContentPolicy,            NS_NewContentPolicy)
 #ifdef MOZ_XUL
 MAKE_CTOR(CreateXULSortService,           nsIXULSortService,           NS_NewXULSortService)
 // NS_NewXULContentBuilder
 // NS_NewXULTreeBuilder
 MAKE_CTOR(CreateXULDocument,              nsIXULDocument,              NS_NewXULDocument)
 // NS_NewXULControllers
-MAKE_CTOR(CreateXULPopupManager,      nsISupports,      NS_NewXULPopupManager)
 #endif
 #ifdef MOZ_XTF
 MAKE_CTOR(CreateXTFService,               nsIXTFService,               NS_NewXTFService)
 MAKE_CTOR(CreateXMLContentBuilder,        nsIXMLContentBuilder,        NS_NewXMLContentBuilder)
 #endif
 MAKE_CTOR(CreateContentDLF,               nsIDocumentLoaderFactory,    NS_NewContentDocumentLoaderFactory)
 MAKE_CTOR(CreateEventListenerService,     nsIEventListenerService,     NS_NewEventListenerService)
 MAKE_CTOR(CreateGlobalMessageManager,     nsIChromeFrameMessageManager,NS_NewGlobalMessageManager)
@@ -771,17 +769,16 @@ NS_DEFINE_NAMED_CID(NS_XBLSERVICE_CID);
 NS_DEFINE_NAMED_CID(NS_CONTENTPOLICY_CID);
 NS_DEFINE_NAMED_CID(NS_DATADOCUMENTCONTENTPOLICY_CID);
 NS_DEFINE_NAMED_CID(NS_NODATAPROTOCOLCONTENTPOLICY_CID);
 NS_DEFINE_NAMED_CID(NS_XULCONTROLLERS_CID);
 #ifdef MOZ_XUL
 NS_DEFINE_NAMED_CID(NS_XULSORTSERVICE_CID);
 NS_DEFINE_NAMED_CID(NS_XULTEMPLATEBUILDER_CID);
 NS_DEFINE_NAMED_CID(NS_XULTREEBUILDER_CID);
-NS_DEFINE_NAMED_CID(NS_XULPOPUPMANAGER_CID);
 NS_DEFINE_NAMED_CID(NS_XULDOCUMENT_CID);
 #endif
 #ifdef MOZ_XTF
 NS_DEFINE_NAMED_CID(NS_XTFSERVICE_CID);
 NS_DEFINE_NAMED_CID(NS_XMLCONTENTBUILDER_CID);
 #endif
 NS_DEFINE_NAMED_CID(NS_CONTENT_DOCUMENT_LOADER_FACTORY_CID);
 NS_DEFINE_NAMED_CID(NS_DOM_SCRIPT_OBJECT_FACTORY_CID);
@@ -904,17 +901,16 @@ static const mozilla::Module::CIDEntry k
   { &kNS_CONTENTPOLICY_CID, false, NULL, CreateContentPolicy },
   { &kNS_DATADOCUMENTCONTENTPOLICY_CID, false, NULL, nsDataDocumentContentPolicyConstructor },
   { &kNS_NODATAPROTOCOLCONTENTPOLICY_CID, false, NULL, nsNoDataProtocolContentPolicyConstructor },
   { &kNS_XULCONTROLLERS_CID, false, NULL, NS_NewXULControllers },
 #ifdef MOZ_XUL
   { &kNS_XULSORTSERVICE_CID, false, NULL, CreateXULSortService },
   { &kNS_XULTEMPLATEBUILDER_CID, false, NULL, NS_NewXULContentBuilder },
   { &kNS_XULTREEBUILDER_CID, false, NULL, NS_NewXULTreeBuilder },
-  { &kNS_XULPOPUPMANAGER_CID, false, NULL, CreateXULPopupManager },
   { &kNS_XULDOCUMENT_CID, false, NULL, CreateXULDocument },
 #endif
 #ifdef MOZ_XTF
   { &kNS_XTFSERVICE_CID, false, NULL, CreateXTFService },
   { &kNS_XMLCONTENTBUILDER_CID, false, NULL, CreateXMLContentBuilder },
 #endif
   { &kNS_CONTENT_DOCUMENT_LOADER_FACTORY_CID, false, NULL, CreateContentDLF },
   { &kNS_DOM_SCRIPT_OBJECT_FACTORY_CID, false, NULL, nsDOMScriptObjectFactoryConstructor },
@@ -1039,17 +1035,16 @@ static const mozilla::Module::ContractID
   { NS_CONTENTPOLICY_CONTRACTID, &kNS_CONTENTPOLICY_CID },
   { NS_DATADOCUMENTCONTENTPOLICY_CONTRACTID, &kNS_DATADOCUMENTCONTENTPOLICY_CID },
   { NS_NODATAPROTOCOLCONTENTPOLICY_CONTRACTID, &kNS_NODATAPROTOCOLCONTENTPOLICY_CID },
   { "@mozilla.org/xul/xul-controllers;1", &kNS_XULCONTROLLERS_CID },
 #ifdef MOZ_XUL
   { "@mozilla.org/xul/xul-sort-service;1", &kNS_XULSORTSERVICE_CID },
   { "@mozilla.org/xul/xul-template-builder;1", &kNS_XULTEMPLATEBUILDER_CID },
   { "@mozilla.org/xul/xul-tree-builder;1", &kNS_XULTREEBUILDER_CID },
-  { "@mozilla.org/xul/xul-popup-manager;1", &kNS_XULPOPUPMANAGER_CID },
   { "@mozilla.org/xul/xul-document;1", &kNS_XULDOCUMENT_CID },
 #endif
 #ifdef MOZ_XTF
   { NS_XTFSERVICE_CONTRACTID, &kNS_XTFSERVICE_CID },
   { NS_XMLCONTENTBUILDER_CONTRACTID, &kNS_XMLCONTENTBUILDER_CID },
 #endif
   { CONTENT_DLF_CONTRACTID, &kNS_CONTENT_DOCUMENT_LOADER_FACTORY_CID },
   { NS_JSPROTOCOLHANDLER_CONTRACTID, &kNS_JSPROTOCOLHANDLER_CID },
--- a/layout/forms/nsComboboxControlFrame.cpp
+++ b/layout/forms/nsComboboxControlFrame.cpp
@@ -468,17 +468,17 @@ nsComboboxControlFrame::ShowList(bool aS
 
   nsIFrame* listFrame = do_QueryFrame(mListControlFrame);
   if (listFrame) {
     nsIView* view = listFrame->GetView();
     NS_ASSERTION(view, "nsComboboxControlFrame view is null");
     if (view) {
       nsIWidget* widget = view->GetWidget();
       if (widget) {
-        widget->CaptureRollupEvents(this, nsnull, mDroppedDown, mDroppedDown);
+        widget->CaptureRollupEvents(this, mDroppedDown, mDroppedDown);
 
         if (!aShowList) {
           nsCOMPtr<nsIRunnable> widgetDestroyer =
             new DestroyWidgetRunnable(GetContent());
           NS_DispatchToMainThread(widgetDestroyer);
         }
       }
     }
@@ -1317,17 +1317,17 @@ nsComboboxControlFrame::DestroyFrom(nsIF
     // Get parent view
     nsIFrame * listFrame = do_QueryFrame(mListControlFrame);
     if (listFrame) {
       nsIView* view = listFrame->GetView();
       NS_ASSERTION(view, "nsComboboxControlFrame view is null");
       if (view) {
         nsIWidget* widget = view->GetWidget();
         if (widget)
-          widget->CaptureRollupEvents(this, nsnull, false, true);
+          widget->CaptureRollupEvents(this, false, true);
       }
     }
   }
 
   // Cleanup frames in popup child list
   mPopupFrames.DestroyFramesFrom(aDestructRoot);
   nsContentUtils::DestroyAnonymousContent(&mDisplayContent);
   nsContentUtils::DestroyAnonymousContent(&mButtonContent);
@@ -1370,34 +1370,31 @@ nsComboboxControlFrame::SetInitialChildL
     rv = nsBlockFrame::SetInitialChildList(aListID, aChildList);
   }
   return rv;
 }
 
 //----------------------------------------------------------------------
   //nsIRollupListener
 //----------------------------------------------------------------------
-NS_IMETHODIMP 
-nsComboboxControlFrame::Rollup(PRUint32 aCount,
-                               nsIContent** aLastRolledUp)
+nsIContent*
+nsComboboxControlFrame::Rollup(PRUint32 aCount, bool aGetLastRolledUp)
 {
-  if (aLastRolledUp)
-    *aLastRolledUp = nsnull;
-
   if (mDroppedDown) {
     nsWeakFrame weakFrame(this);
     mListControlFrame->AboutToRollup(); // might destroy us
     if (!weakFrame.IsAlive())
-      return NS_OK;
+      return nsnull;
     ShowDropDown(false); // might destroy us
     if (!weakFrame.IsAlive())
-      return NS_OK;
+      return nsnull;
     mListControlFrame->CaptureMouseEvents(false);
   }
-  return NS_OK;
+
+  return nsnull;
 }
 
 void
 nsComboboxControlFrame::RollupFromList()
 {
   if (ShowList(false))
     mListControlFrame->CaptureMouseEvents(false);
 }
--- a/layout/forms/nsComboboxControlFrame.h
+++ b/layout/forms/nsComboboxControlFrame.h
@@ -187,30 +187,34 @@ public:
   NS_IMETHOD OnOptionSelected(PRInt32 aIndex, bool aSelected);
   NS_IMETHOD OnSetSelectedIndex(PRInt32 aOldIndex, PRInt32 aNewIndex);
 
   //nsIRollupListener
   /**
    * Hide the dropdown menu and stop capturing mouse events.
    * @note This method might destroy |this|.
    */
-  NS_IMETHOD Rollup(PRUint32 aCount, nsIContent** aLastRolledUp);
+  virtual nsIContent* Rollup(PRUint32 aCount, bool aGetLastRolledUp = false);
+
   /**
    * A combobox should roll up if a mousewheel event happens outside of
    * the popup area.
    */
-  NS_IMETHOD ShouldRollupOnMouseWheelEvent(bool *aShouldRollup)
-    { *aShouldRollup = true; return NS_OK;}
+  virtual bool ShouldRollupOnMouseWheelEvent()
+    { return true; }
 
   /**
    * A combobox should not roll up if activated by a mouse activate message
    * (eg. X-mouse).
    */
-  NS_IMETHOD ShouldRollupOnMouseActivate(bool *aShouldRollup)
-    { *aShouldRollup = false; return NS_OK;}
+  virtual bool ShouldRollupOnMouseActivate()
+    { return false; }
+
+  virtual PRUint32 GetSubmenuWidgetChain(nsTArray<nsIWidget*> *aWidgetChain)
+    { return 0; }
 
   //nsIStatefulFrame
   NS_IMETHOD SaveState(SpecialStateID aStateID, nsPresState** aState);
   NS_IMETHOD RestoreState(nsPresState* aState);
 
   static bool ToolkitHasNativePopup();
 
 protected:
--- a/layout/xul/base/public/nsXULPopupManager.h
+++ b/layout/xul/base/public/nsXULPopupManager.h
@@ -40,17 +40,16 @@
 
 #ifndef nsXULPopupManager_h__
 #define nsXULPopupManager_h__
 
 #include "prlog.h"
 #include "nsGUIEvent.h"
 #include "nsIContent.h"
 #include "nsIRollupListener.h"
-#include "nsIMenuRollup.h"
 #include "nsIDOMEventListener.h"
 #include "nsPoint.h"
 #include "nsCOMPtr.h"
 #include "nsTArray.h"
 #include "nsITimer.h"
 #include "nsIReflowCallback.h"
 #include "nsThreadUtils.h"
 #include "nsStyleConsts.h"
@@ -297,50 +296,49 @@ private:
   bool mAlt;
   bool mMeta;
   bool mUserInput;
   bool mFlipChecked;
   CloseMenuMode mCloseMenuMode;
 };
 
 class nsXULPopupManager : public nsIDOMEventListener,
-                          public nsIMenuRollup,
                           public nsIRollupListener,
                           public nsITimerCallback,
                           public nsIObserver
 {
 
 public:
   friend class nsXULPopupShowingEvent;
   friend class nsXULPopupHidingEvent;
   friend class nsXULMenuCommandEvent;
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSIOBSERVER
   NS_DECL_NSITIMERCALLBACK
   NS_DECL_NSIDOMEVENTLISTENER
 
   // nsIRollupListener
-  NS_IMETHOD Rollup(PRUint32 aCount, nsIContent **aContent);
-  NS_IMETHOD ShouldRollupOnMouseWheelEvent(bool *aShould);
-  NS_IMETHOD ShouldRollupOnMouseActivate(bool *aShould);
-
+  virtual nsIContent* Rollup(PRUint32 aCount, bool aGetLastRolledUp = false);
+  virtual bool ShouldRollupOnMouseWheelEvent();
+  virtual bool ShouldRollupOnMouseActivate();
   virtual PRUint32 GetSubmenuWidgetChain(nsTArray<nsIWidget*> *aWidgetChain);
-  virtual void AdjustPopupsOnWindowChange(nsPIDOMWindow* aWindow);
 
   static nsXULPopupManager* sInstance;
 
   // initialize and shutdown methods called by nsLayoutStatics
   static nsresult Init();
   static void Shutdown();
 
   // returns a weak reference to the popup manager instance, could return null
   // if a popup manager could not be allocated
   static nsXULPopupManager* GetInstance();
 
+  void AdjustPopupsOnWindowChange(nsPIDOMWindow* aWindow);
+
   // get the frame for a content node aContent if the frame's type
   // matches aFrameType. Otherwise, return null. If aShouldFlush is true,
   // then the frames are flushed before retrieving the frame.
   nsIFrame* GetFrameOfTypeForContent(nsIContent* aContent,
                                      nsIAtom* aFrameType,
                                      bool aShouldFlush);
 
   // given a menu frame, find the prevous or next menu frame. If aPopup is
@@ -785,12 +783,9 @@ protected:
   // a popup that is waiting on the timer
   nsMenuPopupFrame* mTimerMenu;
 
   // the popup that is currently being opened, stored only during the
   // popupshowing event
   nsCOMPtr<nsIContent> mOpeningPopup;
 };
 
-nsresult
-NS_NewXULPopupManager(nsISupports** aResult);
-
 #endif
--- a/layout/xul/base/src/nsXULPopupManager.cpp
+++ b/layout/xul/base/src/nsXULPopupManager.cpp
@@ -132,19 +132,18 @@ void nsMenuChainItem::Detach(nsMenuChain
     // An item without a child should be the first item in the chain, so set
     // the first item pointer, pointed to by aRoot, to the parent.
     NS_ASSERTION(this == *aRoot, "Unexpected - popup with no child not at end of chain");
     *aRoot = mParent;
     SetParent(nsnull);
   }
 }
 
-NS_IMPL_ISUPPORTS4(nsXULPopupManager,
+NS_IMPL_ISUPPORTS3(nsXULPopupManager,
                    nsIDOMEventListener,
-                   nsIMenuRollup,
                    nsITimerCallback,
                    nsIObserver)
 
 nsXULPopupManager::nsXULPopupManager() :
   mRangeOffset(0),
   mCachedMousePoint(0, 0),
   mCachedModifiers(0),
   mActiveMenuBar(nsnull),
@@ -202,37 +201,36 @@ nsXULPopupManager::Observe(nsISupports *
 }
 
 nsXULPopupManager*
 nsXULPopupManager::GetInstance()
 {
   return sInstance;
 }
 
-NS_IMETHODIMP
-nsXULPopupManager::Rollup(PRUint32 aCount, nsIContent** aLastRolledUp)
+nsIContent*
+nsXULPopupManager::Rollup(PRUint32 aCount, bool aGetLastRolledUp)
 {
-  if (aLastRolledUp)
-    *aLastRolledUp = nsnull;
+  nsIContent* lastRolledUpPopup = nsnull;
 
   nsMenuChainItem* item = GetTopVisibleMenu();
   if (item) {
-    if (aLastRolledUp) {
+    if (aGetLastRolledUp) {
       // we need to get the popup that will be closed last, so that
       // widget can keep track of it so it doesn't reopen if a mouse
       // down event is going to processed.
       // Keep going up the menu chain to get the first level menu. This will
       // be the one that closes up last. It's possible that this menu doesn't
       // end up closing because the popuphiding event was cancelled, but in
       // that case we don't need to deal with the menu reopening as it will
       // already still be open.
       nsMenuChainItem* first = item;
       while (first->GetParent())
         first = first->GetParent();
-      NS_ADDREF(*aLastRolledUp = first->Content());
+      lastRolledUpPopup = first->Content();
     }
 
     // if a number of popups to close has been specified, determine the last
     // popup to close
     nsIContent* lastPopup = nsnull;
     if (aCount != PR_UINT32_MAX) {
       nsMenuChainItem* last = item;
       while (--aCount && last->GetParent()) {
@@ -240,45 +238,43 @@ nsXULPopupManager::Rollup(PRUint32 aCoun
       }
       if (last) {
         lastPopup = last->Content();
       }
     }
 
     HidePopup(item->Content(), true, true, false, lastPopup);
   }
-  return NS_OK;
+
+  return lastRolledUpPopup;
 }
 
 ////////////////////////////////////////////////////////////////////////
-NS_IMETHODIMP nsXULPopupManager::ShouldRollupOnMouseWheelEvent(bool *aShouldRollup) 
+bool nsXULPopupManager::ShouldRollupOnMouseWheelEvent()
 {
   // should rollup only for autocomplete widgets
   // XXXndeakin this should really be something the popup has more control over
 
-  *aShouldRollup = false;
   nsMenuChainItem* item = GetTopVisibleMenu();
   if (!item)
-    return NS_OK;
+    return false;
 
   nsIContent* content = item->Frame()->GetContent();
-  if (content) {
-    nsAutoString value;
-    content->GetAttr(kNameSpaceID_None, nsGkAtoms::type, value);
-    *aShouldRollup = StringBeginsWith(value, NS_LITERAL_STRING("autocomplete"));
-  }
+  if (!content)
+    return false;
 
-  return NS_OK;
+  nsAutoString value;
+  content->GetAttr(kNameSpaceID_None, nsGkAtoms::type, value);
+  return StringBeginsWith(value, NS_LITERAL_STRING("autocomplete"));
 }
 
 // a menu should not roll up if activated by a mouse activate message (eg. X-mouse)
-NS_IMETHODIMP nsXULPopupManager::ShouldRollupOnMouseActivate(bool *aShouldRollup) 
+bool nsXULPopupManager::ShouldRollupOnMouseActivate()
 {
-  *aShouldRollup = false;
-  return NS_OK;
+  return false;
 }
 
 PRUint32
 nsXULPopupManager::GetSubmenuWidgetChain(nsTArray<nsIWidget*> *aWidgetChain)
 {
   // this method is used by the widget code to determine the list of popups
   // that are open. If a mouse click occurs outside one of these popups, the
   // panels will roll up. If the click is inside a popup, they will not roll up
@@ -1615,27 +1611,26 @@ nsXULPopupManager::HasContextMenu(nsMenu
 void
 nsXULPopupManager::SetCaptureState(nsIContent* aOldPopup)
 {
   nsMenuChainItem* item = GetTopVisibleMenu();
   if (item && aOldPopup == item->Content())
     return;
 
   if (mWidget) {
-    mWidget->CaptureRollupEvents(this, this, false, false);
+    mWidget->CaptureRollupEvents(this, false, false);
     mWidget = nsnull;
   }
 
   if (item) {
     nsMenuPopupFrame* popup = item->Frame();
     nsCOMPtr<nsIWidget> widget;
     popup->GetWidget(getter_AddRefs(widget));
     if (widget) {
-      widget->CaptureRollupEvents(this, this, true,
-                                  popup->ConsumeOutsideClicks());
+      widget->CaptureRollupEvents(this, true, popup->ConsumeOutsideClicks());
       mWidget = widget;
       popup->AttachedDismissalListener();
     }
   }
 
   UpdateKeyboardListeners();
 }
 
@@ -2177,17 +2172,17 @@ nsXULPopupManager::KeyDown(nsIDOMKeyEven
         aKeyEvent->GetShiftKey(&shift);
       bool meta=false;
       if (menuAccessKey != nsIDOMKeyEvent::DOM_VK_META)
         aKeyEvent->GetMetaKey(&meta);
       if (!(ctrl || alt || shift || meta)) {
         // The access key just went down and no other
         // modifiers are already down.
         if (mPopups)
-          Rollup(nsnull, nsnull);
+          Rollup(0);
         else if (mActiveMenuBar)
           mActiveMenuBar->MenuClosed();
       }
     }
   }
 
   // Since a menu was open, eat the event to keep other event
   // listeners from becoming confused.
@@ -2256,17 +2251,17 @@ nsXULPopupManager::KeyPress(nsIDOMKeyEve
   }
   else if (theChar == NS_VK_TAB
 #ifndef XP_MACOSX
            || theChar == NS_VK_F10
 #endif
   ) {
     // close popups or deactivate menubar when Tab or F10 are pressed
     if (item)
-      Rollup(nsnull, nsnull);
+      Rollup(0);
     else if (mActiveMenuBar)
       mActiveMenuBar->MenuClosed();
   }
   else if (theChar == NS_VK_ENTER ||
            theChar == NS_VK_RETURN) {
     // If there is a popup open, check if the current item needs to be opened.
     // Otherwise, tell the active menubar, if any, to activate the menu. The
     // Enter method will return a menu if one needs to be opened as a result.
@@ -2376,17 +2371,8 @@ nsXULMenuCommandEvent::Run()
                                        mControl, mAlt, mShift, mMeta);
   }
 
   if (popup && mCloseMenuMode != CloseMenuMode_None)
     pm->HidePopup(popup, mCloseMenuMode == CloseMenuMode_Auto, true, false);
 
   return NS_OK;
 }
-
-nsresult
-NS_NewXULPopupManager(nsISupports** aResult)
-{
-  nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
-  NS_IF_ADDREF(pm);
-  *aResult = static_cast<nsIMenuRollup *>(pm);
-  return NS_OK;
-}
--- a/widget/public/Makefile.in
+++ b/widget/public/Makefile.in
@@ -69,17 +69,16 @@ EXPORTS		= \
 		nsGUIEvent.h \
 		nsEvent.h \
 		nsNativeWidget.h \
 		nsWidgetInitData.h \
 		nsWidgetsCID.h \
 		nsIPluginWidget.h \
 		nsINativeKeyBindings.h \
 		nsIDeviceContextSpec.h \
-		nsIMenuRollup.h \
 		nsIRollupListener.h \
 		$(NULL)
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa)
 EXPORTS		+= \
 		nsINativeMenuService.h \
 		nsIPrintDialogService.h \
 		$(NULL)
deleted file mode 100644
--- a/widget/public/nsIMenuRollup.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is mozilla.org code.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-
-#ifndef nsIMenuRollup_h___
-#define nsIMenuRollup_h___
-
-#include "nsISupports.h"
-#include "nsTArray.h"
-
-class nsIWidget;
-class nsIContent;
-class nsPIDOMWindow;
-
-#define NS_IMENUROLLUP_IID \
-  {0xa707b588, 0xa564, 0x488d, \
-    { 0x87, 0xb6, 0xdb, 0x71, 0x2d, 0x78, 0x9d, 0x4c }}
-
-class nsIMenuRollup : public nsISupports {
- public: 
-
-  NS_DECLARE_STATIC_IID_ACCESSOR(NS_IMENUROLLUP_IID)
-
-  /*
-   * Retrieve the widgets for open menus are store them in the array
-   * aWidgetChain. The number of menus of the same type should be returned,
-   * for example, if a context menu is open, return only the number of menus
-   * that are part of the context menu chain. This allows closing up only
-   * those menus in different situations.
-   */
-  virtual PRUint32 GetSubmenuWidgetChain(nsTArray<nsIWidget*> *aWidgetChain) = 0;
-
-  /**
-   * Adjust the position of open panels when a window is moved or resized.
-   */ 
-  virtual void AdjustPopupsOnWindowChange(nsPIDOMWindow* aWindow) = 0;
-
-};
-
-  NS_DEFINE_STATIC_IID_ACCESSOR(nsIMenuRollup, NS_IMENUROLLUP_IID)
-
-#endif
--- a/widget/public/nsIRollupListener.h
+++ b/widget/public/nsIRollupListener.h
@@ -37,35 +37,49 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef __nsIRollupListener_h__
 #define __nsIRollupListener_h__
 
+#include "nsTArray.h"
+
 class nsIContent;
+class nsIWidget;
 
 class nsIRollupListener {
  public: 
 
   /**
    * Notifies the object to rollup, optionally returning the node that
    * was just rolled up.
    *
    * aCount is the number of popups in a chain to close. If this is
    * PR_UINT32_MAX, then all popups are closed.
+   * If aGetLastRolledUp is true, then return the last rolled up popup,
+   * if this is supported.
    */
-  NS_IMETHOD Rollup(PRUint32 aCount, nsIContent **aContent) = 0;
+  virtual nsIContent* Rollup(PRUint32 aCount, bool aGetLastRolledUp = false) = 0;
 
   /**
    * Asks the RollupListener if it should rollup on mousevents
    */
-  NS_IMETHOD ShouldRollupOnMouseWheelEvent(bool *aShould) = 0;
+  virtual bool ShouldRollupOnMouseWheelEvent() = 0;
 
   /**
    * Asks the RollupListener if it should rollup on mouse activate, eg. X-Mouse
    */
-  NS_IMETHOD ShouldRollupOnMouseActivate(bool *aShould) = 0;
+  virtual bool ShouldRollupOnMouseActivate() = 0;
 
+  /*
+   * Retrieve the widgets for open menus and store them in the array
+   * aWidgetChain. The number of menus of the same type should be returned,
+   * for example, if a context menu is open, return only the number of menus
+   * that are part of the context menu chain. This allows closing up only
+   * those menus in different situations. The returned value should be exactly
+   * the same number of widgets added to aWidgetChain.
+   */
+  virtual PRUint32 GetSubmenuWidgetChain(nsTArray<nsIWidget*> *aWidgetChain) = 0;
 };
 
 #endif /* __nsIRollupListener_h__ */
--- a/widget/public/nsIWidget.h
+++ b/widget/public/nsIWidget.h
@@ -57,17 +57,16 @@
 #include "nsXULAppAPI.h"
 
 // forward declarations
 class   nsFontMetrics;
 class   nsRenderingContext;
 class   nsDeviceContext;
 struct  nsFont;
 class   nsIRollupListener;
-class   nsIMenuRollup;
 class   nsGUIEvent;
 class   imgIContainer;
 class   gfxASurface;
 class   nsIContent;
 class   ViewWrapper;
 
 namespace mozilla {
 namespace dom {
@@ -114,18 +113,18 @@ typedef nsEventStatus (* EVENT_CALLBACK)
 #endif
 #ifdef XP_WIN
 #define NS_NATIVE_TSF_THREAD_MGR       100
 #define NS_NATIVE_TSF_CATEGORY_MGR     101
 #define NS_NATIVE_TSF_DISPLAY_ATTR_MGR 102
 #endif
 
 #define NS_IWIDGET_IID \
-  { 0x712b07a4, 0x4344, 0x4404, \
-    { 0xaf, 0x85, 0x63, 0x3d, 0x68, 0x0b, 0x21, 0xb0 } }
+  { 0x32966f95, 0x89e0, 0x447a, \
+    { 0x91, 0x8d, 0x58, 0x53, 0xd6, 0x99, 0x4a, 0x72 } }
 
 /*
  * Window shadow styles
  * Also used for the -moz-window-shadow CSS property
  */
 
 #define NS_STYLE_WINDOW_SHADOW_NONE             0
 #define NS_STYLE_WINDOW_SHADOW_DEFAULT          1
@@ -1023,18 +1022,18 @@ class nsIWidget : public nsISupports {
     /**
      * Enables/Disables system capture of any and all events that would cause a
      * dropdown to be rolled up, This method ignores the aConsumeRollupEvent 
      * parameter when aDoCapture is FALSE
      * @param aDoCapture true enables capture, false disables capture 
      * @param aConsumeRollupEvent true consumes the rollup event, false dispatches rollup event
      *
      */
-    NS_IMETHOD CaptureRollupEvents(nsIRollupListener * aListener, nsIMenuRollup * aMenuRollup,
-                                   bool aDoCapture, bool aConsumeRollupEvent) = 0;
+    NS_IMETHOD CaptureRollupEvents(nsIRollupListener * aListener, bool aDoCapture,
+                                   bool aConsumeRollupEvent) = 0;
 
     /**
      * Bring this window to the user's attention.  This is intended to be a more
      * gentle notification than popping the window to the top or putting up an
      * alert.  See, for example, Win32 FlashWindow or the NotificationManager on
      * the Mac.  The notification should be suppressed if the window is already
      * in the foreground and should be dismissed when the user brings this window
      * to the foreground.
--- a/widget/src/android/nsWindow.h
+++ b/widget/src/android/nsWindow.h
@@ -139,17 +139,16 @@ public:
     NS_IMETHOD GetHasTransparentBackground(bool& aTransparent) { aTransparent = false; return NS_OK; }
     NS_IMETHOD HideWindowChrome(bool aShouldHide) { return NS_ERROR_NOT_IMPLEMENTED; }
     virtual void* GetNativeData(PRUint32 aDataType);
     NS_IMETHOD SetTitle(const nsAString& aTitle) { return NS_OK; }
     NS_IMETHOD SetIcon(const nsAString& aIconSpec) { return NS_OK; }
     NS_IMETHOD EnableDragDrop(bool aEnable) { return NS_OK; }
     NS_IMETHOD CaptureMouse(bool aCapture) { return NS_ERROR_NOT_IMPLEMENTED; }
     NS_IMETHOD CaptureRollupEvents(nsIRollupListener *aListener,
-                                   nsIMenuRollup *aMenuRollup,
                                    bool aDoCapture,
                                    bool aConsumeRollupEvent) { return NS_ERROR_NOT_IMPLEMENTED; }
 
     NS_IMETHOD GetAttention(PRInt32 aCycleCount) { return NS_ERROR_NOT_IMPLEMENTED; }
     NS_IMETHOD BeginResizeDrag(nsGUIEvent* aEvent, PRInt32 aHorizontal, PRInt32 aVertical) { return NS_ERROR_NOT_IMPLEMENTED; }
 
     NS_IMETHOD ResetInputState();
     NS_IMETHOD SetInputMode(const IMEContext& aContext);
--- a/widget/src/cocoa/nsAppShell.mm
+++ b/widget/src/cocoa/nsAppShell.mm
@@ -974,17 +974,17 @@ nsAppShell::AfterProcessNextEvent(nsIThr
 // send ourselves (whose 'sender' will be @"org.mozilla.gecko.PopupWindow").
 - (void)beginMenuTracking:(NSNotification*)aNotification
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
 
   NSString *sender = [aNotification object];
   if (!sender || ![sender isEqualToString:@"org.mozilla.gecko.PopupWindow"]) {
     if (gRollupListener && gRollupWidget)
-      gRollupListener->Rollup(nsnull, nsnull);
+      gRollupListener->Rollup(0);
   }
 
   NS_OBJC_END_TRY_ABORT_BLOCK;
 }
 
 @end
 
 // We hook beginModalSessionForWindow: and endModalSession: in order to
--- a/widget/src/cocoa/nsChildView.h
+++ b/widget/src/cocoa/nsChildView.h
@@ -430,18 +430,17 @@ public:
   NS_IMETHOD              DispatchEvent(nsGUIEvent* event, nsEventStatus & aStatus);
 
   NS_IMETHOD              Update();
   virtual bool            GetShouldAccelerate();
 
   NS_IMETHOD        SetCursor(nsCursor aCursor);
   NS_IMETHOD        SetCursor(imgIContainer* aCursor, PRUint32 aHotspotX, PRUint32 aHotspotY);
   
-  NS_IMETHOD        CaptureRollupEvents(nsIRollupListener * aListener, nsIMenuRollup * aMenuRollup, 
-                                        bool aDoCapture, bool aConsumeRollupEvent);
+  NS_IMETHOD        CaptureRollupEvents(nsIRollupListener * aListener, bool aDoCapture, bool aConsumeRollupEvent);
   NS_IMETHOD        SetTitle(const nsAString& title);
 
   NS_IMETHOD        GetAttention(PRInt32 aCycleCount);
 
   virtual bool HasPendingInputEvent();
 
   NS_IMETHOD        ActivateNativeMenuItemAt(const nsAString& indexString);
   NS_IMETHOD        ForceUpdateNativeMenuAt(const nsAString& indexString);
--- a/widget/src/cocoa/nsChildView.mm
+++ b/widget/src/cocoa/nsChildView.mm
@@ -61,17 +61,16 @@
 
 #include "nsFontMetrics.h"
 #include "nsIRollupListener.h"
 #include "nsIViewManager.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsILocalFile.h"
 #include "nsILocalFileMac.h"
 #include "nsGfxCIID.h"
-#include "nsIMenuRollup.h"
 #include "nsIDOMSimpleGestureEvent.h"
 #include "nsNPAPIPluginInstance.h"
 #include "nsThemeConstants.h"
 
 #include "nsDragService.h"
 #include "nsClipboard.h"
 #include "nsCursorManager.h"
 #include "nsWindowMap.h"
@@ -134,17 +133,16 @@ NSWindow* ChildViewMouseTracker::sWindow
 NSPoint ChildViewMouseTracker::sLastScrollEventScreenLocation = NSZeroPoint;
 
 #ifdef INVALIDATE_DEBUGGING
 static void blinkRect(Rect* r);
 static void blinkRgn(RgnHandle rgn);
 #endif
 
 nsIRollupListener * gRollupListener = nsnull;
-nsIMenuRollup     * gMenuRollup = nsnull;
 nsIWidget         * gRollupWidget   = nsnull;
 
 bool gUserCancelledDrag = false;
 
 PRUint32 nsChildView::sLastInputEventCount = 0;
 
 @interface ChildView(Private)
 
@@ -1582,17 +1580,16 @@ nsIntPoint nsChildView::WidgetToScreenOf
   FlipCocoaScreenCoordinate(temp);
   
   return nsIntPoint(NSToIntRound(temp.x), NSToIntRound(temp.y));
 
   NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(nsIntPoint(0,0));
 }
 
 NS_IMETHODIMP nsChildView::CaptureRollupEvents(nsIRollupListener * aListener, 
-                                               nsIMenuRollup * aMenuRollup,
                                                bool aDoCapture, 
                                                bool aConsumeRollupEvent)
 {
   // this never gets called, only top-level windows can be rollup widgets
   return NS_OK;
 }
 
 NS_IMETHODIMP nsChildView::SetTitle(const nsAString& title)
@@ -2754,29 +2751,29 @@ NSEvent* gLastDragMouseDownEvent = nil;
   if (gRollupWidget && gRollupListener) {
     NSWindow* currentPopup = static_cast<NSWindow*>(gRollupWidget->GetNativeData(NS_NATIVE_WINDOW));
     if (!nsCocoaUtils::IsEventOverWindow(theEvent, currentPopup)) {
       // event is not over the rollup window, default is to roll up
       bool shouldRollup = true;
 
       // check to see if scroll events should roll up the popup
       if ([theEvent type] == NSScrollWheel) {
-        gRollupListener->ShouldRollupOnMouseWheelEvent(&shouldRollup);
+        shouldRollup = gRollupListener->ShouldRollupOnMouseWheelEvent();
         // always consume scroll events that aren't over the popup
         consumeEvent = YES;
       }
 
       // if we're dealing with menus, we probably have submenus and
       // we don't want to rollup if the click is in a parent menu of
       // the current submenu
       PRUint32 popupsToRollup = PR_UINT32_MAX;
-      if (gMenuRollup) {
+      if (gRollupListener) {
         nsAutoTArray<nsIWidget*, 5> widgetChain;
-        gMenuRollup->GetSubmenuWidgetChain(&widgetChain);
-        PRUint32 sameTypeCount = gMenuRollup->GetSubmenuWidgetChain(&widgetChain);
+        gRollupListener->GetSubmenuWidgetChain(&widgetChain);
+        PRUint32 sameTypeCount = gRollupListener->GetSubmenuWidgetChain(&widgetChain);
         for (PRUint32 i = 0; i < widgetChain.Length(); i++) {
           nsIWidget* widget = widgetChain[i];
           NSWindow* currWindow = (NSWindow*)widget->GetNativeData(NS_NATIVE_WINDOW);
           if (nsCocoaUtils::IsEventOverWindow(theEvent, currWindow)) {
             // don't roll up if the mouse event occurred within a menu of the
             // same type. If the mouse event occurred in a menu higher than
             // that, roll up, but pass the number of popups to Rollup so
             // that only those of the same type close up.
@@ -2787,17 +2784,17 @@ NSEvent* gLastDragMouseDownEvent = nil;
               popupsToRollup = sameTypeCount;
             }
             break;
           }
         }
       }
 
       if (shouldRollup) {
-        gRollupListener->Rollup(popupsToRollup, nsnull);
+        gRollupListener->Rollup(popupsToRollup);
         consumeEvent = (BOOL)gConsumeRollupEvent;
       }
     }
   }
 
   return consumeEvent;
 
   NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(NO);
--- a/widget/src/cocoa/nsCocoaWindow.h
+++ b/widget/src/cocoa/nsCocoaWindow.h
@@ -255,18 +255,17 @@ public:
     NS_IMETHOD Invalidate(const nsIntRect &aRect, bool aIsSynchronous);
     NS_IMETHOD Update();
     virtual nsresult ConfigureChildren(const nsTArray<Configuration>& aConfigurations);
     virtual LayerManager* GetLayerManager(PLayersChild* aShadowManager = nsnull,
                                           LayersBackend aBackendHint = LayerManager::LAYERS_NONE,
                                           LayerManagerPersistence aPersistence = LAYER_MANAGER_CURRENT,
                                           bool* aAllowRetaining = nsnull);
     NS_IMETHOD DispatchEvent(nsGUIEvent* event, nsEventStatus & aStatus) ;
-    NS_IMETHOD CaptureRollupEvents(nsIRollupListener * aListener, nsIMenuRollup * aMenuRollup,
-                                   bool aDoCapture, bool aConsumeRollupEvent);
+    NS_IMETHOD CaptureRollupEvents(nsIRollupListener * aListener, bool aDoCapture, bool aConsumeRollupEvent);
     NS_IMETHOD GetAttention(PRInt32 aCycleCount);
     virtual bool HasPendingInputEvent();
     virtual nsTransparencyMode GetTransparencyMode();
     virtual void SetTransparencyMode(nsTransparencyMode aMode);
     NS_IMETHOD SetWindowShadowStyle(PRInt32 aStyle);
     virtual void SetShowsToolbarButton(bool aShow);
     NS_IMETHOD SetWindowTitlebarColor(nscolor aColor, bool aActive);
     virtual void SetDrawsInTitlebar(bool aState);
--- a/widget/src/cocoa/nsCocoaWindow.mm
+++ b/widget/src/cocoa/nsCocoaWindow.mm
@@ -56,17 +56,16 @@
 #include "nsPIDOMWindow.h"
 #include "nsIDOMElement.h"
 #include "nsThreadUtils.h"
 #include "nsMenuBarX.h"
 #include "nsMenuUtilsX.h"
 #include "nsStyleConsts.h"
 #include "nsNativeThemeColors.h"
 #include "nsChildView.h"
-#include "nsIMenuRollup.h"
 
 #include "gfxPlatform.h"
 #include "qcms.h"
 
 #include "mozilla/Preferences.h"
 
 namespace mozilla {
 namespace layers {
@@ -90,17 +89,16 @@ nsCocoaWindowList *gGeckoAppModalWindowL
 
 bool gConsumeRollupEvent;
 
 // defined in nsMenuBarX.mm
 extern NSMenu* sApplicationMenu; // Application menu shared by all menubars
 
 // defined in nsChildView.mm
 extern nsIRollupListener * gRollupListener;
-extern nsIMenuRollup     * gMenuRollup;
 extern nsIWidget         * gRollupWidget;
 extern BOOL                gSomeMenuBarPainted;
 
 extern "C" {
   // CGSPrivate.h
   typedef NSInteger CGSConnection;
   typedef NSInteger CGSWindow;
   typedef NSUInteger CGSWindowFilterRef;
@@ -121,17 +119,17 @@ NS_IMPL_ISUPPORTS_INHERITED1(nsCocoaWind
 // |mWindowType == eWindowType_sheet| is true if your gecko nsIWidget is a sheet
 // widget - whether or not the sheet is showing. |[mWindow isSheet]| will return
 // true *only when the sheet is actually showing*. Choose your test wisely.
 
 // roll up any popup windows
 static void RollUpPopups()
 {
   if (gRollupListener && gRollupWidget)
-    gRollupListener->Rollup(nsnull, nsnull);
+    gRollupListener->Rollup(0);
 }
 
 nsCocoaWindow::nsCocoaWindow()
 : mParent(nsnull)
 , mWindow(nil)
 , mDelegate(nil)
 , mSheetWindowParent(nil)
 , mPopupContentView(nil)
@@ -1481,32 +1479,27 @@ nsIntSize nsCocoaWindow::ClientToWindowS
   NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(nsIntSize(0,0));
 }
 
 nsMenuBarX* nsCocoaWindow::GetMenuBar()
 {
   return mMenuBar;
 }
 
-NS_IMETHODIMP nsCocoaWindow::CaptureRollupEvents(nsIRollupListener * aListener, 
-                                                 nsIMenuRollup * aMenuRollup,
-                                                 bool aDoCapture, 
+NS_IMETHODIMP nsCocoaWindow::CaptureRollupEvents(nsIRollupListener * aListener,
+                                                 bool aDoCapture,
                                                  bool aConsumeRollupEvent)
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
 
   gRollupListener = nsnull;
-  NS_IF_RELEASE(gMenuRollup);
   NS_IF_RELEASE(gRollupWidget);
   
   if (aDoCapture) {
     gRollupListener = aListener;
-    NS_IF_RELEASE(gMenuRollup);
-    gMenuRollup = aMenuRollup;
-    NS_IF_ADDREF(aMenuRollup);
     gRollupWidget = this;
     NS_ADDREF(this);
 
     gConsumeRollupEvent = aConsumeRollupEvent;
 
     // Sometimes more than one popup window can be visible at the same time
     // (e.g. nested non-native context menus, or the test case (attachment
     // 276885) for bmo bug 392389, which displays a non-native combo-box in
--- a/widget/src/cocoa/nsMenuX.mm
+++ b/widget/src/cocoa/nsMenuX.mm
@@ -908,17 +908,17 @@ nsresult nsMenuX::SetupIcon()
 
   // Don't do anything while the OS is (re)indexing our menus (on Leopard and
   // higher).  This stops the Help menu from being able to search in our
   // menus, but it also resolves many other problems.
   if (nsMenuX::sIndexingMenuLevel > 0)
     return;
 
   if (gRollupListener && gRollupWidget) {
-    gRollupListener->Rollup(nsnull, nsnull);
+    gRollupListener->Rollup(0);
     [menu cancelTracking];
     return;
   }
   mGeckoMenu->MenuOpened();
 }
 
 - (void)menuDidClose:(NSMenu *)menu
 {
--- a/widget/src/cocoa/nsToolkit.mm
+++ b/widget/src/cocoa/nsToolkit.mm
@@ -213,17 +213,17 @@ static CGEventRef EventTapCallback(CGEve
   NSWindow *ctxMenuWindow = (NSWindow*) gRollupWidget->GetNativeData(NS_NATIVE_WINDOW);
   if (!ctxMenuWindow)
     return event;
   NSPoint screenLocation = ConvertCGGlobalToCocoaScreen(CGEventGetLocation(event));
   // Don't roll up the rollup widget if our mouseDown happens over it (doing
   // so would break the corresponding context menu).
   if (NSPointInRect(screenLocation, [ctxMenuWindow frame]))
     return event;
-  gRollupListener->Rollup(nsnull, nsnull);
+  gRollupListener->Rollup(0);
   return event;
 
   NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(NULL);
 }
 
 // Cocoa Firefox's use of custom context menus requires that we explicitly
 // handle mouse events from other processes that the OS handles
 // "automatically" for native context menus -- mouseMoved events so that
--- a/widget/src/gtk2/nsWindow.cpp
+++ b/widget/src/gtk2/nsWindow.cpp
@@ -46,17 +46,16 @@
 // needed to include hildon parts in gtk.h
 #define MAEMO_CHANGES
 #endif
 
 #include "prlink.h"
 #include "nsWindow.h"
 #include "nsGTKToolkit.h"
 #include "nsIRollupListener.h"
-#include "nsIMenuRollup.h"
 #include "nsIDOMNode.h"
 
 #include "nsWidgetsCID.h"
 #include "nsDragService.h"
 #include "nsIDragSessionGTK.h"
 
 #include "nsGtkKeyUtils.h"
 #include "nsGtkCursors.h"
@@ -327,17 +326,16 @@ static NS_DEFINE_IID(kCDragServiceCID,  
 // The window from which the focus manager asks us to dispatch key events.
 static nsWindow         *gFocusWindow          = NULL;
 static bool              gBlockActivateEvent   = false;
 static bool              gGlobalsInitialized   = false;
 static bool              gRaiseWindows         = true;
 static nsWindow         *gPluginFocusWindow    = NULL;
 
 static nsIRollupListener*          gRollupListener;
-static nsIMenuRollup*              gMenuRollup;
 static nsWeakPtr                   gRollupWindow;
 static bool                        gConsumeRollupEvent;
 
 
 #define NS_WINDOW_TITLE_MAX_LENGTH 4095
 
 // If after selecting profile window, the startup fail, please refer to
 // http://bugzilla.gnome.org/show_bug.cgi?id=88940
@@ -767,18 +765,17 @@ nsWindow::Destroy(void)
     g_signal_handlers_disconnect_by_func(gtk_settings_get_default(),
                                          FuncToGpointer(theme_changed_cb),
                                          this);
 
     // ungrab if required
     nsCOMPtr<nsIWidget> rollupWidget = do_QueryReferent(gRollupWindow);
     if (static_cast<nsIWidget *>(this) == rollupWidget.get()) {
         if (gRollupListener)
-            gRollupListener->Rollup(nsnull, nsnull);
-        NS_IF_RELEASE(gMenuRollup);
+            gRollupListener->Rollup(0);
         gRollupWindow = nsnull;
         gRollupListener = nsnull;
     }
 
     NativeShow(false);
 
     if (mIMModule) {
         mIMModule->OnDestroyWindow(this);
@@ -1862,35 +1859,31 @@ nsWindow::CaptureMouse(bool aCapture)
         gtk_grab_remove(widget);
     }
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsWindow::CaptureRollupEvents(nsIRollupListener *aListener,
-                              nsIMenuRollup     *aMenuRollup,
                               bool               aDoCapture,
                               bool               aConsumeRollupEvent)
 {
     if (!mGdkWindow)
         return NS_OK;
 
     GtkWidget *widget = GetMozContainerWidget();
     if (!widget)
         return NS_ERROR_FAILURE;
 
     LOG(("CaptureRollupEvents %p\n", (void *)this));
 
     if (aDoCapture) {
         gConsumeRollupEvent = aConsumeRollupEvent;
         gRollupListener = aListener;
-        NS_IF_RELEASE(gMenuRollup);
-        gMenuRollup = aMenuRollup;
-        NS_IF_ADDREF(aMenuRollup);
         gRollupWindow = do_GetWeakReference(static_cast<nsIWidget*>
                                                        (this));
         // real grab is only done when there is no dragging
         if (!nsWindow::DragInProgress()) {
             gtk_grab_add(widget);
             GrabPointer();
         }
     }
@@ -1898,17 +1891,16 @@ nsWindow::CaptureRollupEvents(nsIRollupL
         if (!nsWindow::DragInProgress()) {
             ReleaseGrabs();
         }
         // There may not have been a drag in process when aDoCapture was set,
         // so make sure to remove any added grab.  This is a no-op if the grab
         // was not added to this widget.
         gtk_grab_remove(widget);
         gRollupListener = nsnull;
-        NS_IF_RELEASE(gMenuRollup);
         gRollupWindow = nsnull;
     }
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsWindow::GetAttention(PRInt32 aCycleCount)
@@ -5352,26 +5344,26 @@ check_for_rollup(GdkWindow *aWindow, gdo
     nsCOMPtr<nsIWidget> rollupWidget = do_QueryReferent(gRollupWindow);
 
     if (rollupWidget && gRollupListener) {
         GdkWindow *currentPopup =
             (GdkWindow *)rollupWidget->GetNativeData(NS_NATIVE_WINDOW);
         if (aAlwaysRollup || !is_mouse_in_window(currentPopup, aMouseX, aMouseY)) {
             bool rollup = true;
             if (aIsWheel) {
-                gRollupListener->ShouldRollupOnMouseWheelEvent(&rollup);
+                rollup = gRollupListener->ShouldRollupOnMouseWheelEvent();
                 retVal = true;
             }
             // if we're dealing with menus, we probably have submenus and
             // we don't want to rollup if the click is in a parent menu of
             // the current submenu
             PRUint32 popupsToRollup = PR_UINT32_MAX;
-            if (gMenuRollup && !aAlwaysRollup) {
+            if (!aAlwaysRollup) {
                 nsAutoTArray<nsIWidget*, 5> widgetChain;
-                PRUint32 sameTypeCount = gMenuRollup->GetSubmenuWidgetChain(&widgetChain);
+                PRUint32 sameTypeCount = gRollupListener->GetSubmenuWidgetChain(&widgetChain);
                 for (PRUint32 i=0; i<widgetChain.Length(); ++i) {
                     nsIWidget* widget = widgetChain[i];
                     GdkWindow* currWindow =
                         (GdkWindow*) widget->GetNativeData(NS_NATIVE_WINDOW);
                     if (is_mouse_in_window(currWindow, aMouseX, aMouseY)) {
                       // don't roll up if the mouse event occurred within a
                       // menu of the same type. If the mouse event occurred
                       // in a menu higher than that, roll up, but pass the
@@ -5385,26 +5377,25 @@ check_for_rollup(GdkWindow *aWindow, gdo
                       }
                       break;
                     }
                 } // foreach parent menu widget
             } // if rollup listener knows about menus
 
             // if we've determined that we should still rollup, do it.
             if (rollup) {
-                gRollupListener->Rollup(popupsToRollup, nsnull);
+                gRollupListener->Rollup(popupsToRollup);
                 if (popupsToRollup == PR_UINT32_MAX) {
                     retVal = true;
                 }
             }
         }
     } else {
         gRollupWindow = nsnull;
         gRollupListener = nsnull;
-        NS_IF_RELEASE(gMenuRollup);
     }
 
     return retVal;
 }
 
 /* static */
 bool
 nsWindow::DragInProgress(void)
--- a/widget/src/gtk2/nsWindow.h
+++ b/widget/src/gtk2/nsWindow.h
@@ -181,17 +181,16 @@ public:
     virtual void*      GetNativeData(PRUint32 aDataType);
     NS_IMETHOD         SetTitle(const nsAString& aTitle);
     NS_IMETHOD         SetIcon(const nsAString& aIconSpec);
     NS_IMETHOD         SetWindowClass(const nsAString& xulWinType);
     virtual nsIntPoint WidgetToScreenOffset();
     NS_IMETHOD         EnableDragDrop(bool aEnable);
     NS_IMETHOD         CaptureMouse(bool aCapture);
     NS_IMETHOD         CaptureRollupEvents(nsIRollupListener *aListener,
-                                           nsIMenuRollup *aMenuRollup,
                                            bool aDoCapture,
                                            bool aConsumeRollupEvent);
     NS_IMETHOD         GetAttention(PRInt32 aCycleCount);
 
     virtual bool       HasPendingInputEvent();
 
     NS_IMETHOD         MakeFullScreen(bool aFullScreen);
     NS_IMETHOD         HideWindowChrome(bool aShouldHide);
--- a/widget/src/os2/nsWindow.cpp
+++ b/widget/src/os2/nsWindow.cpp
@@ -69,17 +69,16 @@
 #include "os2FrameWindow.h"
 #include "gfxContext.h"
 #include "gfxOS2Surface.h"
 #include "imgIContainer.h"
 #include "npapi.h"
 #include "nsDragService.h"
 #include "nsGfxCIID.h"
 #include "nsHashKeys.h"
-#include "nsIMenuRollup.h"
 #include "nsIRollupListener.h"
 #include "nsIScreenManager.h"
 #include "nsOS2Uni.h"
 #include "nsTHashtable.h"
 #include "nsGkAtoms.h"
 #include "wdgtos2rc.h"
 
 #include "mozilla/Preferences.h"
@@ -179,17 +178,16 @@ using namespace mozilla;
 #endif
 
 //=============================================================================
 //  Variables & Forward declarations
 //=============================================================================
 
 // Rollup Listener - used by nsWindow & os2FrameWindow
 nsIRollupListener*  gRollupListener           = 0;
-nsIMenuRollup*      gMenuRollup               = 0;
 nsIWidget*          gRollupWidget             = 0;
 bool                gRollupConsumeRollupEvent = false;
 
 // Miscellaneous global flags
 PRUint32            gOS2Flags = 0;
 
 // Mouse pointers
 static HPOINTER     sPtrArray[IDC_COUNT];
@@ -481,19 +479,19 @@ NS_METHOD nsWindow::Destroy()
   if ((mWindowState & nsWindowState_eLive) && mParent) {
     nsBaseWidget::Destroy();
   }
 
   // just to be safe. If we're going away and for some reason we're still
   // the rollup widget, rollup and turn off capture.
   if (this == gRollupWidget) {
     if (gRollupListener) {
-      gRollupListener->Rollup(PR_UINT32_MAX, nsnull);
+      gRollupListener->Rollup(PR_UINT32_MAX);
     }
-    CaptureRollupEvents(nsnull, nsnull, false, true);
+    CaptureRollupEvents(nsnull, false, true);
   }
 
   HWND hMain = GetMainWindow();
   if (hMain) {
     DEBUGFOCUS(Destroy);
     if (hMain == WinQueryFocus(HWND_DESKTOP)) {
       WinSetFocus(HWND_DESKTOP, WinQueryWindow(hMain, QW_PARENT));
     }
@@ -1531,36 +1529,31 @@ HBITMAP nsWindow::CreateTransparencyMask
   return hAlpha;
 }
 
 //=============================================================================
 //  Rollup Event Handlers
 //=============================================================================
 
 NS_IMETHODIMP nsWindow::CaptureRollupEvents(nsIRollupListener* aListener,
-                                            nsIMenuRollup* aMenuRollup,
                                             bool aDoCapture,
                                             bool aConsumeRollupEvent)
 {
   // We haven't bothered carrying a weak reference to gRollupWidget
   // because we believe lifespan is properly scoped.  The first
   // assertion helps assure that remains true.
   if (aDoCapture) {
     NS_ASSERTION(!gRollupWidget, "rollup widget reassigned before release");
     gRollupConsumeRollupEvent = aConsumeRollupEvent;
     NS_IF_RELEASE(gRollupWidget);
     gRollupListener = aListener;
-    NS_IF_RELEASE(gMenuRollup);
-    gMenuRollup = aMenuRollup;
-    NS_IF_ADDREF(aMenuRollup);
     gRollupWidget = this;
     NS_ADDREF(this);
  } else {
     gRollupListener = nsnull;
-    NS_IF_RELEASE(gMenuRollup);
     NS_IF_RELEASE(gRollupWidget);
   }
 
   return NS_OK;
 }
 
 //-----------------------------------------------------------------------------
 
@@ -1594,34 +1587,35 @@ bool nsWindow::RollupOnButtonDown(ULONG 
   if (EventIsInsideWindow((nsWindow*)gRollupWidget)) {
     return false;
   }
 
   // See if we're dealing with a menu.  If so, exit if the
   // event was inside a parent of the current submenu.
   PRUint32 popupsToRollup = PR_UINT32_MAX;
 
-  if (gMenuRollup) {
+  if (gRollupListener) {
     nsAutoTArray<nsIWidget*, 5> widgetChain;
-    PRUint32 sameTypeCount = gMenuRollup->GetSubmenuWidgetChain(&widgetChain);
+    PRUint32 sameTypeCount = gRollupListener->GetSubmenuWidgetChain(&widgetChain);
     for (PRUint32 i = 0; i < widgetChain.Length(); ++i) {
       nsIWidget* widget = widgetChain[i];
       if (EventIsInsideWindow((nsWindow*)widget)) {
         if (i < sameTypeCount) {
           return false;
         }
         popupsToRollup = sameTypeCount;
         break;
       }
     } // for each parent menu widget
   } // if rollup listener knows about menus
 
   // We only need to deal with the last rollup for left mouse down events.
-  gRollupListener->Rollup(popupsToRollup,
-                          aMsg == WM_BUTTON1DOWN ? &mLastRollup : nsnull);
+  NS_ASSERTION(!mLastRollup, "mLastRollup is null");
+  mLastRollup = gRollupListener->Rollup(popupsToRollup, aMsg == WM_BUTTON1DOWN);
+  NS_IF_ADDREF(mLastRollup);
 
   // If true, the buttondown event won't be passed on to the wndproc.
   return gRollupConsumeRollupEvent;
 }
 
 //-----------------------------------------------------------------------------
 
 // static
@@ -1630,28 +1624,28 @@ void nsWindow::RollupOnFocusLost(HWND aF
   HWND hRollup = ((nsWindow*)gRollupWidget)->mWnd;
 
   // Exit if focus was lost to the most recent popup.
   if (hRollup == aFocus) {
     return;
   }
 
   // Exit if focus was lost to a parent of the current submenu.
-  if (gMenuRollup) {
+  if (gRollupListener) {
     nsAutoTArray<nsIWidget*, 5> widgetChain;
-    gMenuRollup->GetSubmenuWidgetChain(&widgetChain);
+    gRollupListener->GetSubmenuWidgetChain(&widgetChain);
     for (PRUint32 i = 0; i < widgetChain.Length(); ++i) {
       if (((nsWindow*)widgetChain[i])->mWnd == aFocus) {
         return;
       }
     }
   }
 
   // Rollup all popups.
-  gRollupListener->Rollup(PR_UINT32_MAX, nsnull);
+  gRollupListener->Rollup(PR_UINT32_MAX);
   return;
 }
 
 //=============================================================================
 //  nsWindow's Window Procedure
 //=============================================================================
 
 // This is the actual wndproc;  it does some preprocessing then passes
--- a/widget/src/os2/nsWindow.h
+++ b/widget/src/os2/nsWindow.h
@@ -201,17 +201,16 @@ public:
   NS_IMETHOD            SetTitle(const nsAString& aTitle); 
   NS_IMETHOD            SetIcon(const nsAString& aIconSpec); 
   NS_IMETHOD            ConstrainPosition(bool aAllowSlop,
                                           PRInt32* aX, PRInt32* aY);
   NS_IMETHOD            SetCursor(nsCursor aCursor);
   NS_IMETHOD            SetCursor(imgIContainer* aCursor,
                                   PRUint32 aHotspotX, PRUint32 aHotspotY);
   NS_IMETHOD            CaptureRollupEvents(nsIRollupListener* aListener,
-                                            nsIMenuRollup* aMenuRollup,
                                             bool aDoCapture, bool aConsumeRollupEvent);
   NS_IMETHOD            GetToggledKeyState(PRUint32 aKeyCode,
                                            bool* aLEDState);
   NS_IMETHOD            DispatchEvent(nsGUIEvent* event,
                                       nsEventStatus& aStatus);
   NS_IMETHOD            ReparentNativeWidget(nsIWidget* aNewParent);
 
   // nsWindow
--- a/widget/src/os2/os2FrameWindow.cpp
+++ b/widget/src/os2/os2FrameWindow.cpp
@@ -625,17 +625,17 @@ MRESULT EXPENTRY fnwpFrame(HWND hwnd, UL
 {
   // check to see if we have a rollup listener registered
   if (gRollupListener && gRollupWidget) {
     if (msg == WM_TRACKFRAME || msg == WM_MINMAXFRAME ||
         msg == WM_BUTTON1DOWN || msg == WM_BUTTON2DOWN ||
         msg == WM_BUTTON3DOWN) {
       // Rollup if the event is outside the popup
       if (!nsWindow::EventIsInsideWindow((nsWindow*)gRollupWidget)) {
-        gRollupListener->Rollup(PR_UINT32_MAX, nsnull);
+        gRollupListener->Rollup(PR_UINT32_MAX);
       }
     }
   }
 
   os2FrameWindow* pFrame = (os2FrameWindow*)WinQueryWindowPtr(hwnd, QWL_USER);
   return pFrame->ProcessFrameMessage(msg, mp1, mp2);
 }
 
--- a/widget/src/qt/nsWindow.cpp
+++ b/widget/src/qt/nsWindow.cpp
@@ -93,17 +93,16 @@ using namespace QtMobility;
 
 #ifdef MOZ_ENABLE_QTMOBILITY
 #include "mozqorientationsensorfilter.h"
 #endif
 
 #include "nsIdleService.h"
 #include "nsRenderingContext.h"
 #include "nsIRollupListener.h"
-#include "nsIMenuRollup.h"
 #include "nsWidgetsCID.h"
 #include "nsQtKeyUtils.h"
 #include "mozilla/Services.h"
 #include "mozilla/Preferences.h"
 
 #include "nsIStringBundle.h"
 #include "nsGfxCIID.h"
 
@@ -178,17 +177,16 @@ static NS_DEFINE_IID(kCDragServiceCID,  
 
 #define kWindowPositionSlop 20
 
 // Qt
 static const int WHEEL_DELTA = 120;
 static bool gGlobalsInitialized = false;
 
 static nsIRollupListener*          gRollupListener;
-static nsIMenuRollup*              gMenuRollup;
 static nsWeakPtr                   gRollupWindow;
 static bool                        gConsumeRollupEvent;
 
 static bool       check_for_rollup(double aMouseX, double aMouseY,
                                    bool aIsWheel);
 static bool
 is_mouse_in_window (MozQWidget* aWindow, double aMouseX, double aMouseY);
 
@@ -418,20 +416,19 @@ nsWindow::Destroy(void)
             gOrientation = nsnull;
         }
 #endif
     }
 
     nsCOMPtr<nsIWidget> rollupWidget = do_QueryReferent(gRollupWindow);
     if (static_cast<nsIWidget *>(this) == rollupWidget.get()) {
         if (gRollupListener)
-            gRollupListener->Rollup(nsnull, nsnull);
+            gRollupListener->Rollup(0);
         gRollupWindow = nsnull;
         gRollupListener = nsnull;
-        NS_IF_RELEASE(gMenuRollup);
     }
 
     if (mLayerManager) {
         mLayerManager->Destroy();
     }
     mLayerManager = nsnull;
 
     Show(false);
@@ -934,36 +931,31 @@ nsWindow::CaptureMouse(bool aCapture)
     else
         widget->releaseMouse();
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsWindow::CaptureRollupEvents(nsIRollupListener *aListener,
-                              nsIMenuRollup     *aMenuRollup,
                               bool               aDoCapture,
                               bool               aConsumeRollupEvent)
 {
     if (!mWidget)
         return NS_OK;
 
     LOG(("CaptureRollupEvents %p\n", (void *)this));
 
     if (aDoCapture) {
         gConsumeRollupEvent = aConsumeRollupEvent;
         gRollupListener = aListener;
-        NS_IF_RELEASE(gMenuRollup);
-        gMenuRollup = aMenuRollup;
-        NS_IF_ADDREF(aMenuRollup);
         gRollupWindow = do_GetWeakReference(static_cast<nsIWidget*>(this));
     }
     else {
         gRollupListener = nsnull;
-        NS_IF_RELEASE(gMenuRollup);
         gRollupWindow = nsnull;
     }
 
     return NS_OK;
 }
 
 bool
 check_for_rollup(double aMouseX, double aMouseY,
@@ -974,26 +966,26 @@ check_for_rollup(double aMouseX, double 
 
     if (rollupWidget && gRollupListener) {
         MozQWidget *currentPopup =
             (MozQWidget *)rollupWidget->GetNativeData(NS_NATIVE_WINDOW);
 
         if (!is_mouse_in_window(currentPopup, aMouseX, aMouseY)) {
             bool rollup = true;
             if (aIsWheel) {
-                gRollupListener->ShouldRollupOnMouseWheelEvent(&rollup);
+                rollup = gRollupListener->ShouldRollupOnMouseWheelEvent();
                 retVal = true;
             }
             // if we're dealing with menus, we probably have submenus and
             // we don't want to rollup if the clickis in a parent menu of
             // the current submenu
             PRUint32 popupsToRollup = PR_UINT32_MAX;
-            if (gMenuRollup) {
+            if (gRollupListener) {
                 nsAutoTArray<nsIWidget*, 5> widgetChain;
-                PRUint32 sameTypeCount = gMenuRollup->GetSubmenuWidgetChain(&widgetChain);
+                PRUint32 sameTypeCount = gRollupListener->GetSubmenuWidgetChain(&widgetChain);
                 for (PRUint32 i=0; i<widgetChain.Length(); ++i) {
                     nsIWidget* widget =  widgetChain[i];
                     MozQWidget* currWindow =
                         (MozQWidget*) widget->GetNativeData(NS_NATIVE_WINDOW);
                     if (is_mouse_in_window(currWindow, aMouseX, aMouseY)) {
                       if (i < sameTypeCount) {
                         rollup = false;
                       }
@@ -1002,24 +994,23 @@ check_for_rollup(double aMouseX, double 
                       }
                       break;
                     }
                 } // foreach parent menu widget
             } // if rollup listener knows about menus
 
             // if we've determined that we should still rollup, do it.
             if (rollup) {
-                gRollupListener->Rollup(popupsToRollup, nsnull);
+                gRollupListener->Rollup(popupsToRollup);
                 retVal = true;
             }
         }
     } else {
         gRollupWindow = nsnull;
         gRollupListener = nsnull;
-        NS_IF_RELEASE(gMenuRollup);
     }
 
     return retVal;
 }
 
 /* static */
 bool
 is_mouse_in_window (MozQWidget* aWindow, double aMouseX, double aMouseY)
--- a/widget/src/qt/nsWindow.h
+++ b/widget/src/qt/nsWindow.h
@@ -181,17 +181,16 @@ public:
     NS_IMETHOD         SetTitle(const nsAString& aTitle);
     NS_IMETHOD         SetIcon(const nsAString& aIconSpec);
     virtual nsIntPoint WidgetToScreenOffset();
     NS_IMETHOD         DispatchEvent(nsGUIEvent *aEvent, nsEventStatus &aStatus);
 
     NS_IMETHOD         EnableDragDrop(bool aEnable);
     NS_IMETHOD         CaptureMouse(bool aCapture);
     NS_IMETHOD         CaptureRollupEvents(nsIRollupListener *aListener,
-                                           nsIMenuRollup *aMenuRollup,
                                            bool aDoCapture,
                                            bool aConsumeRollupEvent);
 
     NS_IMETHOD         SetWindowClass(const nsAString& xulWinType);
 
     NS_IMETHOD         GetAttention(PRInt32 aCycleCount);
     NS_IMETHOD         BeginResizeDrag   (nsGUIEvent* aEvent, PRInt32 aHorizontal, PRInt32 aVertical);
 
--- a/widget/src/windows/nsWindow.cpp
+++ b/widget/src/windows/nsWindow.cpp
@@ -124,17 +124,16 @@
 #include "nsISupportsPrimitives.h"
 #include "nsIDOMMouseEvent.h"
 #include "nsITheme.h"
 #include "nsIObserverService.h"
 #include "nsIScreenManager.h"
 #include "imgIContainer.h"
 #include "nsIFile.h"
 #include "nsIRollupListener.h"
-#include "nsIMenuRollup.h"
 #include "nsIServiceManager.h"
 #include "nsIClipboard.h"
 #include "nsIMM32Handler.h"
 #include "nsILocalFile.h"
 #include "nsFontMetrics.h"
 #include "nsIFontEnumerator.h"
 #include "nsGUIEvent.h"
 #include "nsFont.h"
@@ -248,17 +247,16 @@ HHOOK           nsWindow::sCallProcHook 
 HHOOK           nsWindow::sCallMouseHook          = NULL;
 bool            nsWindow::sProcessHook            = false;
 UINT            nsWindow::sRollupMsgId            = 0;
 HWND            nsWindow::sRollupMsgWnd           = NULL;
 UINT            nsWindow::sHookTimerId            = 0;
 
 // Rollup Listener
 nsIRollupListener* nsWindow::sRollupListener      = nsnull;
-nsIMenuRollup*  nsWindow::sMenuRollup             = nsnull;
 nsIWidget*      nsWindow::sRollupWidget           = nsnull;
 bool            nsWindow::sRollupConsumeEvent     = false;
 
 // Mouse Clicks - static variable definitions for figuring
 // out 1 - 3 Clicks.
 POINT           nsWindow::sLastMousePoint         = {0};
 POINT           nsWindow::sLastMouseMovePoint     = {0};
 LONG            nsWindow::sLastMouseDownTime      = 0L;
@@ -3072,40 +3070,35 @@ NS_METHOD nsWindow::CaptureMouse(bool aC
  *
  * Dealing with event rollup on destroy for popups. Enables &
  * Disables system capture of any and all events that would
  * cause a dropdown to be rolled up.
  *
  **************************************************************/
 
 NS_IMETHODIMP nsWindow::CaptureRollupEvents(nsIRollupListener * aListener,
-                                            nsIMenuRollup * aMenuRollup,
                                             bool aDoCapture,
                                             bool aConsumeRollupEvent)
 {
   if (aDoCapture) {
     /* we haven't bothered carrying a weak reference to sRollupWidget because
        we believe lifespan is properly scoped. this next assertion helps
        assure that remains true. */
     NS_ASSERTION(!sRollupWidget, "rollup widget reassigned before release");
     sRollupConsumeEvent = aConsumeRollupEvent;
     NS_IF_RELEASE(sRollupWidget);
-    NS_IF_RELEASE(sMenuRollup);
     sRollupListener = aListener;
-    sMenuRollup = aMenuRollup;
-    NS_IF_ADDREF(aMenuRollup);
     sRollupWidget = this;
     NS_ADDREF(this);
     if (!sMsgFilterHook && !sCallProcHook && !sCallMouseHook) {
       RegisterSpecialDropdownHooks();
     }
     sProcessHook = true;
   } else {
     sRollupListener = nsnull;
-    NS_IF_RELEASE(sMenuRollup);
     NS_IF_RELEASE(sRollupWidget);
     sProcessHook = false;
     UnregisterSpecialDropdownHooks();
   }
 
   return NS_OK;
 }
 
@@ -7408,18 +7401,18 @@ void nsWindow::OnDestroy()
 
   // We have to destroy the native drag target before we null out our window pointer.
   EnableDragDrop(false);
 
   // If we're going away and for some reason we're still the rollup widget, rollup and
   // turn off capture.
   if ( this == sRollupWidget ) {
     if ( sRollupListener )
-      sRollupListener->Rollup(nsnull, nsnull);
-    CaptureRollupEvents(nsnull, nsnull, false, true);
+      sRollupListener->Rollup(0);
+    CaptureRollupEvents(nsnull, false, true);
   }
 
   // Restore the IM context.
   AssociateDefaultIMC(true);
 
   // Turn off mouse trails if enabled.
   MouseTrailer* mtrailer = nsToolkit::gMouseTrailer;
   if (mtrailer) {
@@ -8712,27 +8705,27 @@ nsWindow::DealWithPopups(HWND inWnd, UIN
         inMsg == WM_ACTIVATEAPP ||
         inMsg == WM_MENUSELECT)
     {
       // Rollup if the event is outside the popup.
       bool rollup = !nsWindow::EventIsInsideWindow(inMsg, (nsWindow*)sRollupWidget);
 
       if (rollup && (inMsg == WM_MOUSEWHEEL || inMsg == WM_MOUSEHWHEEL))
       {
-        sRollupListener->ShouldRollupOnMouseWheelEvent(&rollup);
+        rollup = sRollupListener->ShouldRollupOnMouseWheelEvent();
         *outResult = true;
       }
 
       // If we're dealing with menus, we probably have submenus and we don't
       // want to rollup if the click is in a parent menu of the current submenu.
       PRUint32 popupsToRollup = PR_UINT32_MAX;
       if (rollup) {
-        if ( sMenuRollup ) {
+        if ( sRollupListener ) {
           nsAutoTArray<nsIWidget*, 5> widgetChain;
-          PRUint32 sameTypeCount = sMenuRollup->GetSubmenuWidgetChain(&widgetChain);
+          PRUint32 sameTypeCount = sRollupListener->GetSubmenuWidgetChain(&widgetChain);
           for ( PRUint32 i = 0; i < widgetChain.Length(); ++i ) {
             nsIWidget* widget = widgetChain[i];
             if ( nsWindow::EventIsInsideWindow(inMsg, (nsWindow*)widget) ) {
               // don't roll up if the mouse event occurred within a menu of the
               // same type. If the mouse event occurred in a menu higher than
               // that, roll up, but pass the number of popups to Rollup so
               // that only those of the same type close up.
               if (i < sameTypeCount) {
@@ -8758,32 +8751,34 @@ nsWindow::DealWithPopups(HWND inWnd, UIN
         }
         else
         {
           UINT uMsg = HIWORD(inLParam);
           if (uMsg == WM_MOUSEMOVE)
           {
             // WM_MOUSEACTIVATE cause by moving the mouse - X-mouse (eg. TweakUI)
             // must be enabled in Windows.
-            sRollupListener->ShouldRollupOnMouseActivate(&rollup);
+            rollup = sRollupListener->ShouldRollupOnMouseActivate();
             if (!rollup)
             {
               *outResult = MA_NOACTIVATE;
               return true;
             }
           }
         }
       }
       // if we've still determined that we should still rollup everything, do it.
       else if (rollup) {
         // sRollupConsumeEvent may be modified by
         // nsIRollupListener::Rollup.
         bool consumeRollupEvent = sRollupConsumeEvent;
         // only need to deal with the last rollup for left mouse down events.
-        sRollupListener->Rollup(popupsToRollup, inMsg == WM_LBUTTONDOWN ? &mLastRollup : nsnull);
+        NS_ASSERTION(!mLastRollup, "mLastRollup is null");
+        mLastRollup = sRollupListener->Rollup(popupsToRollup, inMsg == WM_LBUTTONDOWN);
+        NS_IF_ADDREF(mLastRollup);
 
         // Tell hook to stop processing messages
         sProcessHook = false;
         sRollupMsgId = 0;
         sRollupMsgWnd = NULL;
 
         // return TRUE tells Windows that the event is consumed,
         // false allows the event to be dispatched
--- a/widget/src/windows/nsWindow.h
+++ b/widget/src/windows/nsWindow.h
@@ -153,17 +153,17 @@ public:
   virtual void            FreeNativeData(void * data, PRUint32 aDataType);
   NS_IMETHOD              SetTitle(const nsAString& aTitle);
   NS_IMETHOD              SetIcon(const nsAString& aIconSpec);
   virtual nsIntPoint      WidgetToScreenOffset();
   virtual nsIntSize       ClientToWindowSize(const nsIntSize& aClientSize);
   NS_IMETHOD              DispatchEvent(nsGUIEvent* event, nsEventStatus & aStatus);
   NS_IMETHOD              EnableDragDrop(bool aEnable);
   NS_IMETHOD              CaptureMouse(bool aCapture);
-  NS_IMETHOD              CaptureRollupEvents(nsIRollupListener * aListener, nsIMenuRollup * aMenuRollup,
+  NS_IMETHOD              CaptureRollupEvents(nsIRollupListener * aListener,
                                               bool aDoCapture, bool aConsumeRollupEvent);
   NS_IMETHOD              GetAttention(PRInt32 aCycleCount);
   virtual bool            HasPendingInputEvent();
   virtual LayerManager*   GetLayerManager(PLayersChild* aShadowManager = nsnull,
                                           LayersBackend aBackendHint = LayerManager::LAYERS_NONE,
                                           LayerManagerPersistence aPersistence = LAYER_MANAGER_CURRENT,
                                           bool* aAllowRetaining = nsnull);
   gfxASurface             *GetThebesSurface();
@@ -589,17 +589,16 @@ protected:
   static UINT           sRollupMsgId;
   static HWND           sRollupMsgWnd;
   static UINT           sHookTimerId;
 
   // Rollup Listener
   static nsIWidget*     sRollupWidget;
   static bool           sRollupConsumeEvent;
   static nsIRollupListener* sRollupListener;
-  static nsIMenuRollup* sMenuRollup;
 
   // Mouse Clicks - static variable definitions for figuring
   // out 1 - 3 Clicks.
   static POINT          sLastMousePoint;
   static POINT          sLastMouseMovePoint;
   static LONG           sLastMouseDownTime;
   static LONG           sLastClickCount;
   static BYTE           sLastMouseButton;
--- a/widget/src/xpwidgets/PuppetWidget.h
+++ b/widget/src/xpwidgets/PuppetWidget.h
@@ -145,17 +145,17 @@ public:
   // PuppetWidgets are always at <0, 0>.
   virtual nsIntPoint WidgetToScreenOffset()
   { return nsIntPoint(0, 0); }
 
   void InitEvent(nsGUIEvent& event, nsIntPoint* aPoint = nsnull);
 
   NS_IMETHOD DispatchEvent(nsGUIEvent* event, nsEventStatus& aStatus);
 
-  NS_IMETHOD CaptureRollupEvents(nsIRollupListener* aListener, nsIMenuRollup* aMenuRollup,
+  NS_IMETHOD CaptureRollupEvents(nsIRollupListener* aListener,
                                  bool aDoCapture, bool aConsumeRollupEvent)
   { return NS_ERROR_UNEXPECTED; }
 
   //
   // nsBaseWidget methods we override
   //
 
 //NS_IMETHOD              CaptureMouse(bool aCapture);
--- a/xpfe/appshell/src/nsWebShellWindow.cpp
+++ b/xpfe/appshell/src/nsWebShellWindow.cpp
@@ -315,31 +315,29 @@ nsWebShellWindow::HandleEvent(nsGUIEvent
     switch(aEvent->message) {
       /*
        * For size events, the DocShell must be resized to fill the entire
        * client area of the window...
        */
       case NS_MOVE: {
         // Adjust any child popups so that their widget offsets and coordinates
         // are correct with respect to the new position of the window
-        nsCOMPtr<nsIMenuRollup> pm =
-          do_GetService("@mozilla.org/xul/xul-popup-manager;1");
+        nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
         if (pm) {
           nsCOMPtr<nsPIDOMWindow> window = do_GetInterface(docShell);
           pm->AdjustPopupsOnWindowChange(window);
         }
 
         // persist position, but not immediately, in case this OS is firing
         // repeated move events as the user drags the window
         eventWindow->SetPersistenceTimer(PAD_POSITION);
         break;
       }
       case NS_SIZE: {
-        nsCOMPtr<nsIMenuRollup> pm =
-          do_GetService("@mozilla.org/xul/xul-popup-manager;1");
+        nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
         if (pm) {
           nsCOMPtr<nsPIDOMWindow> window = do_GetInterface(docShell);
           pm->AdjustPopupsOnWindowChange(window);
         }
  
         nsSizeEvent* sizeEvent = (nsSizeEvent*)aEvent;
         nsCOMPtr<nsIBaseWindow> shellAsWin(do_QueryInterface(docShell));
         shellAsWin->SetPositionAndSize(0, 0, sizeEvent->windowSize->width,