Bug 1192053 - Native theming: Support for Mac OS X source lists (background part). r=gijs, mstange.
authorstefanh@inbox.com
Tue, 17 May 2016 07:37:05 +0200
changeset 297669 0daf8488dbdac81173597f0370ee506b2caeecbf
parent 297668 5bb3981b0c70d1fb3ec763f25654e3cc38f9ee2f
child 297670 d910e79d6aa75050b89e00202df499029b374686
push id19263
push userkwierso@gmail.com
push dateTue, 17 May 2016 21:18:17 +0000
treeherderfx-team@67eb2faeb2ab [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgijs, mstange
bugs1192053
milestone49.0a1
Bug 1192053 - Native theming: Support for Mac OS X source lists (background part). r=gijs, mstange.
browser/themes/osx/browser.css
browser/themes/osx/places/organizer.css
gfx/src/nsThemeConstants.h
layout/style/nsCSSKeywordList.h
layout/style/nsCSSProps.cpp
widget/cocoa/VibrancyManager.h
widget/cocoa/VibrancyManager.mm
widget/cocoa/nsChildView.mm
widget/cocoa/nsNativeThemeCocoa.h
widget/cocoa/nsNativeThemeCocoa.mm
--- a/browser/themes/osx/browser.css
+++ b/browser/themes/osx/browser.css
@@ -2370,26 +2370,20 @@ html|span.ac-emphasize-text-url {
 
 #historySwipeAnimationContainer {
   background: url("chrome://browser/skin/subtle-pattern.png") #B3B9C1;
 }
 
 /* ----- SIDEBAR ELEMENTS ----- */
 
 #sidebar-box {
-  background-color: hsl(212,19%,85%);
-  background-image: linear-gradient(hsl(213,26%,93%), hsl(212,19%,85%));
+  -moz-appearance: -moz-mac-source-list;
   box-shadow: inset -2px 0 0 hsla(0,0%,100%,.2);
 }
 
-#sidebar-box:-moz-window-inactive {
-  background-color: hsl(0,0%,92%);
-  background-image: linear-gradient(hsl(0,0%,97%), hsl(0,0%,92%));
-}
-
 sidebarheader {
   padding: 2px 2px 0;
   text-shadow: 0 1px 0 hsla(0,0%,100%,.5);
 }
 
 .sidebar-splitter {
   border-inline-start: none;
   border-inline-end: 1px solid #b4b4b4;
@@ -2429,25 +2423,19 @@ sidebarheader {
   #sidebar-throbber[loading="true"] {
     list-style-image: url("chrome://global/skin/icons/loading@2x.png");
     width: 16px;
   }
 }
 
 @media (-moz-mac-yosemite-theme) {
   #sidebar-box {
-    -moz-appearance: -moz-mac-vibrancy-light;
-    background-image: none;
     box-shadow: none;
   }
 
-  #sidebar-box:-moz-window-inactive {
-    background-image: none;
-  }
-
   sidebarheader {
     text-shadow: none;
     font-weight: 500;
   }
 
   .sidebar-title,
   #sidebar-title {
     color: #636363;
--- a/browser/themes/osx/places/organizer.css
+++ b/browser/themes/osx/places/organizer.css
@@ -244,40 +244,27 @@
 /* Root View */
 #placesView {
   border-top: 1px solid ThreeDDarkShadow;
   -moz-user-focus: ignore;
 }
 
 /* Place List, Place Content */
 #placesList {
-  background-color: hsl(212,19%,85%);
-  background-image: linear-gradient(hsl(213,26%,93%), hsl(212,19%,85%));
+  -moz-appearance: -moz-mac-source-list;
   box-shadow: inset -2px 0 0 hsla(0,0%,100%,.2);
   width: 160px;
 }
 
