From 98d7b61a4a559802726623569b387d2eee7a9af7 Mon Sep 17 00:00:00 2001 From: "trop[bot]" Date: Tue, 5 Feb 2019 08:09:08 -0800 Subject: [PATCH] fix: crash when calling setProgressBar on macOS (backport: 3-1-x) (#16726) * 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 bb7fed9c3d5..2db097072ab 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -1089,17 +1089,23 @@ void NativeWindowMac::SetProgressBar(double progress, 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]; @@ -1110,7 +1116,7 @@ void NativeWindowMac::SetProgressBar(double progress, } 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) {