Null out weak pointers when they become invalid. b=479749 r=josh sr=roc

This commit is contained in:
Steven Michaud 2009-03-09 11:59:29 -05:00
Родитель ebb622ed2b
Коммит 7472c08540
3 изменённых файлов: 44 добавлений и 11 удалений

Просмотреть файл

@ -736,7 +736,6 @@ NS_IMETHODIMP nsChildView::Destroy()
[mView widgetDestroyed];
nsBaseWidget::OnDestroy();
nsBaseWidget::Destroy();
ReportDestroyEvent();
@ -744,6 +743,8 @@ NS_IMETHODIMP nsChildView::Destroy()
TearDownView();
nsBaseWidget::OnDestroy();
return NS_OK;
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
@ -2942,7 +2943,7 @@ NSEvent* gLastDragEvent = nil;
static const PRInt32 sShadowInvalidationInterval = 100;
- (void)maybeInvalidateShadow
{
if ([mWindow isOpaque] || ![mWindow hasShadow])
if (!mWindow || [mWindow isOpaque] || ![mWindow hasShadow])
return;
PRIntervalTime now = PR_IntervalNow();
@ -2963,7 +2964,7 @@ static const PRInt32 sShadowInvalidationInterval = 100;
- (void)invalidateShadow
{
if (!mNeedsShadowInvalidation)
if (!mWindow || !mNeedsShadowInvalidation)
return;
[mWindow invalidateShadow];
mNeedsShadowInvalidation = NO;
@ -3659,6 +3660,9 @@ static nsEventStatus SendGeckoMouseEnterOrExitEvent(PRBool isTrusted,
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
if (!mWindow)
return;
// Work around an Apple bug that causes the OS to continue sending
// mouseMoved events to a window for a while after it's been miniaturized.
// This may be related to a similar problem with popup windows (bmo bug
@ -4173,10 +4177,13 @@ static nsEventStatus SendGeckoMouseEnterOrExitEvent(PRBool isTrusted,
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
if (!mWindow)
return nil;
WindowDataMap* windowMap = [WindowDataMap sharedWindowDataMap];
TopLevelWindowData* windowData = [windowMap dataForWindow:mWindow];
if (mWindow && !windowData)
if (!windowData)
{
windowData = [[TopLevelWindowData alloc] initWithWindow:mWindow];
[windowMap setData:windowData forWindow:mWindow]; // takes ownership

Просмотреть файл

@ -118,6 +118,25 @@ nsCocoaWindow::nsCocoaWindow()
}
// Under unusual circumstances, an nsCocoaWindow object can be destroyed
// before the nsChildView objects it contains are destroyed. But this will
// invalidate the (weak) mWindow variable in these nsChildView objects
// before their own destructors have been called. So we need to null-out
// this variable in our nsChildView objects as we're destroyed. This helps
// resolve bmo bug 479749.
static void TellNativeViewsGoodbye(NSView *aNativeView)
{
if (!aNativeView)
return;
if ([aNativeView respondsToSelector:@selector(setNativeWindow:)])
[(NSView<mozView>*)aNativeView setNativeWindow:nil];
NSArray *immediateSubviews = [aNativeView subviews];
int count = [immediateSubviews count];
for (int i = 0; i < count; ++i)
TellNativeViewsGoodbye((NSView *)[immediateSubviews objectAtIndex:i]);
}
nsCocoaWindow::~nsCocoaWindow()
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
@ -128,12 +147,15 @@ nsCocoaWindow::~nsCocoaWindow()
childWindow->mParent = nsnull;
}
if (mWindow && mWindowMadeHere) {
// we want to unhook the delegate here because we don't want events
// sent to it after this object has been destroyed
[mWindow setDelegate:nil];
[mWindow autorelease];
[mDelegate autorelease];
if (mWindow) {
TellNativeViewsGoodbye([mWindow contentView]);
if (mWindowMadeHere) {
// we want to unhook the delegate here because we don't want events
// sent to it after this object has been destroyed
[mWindow setDelegate:nil];
[mWindow autorelease];
[mDelegate autorelease];
}
}
NS_IF_RELEASE(mPopupContentView);
@ -429,8 +451,8 @@ NS_IMETHODIMP nsCocoaWindow::Destroy()
if (mPopupContentView)
mPopupContentView->Destroy();
nsBaseWidget::OnDestroy();
nsBaseWidget::Destroy();
nsBaseWidget::OnDestroy();
return NS_OK;
}

Просмотреть файл

@ -256,6 +256,10 @@ NS_METHOD nsBaseWidget::Destroy()
// Just in case our parent is the only ref to us
nsCOMPtr<nsIWidget> kungFuDeathGrip(this);
// Clear the device context's mWidget field -- otherwise it may get accessed
// after it's been deleted. See bug 479749.
if (mContext)
mContext->Init(nsnull);
// disconnect from the parent
nsIWidget *parent = GetParent();
if (parent) {