-#placesList:-moz-window-inactive {
-  background-color: hsl(0,0%,92%);
-  background-image: linear-gradient(hsl(0,0%,97%), hsl(0,0%,92%));
-}
-
 @media (-moz-mac-yosemite-theme) {
   #placesList {
-    -moz-appearance: -moz-mac-vibrancy-light;
-    background-image: none;
     box-shadow: none;
   }
-
-  #placesList:-moz-window-inactive {
-    background-image: none;
-  }
 }
 
-
 /* Info box */
 #detailsDeck {
   border-top: 1px solid #919191;
   background-color: #f0f0f0;
   padding: 10px;
 }
 
 #placeContent {
--- a/gfx/src/nsThemeConstants.h
+++ b/gfx/src/nsThemeConstants.h
@@ -286,8 +286,9 @@
 #define NS_THEME_WIN_EXCLUDE_GLASS                         242
 
 #define NS_THEME_MAC_VIBRANCY_LIGHT                        243
 #define NS_THEME_MAC_VIBRANCY_DARK                         244
 #define NS_THEME_MAC_DISCLOSURE_BUTTON_OPEN                245
 #define NS_THEME_MAC_DISCLOSURE_BUTTON_CLOSED              246
 
 #define NS_THEME_GTK_INFO_BAR                              247
+#define NS_THEME_MAC_SOURCE_LIST                           248
--- a/layout/style/nsCSSKeywordList.h
+++ b/layout/style/nsCSSKeywordList.h
@@ -751,16 +751,17 @@ CSS_KEY(-moz-window-button-restore, _moz
 CSS_KEY(-moz-window-button-box, _moz_window_button_box)
 CSS_KEY(-moz-window-button-box-maximized, _moz_window_button_box_maximized)
 CSS_KEY(-moz-mac-help-button, _moz_mac_help_button)
 CSS_KEY(-moz-win-exclude-glass, _moz_win_exclude_glass)
 CSS_KEY(-moz-mac-vibrancy-light, _moz_mac_vibrancy_light)
 CSS_KEY(-moz-mac-vibrancy-dark, _moz_mac_vibrancy_dark)
 CSS_KEY(-moz-mac-disclosure-button-closed, _moz_mac_disclosure_button_closed)
 CSS_KEY(-moz-mac-disclosure-button-open, _moz_mac_disclosure_button_open)
+CSS_KEY(-moz-mac-source-list, _moz_mac_source_list)
 CSS_KEY(alphabetic, alphabetic)
 CSS_KEY(bevel, bevel)
 CSS_KEY(butt, butt)
 CSS_KEY(central, central)
 CSS_KEY(crispedges, crispedges)
 CSS_KEY(evenodd, evenodd)
 CSS_KEY(geometricprecision, geometricprecision)
 CSS_KEY(hanging, hanging)
--- a/layout/style/nsCSSProps.cpp
+++ b/layout/style/nsCSSProps.cpp
@@ -862,16 +862,17 @@ const KTableEntry nsCSSProps::kAppearanc
   { eCSSKeyword__moz_window_button_box,         NS_THEME_WINDOW_BUTTON_BOX },
   { eCSSKeyword__moz_window_button_box_maximized, NS_THEME_WINDOW_BUTTON_BOX_MAXIMIZED },
   { eCSSKeyword__moz_win_exclude_glass,         NS_THEME_WIN_EXCLUDE_GLASS },
   { eCSSKeyword__moz_mac_vibrancy_light,        NS_THEME_MAC_VIBRANCY_LIGHT },
   { eCSSKeyword__moz_mac_vibrancy_dark,         NS_THEME_MAC_VIBRANCY_DARK },
   { eCSSKeyword__moz_mac_disclosure_button_open,   NS_THEME_MAC_DISCLOSURE_BUTTON_OPEN },
   { eCSSKeyword__moz_mac_disclosure_button_closed, NS_THEME_MAC_DISCLOSURE_BUTTON_CLOSED },
   { eCSSKeyword__moz_gtk_info_bar,              NS_THEME_GTK_INFO_BAR },
+  { eCSSKeyword__moz_mac_source_list,           NS_THEME_MAC_SOURCE_LIST },
   { eCSSKeyword_UNKNOWN,                        -1 }
 };
 
 const KTableEntry nsCSSProps::kBackfaceVisibilityKTable[] = {
   { eCSSKeyword_visible, NS_STYLE_BACKFACE_VISIBILITY_VISIBLE },
   { eCSSKeyword_hidden, NS_STYLE_BACKFACE_VISIBILITY_HIDDEN },
   { eCSSKeyword_UNKNOWN, -1 }
 };
