From 7c840e862013aa74cbf20886494185d8b2c1453c Mon Sep 17 00:00:00 2001 From: "mozilla.mano%sent.com" Date: Wed, 21 Feb 2007 23:37:34 +0000 Subject: [PATCH] Bug 365405 - the xbl binding for a menupopup is attached only once the menu is opened, after popupshowing is dispatched. r=josh, sr=jst. --- widget/src/cocoa/Makefile.in | 2 ++ widget/src/cocoa/nsMenuX.h | 1 + widget/src/cocoa/nsMenuX.mm | 37 +++++++++++++++++++++++++++++++++--- 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/widget/src/cocoa/Makefile.in b/widget/src/cocoa/Makefile.in index 67e990f25f6a..6f28a820af1c 100644 --- a/widget/src/cocoa/Makefile.in +++ b/widget/src/cocoa/Makefile.in @@ -74,6 +74,8 @@ REQUIRES = xpcom \ appshell \ thebes \ cairo \ + js \ + xpconnect \ $(NULL) ifdef MOZ_ENABLE_GLITZ diff --git a/widget/src/cocoa/nsMenuX.h b/widget/src/cocoa/nsMenuX.h index 33ff38416748..34350dff9109 100644 --- a/widget/src/cocoa/nsMenuX.h +++ b/widget/src/cocoa/nsMenuX.h @@ -159,6 +159,7 @@ protected: PRPackedBool mDestroyHandlerCalled; PRPackedBool mNeedsRebuild; PRPackedBool mConstructed; + PRPackedBool mXBLAttached; PRPackedBool mVisible; // are we visible to the user? }; diff --git a/widget/src/cocoa/nsMenuX.mm b/widget/src/cocoa/nsMenuX.mm index 3b59ceb624ec..1c78fbe82767 100644 --- a/widget/src/cocoa/nsMenuX.mm +++ b/widget/src/cocoa/nsMenuX.mm @@ -69,6 +69,11 @@ #include "nsCRT.h" +#include "jsapi.h" +#include "nsIScriptGlobalObject.h" +#include "nsIScriptContext.h" +#include "nsIXPConnect.h" + // externs defined in nsChildView.mm extern nsIRollupListener * gRollupListener; extern nsIWidget * gRollupWidget; @@ -102,7 +107,8 @@ NS_IMPL_ISUPPORTS4(nsMenuX, nsIMenu, nsIMenuListener, nsIChangeObserver, nsISupp nsMenuX::nsMenuX() : mParent(nsnull), mManager(nsnull), mMacMenuID(0), mMacMenu(nil), mIsEnabled(PR_TRUE), mDestroyHandlerCalled(PR_FALSE), - mNeedsRebuild(PR_TRUE), mConstructed(PR_FALSE), mVisible(PR_TRUE) + mNeedsRebuild(PR_TRUE), mConstructed(PR_FALSE), mVisible(PR_TRUE), + mXBLAttached(PR_FALSE) { mMenuDelegate = [[MenuDelegate alloc] initWithGeckoMenu:this]; @@ -469,7 +475,32 @@ nsEventStatus nsMenuX::MenuConstruct( GetMenuPopupContent(getter_AddRefs(menuPopup)); if (!menuPopup) return nsEventStatus_eIgnore; - + + // bug 365405: Manually wrap the menupopup node to make sure it's bounded + if (!mXBLAttached) { + nsresult rv; + nsCOMPtr xpconnect = + do_GetService(nsIXPConnect::GetCID(), &rv); + if (NS_SUCCEEDED(rv)) { + nsIDocument* ownerDoc = menuPopup->GetOwnerDoc(); + nsIScriptGlobalObject* sgo; + if (ownerDoc && (sgo = ownerDoc->GetScriptGlobalObject())) { + nsCOMPtr scriptContext = sgo->GetContext(); + JSObject* global = sgo->GetGlobalJSObject(); + if (scriptContext && global) { + JSContext* cx = (JSContext*)scriptContext->GetNativeContext(); + if (cx) { + nsCOMPtr wrapper; + xpconnect->WrapNative(cx, global, + menuPopup, NS_GET_IID(nsISupports), + getter_AddRefs(wrapper)); + mXBLAttached = PR_TRUE; + } + } + } + } + } + // Iterate over the kids PRUint32 count = menuPopup->GetChildCount(); for (PRUint32 i = 0; i < count; i++) { @@ -485,7 +516,7 @@ nsEventStatus nsMenuX::MenuConstruct( LoadSubMenu(this, child); } } // for each menu item - + gConstructingMenu = PR_FALSE; mNeedsRebuild = PR_FALSE; // printf("Done building, mMenuItemVoidArray.Count() = %d \n", mMenuItemVoidArray.Count());