зеркало из https://github.com/mozilla/pjs.git
Stop nsMenuItemIconX object from possibly outliving its nsMenuObjectX owner. b=499600 r=josh
This commit is contained in:
Родитель
1ec8d353f5
Коммит
6bed2b38b0
|
@ -79,13 +79,19 @@ public:
|
||||||
// icon. The request may not complete until after LoadIcon returns.
|
// icon. The request may not complete until after LoadIcon returns.
|
||||||
nsresult LoadIcon(nsIURI* aIconURI);
|
nsresult LoadIcon(nsIURI* aIconURI);
|
||||||
|
|
||||||
|
// Unless we take precautions, we may outlive the object that created us
|
||||||
|
// (mMenuObject, which owns our native menu item (mNativeMenuItem)).
|
||||||
|
// Destroy() should be called from mMenuObject's destructor to prevent
|
||||||
|
// this from happening. See bug 499600.
|
||||||
|
void Destroy();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
nsCOMPtr<nsIContent> mContent;
|
nsCOMPtr<nsIContent> mContent;
|
||||||
nsCOMPtr<imgIRequest> mIconRequest;
|
nsCOMPtr<imgIRequest> mIconRequest;
|
||||||
nsMenuObjectX* mMenuObject;
|
nsMenuObjectX* mMenuObject; // [weak]
|
||||||
PRPackedBool mLoadedIcon;
|
PRPackedBool mLoadedIcon;
|
||||||
PRPackedBool mSetIcon;
|
PRPackedBool mSetIcon;
|
||||||
NSMenuItem* mNativeMenuItem;
|
NSMenuItem* mNativeMenuItem; // [weak]
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // nsMenuItemIconX_h_
|
#endif // nsMenuItemIconX_h_
|
||||||
|
|
|
@ -97,6 +97,19 @@ nsMenuItemIconX::~nsMenuItemIconX()
|
||||||
mIconRequest->CancelAndForgetObserver(NS_BINDING_ABORTED);
|
mIconRequest->CancelAndForgetObserver(NS_BINDING_ABORTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Called from mMenuObjectX's destructor, to prevent us from outliving it
|
||||||
|
// (as might otherwise happen if calls to our imgIDecoderObserver methods
|
||||||
|
// are still outstanding). mMenuObjectX owns our nNativeMenuItem.
|
||||||
|
void nsMenuItemIconX::Destroy()
|
||||||
|
{
|
||||||
|
if (mIconRequest) {
|
||||||
|
mIconRequest->CancelAndForgetObserver(NS_BINDING_ABORTED);
|
||||||
|
mIconRequest = nsnull;
|
||||||
|
}
|
||||||
|
mMenuObject = nsnull;
|
||||||
|
mNativeMenuItem = nil;
|
||||||
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsMenuItemIconX::SetupIcon()
|
nsMenuItemIconX::SetupIcon()
|
||||||
{
|
{
|
||||||
|
@ -126,6 +139,9 @@ nsMenuItemIconX::SetupIcon()
|
||||||
nsresult
|
nsresult
|
||||||
nsMenuItemIconX::GetIconURI(nsIURI** aIconURI)
|
nsMenuItemIconX::GetIconURI(nsIURI** aIconURI)
|
||||||
{
|
{
|
||||||
|
if (!mMenuObject)
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
// Mac native menu items support having both a checkmark and an icon
|
// Mac native menu items support having both a checkmark and an icon
|
||||||
// simultaneously, but this is unheard of in the cross-platform toolkit,
|
// simultaneously, but this is unheard of in the cross-platform toolkit,
|
||||||
// seemingly because the win32 theme is unable to cope with both at once.
|
// seemingly because the win32 theme is unable to cope with both at once.
|
||||||
|
@ -320,6 +336,8 @@ nsMenuItemIconX::OnStopFrame(imgIRequest* aRequest,
|
||||||
if (mLoadedIcon)
|
if (mLoadedIcon)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
||||||
|
if (!mNativeMenuItem) return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
nsCOMPtr<gfxIImageFrame> frame = aFrame;
|
nsCOMPtr<gfxIImageFrame> frame = aFrame;
|
||||||
nsCOMPtr<nsIImage> image = do_GetInterface(frame);
|
nsCOMPtr<nsIImage> image = do_GetInterface(frame);
|
||||||
if (!image) return NS_ERROR_FAILURE;
|
if (!image) return NS_ERROR_FAILURE;
|
||||||
|
|
|
@ -72,6 +72,10 @@ nsMenuItemX::~nsMenuItemX()
|
||||||
{
|
{
|
||||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||||
|
|
||||||
|
// Prevent the icon object from outliving us.
|
||||||
|
if (mIcon)
|
||||||
|
mIcon->Destroy();
|
||||||
|
|
||||||
// autorelease the native menu item so that anything else happening to this
|
// autorelease the native menu item so that anything else happening to this
|
||||||
// object happens before the native menu item actually dies
|
// object happens before the native menu item actually dies
|
||||||
[mNativeMenuItem autorelease];
|
[mNativeMenuItem autorelease];
|
||||||
|
|
|
@ -117,6 +117,10 @@ nsMenuX::~nsMenuX()
|
||||||
{
|
{
|
||||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||||
|
|
||||||
|
// Prevent the icon object from outliving us.
|
||||||
|
if (mIcon)
|
||||||
|
mIcon->Destroy();
|
||||||
|
|
||||||
RemoveAll();
|
RemoveAll();
|
||||||
|
|
||||||
[mNativeMenu setDelegate:nil];
|
[mNativeMenu setDelegate:nil];
|
||||||
|
|
Загрузка…
Ссылка в новой задаче