Bug 1702097 - Reset NSAppearance.currentAppearance before native theme drawing. r=spohl
authorMarkus Stange <mstange.moz@gmail.com>
Wed, 31 Mar 2021 15:53:39 +0000
changeset 573898 1a95326e8e60d1045fd3cb733c9e52c235b113fa
parent 573897 c83c9af968f89c6c517d818fc17c2de2652edb0a
child 573899 5716af4f41fe648551b36f4db84304e66890fed9
push id38337
push userncsoregi@mozilla.com
push dateWed, 31 Mar 2021 21:54:44 +0000
treeherdermozilla-central@32a9e6e145d6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersspohl
bugs1702097
milestone89.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1702097 - Reset NSAppearance.currentAppearance before native theme drawing. r=spohl This is global state, so it can have remnants from random other state changes. Starting with Big Sur, currentAppearance is deprecated in favor of performAsCurrentDrawingAppearance, which really does seem like a better API for this. Differential Revision: https://phabricator.services.mozilla.com/D110361
widget/cocoa/nsNativeThemeCocoa.mm
--- a/widget/cocoa/nsNativeThemeCocoa.mm
+++ b/widget/cocoa/nsNativeThemeCocoa.mm
@@ -2641,18 +2641,17 @@ Maybe<nsNativeThemeCocoa::WidgetInfo> ns
   return Nothing();
 
   NS_OBJC_END_TRY_BLOCK_RETURN(Nothing());
 }
 
 NS_IMETHODIMP
 nsNativeThemeCocoa::DrawWidgetBackground(gfxContext* aContext, nsIFrame* aFrame,
                                          StyleAppearance aAppearance, const nsRect& aRect,
-                                         const nsRect& aDirtyRect,
-                                         DrawOverflow) {
+                                         const nsRect& aDirtyRect, DrawOverflow) {
   NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
 
   Maybe<WidgetInfo> widgetInfo = ComputeWidgetInfo(aFrame, aAppearance, aRect);
 
   if (!widgetInfo) {
     return NS_OK;
   }
 
@@ -2669,16 +2668,26 @@ nsNativeThemeCocoa::DrawWidgetBackground
   return NS_OK;
 
   NS_OBJC_END_TRY_BLOCK_RETURN(NS_ERROR_FAILURE);
 }
 
 void nsNativeThemeCocoa::RenderWidget(const WidgetInfo& aWidgetInfo, DrawTarget& aDrawTarget,
                                       const gfx::Rect& aWidgetRect, const gfx::Rect& aDirtyRect,
                                       float aScale) {
+  if (@available(macOS 10.14, *)) {
+    // Some of the drawing below uses NSAppearance.currentAppearance behind the scenes.
+    // Set it to the appearance we want, to overwrite any state that's still around from earlier
+    // paints. We set it to NSApp.effectiveAppearance, which is consistent with what nsLookAndFeel
+    // uses for CSS system colors; it's either the system appearance or our Aqua override.
+    // We could also make nsNativeThemeCocoa respect the per-window appearance, but only once CSS
+    // system colors also respect the window appearance.
+    NSAppearance.currentAppearance = NSApp.effectiveAppearance;
+  }
+
   const Widget widget = aWidgetInfo.Widget();
 
   // Some widgets render using DrawTarget, and some using CGContext.
   switch (widget) {
     case Widget::eColorFill: {
       sRGBColor color = aWidgetInfo.Params<sRGBColor>();
       aDrawTarget.FillRect(aWidgetRect, ColorPattern(ToDeviceColor(color)));
       break;