Bug 1045213 - Add nsITheme::ThemeGeometryTypeForWidget. r=roc
authorMarkus Stange <mstange@themasta.com>
Wed, 04 Feb 2015 17:25:18 -0500
changeset 227515 4e3291b79e574b4f2b922455143b9287657b01dc
parent 227514 984a21c9423cf512dc74b941f02cb71f225ea304
child 227516 fa950339690a9d96d9894de0df350cc09de2ed2d
push id55145
push usermstange@themasta.com
push dateWed, 04 Feb 2015 22:25:37 +0000
treeherdermozilla-inbound@b46cb1ef16f8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs1045213
milestone38.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 1045213 - Add nsITheme::ThemeGeometryTypeForWidget. r=roc
gfx/src/nsITheme.h
layout/base/nsDisplayList.cpp
widget/cocoa/nsChildView.h
widget/cocoa/nsChildView.mm
widget/cocoa/nsNativeThemeCocoa.h
widget/cocoa/nsNativeThemeCocoa.mm
widget/nsIWidget.h
widget/windows/nsNativeThemeWin.cpp
widget/windows/nsNativeThemeWin.h
widget/windows/nsWindow.cpp
--- a/gfx/src/nsITheme.h
+++ b/gfx/src/nsITheme.h
@@ -23,20 +23,20 @@ class nsPresContext;
 class nsRenderingContext;
 class nsDeviceContext;
 class nsIFrame;
 class nsIContent;
 class nsIAtom;
 class nsIWidget;
 
 // IID for the nsITheme interface
-// {cc3a6c72-50c2-414d-b9f2-b778a5e0f136}
+// {a21dd936-5960-46da-a724-7c114e421b41}
  #define NS_ITHEME_IID     \
-{ 0xcc3a6c72, 0x50c2, 0x414d, \
-  { 0xb9, 0xf2, 0xb7, 0x78, 0xa5, 0xe0, 0xf1, 0x36 } }
+{ 0xa21dd936, 0x5960, 0x46da, \
+  { 0xa7, 0x24, 0x7c, 0x11, 0x4e, 0x42, 0x1b, 0x41 } }
 // {0ae05515-cf7a-45a8-9e02-6556de7685b1}
 #define NS_THEMERENDERER_CID \
 { 0x0ae05515, 0xcf7a, 0x45a8, \
   { 0x9e, 0x02, 0x65, 0x56, 0xde, 0x76, 0x85, 0xb1 } }
 
 /**
  * nsITheme is a service that provides platform-specific native
  * rendering for widgets.  In other words, it provides the necessary
@@ -143,16 +143,43 @@ public:
   virtual bool NeedToClearBackgroundBehindWidget(uint8_t aWidgetType)
   { return false; }
 
   virtual bool WidgetProvidesFontSmoothingBackgroundColor(nsIFrame* aFrame,
                                       uint8_t aWidgetType, nscolor* aColor)
   { return false; }
 
   /**
+   * ThemeGeometryType values are used for describing themed nsIFrames in
+   * calls to nsIWidget::UpdateThemeGeometries. We don't simply pass the
+   * -moz-appearance value ("widget type") of the frame because the widget may
+   * want to treat different frames with the same -moz-appearance differently
+   * based on other properties of the frame. So we give the theme a first look
+   * at the frame in nsITheme::ThemeGeometryTypeForWidget and pass the
+   * returned ThemeGeometryType along to the widget.
+   * Each theme backend defines the ThemeGeometryType values it needs in its
+   * own nsITheme subclass. eThemeGeometryTypeUnknown is the only value that's
+   * shared between backends.
+   */
+  typedef uint8_t ThemeGeometryType;
+  enum {
+    eThemeGeometryTypeUnknown = 0
+  };
+
+  /**
+   * Returns the theme geometry type that should be used in the ThemeGeometry
+   * array that's passed to the widget using nsIWidget::UpdateThemeGeometries.
+   * A return value of eThemeGeometryTypeUnknown means that this frame will
+   * not be included in the ThemeGeometry array.
+   */
+  virtual ThemeGeometryType ThemeGeometryTypeForWidget(nsIFrame* aFrame,
+                                                       uint8_t aWidgetType)
+  { return eThemeGeometryTypeUnknown; }
+
+  /**
    * Can the nsITheme implementation handle this widget?
    */
   virtual bool ThemeSupportsWidget(nsPresContext* aPresContext,
                                      nsIFrame* aFrame,
                                      uint8_t aWidgetType)=0;
 
   virtual bool WidgetIsContainer(uint8_t aWidgetType)=0;
 
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -2109,22 +2109,23 @@ nsDisplaySolidColor::WriteDebugInfo(std:
   aStream << " (rgba "
           << (int)NS_GET_R(mColor) << ","
           << (int)NS_GET_G(mColor) << ","
           << (int)NS_GET_B(mColor) << ","
           << (int)NS_GET_A(mColor) << ")";
 }
 
 static void
