From 8c10cb059badb27d597c7ae2cc1092932c14583e Mon Sep 17 00:00:00 2001 From: Zorg Date: Sun, 21 Apr 2024 07:34:29 -0700 Subject: [PATCH 1/2] Fix the WebKit view not transitioning from light to dark mode 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. --- Sparkle/SUUpdateAlert.m | 76 +++++++++-------------------------------- 1 file changed, 17 insertions(+), 59 deletions(-) diff --git a/Sparkle/SUUpdateAlert.m b/Sparkle/SUUpdateAlert.m index f0612ceb94..a504c6fd88 100644 --- a/Sparkle/SUUpdateAlert.m +++ b/Sparkle/SUUpdateAlert.m @@ -42,7 +42,7 @@ @implementation SUUpdateAlert SUHost *_host; SPUUserUpdateState *_state; NSProgressIndicator *_releaseNotesSpinner; - NSBox *_darkBackgroundView; + NSBox *_backgroundView; id _releaseNotesView; id _versionDisplayer; @@ -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)versionDisplayer completionBlock:(void (^)(SPUUserUpdateChoice, NSRect, BOOL))completionBlock didBecomeKeyBlock:(void (^)(void))didBecomeKeyBlock @@ -183,62 +182,6 @@ - (void)displayReleaseNotesSpinner SPU_OBJC_DIRECT } } -- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(__attribute__((unused)) NSDictionary *)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 contraints 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]) { @@ -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 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 contraints works well enough + _backgroundView.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable; + [_releaseNotesView.view.superview addSubview:_backgroundView positioned:NSWindowBelow relativeTo:_releaseNotesView.view]; + } } - (void)windowDidLoad From fb961e08c26b2c0db7cad518006dca022911311f Mon Sep 17 00:00:00 2001 From: Zorg Date: Sun, 21 Apr 2024 08:50:26 -0700 Subject: [PATCH 2/2] Clarify the view background --- Sparkle/SUUpdateAlert.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sparkle/SUUpdateAlert.m b/Sparkle/SUUpdateAlert.m index 81c99fc294..e38f806771 100644 --- a/Sparkle/SUUpdateAlert.m +++ b/Sparkle/SUUpdateAlert.m @@ -322,7 +322,7 @@ - (void)_createReleaseNotesViewPreferringPlainText:(BOOL)preferringPlainText SPU [_releaseNotesView setDrawsBackground:NO]; // Use NSBox to get the proper dynamically colored background behind the release notes view when - // the release notes view is transparent + // the release notes view background is transparent _backgroundView = [[NSBox alloc] initWithFrame:_releaseNotesView.view.frame]; _backgroundView.boxType = NSBoxCustom; _backgroundView.fillColor = [NSColor textBackgroundColor];