Bug 1403690 Part 3: macOS change nsLookAndFeel::NativeGetColor to use cached colors. r=mstange
authorBrad Werth <bwerth@mozilla.com>
Mon, 02 Oct 2017 17:13:48 -0700
changeset 688094 1570e72037e260c094b4db4cd3a3263ac6e990de
parent 688093 cf0f2ec461a77494a58001efe8c917b5ca979800
child 688095 4df8244690cf51becf42e70ce846c91c92e3780c
push id86669
push userhikezoe@mozilla.com
push dateSat, 28 Oct 2017 10:13:18 +0000
reviewersmstange
bugs1403690
milestone58.0a1
Bug 1403690 Part 3: macOS change nsLookAndFeel::NativeGetColor to use cached colors. r=mstange MozReview-Commit-ID: FHm6d2Vz2sJ
widget/cocoa/nsLookAndFeel.h
widget/cocoa/nsLookAndFeel.mm
--- a/widget/cocoa/nsLookAndFeel.h
+++ b/widget/cocoa/nsLookAndFeel.h
@@ -8,41 +8,79 @@
 #include "nsXPLookAndFeel.h"
 
 class nsLookAndFeel final : public nsXPLookAndFeel
 {
 public:
   nsLookAndFeel();
   virtual ~nsLookAndFeel();
 
+  virtual void NativeInit() final;
+  virtual void RefreshImpl();
   virtual nsresult NativeGetColor(ColorID aID, nscolor &aResult);
-  virtual void NativeInit() final;
   virtual nsresult GetIntImpl(IntID aID, int32_t &aResult);
   virtual nsresult GetFloatImpl(FloatID aID, float &aResult);
   virtual bool GetFontImpl(FontID aID, nsString& aFontName,
                            gfxFontStyle& aFontStyle,
                            float aDevPixPerCSSPixel);
   virtual char16_t GetPasswordCharacterImpl()
   {
     // unicode value for the bullet character, used for password textfields.
     return 0x2022;
   }
 
   static bool UseOverlayScrollbars();
 
   virtual nsTArray<LookAndFeelInt> GetIntCacheImpl();
   virtual void SetIntCacheImpl(const nsTArray<LookAndFeelInt>& aLookAndFeelIntCache);
 
-  virtual void RefreshImpl();
-
 protected:
   static bool SystemWantsOverlayScrollbars();
   static bool AllowOverlayScrollbarsOverlap();
 
 private:
   int32_t mUseOverlayScrollbars;
   bool mUseOverlayScrollbarsCached;
 
   int32_t mAllowOverlayScrollbarsOverlap;
   bool mAllowOverlayScrollbarsOverlapCached;
+
+  nscolor mColorTextSelectBackground;
+  nscolor mColorTextSelectBackgroundDisabled;
+  nscolor mColorHighlight;
+  nscolor mColorMenuHover;
+  nscolor mColorTextSelectForeground;
+  nscolor mColorMenuHoverText;
+  nscolor mColorButtonText;
+  bool mHasColorButtonText;
+  nscolor mColorButtonHoverText;
+  nscolor mColorText;
+  nscolor mColorWindowText;
+  nscolor mColorActiveCaption;
+  nscolor mColorActiveBorder;
+  nscolor mColorGrayText;
+  nscolor mColorInactiveBorder;
+  nscolor mColorInactiveCaption;
+  nscolor mColorScrollbar;
+  nscolor mColorThreeDHighlight;
+  nscolor mColorMenu;
+  nscolor mColorWindowFrame;
+  nscolor mColorFieldText;
+  nscolor mColorDialog;
+  nscolor mColorDialogText;
+  nscolor mColorDragTargetZone;
+  nscolor mColorChromeActive;
+  nscolor mColorChromeInactive;
+  nscolor mColorFocusRing;
+  nscolor mColorTextSelect;
+  nscolor mColorDisabledToolbarText;
+  nscolor mColorMenuSelect;
+  nscolor mColorCellHighlight;
+  nscolor mColorEvenTreeRow;
+  nscolor mColorOddTreeRow;
+  nscolor mColorActiveSourceListSelection;
+
+  bool mInitialized;
+
+  void EnsureInit();
 };
 
 #endif // nsLookAndFeel_h_