-RegisterThemeGeometry(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
+RegisterThemeGeometry(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
+                      nsITheme::ThemeGeometryType aType)
 {
   if (aBuilder->IsInRootChromeDocument() && !aBuilder->IsInTransform()) {
     nsIFrame* displayRoot = nsLayoutUtils::GetDisplayRootFrame(aFrame);
     nsRect borderBox(aFrame->GetOffsetTo(displayRoot), aFrame->GetSize());
-    aBuilder->RegisterThemeGeometry(aFrame->StyleDisplay()->mAppearance,
+    aBuilder->RegisterThemeGeometry(aType,
         borderBox.ToNearestPixels(aFrame->PresContext()->AppUnitsPerDevPixel()));
   }
 }
 
 nsDisplayBackgroundImage::nsDisplayBackgroundImage(nsDisplayListBuilder* aBuilder,
                                                    nsIFrame* aFrame,
                                                    uint32_t aLayer,
                                                    const nsStyleBackground* aBackgroundStyle)
@@ -2787,35 +2788,26 @@ nsDisplayThemedBackground::nsDisplayThem
 {
   MOZ_COUNT_CTOR(nsDisplayThemedBackground);
 
   const nsStyleDisplay* disp = mFrame->StyleDisplay();
   mAppearance = disp->mAppearance;
   mFrame->IsThemed(disp, &mThemeTransparency);
 
   // Perform necessary RegisterThemeGeometry
-  switch (disp->mAppearance) {
-    case NS_THEME_MOZ_MAC_UNIFIED_TOOLBAR:
-    case NS_THEME_TOOLBAR:
-    case NS_THEME_TOOLTIP:
-    case NS_THEME_MENUPOPUP:
-    case NS_THEME_MENUITEM:
-    case NS_THEME_CHECKMENUITEM:
-    case NS_THEME_WINDOW_TITLEBAR:
-    case NS_THEME_WINDOW_BUTTON_BOX:
-    case NS_THEME_MOZ_MAC_FULLSCREEN_BUTTON:
-    case NS_THEME_WINDOW_BUTTON_BOX_MAXIMIZED:
-    case NS_THEME_MAC_VIBRANCY_LIGHT:
-    case NS_THEME_MAC_VIBRANCY_DARK:
-      RegisterThemeGeometry(aBuilder, aFrame);
-      break;
-    case NS_THEME_WIN_BORDERLESS_GLASS:
-    case NS_THEME_WIN_GLASS:
-      aBuilder->SetGlassDisplayItem(this);
-      break;
+  nsITheme* theme = mFrame->PresContext()->GetTheme();
+  nsITheme::ThemeGeometryType type =
+    theme->ThemeGeometryTypeForWidget(mFrame, disp->mAppearance);
+  if (type != nsITheme::eThemeGeometryTypeUnknown) {
+    RegisterThemeGeometry(aBuilder, aFrame, type);
+  }
+
+  if (disp->mAppearance == NS_THEME_WIN_BORDERLESS_GLASS ||
+      disp->mAppearance == NS_THEME_WIN_GLASS) {
+    aBuilder->SetGlassDisplayItem(this);
   }
 
   mBounds = GetBoundsInternal();
 }
 
 nsDisplayThemedBackground::~nsDisplayThemedBackground()
 {
 #ifdef NS_BUILD_REFCNT_LOGGING
--- a/widget/cocoa/nsChildView.h
+++ b/widget/cocoa/nsChildView.h
@@ -272,18 +272,18 @@ typedef NSInteger NSEventGestureAxis;
 - (void)_surfaceNeedsUpdate:(NSNotification*)notification;
 
 - (void)setGLContext:(NSOpenGLContext *)aGLContext;
 - (bool)preRender:(NSOpenGLContext *)aGLContext;
 - (void)postRender:(NSOpenGLContext *)aGLContext;
 
 - (BOOL)isCoveringTitlebar;
 
-- (NSColor*)vibrancyFillColorForWidgetType:(uint8_t)aWidgetType;
-- (NSColor*)vibrancyFontSmoothingBackgroundColorForWidgetType:(uint8_t)aWidgetType;
+- (NSColor*)vibrancyFillColorForThemeGeometryType:(nsITheme::ThemeGeometryType)aThemeGeometryType;
+- (NSColor*)vibrancyFontSmoothingBackgroundColorForThemeGeometryType:(nsITheme::ThemeGeometryType)aThemeGeometryType;
 
 // Simple gestures support
 //
 // XXX - The swipeWithEvent, beginGestureWithEvent, magnifyWithEvent,
 // rotateWithEvent, and endGestureWithEvent methods are part of a
 // PRIVATE interface exported by nsResponder and reverse-engineering
 // was necessary to obtain the methods' prototypes. Thus, Apple may
 // change the interface in the future without notice.
@@ -497,18 +497,18 @@ public:
   NS_IMETHOD        ReparentNativeWidget(nsIWidget* aNewParent) MOZ_OVERRIDE;
 
   mozilla::widget::TextInputHandler* GetTextInputHandler()
   {
     return mTextInputHandler;
   }
 
   void              ClearVibrantAreas();
-  NSColor*          VibrancyFillColorForWidgetType(uint8_t aWidgetType);
-  NSColor*          VibrancyFontSmoothingBackgroundColorForWidgetType(uint8_t aWidgetType);
+  NSColor*          VibrancyFillColorForThemeGeometryType(nsITheme::ThemeGeometryType aThemeGeometryType);
+  NSColor*          VibrancyFontSmoothingBackgroundColorForThemeGeometryType(nsITheme::ThemeGeometryType aThemeGeometryType);
 
   // unit conversion convenience functions
   int32_t           CocoaPointsToDevPixels(CGFloat aPts) const {
     return nsCocoaUtils::CocoaPointsToDevPixels(aPts, BackingScaleFactor());
   }
   nsIntPoint        CocoaPointsToDevPixels(const NSPoint& aPt) const {
     return nsCocoaUtils::CocoaPointsToDevPixels(aPt, BackingScaleFactor());
   }
--- a/widget/cocoa/nsChildView.mm
+++ b/widget/cocoa/nsChildView.mm
@@ -83,16 +83,17 @@
 
 #include "GeckoProfiler.h"
 
 #include "nsIDOMWheelEvent.h"
 #include "mozilla/layers/ChromeProcessController.h"
 #include "nsLayoutUtils.h"
 #include "InputData.h"
 #include "VibrancyManager.h"
+#include "nsNativeThemeCocoa.h"
 
 using namespace mozilla;
 using namespace mozilla::layers;
 using namespace mozilla::gl;
 using namespace mozilla::widget;
 
 using mozilla::gfx::Matrix4x4;
 
@@ -2271,51 +2272,50 @@ nsChildView::MaybeDrawRoundedCorners(GLM
 
 static int32_t
 FindTitlebarBottom(const nsTArray<nsIWidget::ThemeGeometry>& aThemeGeometries,
                    int32_t aWindowWidth)
 {
   int32_t titlebarBottom = 0;
   for (uint32_t i = 0; i < aThemeGeometries.Length(); ++i) {
     const nsIWidget::ThemeGeometry& g = aThemeGeometries[i];
-    if ((g.mWidgetType == NS_THEME_WINDOW_TITLEBAR) &&
+    if ((g.mType == nsNativeThemeCocoa::eThemeGeometryTypeTitlebar) &&
         g.mRect.X() <= 0 &&
         g.mRect.XMost() >= aWindowWidth &&
         g.mRect.Y() <= 0) {
       titlebarBottom = std::max(titlebarBottom, g.mRect.YMost());
     }
   }
   return titlebarBottom;
 }
 
 static int32_t
 FindUnifiedToolbarBottom(const nsTArray<nsIWidget::ThemeGeometry>& aThemeGeometries,
                          int32_t aWindowWidth, int32_t aTitlebarBottom)
 {
   int32_t unifiedToolbarBottom = aTitlebarBottom;
   for (uint32_t i = 0; i < aThemeGeometries.Length(); ++i) {
     const nsIWidget::ThemeGeometry& g = aThemeGeometries[i];
-    if ((g.mWidgetType == NS_THEME_MOZ_MAC_UNIFIED_TOOLBAR ||
-         g.mWidgetType == NS_THEME_TOOLBAR) &&
+    if ((g.mType == nsNativeThemeCocoa::eThemeGeometryTypeToolbar) &&
         g.mRect.X() <= 0 &&
         g.mRect.XMost() >= aWindowWidth &&
         g.mRect.Y() <= aTitlebarBottom) {
       unifiedToolbarBottom = std::max(unifiedToolbarBottom, g.mRect.YMost());
     }
   }
   return unifiedToolbarBottom;
 }
 
 static nsIntRect
 FindFirstRectOfType(const nsTArray<nsIWidget::ThemeGeometry>& aThemeGeometries,
-                    uint8_t aWidgetType)
+                    nsITheme::ThemeGeometryType aThemeGeometryType)
 {
   for (uint32_t i = 0; i < aThemeGeometries.Length(); ++i) {
     const nsIWidget::ThemeGeometry& g = aThemeGeometries[i];
-    if (g.mWidgetType == aWidgetType) {
+    if (g.mType == aThemeGeometryType) {
       return g.mRect;
     }
   }
   return nsIntRect();
 }
 
 void
 nsChildView::UpdateThemeGeometries(const nsTArray<ThemeGeometry>& aThemeGeometries)
@@ -2337,53 +2337,51 @@ nsChildView::UpdateThemeGeometries(const
   ToolbarWindow* win = (ToolbarWindow*)[mView window];
   bool drawsContentsIntoWindowFrame = [win drawsContentsIntoWindowFrame];
   int32_t titlebarHeight = CocoaPointsToDevPixels([win titlebarHeight]);
   int32_t contentOffset = drawsContentsIntoWindowFrame ? titlebarHeight : 0;
   int32_t devUnifiedHeight = titlebarHeight + unifiedToolbarBottom - contentOffset;
   [win setUnifiedToolbarHeight:DevPixelsToCocoaPoints(devUnifiedHeight)];
 
   // Update titlebar control offsets.
-  nsIntRect windowButtonRect = FindFirstRectOfType(aThemeGeometries, NS_THEME_WINDOW_BUTTON_BOX);
+  nsIntRect windowButtonRect = FindFirstRectOfType(aThemeGeometries, nsNativeThemeCocoa::eThemeGeometryTypeWindowButtons);
   [win placeWindowButtons:[mView convertRect:DevPixelsToCocoaPoints(windowButtonRect) toView:nil]];
-  nsIntRect fullScreenButtonRect = FindFirstRectOfType(aThemeGeometries, NS_THEME_MOZ_MAC_FULLSCREEN_BUTTON);
+  nsIntRect fullScreenButtonRect = FindFirstRectOfType(aThemeGeometries, nsNativeThemeCocoa::eThemeGeometryTypeFullscreenButton);
   [win placeFullScreenButton:[mView convertRect:DevPixelsToCocoaPoints(fullScreenButtonRect) toView:nil]];
 }
 
 static nsIntRegion
 GatherThemeGeometryRegion(const nsTArray<nsIWidget::ThemeGeometry>& aThemeGeometries,
-                          uint8_t aWidgetType)
+                          nsITheme::ThemeGeometryType aThemeGeometryType)
 {
   nsIntRegion region;
   for (size_t i = 0; i < aThemeGeometries.Length(); ++i) {
     const nsIWidget::ThemeGeometry& g = aThemeGeometries[i];
-    if (g.mWidgetType == aWidgetType) {
+    if (g.mType == aThemeGeometryType) {
       region.OrWith(g.mRect);
     }
   }
   return region;
 }
 
 void
 nsChildView::UpdateVibrancy(const nsTArray<ThemeGeometry>& aThemeGeometries)
 {
   if (!VibrancyManager::SystemSupportsVibrancy()) {
     return;
   }
 
   nsIntRegion vibrantLightRegion =
-    GatherThemeGeometryRegion(aThemeGeometries, NS_THEME_MAC_VIBRANCY_LIGHT);
+    GatherThemeGeometryRegion(aThemeGeometries, nsNativeThemeCocoa::eThemeGeometryTypeVibrancyLight);
   nsIntRegion vibrantDarkRegion =
-    GatherThemeGeometryRegion(aThemeGeometries, NS_THEME_MAC_VIBRANCY_DARK);
+    GatherThemeGeometryRegion(aThemeGeometries, nsNativeThemeCocoa::eThemeGeometryTypeVibrancyDark);
   nsIntRegion menuRegion =
-    GatherThemeGeometryRegion(aThemeGeometries, NS_THEME_MENUPOPUP).OrWith(
-      GatherThemeGeometryRegion(aThemeGeometries, NS_THEME_MENUITEM).OrWith(
-        GatherThemeGeometryRegion(aThemeGeometries, NS_THEME_CHECKMENUITEM)));
+    GatherThemeGeometryRegion(aThemeGeometries, nsNativeThemeCocoa::eThemeGeometryTypeMenu);
   nsIntRegion tooltipRegion =
-    GatherThemeGeometryRegion(aThemeGeometries, NS_THEME_TOOLTIP);
+    GatherThemeGeometryRegion(aThemeGeometries, nsNativeThemeCocoa::eThemeGeometryTypeTooltip);
 
   vibrantDarkRegion.SubOut(vibrantLightRegion);
   vibrantDarkRegion.SubOut(menuRegion);
   vibrantDarkRegion.SubOut(tooltipRegion);
   vibrantLightRegion.SubOut(menuRegion);
   vibrantLightRegion.SubOut(tooltipRegion);
   menuRegion.SubOut(tooltipRegion);
 
@@ -2398,50 +2396,48 @@ void
 nsChildView::ClearVibrantAreas()
 {
   if (VibrancyManager::SystemSupportsVibrancy()) {
     EnsureVibrancyManager().ClearVibrantAreas();
   }
 }
 
 static VibrancyType
-WidgetTypeToVibrancyType(uint8_t aWidgetType)
-{
-  switch (aWidgetType) {
-    case NS_THEME_MAC_VIBRANCY_LIGHT:
+ThemeGeometryTypeToVibrancyType(nsITheme::ThemeGeometryType aThemeGeometryType)
+{
+  switch (aThemeGeometryType) {
+    case nsNativeThemeCocoa::eThemeGeometryTypeVibrancyLight:
       return VibrancyType::LIGHT;
-    case NS_THEME_MAC_VIBRANCY_DARK:
+    case nsNativeThemeCocoa::eThemeGeometryTypeVibrancyDark:
       return VibrancyType::DARK;
-    case NS_THEME_TOOLTIP:
+    case nsNativeThemeCocoa::eThemeGeometryTypeTooltip:
       return VibrancyType::TOOLTIP;
-    case NS_THEME_MENUPOPUP:
-    case NS_THEME_MENUITEM:
-    case NS_THEME_CHECKMENUITEM:
+    case nsNativeThemeCocoa::eThemeGeometryTypeMenu:
       return VibrancyType::MENU;
     default:
       MOZ_CRASH();
   }
 }
 
 NSColor*
-nsChildView::VibrancyFillColorForWidgetType(uint8_t aWidgetType)
+nsChildView::VibrancyFillColorForThemeGeometryType(nsITheme::ThemeGeometryType aThemeGeometryType)
 {
   if (VibrancyManager::SystemSupportsVibrancy()) {
     return EnsureVibrancyManager().VibrancyFillColorForType(
-      WidgetTypeToVibrancyType(aWidgetType));
+      ThemeGeometryTypeToVibrancyType(aThemeGeometryType));
   }
   return [NSColor whiteColor];
 }
 
 NSColor*
-nsChildView::VibrancyFontSmoothingBackgroundColorForWidgetType(uint8_t aWidgetType)
+nsChildView::VibrancyFontSmoothingBackgroundColorForThemeGeometryType(nsITheme::ThemeGeometryType aThemeGeometryType)
 {
   if (VibrancyManager::SystemSupportsVibrancy()) {
     return EnsureVibrancyManager().VibrancyFontSmoothingBackgroundColorForType(
-      WidgetTypeToVibrancyType(aWidgetType));
+      ThemeGeometryTypeToVibrancyType(aThemeGeometryType));
   }
   return [NSColor clearColor];
 }
 
 mozilla::VibrancyManager&
 nsChildView::EnsureVibrancyManager()
 {
   MOZ_ASSERT(mView, "Only call this once we have a view!");
@@ -3251,30 +3247,30 @@ NSEvent* gLastDragMouseDownEvent = nil;
 
 - (BOOL)isCoveringTitlebar
 {
   return [[self window] isKindOfClass:[BaseWindow class]] &&
          [(BaseWindow*)[self window] mainChildView] == self &&
          [(BaseWindow*)[self window] drawsContentsIntoWindowFrame];
 }
 
-- (NSColor*)vibrancyFillColorForWidgetType:(uint8_t)aWidgetType
+- (NSColor*)vibrancyFillColorForThemeGeometryType:(nsITheme::ThemeGeometryType)aThemeGeometryType
 {
   if (!mGeckoChild) {
     return [NSColor whiteColor];
   }
-  return mGeckoChild->VibrancyFillColorForWidgetType(aWidgetType);
-}
-
-- (NSColor*)vibrancyFontSmoothingBackgroundColorForWidgetType:(uint8_t)aWidgetType
+  return mGeckoChild->VibrancyFillColorForThemeGeometryType(aThemeGeometryType);
+}
+
+- (NSColor*)vibrancyFontSmoothingBackgroundColorForThemeGeometryType:(nsITheme::ThemeGeometryType)aThemeGeometryType
 {
   if (!mGeckoChild) {
     return [NSColor clearColor];
   }
-  return mGeckoChild->VibrancyFontSmoothingBackgroundColorForWidgetType(aWidgetType);
+  return mGeckoChild->VibrancyFontSmoothingBackgroundColorForThemeGeometryType(aThemeGeometryType);
 }
 
 - (nsIntRegion)nativeDirtyRegionWithBoundingRect:(NSRect)aRect
 {
   nsIntRect boundingRect = mGeckoChild->CocoaPointsToDevPixels(aRect);
   const NSRect *rects;
   NSInteger count;
   [self getRectsBeingDrawn:&rects count:&count];
--- a/widget/cocoa/nsNativeThemeCocoa.h
+++ b/widget/cocoa/nsNativeThemeCocoa.h
@@ -23,16 +23,28 @@ struct SegmentedControlRenderSettings;
 namespace mozilla {
 class EventStates;
 } // namespace mozilla
 
 class nsNativeThemeCocoa : private nsNativeTheme,
                            public nsITheme
 {
 public:
+  enum {
+    eThemeGeometryTypeTitlebar = eThemeGeometryTypeUnknown + 1,
+    eThemeGeometryTypeToolbar,
+    eThemeGeometryTypeWindowButtons,
+    eThemeGeometryTypeFullscreenButton,
+    eThemeGeometryTypeMenu,
+    eThemeGeometryTypeHighlightedMenuItem,
+    eThemeGeometryTypeVibrancyLight,
+    eThemeGeometryTypeVibrancyDark,
+    eThemeGeometryTypeTooltip,
+  };
+
   nsNativeThemeCocoa();
 
   NS_DECL_ISUPPORTS_INHERITED
 
   // The nsITheme interface.
   NS_IMETHOD DrawWidgetBackground(nsRenderingContext* aContext,
                                   nsIFrame* aFrame,
                                   uint8_t aWidgetType,
@@ -60,16 +72,18 @@ public:
   bool ThemeSupportsWidget(nsPresContext* aPresContext, nsIFrame* aFrame, uint8_t aWidgetType) MOZ_OVERRIDE;
   bool WidgetIsContainer(uint8_t aWidgetType) MOZ_OVERRIDE;
   bool ThemeDrawsFocusForWidget(uint8_t aWidgetType) MOZ_OVERRIDE;
   bool ThemeNeedsComboboxDropmarker() MOZ_OVERRIDE;
   virtual bool WidgetAppearanceDependsOnWindowFocus(uint8_t aWidgetType) MOZ_OVERRIDE;
   virtual bool NeedToClearBackgroundBehindWidget(uint8_t aWidgetType) MOZ_OVERRIDE;
   virtual bool WidgetProvidesFontSmoothingBackgroundColor(nsIFrame* aFrame, uint8_t aWidgetType,
                                                           nscolor* aColor) MOZ_OVERRIDE;
+  virtual ThemeGeometryType ThemeGeometryTypeForWidget(nsIFrame* aFrame,
+                                                       uint8_t aWidgetType) MOZ_OVERRIDE;
   virtual Transparency GetWidgetTransparency(nsIFrame* aFrame, uint8_t aWidgetType) MOZ_OVERRIDE;
 
   void DrawProgress(CGContextRef context, const HIRect& inBoxRect,
                     bool inIsIndeterminate, bool inIsHorizontal,
                     double inValue, double inMaxValue, nsIFrame* aFrame);
 
   static void DrawNativeTitlebar(CGContextRef aContext, CGRect aTitlebarRect,
                                  CGFloat aUnifiedHeight, BOOL aIsMain, BOOL aIsFlipped);
--- a/widget/cocoa/nsNativeThemeCocoa.mm
+++ b/widget/cocoa/nsNativeThemeCocoa.mm
@@ -2251,31 +2251,31 @@ nsNativeThemeCocoa::DrawResizer(CGContex
   RenderTransformedHIThemeControl(cgContext, aRect, RenderResizer, &drawInfo,
                                   IsFrameRTL(aFrame));
 
   NS_OBJC_END_TRY_ABORT_BLOCK;
 }
 
 static void
 DrawVibrancyBackground(CGContextRef cgContext, CGRect inBoxRect,
-                       nsIFrame* aFrame, uint8_t aWidgetType,
+                       nsIFrame* aFrame, nsITheme::ThemeGeometryType aThemeGeometryType,
                        int aCornerRadius = 0)
 {
   ChildView* childView = ChildViewForFrame(aFrame);
   if (childView) {
     NSRect rect = NSRectFromCGRect(inBoxRect);
     NSGraphicsContext* savedContext = [NSGraphicsContext currentContext];
     [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithGraphicsPort:cgContext flipped:YES]];
     [NSGraphicsContext saveGraphicsState];
 
     if (aCornerRadius > 0) {
       [[NSBezierPath bezierPathWithRoundedRect:rect xRadius:aCornerRadius yRadius:aCornerRadius] addClip];
     }
 
-    [[childView vibrancyFillColorForWidgetType:aWidgetType] set];
+    [[childView vibrancyFillColorForThemeGeometryType:aThemeGeometryType] set];
     NSRectFill(rect);
 
     [NSGraphicsContext restoreGraphicsState];
     [NSGraphicsContext setCurrentContext:savedContext];
   }
 }
 
 static bool
@@ -2386,17 +2386,17 @@ nsNativeThemeCocoa::DrawWidgetBackground
     case NS_THEME_DIALOG: {
       HIThemeSetFill(kThemeBrushDialogBackgroundActive, NULL, cgContext, HITHEME_ORIENTATION);
       CGContextFillRect(cgContext, macRect);
     }
       break;
 
     case NS_THEME_MENUPOPUP:
       if (VibrancyManager::SystemSupportsVibrancy()) {
-        DrawVibrancyBackground(cgContext, macRect, aFrame, aWidgetType, 4);
+        DrawVibrancyBackground(cgContext, macRect, aFrame, eThemeGeometryTypeMenu, 4);
       } else {
         HIThemeMenuDrawInfo mdi;
         memset(&mdi, 0, sizeof(mdi));
         mdi.version = 0;
         mdi.menuType = IsDisabled(aFrame, eventState) ?
                          static_cast<ThemeMenuType>(kThemeMenuTypeInactive) :
                          static_cast<ThemeMenuType>(kThemeMenuTypePopUp);
 
@@ -2419,17 +2419,17 @@ nsNativeThemeCocoa::DrawWidgetBackground
     }
       break;
 
     case NS_THEME_MENUITEM:
     case NS_THEME_CHECKMENUITEM: {
       bool isDisabled = IsDisabled(aFrame, eventState);
       bool isSelected = !isDisabled && CheckBooleanAttr(aFrame, nsGkAtoms::menuactive);
       if (!isSelected && VibrancyManager::SystemSupportsVibrancy()) {
-        DrawVibrancyBackground(cgContext, macRect, aFrame, aWidgetType);
+        DrawVibrancyBackground(cgContext, macRect, aFrame, eThemeGeometryTypeMenu);
       } else {
         // maybe use kThemeMenuItemHierBackground or PopUpBackground instead of just Plain?
         HIThemeMenuItemDrawInfo drawInfo;
         memset(&drawInfo, 0, sizeof(drawInfo));
         drawInfo.version = 0;
         drawInfo.itemType = kThemeMenuItemPlain;
         drawInfo.state = (isDisabled ?
                            static_cast<ThemeMenuState>(kThemeMenuDisabled) :
@@ -2467,17 +2467,17 @@ nsNativeThemeCocoa::DrawWidgetBackground
     case NS_THEME_BUTTON_ARROW_DOWN:
       DrawMenuIcon(cgContext, macRect, eventState, aFrame, kMenuScrollArrowSize,
                    aWidgetType == NS_THEME_BUTTON_ARROW_UP ?
                    kMenuUpScrollArrowImage : kMenuDownScrollArrowImage, true);
       break;
 
     case NS_THEME_TOOLTIP:
       if (VibrancyManager::SystemSupportsVibrancy()) {
-        DrawVibrancyBackground(cgContext, macRect, aFrame, aWidgetType);
+        DrawVibrancyBackground(cgContext, macRect, aFrame, ThemeGeometryTypeForWidget(aFrame, aWidgetType));
       } else {
         CGContextSetRGBFillColor(cgContext, 0.996, 1.000, 0.792, 0.950);
         CGContextFillRect(cgContext, macRect);
       }
       break;
 
     case NS_THEME_CHECKBOX:
     case NS_THEME_RADIO: {
@@ -2904,19 +2904,21 @@ nsNativeThemeCocoa::DrawWidgetBackground
       DrawTabPanel(cgContext, macRect, aFrame);
       break;
 
     case NS_THEME_RESIZER:
       DrawResizer(cgContext, macRect, aFrame);
       break;
 
     case NS_THEME_MAC_VIBRANCY_LIGHT:
-    case NS_THEME_MAC_VIBRANCY_DARK:
-      DrawVibrancyBackground(cgContext, macRect, aFrame, aWidgetType);
+    case NS_THEME_MAC_VIBRANCY_DARK: {
+      ThemeGeometryType type = ThemeGeometryTypeForWidget(aFrame, aWidgetType);
+      DrawVibrancyBackground(cgContext, macRect, aFrame, type);
       break;
+    }
   }
 
   if (hidpi) {
     // Reset the base CTM.
     CGContextSetBaseCTM(cgContext, CGAffineTransformIdentity);
   }
 
   nativeDrawing.EndNativeDrawing();
@@ -3788,27 +3790,56 @@ nsNativeThemeCocoa::WidgetProvidesFontSm
     case NS_THEME_MAC_VIBRANCY_DARK:
     case NS_THEME_TOOLTIP:
     case NS_THEME_MENUPOPUP:
     case NS_THEME_MENUITEM:
     case NS_THEME_CHECKMENUITEM:
     {
       ChildView* childView = ChildViewForFrame(aFrame);
       if (childView) {
-        NSColor* color = [childView vibrancyFontSmoothingBackgroundColorForWidgetType:aWidgetType];
+        ThemeGeometryType type = ThemeGeometryTypeForWidget(aFrame, aWidgetType);
+        NSColor* color = [childView vibrancyFontSmoothingBackgroundColorForThemeGeometryType:type];
         *aColor = ConvertNSColor(color);
         return true;
       }
       return false;
     }
     default:
       return false;
   }
 }
 
+nsITheme::ThemeGeometryType
+nsNativeThemeCocoa::ThemeGeometryTypeForWidget(nsIFrame* aFrame, uint8_t aWidgetType)
+{
+  switch (aWidgetType) {
+    case NS_THEME_WINDOW_TITLEBAR:
+      return eThemeGeometryTypeTitlebar;
+    case NS_THEME_TOOLBAR:
+    case NS_THEME_MOZ_MAC_UNIFIED_TOOLBAR:
+      return eThemeGeometryTypeToolbar;
+    case NS_THEME_WINDOW_BUTTON_BOX:
+      return eThemeGeometryTypeWindowButtons;
+    case NS_THEME_MOZ_MAC_FULLSCREEN_BUTTON:
+      return eThemeGeometryTypeFullscreenButton;
+    case NS_THEME_MAC_VIBRANCY_LIGHT:
+      return eThemeGeometryTypeVibrancyLight;
+    case NS_THEME_MAC_VIBRANCY_DARK:
+      return eThemeGeometryTypeVibrancyDark;
+    case NS_THEME_TOOLTIP:
+      return eThemeGeometryTypeTooltip;
+    case NS_THEME_MENUPOPUP:
+    case NS_THEME_MENUITEM:
+    case NS_THEME_CHECKMENUITEM:
+      return eThemeGeometryTypeMenu;
+    default:
+      return eThemeGeometryTypeUnknown;
+  }
+}
+
 nsITheme::Transparency
 nsNativeThemeCocoa::GetWidgetTransparency(nsIFrame* aFrame, uint8_t aWidgetType)
 {
   switch (aWidgetType) {
   case NS_THEME_MENUPOPUP:
   case NS_THEME_TOOLTIP:
     return eTransparent;
 
--- a/widget/nsIWidget.h
+++ b/widget/nsIWidget.h
@@ -10,16 +10,17 @@
 #include "nsColor.h"
 #include "nsRect.h"
 #include "nsStringGlue.h"
 
 #include "nsCOMPtr.h"
 #include "nsAutoPtr.h"
 #include "nsWidgetInitData.h"
 #include "nsTArray.h"
+#include "nsITheme.h"
 #include "nsITimer.h"
 #include "nsXULAppAPI.h"
 #include "mozilla/EventForwards.h"
 #include "mozilla/layers/LayersTypes.h"
 #include "mozilla/RefPtr.h"
 #include "mozilla/TimeStamp.h"
 #include "Units.h"
 
@@ -735,24 +736,25 @@ class nsIWidget : public nsISupports {
     typedef mozilla::widget::InputContext InputContext;
     typedef mozilla::widget::InputContextAction InputContextAction;
     typedef mozilla::widget::SizeConstraints SizeConstraints;
     typedef mozilla::widget::TextEventDispatcher TextEventDispatcher;
     typedef mozilla::CompositorVsyncDispatcher CompositorVsyncDispatcher;
 
     // Used in UpdateThemeGeometries.
     struct ThemeGeometry {
-      // The -moz-appearance value for the themed widget
-      uint8_t mWidgetType;
+      // The ThemeGeometryType value for the themed widget, see
+      // nsITheme::ThemeGeometryTypeForWidget.
+      nsITheme::ThemeGeometryType mType;
       // The device-pixel rect within the window for the themed widget
       nsIntRect mRect;
 
-      ThemeGeometry(uint8_t aWidgetType, const nsIntRect& aRect)
-       : mWidgetType(aWidgetType)
-       , mRect(aRect)
+      ThemeGeometry(nsITheme::ThemeGeometryType aType, const nsIntRect& aRect)
+        : mType(aType)
+        , mRect(aRect)
       { }
     };
 
     NS_DECLARE_STATIC_IID_ACCESSOR(NS_IWIDGET_IID)
 
     nsIWidget()
       : mLastChild(nullptr)
       , mPrevSibling(nullptr)
--- a/widget/windows/nsNativeThemeWin.cpp
+++ b/widget/windows/nsNativeThemeWin.cpp
@@ -2659,16 +2659,29 @@ nsNativeThemeWin::WidgetAppearanceDepend
     case NS_THEME_WINDOW_BUTTON_MAXIMIZE:
     case NS_THEME_WINDOW_BUTTON_RESTORE:
       return true;
     default:
       return false;
   }
 }
 
+nsITheme::ThemeGeometryType
+nsNativeThemeWin::ThemeGeometryTypeForWidget(nsIFrame* aFrame,
+                                             uint8_t aWidgetType)
+{
+  switch (aWidgetType) {
+    case NS_THEME_WINDOW_BUTTON_BOX:
+    case NS_THEME_WINDOW_BUTTON_BOX_MAXIMIZED:
+      return eThemeGeometryTypeWindowButtons;
+    default:
+      return eThemeGeometryTypeUnknown;
+  }
+}
+
 bool
 nsNativeThemeWin::ShouldHideScrollbars()
 {
   return WinUtils::ShouldHideScrollbars();
 }
 
 nsITheme::Transparency
 nsNativeThemeWin::GetWidgetTransparency(nsIFrame* aFrame, uint8_t aWidgetType)
--- a/widget/windows/nsNativeThemeWin.h
+++ b/widget/windows/nsNativeThemeWin.h
@@ -69,16 +69,22 @@ public:
   bool WidgetIsContainer(uint8_t aWidgetType);
 
   bool ThemeDrawsFocusForWidget(uint8_t aWidgetType) MOZ_OVERRIDE;
 
   bool ThemeNeedsComboboxDropmarker();
 
   virtual bool WidgetAppearanceDependsOnWindowFocus(uint8_t aWidgetType) MOZ_OVERRIDE;
 
+  enum {
+    eThemeGeometryTypeWindowButtons = eThemeGeometryTypeUnknown + 1
+  };
+  virtual ThemeGeometryType ThemeGeometryTypeForWidget(nsIFrame* aFrame,
+                                                       uint8_t aWidgetType) MOZ_OVERRIDE;
+
   virtual bool ShouldHideScrollbars() MOZ_OVERRIDE;
 
   nsNativeThemeWin();
 
 protected:
   HANDLE GetTheme(uint8_t aWidgetType);
   nsresult GetThemePartAndState(nsIFrame* aFrame, uint8_t aWidgetType,
                                 int32_t& aPart, int32_t& aState);
--- a/widget/windows/nsWindow.cpp
+++ b/widget/windows/nsWindow.cpp
@@ -3526,18 +3526,17 @@ nsWindow::EndRemoteDrawing()
   mCompositeDC = nullptr;
 }
 
 void
 nsWindow::UpdateThemeGeometries(const nsTArray<ThemeGeometry>& aThemeGeometries)
 {
   nsIntRegion clearRegion;
   for (size_t i = 0; i < aThemeGeometries.Length(); i++) {
-    if ((aThemeGeometries[i].mWidgetType == NS_THEME_WINDOW_BUTTON_BOX ||
-         aThemeGeometries[i].mWidgetType == NS_THEME_WINDOW_BUTTON_BOX_MAXIMIZED) &&
+    if (aThemeGeometries[i].mType == nsNativeThemeWin::eThemeGeometryTypeWindowButtons &&
         nsUXThemeData::CheckForCompositor())
     {
       nsIntRect bounds = aThemeGeometries[i].mRect;
       clearRegion = nsIntRect(bounds.X(), bounds.Y(), bounds.Width(), bounds.Height() - 2.0);
       clearRegion.Or(clearRegion, nsIntRect(bounds.X() + 1.0, bounds.YMost() - 2.0, bounds.Width() - 1.0, 1.0));
       clearRegion.Or(clearRegion, nsIntRect(bounds.X() + 2.0, bounds.YMost() - 1.0, bounds.Width() - 3.0, 1.0));
     }
   }