--- a/widget/cocoa/VibrancyManager.h
+++ b/widget/cocoa/VibrancyManager.h
@@ -21,17 +21,18 @@ class nsChildView;
 namespace mozilla {
 
 enum class VibrancyType {
   LIGHT,
   DARK,
   TOOLTIP,
   MENU,
   HIGHLIGHTED_MENUITEM,
-  SHEET
+  SHEET,
+  SOURCE_LIST
 };
 
 /**
  * VibrancyManager takes care of updating the vibrant regions of a window.
  * Vibrancy is a visual look that was introduced on OS X starting with 10.10.
  * An app declares vibrant window regions to the window server, and the window
  * server will display a blurred rendering of the screen contents from behind
  * the window in these areas, behind the actual window contents. Consequently,
--- a/widget/cocoa/VibrancyManager.mm
+++ b/widget/cocoa/VibrancyManager.mm
@@ -181,16 +181,17 @@ AppearanceForVibrancyType(VibrancyType a
 {
   Class NSAppearanceClass = NSClassFromString(@"NSAppearance");
   switch (aType) {
     case VibrancyType::LIGHT:
     case VibrancyType::TOOLTIP:
     case VibrancyType::MENU:
     case VibrancyType::HIGHLIGHTED_MENUITEM:
     case VibrancyType::SHEET:
+    case VibrancyType::SOURCE_LIST:
       return [NSAppearanceClass performSelector:@selector(appearanceNamed:)
                                      withObject:@"NSAppearanceNameVibrantLight"];
     case VibrancyType::DARK:
       return [NSAppearanceClass performSelector:@selector(appearanceNamed:)
                                      withObject:@"NSAppearanceNameVibrantDark"];
   }
 }
 
@@ -203,17 +204,18 @@ enum {
 
 enum {
   NSVisualEffectMaterialTitlebar = 3
 };
 #endif
 
 #if !defined(MAC_OS_X_VERSION_10_11) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_11
 enum {
-  NSVisualEffectMaterialMenu = 5
+  NSVisualEffectMaterialMenu = 5,
+  NSVisualEffectMaterialSidebar = 7
 };
 #endif
 
 static NSUInteger
 VisualEffectStateForVibrancyType(VibrancyType aType)
 {
   switch (aType) {
     case VibrancyType::TOOLTIP:
@@ -258,25 +260,25 @@ VibrancyManager::CreateEffectView(Vibran
 
   Class EffectViewClass = HasVibrantForeground(aType)
     ? EffectViewClassWithForegroundVibrancy : EffectViewClassWithoutForegroundVibrancy;
   NSView* effectView = [[EffectViewClass alloc] initWithFrame:aRect];
   [effectView performSelector:@selector(setAppearance:)
                    withObject:AppearanceForVibrancyType(aType)];
   [effectView setState:VisualEffectStateForVibrancyType(aType)];
 
+  BOOL canUseElCapitanMaterials = nsCocoaFeatures::OnElCapitanOrLater();
   if (aType == VibrancyType::MENU) {
-    if (nsCocoaFeatures::OnElCapitanOrLater()) {
-      [effectView setMaterial:NSVisualEffectMaterialMenu];
-    } else {
-      // Before 10.11 there is no material that perfectly matches the menu
-      // look. Of all available material types, NSVisualEffectMaterialTitlebar
-      // is the one that comes closest.
-      [effectView setMaterial:NSVisualEffectMaterialTitlebar];
-    }
+    // Before 10.11 there is no material that perfectly matches the menu
+    // look. Of all available material types, NSVisualEffectMaterialTitlebar
+    // is the one that comes closest.
+    [effectView setMaterial:canUseElCapitanMaterials ? NSVisualEffectMaterialMenu
+                                                     : NSVisualEffectMaterialTitlebar];
+  } else if (aType == VibrancyType::SOURCE_LIST && canUseElCapitanMaterials) {
+    [effectView setMaterial:NSVisualEffectMaterialSidebar];
   } else if (aType == VibrancyType::HIGHLIGHTED_MENUITEM) {
     [effectView setMaterial:NSVisualEffectMaterialMenuItem];
     if ([effectView respondsToSelector:@selector(setEmphasized:)]) {
       [effectView setEmphasized:YES];
     }
   }
 
   return effectView;
--- a/widget/cocoa/nsChildView.mm
+++ b/widget/cocoa/nsChildView.mm
@@ -2483,26 +2483,30 @@ nsChildView::UpdateVibrancy(const nsTArr
   LayoutDeviceIntRegion vibrantDarkRegion =
     GatherThemeGeometryRegion(aThemeGeometries, nsNativeThemeCocoa::eThemeGeometryTypeVibrancyDark);
   LayoutDeviceIntRegion menuRegion =
     GatherThemeGeometryRegion(aThemeGeometries, nsNativeThemeCocoa::eThemeGeometryTypeMenu);
   LayoutDeviceIntRegion tooltipRegion =
     GatherThemeGeometryRegion(aThemeGeometries, nsNativeThemeCocoa::eThemeGeometryTypeTooltip);
   LayoutDeviceIntRegion highlightedMenuItemRegion =
     GatherThemeGeometryRegion(aThemeGeometries, nsNativeThemeCocoa::eThemeGeometryTypeHighlightedMenuItem);
+  LayoutDeviceIntRegion sourceListRegion =
+    GatherThemeGeometryRegion(aThemeGeometries, nsNativeThemeCocoa::eThemeGeometryTypeSourceList);
 
   MakeRegionsNonOverlapping(sheetRegion, vibrantLightRegion, vibrantDarkRegion,
-                            menuRegion, tooltipRegion, highlightedMenuItemRegion);
+                            menuRegion, tooltipRegion, highlightedMenuItemRegion,
+                            sourceListRegion);
 
   auto& vm = EnsureVibrancyManager();
   vm.UpdateVibrantRegion(VibrancyType::LIGHT, vibrantLightRegion);
   vm.UpdateVibrantRegion(VibrancyType::TOOLTIP, tooltipRegion);
   vm.UpdateVibrantRegion(VibrancyType::MENU, menuRegion);
   vm.UpdateVibrantRegion(VibrancyType::HIGHLIGHTED_MENUITEM, highlightedMenuItemRegion);
   vm.UpdateVibrantRegion(VibrancyType::SHEET, sheetRegion);
+  vm.UpdateVibrantRegion(VibrancyType::SOURCE_LIST, sourceListRegion);
   vm.UpdateVibrantRegion(VibrancyType::DARK, vibrantDarkRegion);
 }
 
 void
 nsChildView::ClearVibrantAreas()
 {
   if (VibrancyManager::SystemSupportsVibrancy()) {
     EnsureVibrancyManager().ClearVibrantAreas();
@@ -2520,16 +2524,18 @@ ThemeGeometryTypeToVibrancyType(nsITheme
     case nsNativeThemeCocoa::eThemeGeometryTypeTooltip:
       return VibrancyType::TOOLTIP;
     case nsNativeThemeCocoa::eThemeGeometryTypeMenu:
       return VibrancyType::MENU;
     case nsNativeThemeCocoa::eThemeGeometryTypeHighlightedMenuItem:
       return VibrancyType::HIGHLIGHTED_MENUITEM;
     case nsNativeThemeCocoa::eThemeGeometryTypeSheet:
       return VibrancyType::SHEET;
+    case nsNativeThemeCocoa::eThemeGeometryTypeSourceList:
+      return VibrancyType::SOURCE_LIST;
     default:
       MOZ_CRASH();
   }
 }
 
 NSColor*
 nsChildView::VibrancyFillColorForThemeGeometryType(nsITheme::ThemeGeometryType aThemeGeometryType)
 {
--- a/widget/cocoa/nsNativeThemeCocoa.h
+++ b/widget/cocoa/nsNativeThemeCocoa.h
@@ -35,16 +35,17 @@ public:
     eThemeGeometryTypeWindowButtons,
     eThemeGeometryTypeFullscreenButton,
     eThemeGeometryTypeMenu,
     eThemeGeometryTypeHighlightedMenuItem,
     eThemeGeometryTypeVibrancyLight,
     eThemeGeometryTypeVibrancyDark,
     eThemeGeometryTypeTooltip,
     eThemeGeometryTypeSheet,
+    eThemeGeometryTypeSourceList,
   };
 
   nsNativeThemeCocoa();
 
   NS_DECL_ISUPPORTS_INHERITED
 
   // The nsITheme interface.
   NS_IMETHOD DrawWidgetBackground(nsRenderingContext* aContext,
--- a/widget/cocoa/nsNativeThemeCocoa.mm
+++ b/widget/cocoa/nsNativeThemeCocoa.mm
@@ -3001,16 +3001,41 @@ nsNativeThemeCocoa::DrawWidgetBackground
       CGContextSetRGBFillColor(cgContext, 0.557, 0.557, 0.557, 1.0);
       CGContextFillRect(cgContext, CGRectMake(x, y, w, 1));
       CGContextSetRGBFillColor(cgContext, 0.745, 0.745, 0.745, 1.0);
       CGContextFillRect(cgContext, CGRectMake(x, y + 1, 1, h - 1));
       CGContextFillRect(cgContext, CGRectMake(x + w - 1, y + 1, 1, h - 1));
       CGContextFillRect(cgContext, CGRectMake(x + 1, y + h - 1, w - 2, 1));
     }
       break;
+
+    case NS_THEME_MAC_SOURCE_LIST: {
+      if (VibrancyManager::SystemSupportsVibrancy()) {
+        ThemeGeometryType type = ThemeGeometryTypeForWidget(aFrame, aWidgetType);
+        DrawVibrancyBackground(cgContext, macRect, aFrame, type);
+      } else {
+        CGGradientRef backgroundGradient;
+        CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB();
+        CGFloat activeGradientColors[8] = { 0.9137, 0.9294, 0.9490, 1.0,
+                                            0.8196, 0.8471, 0.8784, 1.0 };
+        CGFloat inactiveGradientColors[8] = { 0.9686, 0.9686, 0.9686, 1.0,
+                                              0.9216, 0.9216, 0.9216, 1.0 };
+        CGPoint start = macRect.origin;
+        CGPoint end = CGPointMake(macRect.origin.x,
+                                  macRect.origin.y + macRect.size.height);
+        BOOL isActive = FrameIsInActiveWindow(aFrame);
+        backgroundGradient =
+          CGGradientCreateWithColorComponents(rgb, isActive ? activeGradientColors
+                                                            : inactiveGradientColors, NULL, 2);
+        CGContextDrawLinearGradient(cgContext, backgroundGradient, start, end, 0);
+        CGGradientRelease(backgroundGradient);
+        CGColorSpaceRelease(rgb);
+      }
+    }
+      break;
     
     case NS_THEME_TAB:
       DrawSegment(cgContext, macRect, eventState, aFrame, tabRenderSettings);
       break;
 
     case NS_THEME_TAB_PANELS:
       DrawTabPanel(cgContext, macRect, aFrame);
       break;
@@ -3743,16 +3768,17 @@ nsNativeThemeCocoa::ThemeSupportsWidget(
     case NS_THEME_TREEVIEW_TWISTY:
     case NS_THEME_TREEVIEW_TWISTY_OPEN:
     case NS_THEME_TREEVIEW:
     case NS_THEME_TREEVIEW_HEADER:
     case NS_THEME_TREEVIEW_HEADER_CELL:
     case NS_THEME_TREEVIEW_HEADER_SORTARROW:
     case NS_THEME_TREEVIEW_TREEITEM:
     case NS_THEME_TREEVIEW_LINE:
+    case NS_THEME_MAC_SOURCE_LIST:
 
     case NS_THEME_RANGE:
 
     case NS_THEME_SCALE_HORIZONTAL:
     case NS_THEME_SCALE_THUMB_HORIZONTAL:
     case NS_THEME_SCALE_VERTICAL:
     case NS_THEME_SCALE_THUMB_VERTICAL:
 
@@ -3883,16 +3909,17 @@ nsNativeThemeCocoa::IsWindowSheet(nsIFra
   return (widget->WindowType() == eWindowType_sheet);
 }
 
 bool
 nsNativeThemeCocoa::NeedToClearBackgroundBehindWidget(nsIFrame* aFrame,
                                                       uint8_t aWidgetType)
 {
   switch (aWidgetType) {
+    case NS_THEME_MAC_SOURCE_LIST:
     case NS_THEME_MAC_VIBRANCY_LIGHT:
     case NS_THEME_MAC_VIBRANCY_DARK:
     case NS_THEME_TOOLTIP:
     case NS_THEME_MENUPOPUP:
     case NS_THEME_MENUITEM:
     case NS_THEME_CHECKMENUITEM:
       return true;
     case NS_THEME_DIALOG:
@@ -3912,16 +3939,17 @@ static nscolor ConvertNSColor(NSColor* a
 }
 
 bool
 nsNativeThemeCocoa::WidgetProvidesFontSmoothingBackgroundColor(nsIFrame* aFrame,
                                                                uint8_t aWidgetType,
                                                                nscolor* aColor)
 {
   switch (aWidgetType) {
+    case NS_THEME_MAC_SOURCE_LIST:
     case NS_THEME_MAC_VIBRANCY_LIGHT:
     case NS_THEME_MAC_VIBRANCY_DARK:
     case NS_THEME_TOOLTIP:
     case NS_THEME_MENUPOPUP:
     case NS_THEME_MENUITEM:
     case NS_THEME_CHECKMENUITEM:
     case NS_THEME_DIALOG:
     {
@@ -3968,16 +3996,18 @@ nsNativeThemeCocoa::ThemeGeometryTypeFor
     case NS_THEME_CHECKMENUITEM: {
       EventStates eventState = GetContentState(aFrame, aWidgetType);
       bool isDisabled = IsDisabled(aFrame, eventState);
       bool isSelected = !isDisabled && CheckBooleanAttr(aFrame, nsGkAtoms::menuactive);
       return isSelected ? eThemeGeometryTypeHighlightedMenuItem : eThemeGeometryTypeMenu;
     }
     case NS_THEME_DIALOG:
       return IsWindowSheet(aFrame) ? eThemeGeometryTypeSheet : eThemeGeometryTypeUnknown;
+    case NS_THEME_MAC_SOURCE_LIST:
+      return eThemeGeometryTypeSourceList;
     default:
       return eThemeGeometryTypeUnknown;
   }
 }
 
 nsITheme::Transparency
 nsNativeThemeCocoa::GetWidgetTransparency(nsIFrame* aFrame, uint8_t aWidgetType)
 {