--- a/widget/cocoa/nsLookAndFeel.mm
+++ b/widget/cocoa/nsLookAndFeel.mm
@@ -32,16 +32,18 @@ typedef NSInteger mozNSScrollerStyle;
 @end
 
 nsLookAndFeel::nsLookAndFeel()
  : nsXPLookAndFeel()
  , mUseOverlayScrollbars(-1)
  , mUseOverlayScrollbarsCached(false)
  , mAllowOverlayScrollbarsOverlap(-1)
  , mAllowOverlayScrollbarsOverlapCached(false)
+ , mHasColorButtonText(false)
+ , mInitialized(false)
 {
 }
 
 nsLookAndFeel::~nsLookAndFeel()
 {
 }
 
 static nscolor GetColorFromNSColor(NSColor* aColor)
@@ -56,35 +58,58 @@ static nscolor GetColorFromNSColorWithAl
 {
   NSColor* deviceColor = [aColor colorUsingColorSpaceName:NSDeviceRGBColorSpace];
   return NS_RGBA((unsigned int)([deviceColor redComponent] * 255.0),
                  (unsigned int)([deviceColor greenComponent] * 255.0),
                  (unsigned int)([deviceColor blueComponent] * 255.0),
                  (unsigned int)(alpha * 255.0));
 }
 
