Skip to content

Commit

Permalink
Fix the WebKit view not transitioning from light to dark mode (#2542)
Browse files Browse the repository at this point in the history
adaptReleaseNotesAppearance was over-engineered to update the transparent background state of the web view (which was causing the issue) and the background NSBox view when the system changes to dark or light mode. This is because when dark mode support was originally written, it used to use a stylesheet that was only specific to dark aqua. However this code has changed some time ago to use a universal stylesheet for both light/dark mode.

So now when the WebKit view is created, we just opt into a transparent background and set up a background NSBox view once and don't do anything when the effectiveAppearance of the views change. This fixes visual issues on current and older OS systems when changing system appearance.
  • Loading branch information
zorgiepoo authored Apr 21, 2024
1 parent e9989a8 commit 0cff817
Showing 1 changed file with 17 additions and 59 deletions.
76 changes: 17 additions & 59 deletions Sparkle/SUUpdateAlert.m
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ @implementation SUUpdateAlert
SUHost *_host;
SPUUserUpdateState *_state;
NSProgressIndicator *_releaseNotesSpinner;
NSBox *_darkBackgroundView;
NSBox *_backgroundView;
id<SUReleaseNotesView> _releaseNotesView;
id<SUVersionDisplay> _versionDisplayer;

Expand All @@ -58,7 +58,6 @@ @implementation SUUpdateAlert
void(^_completionBlock)(SPUUserUpdateChoice, NSRect, BOOL);

BOOL _allowsAutomaticUpdates;
BOOL _observingAppearance;
}

- (instancetype)initWithAppcastItem:(SUAppcastItem *)item state:(SPUUserUpdateState *)state host:(SUHost *)aHost versionDisplayer:(id<SUVersionDisplay>)versionDisplayer completionBlock:(void (^)(SPUUserUpdateChoice, NSRect, BOOL))completionBlock didBecomeKeyBlock:(void (^)(void))didBecomeKeyBlock
Expand Down Expand Up @@ -183,62 +182,6 @@ - (void)displayReleaseNotesSpinner SPU_OBJC_DIRECT
}
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(__attribute__((unused)) NSDictionary<NSKeyValueChangeKey,id> *)change context:(__attribute__((unused)) void *)context {
if (@available(macOS 10.14, *)) {
if (object == _releaseNotesView.view && [keyPath isEqualToString:@"effectiveAppearance"]) {
[self adaptReleaseNotesAppearance];
}
}
}

- (void)dealloc {
if (@available(macOS 10.14, *)) {
if (_observingAppearance) {
[_releaseNotesView.view removeObserver:self forKeyPath:@"effectiveAppearance"];
_observingAppearance = NO;
}
}
}

- (void)adaptReleaseNotesAppearance SPU_OBJC_DIRECT
{
if (@available(macOS 10.14, *)) {
NSAppearanceName bestAppearance = [_releaseNotesView.view.effectiveAppearance bestMatchFromAppearancesWithNames:@[NSAppearanceNameAqua, NSAppearanceNameDarkAqua]];
if ([bestAppearance isEqualToString:NSAppearanceNameDarkAqua])
{
// Remove web view background...
[_releaseNotesView setDrawsBackground:NO];
// ... and use NSBox to get the dynamically colored background
if (_darkBackgroundView == nil)
{
_darkBackgroundView = [[NSBox alloc] initWithFrame:_releaseNotesView.view.frame];
_darkBackgroundView.boxType = NSBoxCustom;
_darkBackgroundView.fillColor = [NSColor textBackgroundColor];
_darkBackgroundView.borderColor = [NSColor clearColor];
// Using auto-resizing mask instead of constraints works well enough
_darkBackgroundView.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
[_releaseNotesView.view.superview addSubview:_darkBackgroundView positioned:NSWindowBelow relativeTo:_releaseNotesView.view];

// The release note user stylesheet will not adjust to the user changing the theme until adaptReleaseNoteAppearance is called again.
// So lock the appearance of the background to keep the text readable if the system theme changes.
_darkBackgroundView.appearance = _darkBackgroundView.effectiveAppearance;
}
}
else
{
// Restore standard dark on light appearance
[_darkBackgroundView removeFromSuperview];
_darkBackgroundView = nil;
[_releaseNotesView setDrawsBackground:YES];
}

if (!_observingAppearance) {
[_releaseNotesView.view addObserver:self forKeyPath:@"effectiveAppearance" options:0 context:nil];
_observingAppearance = YES;
}
}
}

- (void)showUpdateReleaseNotesWithDownloadData:(SPUDownloadData *)downloadData
{
if (![self showsReleaseNotes]) {
Expand Down Expand Up @@ -372,7 +315,22 @@ - (void)_createReleaseNotesViewPreferringPlainText:(BOOL)preferringPlainText SPU
_releaseNotesView.view.frame = boxContentView.bounds;
_releaseNotesView.view.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;

[self adaptReleaseNotesAppearance];
if (@available(macOS 10.14, *)) {
// We need a transparent background
// This avoids a "white flash" that may be present when the webview initially loads in dark mode
// This also is necessary for macOS 10.14, otherwise the background may stay white on 10.14 (but not in later OS's)
[_releaseNotesView setDrawsBackground:NO];

// Use NSBox to get the proper dynamically colored background behind the release notes view when
// the release notes view background is transparent
_backgroundView = [[NSBox alloc] initWithFrame:_releaseNotesView.view.frame];
_backgroundView.boxType = NSBoxCustom;
_backgroundView.fillColor = [NSColor textBackgroundColor];
_backgroundView.borderColor = [NSColor clearColor];
// Using auto-resizing mask instead of constraints works well enough
_backgroundView.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
[_releaseNotesView.view.superview addSubview:_backgroundView positioned:NSWindowBelow relativeTo:_releaseNotesView.view];
}
}

- (void)windowDidLoad
Expand Down

0 comments on commit 0cff817

Please sign in to comment.