diff --git a/mozilla/camino/DownloadProgressDisplay.h b/mozilla/camino/DownloadProgressDisplay.h index e5a88930e37..fc1fe6ce074 100644 --- a/mozilla/camino/DownloadProgressDisplay.h +++ b/mozilla/camino/DownloadProgressDisplay.h @@ -149,6 +149,7 @@ public: virtual void ResumeDownload() = 0; virtual void CancelDownload() = 0; virtual void DownloadDone() = 0; + virtual void DetachDownloadDisplay() = 0; // tell downloader to forget about its display virtual void CreateDownloadDisplay(); diff --git a/mozilla/camino/ProgressDlgController.mm b/mozilla/camino/ProgressDlgController.mm index 1d5c20852b6..80b4e63b573 100644 --- a/mozilla/camino/ProgressDlgController.mm +++ b/mozilla/camino/ProgressDlgController.mm @@ -82,6 +82,11 @@ static NSString *ProgressWindowFrameSaveName = @"ProgressWindow"; - (void)dealloc { + // if we get here because we're quitting, the listener will still be alive + // yet we're going away. As a result, we need to tell the d/l listener to + // forget it ever met us and necko will clean it up on its own. + if ( mDownloader) + mDownloader->DetachDownloadDisplay(); NS_IF_RELEASE(mDownloader); [super dealloc]; } @@ -486,8 +491,15 @@ static NSString *ProgressWindowFrameSaveName = @"ProgressWindow"; - (void)onEndDownload { - [self killDownloadTimer]; - [self setDownloadProgress:nil]; + // if we're quitting, our progress window is already gone and we're in the + // process of shutting down gecko and all the d/l listeners. The timer, at + // that point, is the only thing keeping us alive. Killing it will cause + // us to go away immediately, so kung-fu deathgrip it until we're done twiddling + // bits on ourself. + [self retain]; // Enter The Dragon! + [self killDownloadTimer]; + [self setDownloadProgress:nil]; + [self release]; } - (void)setProgressTo:(long)aCurProgress ofMax:(long)aMaxProgress diff --git a/mozilla/camino/nsDownloadListener.h b/mozilla/camino/nsDownloadListener.h index a2e7b249f2e..cd15b3626cd 100644 --- a/mozilla/camino/nsDownloadListener.h +++ b/mozilla/camino/nsDownloadListener.h @@ -73,6 +73,7 @@ public: virtual void ResumeDownload(); virtual void CancelDownload(); virtual void DownloadDone(); + virtual void DetachDownloadDisplay(); private: diff --git a/mozilla/camino/nsDownloadListener.mm b/mozilla/camino/nsDownloadListener.mm index ea8986296bc..5d84fdd2d3d 100644 --- a/mozilla/camino/nsDownloadListener.mm +++ b/mozilla/camino/nsDownloadListener.mm @@ -307,4 +307,17 @@ nsDownloadListener::DownloadDone() [mDownloadDisplay onEndDownload]; } +// +// DetachDownloadDisplay +// +// there are times when the download dislpay UI goes away before the +// listener (quit, for example). This alerts us that we should forget all +// about having any UI. +// +void +nsDownloadListener::DetachDownloadDisplay() +{ + mDownloadDisplay = nil; +} + #pragma mark - diff --git a/mozilla/camino/src/download/ProgressDlgController.mm b/mozilla/camino/src/download/ProgressDlgController.mm index 1d5c20852b6..80b4e63b573 100644 --- a/mozilla/camino/src/download/ProgressDlgController.mm +++ b/mozilla/camino/src/download/ProgressDlgController.mm @@ -82,6 +82,11 @@ static NSString *ProgressWindowFrameSaveName = @"ProgressWindow"; - (void)dealloc { + // if we get here because we're quitting, the listener will still be alive + // yet we're going away. As a result, we need to tell the d/l listener to + // forget it ever met us and necko will clean it up on its own. + if ( mDownloader) + mDownloader->DetachDownloadDisplay(); NS_IF_RELEASE(mDownloader); [super dealloc]; } @@ -486,8 +491,15 @@ static NSString *ProgressWindowFrameSaveName = @"ProgressWindow"; - (void)onEndDownload { - [self killDownloadTimer]; - [self setDownloadProgress:nil]; + // if we're quitting, our progress window is already gone and we're in the + // process of shutting down gecko and all the d/l listeners. The timer, at + // that point, is the only thing keeping us alive. Killing it will cause + // us to go away immediately, so kung-fu deathgrip it until we're done twiddling + // bits on ourself. + [self retain]; // Enter The Dragon! + [self killDownloadTimer]; + [self setDownloadProgress:nil]; + [self release]; } - (void)setProgressTo:(long)aCurProgress ofMax:(long)aMaxProgress diff --git a/mozilla/camino/src/download/nsDownloadListener.h b/mozilla/camino/src/download/nsDownloadListener.h index a2e7b249f2e..cd15b3626cd 100644 --- a/mozilla/camino/src/download/nsDownloadListener.h +++ b/mozilla/camino/src/download/nsDownloadListener.h @@ -73,6 +73,7 @@ public: virtual void ResumeDownload(); virtual void CancelDownload(); virtual void DownloadDone(); + virtual void DetachDownloadDisplay(); private: diff --git a/mozilla/camino/src/download/nsDownloadListener.mm b/mozilla/camino/src/download/nsDownloadListener.mm index ea8986296bc..5d84fdd2d3d 100644 --- a/mozilla/camino/src/download/nsDownloadListener.mm +++ b/mozilla/camino/src/download/nsDownloadListener.mm @@ -307,4 +307,17 @@ nsDownloadListener::DownloadDone() [mDownloadDisplay onEndDownload]; } +// +// DetachDownloadDisplay +// +// there are times when the download dislpay UI goes away before the +// listener (quit, for example). This alerts us that we should forget all +// about having any UI. +// +void +nsDownloadListener::DetachDownloadDisplay() +{ + mDownloadDisplay = nil; +} + #pragma mark - diff --git a/mozilla/camino/src/embedding/CHDownloadProgressDisplay.h b/mozilla/camino/src/embedding/CHDownloadProgressDisplay.h index e5a88930e37..fc1fe6ce074 100644 --- a/mozilla/camino/src/embedding/CHDownloadProgressDisplay.h +++ b/mozilla/camino/src/embedding/CHDownloadProgressDisplay.h @@ -149,6 +149,7 @@ public: virtual void ResumeDownload() = 0; virtual void CancelDownload() = 0; virtual void DownloadDone() = 0; + virtual void DetachDownloadDisplay() = 0; // tell downloader to forget about its display virtual void CreateDownloadDisplay(); diff --git a/mozilla/chimera/DownloadProgressDisplay.h b/mozilla/chimera/DownloadProgressDisplay.h index e5a88930e37..fc1fe6ce074 100644 --- a/mozilla/chimera/DownloadProgressDisplay.h +++ b/mozilla/chimera/DownloadProgressDisplay.h @@ -149,6 +149,7 @@ public: virtual void ResumeDownload() = 0; virtual void CancelDownload() = 0; virtual void DownloadDone() = 0; + virtual void DetachDownloadDisplay() = 0; // tell downloader to forget about its display virtual void CreateDownloadDisplay(); diff --git a/mozilla/chimera/ProgressDlgController.mm b/mozilla/chimera/ProgressDlgController.mm index 1d5c20852b6..80b4e63b573 100644 --- a/mozilla/chimera/ProgressDlgController.mm +++ b/mozilla/chimera/ProgressDlgController.mm @@ -82,6 +82,11 @@ static NSString *ProgressWindowFrameSaveName = @"ProgressWindow"; - (void)dealloc { + // if we get here because we're quitting, the listener will still be alive + // yet we're going away. As a result, we need to tell the d/l listener to + // forget it ever met us and necko will clean it up on its own. + if ( mDownloader) + mDownloader->DetachDownloadDisplay(); NS_IF_RELEASE(mDownloader); [super dealloc]; } @@ -486,8 +491,15 @@ static NSString *ProgressWindowFrameSaveName = @"ProgressWindow"; - (void)onEndDownload { - [self killDownloadTimer]; - [self setDownloadProgress:nil]; + // if we're quitting, our progress window is already gone and we're in the + // process of shutting down gecko and all the d/l listeners. The timer, at + // that point, is the only thing keeping us alive. Killing it will cause + // us to go away immediately, so kung-fu deathgrip it until we're done twiddling + // bits on ourself. + [self retain]; // Enter The Dragon! + [self killDownloadTimer]; + [self setDownloadProgress:nil]; + [self release]; } - (void)setProgressTo:(long)aCurProgress ofMax:(long)aMaxProgress diff --git a/mozilla/chimera/nsDownloadListener.h b/mozilla/chimera/nsDownloadListener.h index a2e7b249f2e..cd15b3626cd 100644 --- a/mozilla/chimera/nsDownloadListener.h +++ b/mozilla/chimera/nsDownloadListener.h @@ -73,6 +73,7 @@ public: virtual void ResumeDownload(); virtual void CancelDownload(); virtual void DownloadDone(); + virtual void DetachDownloadDisplay(); private: diff --git a/mozilla/chimera/nsDownloadListener.mm b/mozilla/chimera/nsDownloadListener.mm index ea8986296bc..5d84fdd2d3d 100644 --- a/mozilla/chimera/nsDownloadListener.mm +++ b/mozilla/chimera/nsDownloadListener.mm @@ -307,4 +307,17 @@ nsDownloadListener::DownloadDone() [mDownloadDisplay onEndDownload]; } +// +// DetachDownloadDisplay +// +// there are times when the download dislpay UI goes away before the +// listener (quit, for example). This alerts us that we should forget all +// about having any UI. +// +void +nsDownloadListener::DetachDownloadDisplay() +{ + mDownloadDisplay = nil; +} + #pragma mark - diff --git a/mozilla/chimera/src/download/ProgressDlgController.mm b/mozilla/chimera/src/download/ProgressDlgController.mm index 1d5c20852b6..80b4e63b573 100644 --- a/mozilla/chimera/src/download/ProgressDlgController.mm +++ b/mozilla/chimera/src/download/ProgressDlgController.mm @@ -82,6 +82,11 @@ static NSString *ProgressWindowFrameSaveName = @"ProgressWindow"; - (void)dealloc { + // if we get here because we're quitting, the listener will still be alive + // yet we're going away. As a result, we need to tell the d/l listener to + // forget it ever met us and necko will clean it up on its own. + if ( mDownloader) + mDownloader->DetachDownloadDisplay(); NS_IF_RELEASE(mDownloader); [super dealloc]; } @@ -486,8 +491,15 @@ static NSString *ProgressWindowFrameSaveName = @"ProgressWindow"; - (void)onEndDownload { - [self killDownloadTimer]; - [self setDownloadProgress:nil]; + // if we're quitting, our progress window is already gone and we're in the + // process of shutting down gecko and all the d/l listeners. The timer, at + // that point, is the only thing keeping us alive. Killing it will cause + // us to go away immediately, so kung-fu deathgrip it until we're done twiddling + // bits on ourself. + [self retain]; // Enter The Dragon! + [self killDownloadTimer]; + [self setDownloadProgress:nil]; + [self release]; } - (void)setProgressTo:(long)aCurProgress ofMax:(long)aMaxProgress diff --git a/mozilla/chimera/src/download/nsDownloadListener.h b/mozilla/chimera/src/download/nsDownloadListener.h index a2e7b249f2e..cd15b3626cd 100644 --- a/mozilla/chimera/src/download/nsDownloadListener.h +++ b/mozilla/chimera/src/download/nsDownloadListener.h @@ -73,6 +73,7 @@ public: virtual void ResumeDownload(); virtual void CancelDownload(); virtual void DownloadDone(); + virtual void DetachDownloadDisplay(); private: diff --git a/mozilla/chimera/src/download/nsDownloadListener.mm b/mozilla/chimera/src/download/nsDownloadListener.mm index ea8986296bc..5d84fdd2d3d 100644 --- a/mozilla/chimera/src/download/nsDownloadListener.mm +++ b/mozilla/chimera/src/download/nsDownloadListener.mm @@ -307,4 +307,17 @@ nsDownloadListener::DownloadDone() [mDownloadDisplay onEndDownload]; } +// +// DetachDownloadDisplay +// +// there are times when the download dislpay UI goes away before the +// listener (quit, for example). This alerts us that we should forget all +// about having any UI. +// +void +nsDownloadListener::DetachDownloadDisplay() +{ + mDownloadDisplay = nil; +} + #pragma mark - diff --git a/mozilla/chimera/src/embedding/CHDownloadProgressDisplay.h b/mozilla/chimera/src/embedding/CHDownloadProgressDisplay.h index e5a88930e37..fc1fe6ce074 100644 --- a/mozilla/chimera/src/embedding/CHDownloadProgressDisplay.h +++ b/mozilla/chimera/src/embedding/CHDownloadProgressDisplay.h @@ -149,6 +149,7 @@ public: virtual void ResumeDownload() = 0; virtual void CancelDownload() = 0; virtual void DownloadDone() = 0; + virtual void DetachDownloadDisplay() = 0; // tell downloader to forget about its display virtual void CreateDownloadDisplay();