зеркало из https://github.com/mozilla/gecko-dev.git
Null out weak pointers when they become invalid. b=479749 r=josh sr=roc
This commit is contained in:
Родитель
ebb622ed2b
Коммит
7472c08540
|
@ -736,7 +736,6 @@ NS_IMETHODIMP nsChildView::Destroy()
|
||||||
|
|
||||||
[mView widgetDestroyed];
|
[mView widgetDestroyed];
|
||||||
|
|
||||||
nsBaseWidget::OnDestroy();
|
|
||||||
nsBaseWidget::Destroy();
|
nsBaseWidget::Destroy();
|
||||||
|
|
||||||
ReportDestroyEvent();
|
ReportDestroyEvent();
|
||||||
|
@ -744,6 +743,8 @@ NS_IMETHODIMP nsChildView::Destroy()
|
||||||
|
|
||||||
TearDownView();
|
TearDownView();
|
||||||
|
|
||||||
|
nsBaseWidget::OnDestroy();
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
||||||
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
|
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
|
||||||
|
@ -2942,7 +2943,7 @@ NSEvent* gLastDragEvent = nil;
|
||||||
static const PRInt32 sShadowInvalidationInterval = 100;
|
static const PRInt32 sShadowInvalidationInterval = 100;
|
||||||
- (void)maybeInvalidateShadow
|
- (void)maybeInvalidateShadow
|
||||||
{
|
{
|
||||||
if ([mWindow isOpaque] || ![mWindow hasShadow])
|
if (!mWindow || [mWindow isOpaque] || ![mWindow hasShadow])
|
||||||
return;
|
return;
|
||||||
|
|
||||||
PRIntervalTime now = PR_IntervalNow();
|
PRIntervalTime now = PR_IntervalNow();
|
||||||
|
@ -2963,7 +2964,7 @@ static const PRInt32 sShadowInvalidationInterval = 100;
|
||||||
|
|
||||||
- (void)invalidateShadow
|
- (void)invalidateShadow
|
||||||
{
|
{
|
||||||
if (!mNeedsShadowInvalidation)
|
if (!mWindow || !mNeedsShadowInvalidation)
|
||||||
return;
|
return;
|
||||||
[mWindow invalidateShadow];
|
[mWindow invalidateShadow];
|
||||||
mNeedsShadowInvalidation = NO;
|
mNeedsShadowInvalidation = NO;
|
||||||
|
@ -3659,6 +3660,9 @@ static nsEventStatus SendGeckoMouseEnterOrExitEvent(PRBool isTrusted,
|
||||||
{
|
{
|
||||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||||
|
|
||||||
|
if (!mWindow)
|
||||||
|
return;
|
||||||
|
|
||||||
// Work around an Apple bug that causes the OS to continue sending
|
// 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.
|
// 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
|
// 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;
|
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||||
|
|
||||||
|
if (!mWindow)
|
||||||
|
return nil;
|
||||||
|
|
||||||
WindowDataMap* windowMap = [WindowDataMap sharedWindowDataMap];
|
WindowDataMap* windowMap = [WindowDataMap sharedWindowDataMap];
|
||||||
|
|
||||||
TopLevelWindowData* windowData = [windowMap dataForWindow:mWindow];
|
TopLevelWindowData* windowData = [windowMap dataForWindow:mWindow];
|
||||||
if (mWindow && !windowData)
|
if (!windowData)
|
||||||
{
|
{
|
||||||
windowData = [[TopLevelWindowData alloc] initWithWindow:mWindow];
|
windowData = [[TopLevelWindowData alloc] initWithWindow:mWindow];
|
||||||
[windowMap setData:windowData forWindow:mWindow]; // takes ownership
|
[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()
|
nsCocoaWindow::~nsCocoaWindow()
|
||||||
{
|
{
|
||||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||||
|
@ -128,12 +147,15 @@ nsCocoaWindow::~nsCocoaWindow()
|
||||||
childWindow->mParent = nsnull;
|
childWindow->mParent = nsnull;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mWindow && mWindowMadeHere) {
|
if (mWindow) {
|
||||||
// we want to unhook the delegate here because we don't want events
|
TellNativeViewsGoodbye([mWindow contentView]);
|
||||||
// sent to it after this object has been destroyed
|
if (mWindowMadeHere) {
|
||||||
[mWindow setDelegate:nil];
|
// we want to unhook the delegate here because we don't want events
|
||||||
[mWindow autorelease];
|
// sent to it after this object has been destroyed
|
||||||
[mDelegate autorelease];
|
[mWindow setDelegate:nil];
|
||||||
|
[mWindow autorelease];
|
||||||
|
[mDelegate autorelease];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IF_RELEASE(mPopupContentView);
|
NS_IF_RELEASE(mPopupContentView);
|
||||||
|
@ -429,8 +451,8 @@ NS_IMETHODIMP nsCocoaWindow::Destroy()
|
||||||
if (mPopupContentView)
|
if (mPopupContentView)
|
||||||
mPopupContentView->Destroy();
|
mPopupContentView->Destroy();
|
||||||
|
|
||||||
nsBaseWidget::OnDestroy();
|
|
||||||
nsBaseWidget::Destroy();
|
nsBaseWidget::Destroy();
|
||||||
|
nsBaseWidget::OnDestroy();
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -256,6 +256,10 @@ NS_METHOD nsBaseWidget::Destroy()
|
||||||
// Just in case our parent is the only ref to us
|
// Just in case our parent is the only ref to us
|
||||||
nsCOMPtr<nsIWidget> kungFuDeathGrip(this);
|
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
|
// disconnect from the parent
|
||||||
nsIWidget *parent = GetParent();
|
nsIWidget *parent = GetParent();
|
||||||
if (parent) {
|
if (parent) {
|
||||||
|
|
Загрузка…
Ссылка в новой задаче