Browse Source

fix: crash on systemPreferences.getAccentColor() (#18144)

Shelley Vohr 6 years ago
parent
commit
0ab3d7a0be

+ 4 - 18
atom/browser/api/atom_api_system_preferences_mac.mm

@@ -16,6 +16,7 @@
 
 #include "atom/browser/mac/atom_application.h"
 #include "atom/browser/mac/dict_util.h"
+#include "atom/browser/ui/cocoa/NSColor+Hex.h"
 #include "atom/common/native_mate_converters/gurl_converter.h"
 #include "atom/common/native_mate_converters/value_converter.h"
 #include "base/mac/scoped_cftyperef.h"
@@ -114,21 +115,6 @@ std::string ConvertAuthorizationStatus(AVAuthorizationStatusMac status) {
   }
 }
 
-// Convert color to RGBA value like "aabbccdd"
-std::string ToRGBA(NSColor* color) {
-  return base::StringPrintf(
-      "%02X%02X%02X%02X", (int)(color.redComponent * 0xFF),
-      (int)(color.greenComponent * 0xFF), (int)(color.blueComponent * 0xFF),
-      (int)(color.alphaComponent * 0xFF));
-}
-
-// Convert color to RGB hex value like "#ABCDEF"
-std::string ToRGBHex(NSColor* color) {
-  return base::StringPrintf("#%02X%02X%02X", (int)(color.redComponent * 0xFF),
-                            (int)(color.greenComponent * 0xFF),
-                            (int)(color.blueComponent * 0xFF));
-}
-
 }  // namespace
 
 void SystemPreferences::PostNotification(const std::string& name,
@@ -408,7 +394,7 @@ std::string SystemPreferences::GetAccentColor() {
   if (@available(macOS 10.14, *))
     sysColor = [NSColor controlAccentColor];
 
-  return ToRGBA(sysColor);
+  return base::SysNSStringToUTF8([sysColor RGBAValue]);
 }
 
 std::string SystemPreferences::GetSystemColor(const std::string& color,
@@ -437,7 +423,7 @@ std::string SystemPreferences::GetSystemColor(const std::string& color,
     return "";
   }
 
-  return ToRGBHex(sysColor);
+  return base::SysNSStringToUTF8([sysColor hexadecimalValue]);
 }
 
 bool SystemPreferences::CanPromptTouchID() {
@@ -590,7 +576,7 @@ std::string SystemPreferences::GetColor(const std::string& color,
     return "";
   }
 
-  return ToRGBHex(sysColor);
+  return base::SysNSStringToUTF8([sysColor hexadecimalValue]);
 }
 
 std::string SystemPreferences::GetMediaAccessStatus(

+ 2 - 0
atom/browser/ui/cocoa/NSColor+Hex.h

@@ -10,6 +10,8 @@
 #import <Cocoa/Cocoa.h>
 
 @interface NSColor (Hex)
+- (NSString*)hexadecimalValue;
+- (NSString*)RGBAValue;
 + (NSColor*)colorWithHexColorString:(NSString*)hex;
 @end
 

+ 52 - 4
atom/browser/ui/cocoa/NSColor+Hex.mm

@@ -8,17 +8,65 @@
 
 @implementation NSColor (Hex)
 
+- (NSString*)RGBAValue {
+  double redFloatValue, greenFloatValue, blueFloatValue, alphaFloatValue;
+
+  NSColor* convertedColor =
+      [self colorUsingColorSpaceName:NSCalibratedRGBColorSpace];
+
+  if (convertedColor) {
+    [convertedColor getRed:&redFloatValue
+                     green:&greenFloatValue
+                      blue:&blueFloatValue
+                     alpha:&alphaFloatValue];
+
+    int redIntValue = redFloatValue * 255.99999f;
+    int greenIntValue = greenFloatValue * 255.99999f;
+    int blueIntValue = blueFloatValue * 255.99999f;
+    int alphaIntValue = alphaFloatValue * 255.99999f;
+
+    return
+        [NSString stringWithFormat:@"%02x%02x%02x%02x", redIntValue,
+                                   greenIntValue, blueIntValue, alphaIntValue];
+  }
+
+  return nil;
+}
+
+- (NSString*)hexadecimalValue {
+  double redFloatValue, greenFloatValue, blueFloatValue;
+
+  NSColor* convertedColor =
+      [self colorUsingColorSpaceName:NSCalibratedRGBColorSpace];
+
+  if (convertedColor) {
+    [convertedColor getRed:&redFloatValue
+                     green:&greenFloatValue
+                      blue:&blueFloatValue
+                     alpha:NULL];
+
+    int redIntValue = redFloatValue * 255.99999f;
+    int greenIntValue = greenFloatValue * 255.99999f;
+    int blueIntValue = blueFloatValue * 255.99999f;
+
+    return [NSString stringWithFormat:@"#%02x%02x%02x", redIntValue,
+                                      greenIntValue, blueIntValue];
+  }
+
+  return nil;
+}
+
 + (NSColor*)colorWithHexColorString:(NSString*)inColorString {
   unsigned colorCode = 0;
-  unsigned char redByte, greenByte, blueByte;
 
   if (inColorString) {
     NSScanner* scanner = [NSScanner scannerWithString:inColorString];
     (void)[scanner scanHexInt:&colorCode];  // ignore error
   }
-  redByte = (unsigned char)(colorCode >> 16);
-  greenByte = (unsigned char)(colorCode >> 8);
-  blueByte = (unsigned char)(colorCode);  // masks off high bits
+
+  unsigned char redByte = (unsigned char)(colorCode >> 16);
+  unsigned char greenByte = (unsigned char)(colorCode >> 8);
+  unsigned char blueByte = (unsigned char)(colorCode);  // masks off high bits
 
   return [NSColor colorWithCalibratedRed:(CGFloat)redByte / 0xff
                                    green:(CGFloat)greenByte / 0xff