From 758d709c7a1d2ba3bef8f4d5c7d16dd180348b56 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 5 Feb 2019 08:59:06 +0900 Subject: [PATCH] fix: crash when calling setProgressBar on macOS (#16374) * fix: correctly check whether dock has progress bar * fix: do not leak memory when setting dockTile --- atom/browser/native_window_mac.mm | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 2600d9b201cb8..1d46332bd770f 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -1131,17 +1131,23 @@ void ViewDidMoveToSuperview(NSView* self, SEL _cmd) { const NativeWindow::ProgressState state) { NSDockTile* dock_tile = [NSApp dockTile]; + // Sometimes macOS would install a default contentView for dock, we must + // verify whether NSProgressIndicator has been installed. + bool first_time = !dock_tile.contentView || + [[dock_tile.contentView subviews] count] == 0 || + ![[[dock_tile.contentView subviews] lastObject] + isKindOfClass:[NSProgressIndicator class]]; + // For the first time API invoked, we need to create a ContentView in // DockTile. - if (dock_tile.contentView == nullptr) { - NSImageView* image_view = [[NSImageView alloc] init]; + if (first_time) { + NSImageView* image_view = [[[NSImageView alloc] init] autorelease]; [image_view setImage:[NSApp applicationIconImage]]; [dock_tile setContentView:image_view]; - } - if ([[dock_tile.contentView subviews] count] == 0) { - NSProgressIndicator* progress_indicator = [[AtomProgressBar alloc] - initWithFrame:NSMakeRect(0.0f, 0.0f, dock_tile.size.width, 15.0)]; + NSRect frame = NSMakeRect(0.0f, 0.0f, dock_tile.size.width, 15.0); + NSProgressIndicator* progress_indicator = + [[[AtomProgressBar alloc] initWithFrame:frame] autorelease]; [progress_indicator setStyle:NSProgressIndicatorBarStyle]; [progress_indicator setIndeterminate:NO]; [progress_indicator setBezeled:YES]; @@ -1152,7 +1158,7 @@ void ViewDidMoveToSuperview(NSView* self, SEL _cmd) { } NSProgressIndicator* progress_indicator = static_cast( - [[[dock_tile contentView] subviews] objectAtIndex:0]); + [[[dock_tile contentView] subviews] lastObject]); if (progress < 0) { [progress_indicator setHidden:YES]; } else if (progress > 1) {