+void
+nsLookAndFeel::NativeInit()
+{
+  EnsureInit();
+}
+
+void
+nsLookAndFeel::RefreshImpl()
+{
+  nsXPLookAndFeel::RefreshImpl();
+
+  // We should only clear the cache if we're in the main browser process.
+  // Otherwise, we should wait for the parent to inform us of new values
+  // to cache via LookAndFeel::SetIntCache.
+  if (XRE_IsParentProcess()) {
+    mUseOverlayScrollbarsCached = false;
+    mAllowOverlayScrollbarsOverlapCached = false;
+  }
+
+  // Fetch colors next time they are requested.
+  mInitialized = false;
+}
+
 nsresult
 nsLookAndFeel::NativeGetColor(ColorID aID, nscolor &aColor)
 {
-  NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
+  EnsureInit();
 
   nsresult res = NS_OK;
-  
+
   switch (aID) {
     case eColorID_WindowBackground:
       aColor = NS_RGB(0xff,0xff,0xff);
       break;
     case eColorID_WindowForeground:
-      aColor = NS_RGB(0x00,0x00,0x00);        
+      aColor = NS_RGB(0x00,0x00,0x00);
       break;
     case eColorID_WidgetBackground:
       aColor = NS_RGB(0xdd,0xdd,0xdd);
       break;
     case eColorID_WidgetForeground:
-      aColor = NS_RGB(0x00,0x00,0x00);        
+      aColor = NS_RGB(0x00,0x00,0x00);
       break;
     case eColorID_WidgetSelectBackground:
       aColor = NS_RGB(0x80,0x80,0x80);
       break;
     case eColorID_WidgetSelectForeground:
       aColor = NS_RGB(0x00,0x00,0x80);
       break;
     case eColorID_Widget3DHighlight:
@@ -95,39 +120,35 @@ nsLookAndFeel::NativeGetColor(ColorID aI
       break;
     case eColorID_TextBackground:
       aColor = NS_RGB(0xff,0xff,0xff);
       break;
     case eColorID_TextForeground:
       aColor = NS_RGB(0x00,0x00,0x00);
       break;
     case eColorID_TextSelectBackground:
-      aColor = GetColorFromNSColor([NSColor selectedTextBackgroundColor]);
+      aColor = mColorTextSelectBackground;
       break;
     // This is used to gray out the selection when it's not focused. Used with
     // nsISelectionController::SELECTION_DISABLED.
     case eColorID_TextSelectBackgroundDisabled:
-      aColor = GetColorFromNSColor([NSColor secondarySelectedControlColor]);
+      aColor = mColorTextSelectBackgroundDisabled;
       break;
     case eColorID_highlight: // CSS2 color
-      aColor = GetColorFromNSColor([NSColor alternateSelectedControlColor]);
+      aColor = mColorHighlight;
       break;
     case eColorID__moz_menuhover:
-      aColor = GetColorFromNSColor([NSColor alternateSelectedControlColor]);
-      break;      
+      aColor = mColorMenuHover;
+      break;
     case eColorID_TextSelectForeground:
-      GetColor(eColorID_TextSelectBackground, aColor);
-      if (aColor == 0x000000)
-        aColor = NS_RGB(0xff,0xff,0xff);
-      else
-        aColor = NS_DONT_CHANGE_COLOR;
+      aColor = mColorTextSelectForeground;
       break;
     case eColorID_highlighttext:  // CSS2 color
     case eColorID__moz_menuhovertext:
-      aColor = GetColorFromNSColor([NSColor alternateSelectedControlTextColor]);
+      aColor = mColorMenuHoverText;
       break;
     case eColorID_IMESelectedRawTextBackground:
     case eColorID_IMESelectedConvertedTextBackground:
     case eColorID_IMERawInputBackground:
     case eColorID_IMEConvertedTextBackground:
       aColor = NS_TRANSPARENT;
       break;
     case eColorID_IMESelectedRawTextForeground:
@@ -147,49 +168,49 @@ nsLookAndFeel::NativeGetColor(ColorID aI
     case eColorID_SpellCheckerUnderline:
       aColor = NS_RGB(0xff, 0, 0);
       break;
 
       //
       // css2 system colors http://www.w3.org/TR/REC-CSS2/ui.html#system-colors
       //
       // It's really hard to effectively map these to the Appearance Manager properly,
-      // since they are modeled word for word after the win32 system colors and don't have any 
-      // real counterparts in the Mac world. I'm sure we'll be tweaking these for 
-      // years to come. 
+      // since they are modeled word for word after the win32 system colors and don't have any
+      // real counterparts in the Mac world. I'm sure we'll be tweaking these for
+      // years to come.
       //
       // Thanks to mpt26@student.canterbury.ac.nz for the hardcoded values that form the defaults
       //  if querying the Appearance Manager fails ;)
       //
     case eColorID__moz_mac_buttonactivetext:
     case eColorID__moz_mac_defaultbuttontext:
-      if (nsCocoaFeatures::OnYosemiteOrLater()) {
-        aColor = NS_RGB(0xFF,0xFF,0xFF);
+      if (mHasColorButtonText) {
+        aColor = mColorButtonText;
         break;
       }
       // Otherwise fall through and return the regular button text:
-      
+      MOZ_FALLTHROUGH;
     case eColorID_buttontext:
     case eColorID__moz_buttonhovertext:
-      aColor = GetColorFromNSColor([NSColor controlTextColor]);
+      aColor = mColorButtonHoverText;
       break;
     case eColorID_captiontext:
     case eColorID_menutext:
     case eColorID_infotext:
     case eColorID__moz_menubartext:
-      aColor = GetColorFromNSColor([NSColor textColor]);
+      aColor = mColorText;
       break;
     case eColorID_windowtext:
-      aColor = GetColorFromNSColor([NSColor windowFrameTextColor]);
+      aColor = mColorWindowText;
       break;
     case eColorID_activecaption:
-      aColor = GetColorFromNSColor([NSColor gridColor]);
+      aColor = mColorActiveCaption;
       break;
     case eColorID_activeborder:
-      aColor = GetColorFromNSColor([NSColor keyboardFocusIndicatorColor]);
+      aColor = mColorActiveBorder;
       break;
      case eColorID_appworkspace:
       aColor = NS_RGB(0xFF,0xFF,0xFF);
       break;
     case eColorID_background:
       aColor = NS_RGB(0x63,0x63,0xCE);
       break;
     case eColorID_buttonface:
@@ -198,114 +219,114 @@ nsLookAndFeel::NativeGetColor(ColorID aI
       break;
     case eColorID_buttonhighlight:
       aColor = NS_RGB(0xFF,0xFF,0xFF);
       break;
     case eColorID_buttonshadow:
       aColor = NS_RGB(0xDC,0xDC,0xDC);
       break;
     case eColorID_graytext:
-      aColor = GetColorFromNSColor([NSColor disabledControlTextColor]);
+      aColor = mColorGrayText;
       break;
     case eColorID_inactiveborder:
-      aColor = GetColorFromNSColor([NSColor controlBackgroundColor]);
+      aColor = mColorInactiveBorder;
       break;
     case eColorID_inactivecaption:
-      aColor = GetColorFromNSColor([NSColor controlBackgroundColor]);
+      aColor = mColorInactiveCaption;
       break;
     case eColorID_inactivecaptiontext:
       aColor = NS_RGB(0x45,0x45,0x45);
       break;
     case eColorID_scrollbar:
-      aColor = GetColorFromNSColor([NSColor scrollBarColor]);
+      aColor = mColorScrollbar;
       break;
     case eColorID_threeddarkshadow:
       aColor = NS_RGB(0xDC,0xDC,0xDC);
       break;
     case eColorID_threedshadow:
       aColor = NS_RGB(0xE0,0xE0,0xE0);
       break;
     case eColorID_threedface:
       aColor = NS_RGB(0xF0,0xF0,0xF0);
       break;
     case eColorID_threedhighlight:
-      aColor = GetColorFromNSColor([NSColor highlightColor]);
+      aColor = mColorThreeDHighlight;
       break;
     case eColorID_threedlightshadow:
       aColor = NS_RGB(0xDA,0xDA,0xDA);
       break;
     case eColorID_menu:
-      aColor = GetColorFromNSColor([NSColor alternateSelectedControlTextColor]);
+      aColor = mColorMenu;
       break;
     case eColorID_infobackground:
       aColor = NS_RGB(0xFF,0xFF,0xC7);
       break;
     case eColorID_windowframe:
-      aColor = GetColorFromNSColor([NSColor gridColor]);
+      aColor = mColorWindowFrame;
       break;
     case eColorID_window:
     case eColorID__moz_field:
     case eColorID__moz_combobox:
       aColor = NS_RGB(0xff,0xff,0xff);
       break;
     case eColorID__moz_fieldtext:
     case eColorID__moz_comboboxtext:
-      aColor = GetColorFromNSColor([NSColor controlTextColor]);
+      aColor = mColorFieldText;
       break;
     case eColorID__moz_dialog:
-      aColor = GetColorFromNSColor([NSColor controlHighlightColor]);
+      aColor = mColorDialog;
       break;
     case eColorID__moz_dialogtext:
     case eColorID__moz_cellhighlighttext:
     case eColorID__moz_html_cellhighlighttext:
-      aColor = GetColorFromNSColor([NSColor controlTextColor]);
+      aColor = mColorDialogText;
       break;
     case eColorID__moz_dragtargetzone:
-      aColor = GetColorFromNSColor([NSColor selectedControlColor]);
+      aColor = mColorDragTargetZone;
       break;
     case eColorID__moz_mac_chrome_active:
-    case eColorID__moz_mac_chrome_inactive: {
-      int grey = NativeGreyColorAsInt(toolbarFillGrey, (aID == eColorID__moz_mac_chrome_active));
-      aColor = NS_RGB(grey, grey, grey);
-    }
+      aColor = mColorChromeActive;
+      break;
+    case eColorID__moz_mac_chrome_inactive:
+      aColor = mColorChromeInactive;
       break;
     case eColorID__moz_mac_focusring:
-      aColor = GetColorFromNSColorWithAlpha([NSColor keyboardFocusIndicatorColor], 0.48);
+      aColor = mColorFocusRing;
       break;
     case eColorID__moz_mac_menushadow:
       aColor = NS_RGB(0xA3,0xA3,0xA3);
-      break;          
+      break;
     case eColorID__moz_mac_menutextdisable:
       aColor = NS_RGB(0x98,0x98,0x98);
-      break;      
+      break;
     case eColorID__moz_mac_menutextselect:
-      aColor = GetColorFromNSColor([NSColor selectedMenuItemTextColor]);
-      break;      
+      aColor = mColorTextSelect;
+      break;
     case eColorID__moz_mac_disabledtoolbartext:
-      aColor = GetColorFromNSColor([NSColor disabledControlTextColor]);
+      aColor = mColorDisabledToolbarText;
       break;
     case eColorID__moz_mac_menuselect:
-      aColor = GetColorFromNSColor([NSColor alternateSelectedControlColor]);
+      aColor = mColorMenuSelect;
       break;
     case eColorID__moz_buttondefault:
       aColor = NS_RGB(0xDC,0xDC,0xDC);
       break;
     case eColorID__moz_cellhighlight:
     case eColorID__moz_html_cellhighlight:
     case eColorID__moz_mac_secondaryhighlight:
       // For inactive list selection
-      aColor = GetColorFromNSColor([NSColor secondarySelectedControlColor]);
+      aColor = mColorCellHighlight;
       break;
     case eColorID__moz_eventreerow:
       // Background color of even list rows.
-      aColor = GetColorFromNSColor([[NSColor controlAlternatingRowBackgroundColors] objectAtIndex:0]);
+      aColor = mColorEvenTreeRow;
       break;
     case eColorID__moz_oddtreerow:
       // Background color of odd list rows.
-      aColor = GetColorFromNSColor([[NSColor controlAlternatingRowBackgroundColors] objectAtIndex:1]);
+      aColor = mColorOddTreeRow;
       break;
     case eColorID__moz_nativehyperlinktext:
       // There appears to be no available system defined color. HARDCODING to the appropriate color.
       aColor = NS_RGB(0x14,0x4F,0xAE);
       break;
     // The following colors are supposed to be used as font-smoothing background
     // colors, in the chrome-only -moz-font-smoothing-background-color property.
     // This property is used for text on "vibrant" -moz-appearances.
@@ -326,41 +347,38 @@ nsLookAndFeel::NativeGetColor(ColorID aI
     case eColorID__moz_mac_menuitem:
       aColor = NS_RGB(0xe6,0xe6,0xe6);
       break;
     case eColorID__moz_mac_source_list_selection:
       aColor = NS_RGB(0xc8,0xc8,0xc8);
       break;
     case eColorID__moz_mac_active_menuitem:
     case eColorID__moz_mac_active_source_list_selection:
-      aColor = [NSColor currentControlTint] == NSGraphiteControlTint
-        ? NS_RGB(0xa0,0xa0,0xa0) : NS_RGB(0x0a,0x64,0xdc);
+      aColor = mColorActiveSourceListSelection;
       break;
     default:
       NS_WARNING("Someone asked nsILookAndFeel for a color I don't know about");
       aColor = NS_RGB(0xff,0xff,0xff);
       res = NS_ERROR_FAILURE;
       break;
     }
 
   return res;
-
-  NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
 }
 
 nsresult
 nsLookAndFeel::GetIntImpl(IntID aID, int32_t &aResult)
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
 
   nsresult res = nsXPLookAndFeel::GetIntImpl(aID, aResult);
   if (NS_SUCCEEDED(res))
     return res;
   res = NS_OK;
-  
+
   switch (aID) {
     case eIntID_CaretBlinkTime:
       aResult = 567;
       break;
     case eIntID_CaretWidth:
       aResult = 1;
       break;
     case eIntID_ShowCaretDuringSelection:
@@ -498,17 +516,17 @@ nsLookAndFeel::GetIntImpl(IntID aID, int
 
 nsresult
 nsLookAndFeel::GetFloatImpl(FloatID aID, float &aResult)
 {
   nsresult res = nsXPLookAndFeel::GetFloatImpl(aID, aResult);
   if (NS_SUCCEEDED(res))
     return res;
   res = NS_OK;
-  
+
   switch (aID) {
     case eFloatID_IMEUnderlineRelativeSize:
       aResult = 2.0f;
       break;
     case eFloatID_SpellCheckerUnderlineRelativeSize:
       aResult = 2.0f;
       break;
     default:
@@ -594,18 +612,83 @@ nsLookAndFeel::SetIntCacheImpl(const nsT
         mAllowOverlayScrollbarsOverlap = entry.value;
         mAllowOverlayScrollbarsOverlapCached = true;
         break;
     }
   }
 }
 
 void
-nsLookAndFeel::RefreshImpl()
+nsLookAndFeel::EnsureInit()
 {
-  // We should only clear the cache if we're in the main browser process.
-  // Otherwise, we should wait for the parent to inform us of new values
-  // to cache via LookAndFeel::SetIntCache.
-  if (XRE_IsParentProcess()) {
-    mUseOverlayScrollbarsCached = false;
-    mAllowOverlayScrollbarsOverlapCached = false;
+  if (mInitialized) {
+    return;
+  }
+  mInitialized = true;
+
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK
+
+  nscolor color;
+
+  mColorTextSelectBackground = GetColorFromNSColor(
+    [NSColor selectedTextBackgroundColor]);
+  mColorTextSelectBackgroundDisabled = GetColorFromNSColor(
+    [NSColor secondarySelectedControlColor]);
+
+  mColorHighlight = GetColorFromNSColor([NSColor alternateSelectedControlColor]);
+  mColorMenuHover = GetColorFromNSColor([NSColor alternateSelectedControlColor]);
+
+  GetColor(eColorID_TextSelectBackground, color);
+  if (color == 0x000000) {
+    mColorTextSelectForeground = NS_RGB(0xff,0xff,0xff);
+  } else {
+    mColorTextSelectForeground = NS_DONT_CHANGE_COLOR;
+  }
+
+  mColorMenuHoverText = GetColorFromNSColor(
+    [NSColor alternateSelectedControlTextColor]);
+
+  if (nsCocoaFeatures::OnYosemiteOrLater()) {
+    mColorButtonText = NS_RGB(0xFF,0xFF,0xFF);
+    mHasColorButtonText = true;
   }
+
+  mColorButtonHoverText = GetColorFromNSColor([NSColor controlTextColor]);
+  mColorText = GetColorFromNSColor([NSColor textColor]);
+  mColorWindowText = GetColorFromNSColor([NSColor windowFrameTextColor]);
+  mColorActiveCaption = GetColorFromNSColor([NSColor gridColor]);
+  mColorActiveBorder = GetColorFromNSColor([NSColor keyboardFocusIndicatorColor]);
+  mColorGrayText = GetColorFromNSColor([NSColor disabledControlTextColor]);
+  mColorInactiveBorder = GetColorFromNSColor([NSColor controlBackgroundColor]);
+  mColorInactiveCaption = GetColorFromNSColor([NSColor controlBackgroundColor]);
+  mColorScrollbar = GetColorFromNSColor([NSColor scrollBarColor]);
+  mColorThreeDHighlight = GetColorFromNSColor([NSColor highlightColor]);
+  mColorMenu = GetColorFromNSColor([NSColor alternateSelectedControlTextColor]);
+  mColorWindowFrame = GetColorFromNSColor([NSColor gridColor]);
+  mColorFieldText = GetColorFromNSColor([NSColor controlTextColor]);
+  mColorDialog = GetColorFromNSColor([NSColor controlHighlightColor]);
+  mColorDialogText = GetColorFromNSColor([NSColor controlTextColor]);
+  mColorDragTargetZone = GetColorFromNSColor([NSColor selectedControlColor]);
+
+  int grey = NativeGreyColorAsInt(toolbarFillGrey, true);
+  mColorChromeActive = NS_RGB(grey, grey, grey);
+  grey = NativeGreyColorAsInt(toolbarFillGrey, false);
+  mColorChromeInactive = NS_RGB(grey, grey, grey);
+
+  mColorFocusRing = GetColorFromNSColorWithAlpha([NSColor keyboardFocusIndicatorColor],
+                                                 0.48);
+
+  mColorTextSelect = GetColorFromNSColor([NSColor selectedMenuItemTextColor]);
+  mColorDisabledToolbarText = GetColorFromNSColor([NSColor disabledControlTextColor]);
+  mColorMenuSelect = GetColorFromNSColor([NSColor alternateSelectedControlColor]);
+  mColorCellHighlight = GetColorFromNSColor([NSColor secondarySelectedControlColor]);
+  mColorEvenTreeRow = GetColorFromNSColor([[NSColor controlAlternatingRowBackgroundColors]
+                                           objectAtIndex:0]);
+  mColorOddTreeRow = GetColorFromNSColor([[NSColor controlAlternatingRowBackgroundColors]
+                                          objectAtIndex:1]);
+
+  color = [NSColor currentControlTint];
+  mColorActiveSourceListSelection = (color == NSGraphiteControlTint) ?
+                                    NS_RGB(0xa0,0xa0,0xa0) :
+                                    NS_RGB(0x0a,0x64,0xdc);
+
+  NS_OBJC_END_TRY_ABORT_BLOCK
 }