Skip to content

Commit

Permalink
Simplify occlusion logic to work better on modern versions of macOS
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael Buckley authored and MichaelBuckley committed Aug 19, 2018
1 parent 1f0a2ef commit a57a80f
Showing 1 changed file with 36 additions and 44 deletions.
80 changes: 36 additions & 44 deletions NCProgressIndicator.m
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (c) 2011-2017 Michael Buckley
/* Copyright (c) 2011-2018 Michael Buckley
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
Expand Down Expand Up @@ -40,7 +40,6 @@ @interface NSProgressIndicator ()
@property (nonatomic, readonly, assign) BOOL bouncesRainbow;
@property (nonatomic, readonly, assign) BOOL shouldResize;
@property (nonatomic, readwrite, assign, getter=isAnimating) BOOL animating;
@property (nonatomic, readwrite, assign) NSInteger occulsionCount;
@property (nonatomic, readonly, assign) double percentValue;

@property (class, nonatomic, readonly) NSBundle* bundle;
Expand Down Expand Up @@ -78,7 +77,6 @@ @implementation NCProgressIndicator
@dynamic percentValue;

@synthesize animating;
@synthesize occulsionCount;

- (void)dealloc
{
Expand All @@ -92,7 +90,8 @@ + (NSBundle*)bundle
static dispatch_once_t onceToken = 0;
static NSBundle* bundle = nil;

dispatch_once(&onceToken, ^{
dispatch_once(&onceToken, ^
{
bundle = [NSBundle bundleWithIdentifier:@"com.buckleyisms.NCProgressIndicator"];
});

Expand Down Expand Up @@ -153,7 +152,8 @@ + (NSBundle*)bundle
static dispatch_once_t onceToken = 0;
static NSArray<NSColor*>* rainbowColors = nil;

dispatch_once(&onceToken, ^{
dispatch_once(&onceToken, ^
{
rainbowColors = @[[NSColor colorWithDeviceRed:1.0 green:0 blue:0 alpha:1.0],
[NSColor colorWithDeviceRed:1.0 green:0.6 blue:0 alpha:1.0],
[NSColor colorWithDeviceRed:1.0 green:1.0 blue:0 alpha:1.0],
Expand Down Expand Up @@ -182,7 +182,8 @@ + (dispatch_source_t)animationTimer
{
static dispatch_once_t onceToken = 0;

dispatch_once(&onceToken, ^{
dispatch_once(&onceToken, ^
{
animationTimerQueue = dispatch_queue_create("com.buckleyisms.NCProgressIndicator.timer", DISPATCH_QUEUE_SERIAL);
animationTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, animationTimerQueue);

Expand Down Expand Up @@ -254,41 +255,34 @@ - (void)occulsionChanged:(NSNotification*)notification
{
if (self.window.occlusionState & NSWindowOcclusionStateVisible)
{
if (self.occulsionCount > 0)
if (self.overridesDrawing)
{
[self startAnimation:self];
self.occulsionCount = 0;
}
}
else if (self.isAnimating)
{
// After this method returns, Appkit will immediately call
// -stopAnimation:, which will decrement this to 1. If the user calls
// -stopAnimation while the window is still occluded, it will be
// decremented again, so we don't restart the animation when the window
// becomes visible again.
self.occulsionCount = 2;
}
}

- (void)startAnimation:(nullable id)sender
{
self.animating = YES;

if (self.overridesDrawing)
{
dispatch_async(self.class.queue, ^
{
if (![self.class.animatingViews containsObject: self])
{
[self.class.animatingViews addObject: self];

if (self.class.animatingViews.count == 1)
{
dispatch_resume(self.class.animationTimer);
}
}
});
if (!self.isAnimating)
{
self.animating = YES;

dispatch_async(self.class.queue, ^
{
if (![self.class.animatingViews containsObject: self])
{
[self.class.animatingViews addObject: self];

if (self.class.animatingViews.count == 1)
{
dispatch_resume(self.class.animationTimer);
}
}
});
}
}
else
{
Expand All @@ -298,24 +292,22 @@ - (void)startAnimation:(nullable id)sender

- (void)stopAnimation:(nullable id)sender
{
self.animating = NO;

if (self.overridesDrawing)
{
if (self.occulsionCount > 0)
if (self.isAnimating)
{
--self.occulsionCount;
}
self.animating = NO;

dispatch_async(self.class.queue, ^
{
[self.class.animatingViews removeObject: self];
dispatch_async(self.class.queue, ^
{
[self.class.animatingViews removeObject: self];

if (self.class.animatingViews.count == 0)
{
dispatch_suspend(self.class.animationTimer);
}
});
if (self.class.animatingViews.count == 0)
{
dispatch_suspend(self.class.animationTimer);
}
});
}
}
else
{
Expand Down

0 comments on commit a57a80f

Please sign in to comment.