--- a/widget/cocoa/nsNativeThemeCocoa.h
+++ b/widget/cocoa/nsNativeThemeCocoa.h
@@ -72,16 +72,22 @@ public:
bool disabled : 1;
bool insideActiveWindow : 1;
bool pressed : 1;
bool focused : 1;
bool rtl : 1;
};
+ struct MenuBackgroundParams {
+ mozilla::Maybe<mozilla::gfx::Color> vibrancyColor;
+ bool disabled = false;
+ bool submenuRightOfParent = false;
+ };
+
struct ButtonParams {
ControlParams controlParams;
ButtonType button = ButtonType::eRegularPushButton;
};
struct TreeHeaderCellParams {
ControlParams controlParams;
TreeSortDirection sortDirection = eTreeSortDirection_Natural;
@@ -148,16 +154,18 @@ protected:
nsIntMargin DirectionAwareMargin(const nsIntMargin& aMargin, nsIFrame* aFrame);
nsIFrame* SeparatorResponsibility(nsIFrame* aBefore, nsIFrame* aAfter);
CGRect SeparatorAdjustedRect(CGRect aRect, nsIFrame* aLeft,
nsIFrame* aCurrent, nsIFrame* aRight);
bool IsWindowSheet(nsIFrame* aFrame);
ControlParams ComputeControlParams(nsIFrame* aFrame,
mozilla::EventStates aEventState);
+ MenuBackgroundParams ComputeMenuBackgroundParams(nsIFrame* aFrame,
+ mozilla::EventStates aEventState);
TreeHeaderCellParams ComputeTreeHeaderCellParams(nsIFrame* aFrame,
mozilla::EventStates aEventState);
// HITheme drawing routines
void DrawFrame(CGContextRef context, HIThemeFrameKind inKind,
const HIRect& inBoxRect, bool inReadOnly,
mozilla::EventStates inState);
void DrawMeter(CGContextRef context, const HIRect& inBoxRect,
@@ -180,16 +188,18 @@ protected:
ControlParams aControlParams);
void DrawSquareBezelPushButton(CGContextRef cgContext,
const HIRect& inBoxRect,
ControlParams aControlParams);
void DrawHelpButton(CGContextRef cgContext, const HIRect& inBoxRect,
ControlParams aControlParams);
void DrawDisclosureButton(CGContextRef cgContext, const HIRect& inBoxRect,
ControlParams aControlParams, NSCellStateValue aState);
+ void DrawMenuBackground(CGContextRef cgContext, const CGRect& inBoxRect,
+ const MenuBackgroundParams& aParams);
void DrawMenuIcon(CGContextRef cgContext, const CGRect& aRect,
mozilla::EventStates inState, nsIFrame* aFrame,
const NSSize& aIconSize, NSString* aImageName,
bool aCenterHorizontally);
void DrawHIThemeButton(CGContextRef cgContext, const HIRect& aRect,
ThemeButtonKind aKind, ThemeButtonValue aValue,
ThemeDrawState aState, ThemeButtonAdornment aAdornment,
const ControlParams& aParams);
--- a/widget/cocoa/nsNativeThemeCocoa.mm
+++ b/widget/cocoa/nsNativeThemeCocoa.mm
@@ -1107,16 +1107,119 @@ nsNativeThemeCocoa::DrawSearchField(CGCo
DrawCellWithSnapping(cell, cgContext, inBoxRect, searchFieldSettings,
VerticalAlignFactor(aFrame), mCellDrawView,
IsFrameRTL(aFrame));
NS_OBJC_END_TRY_ABORT_BLOCK;
}
+static Color
+NSColorToColor(NSColor* aColor)
+{
+ NSColor* deviceColor = [aColor colorUsingColorSpaceName:NSDeviceRGBColorSpace];
+ return Color([deviceColor redComponent],
+ [deviceColor greenComponent],
+ [deviceColor blueComponent],
+ [deviceColor alphaComponent]);
+}
+
+static Color
+VibrancyFillColor(nsIFrame* aFrame, nsITheme::ThemeGeometryType aThemeGeometryType)
+{
+ ChildView* childView = ChildViewForFrame(aFrame);
+ if (childView) {
+ return NSColorToColor(
+ [childView vibrancyFillColorForThemeGeometryType:aThemeGeometryType]);
+ }
+ return Color();
+}
+
+static void
+DrawVibrancyBackground(CGContextRef cgContext, CGRect inBoxRect,
+ const Color& aColor, int aCornerRadiusIfOpaque = 0)
+{
+ NSRect rect = NSRectFromCGRect(inBoxRect);
+ NSGraphicsContext* savedContext = [NSGraphicsContext currentContext];
+ NSGraphicsContext* context =
+ [NSGraphicsContext graphicsContextWithGraphicsPort:cgContext flipped:YES];
+ [NSGraphicsContext setCurrentContext:context];
+ [NSGraphicsContext saveGraphicsState];
+
+ NSColor* fillColor = [NSColor colorWithDeviceRed:aColor.r
+ green:aColor.g
+ blue:aColor.b
+ alpha:aColor.a];
+
+ if ([fillColor alphaComponent] == 1.0 && aCornerRadiusIfOpaque > 0) {
+ // The fillColor being opaque means that the system-wide pref "reduce
+ // transparency" is set. In that scenario, we still go through all the
+ // vibrancy rendering paths (VibrancyManager::SystemSupportsVibrancy()
+ // will still return true), but the result just won't look "vibrant".
+ // However, there's one unfortunate change of behavior that this pref
+ // has: It stops the window server from applying window masks. We use
+ // a window mask to get rounded corners on menus. So since the mask
+ // doesn't work in "reduce vibrancy" mode, we need to do our own rounded
+ // corner clipping here.
+ [[NSBezierPath bezierPathWithRoundedRect:rect
+ xRadius:aCornerRadiusIfOpaque
+ yRadius:aCornerRadiusIfOpaque] addClip];
+ }
+
+ [fillColor set];
+ NSRectFill(rect);
+
+ [NSGraphicsContext restoreGraphicsState];
+ [NSGraphicsContext setCurrentContext:savedContext];
+}
+
+nsNativeThemeCocoa::MenuBackgroundParams
+nsNativeThemeCocoa::ComputeMenuBackgroundParams(nsIFrame* aFrame,
+ EventStates aEventState)
+{
+ MenuBackgroundParams params;
+ if (VibrancyManager::SystemSupportsVibrancy()) {
+ params.vibrancyColor = Some(VibrancyFillColor(aFrame, eThemeGeometryTypeMenu));
+ } else {
+ params.disabled = IsDisabled(aFrame, aEventState);
+ bool isLeftOfParent = false;
+ params.submenuRightOfParent =
+ IsSubmenu(aFrame, &isLeftOfParent) && !isLeftOfParent;
+ }
+ return params;
+}
+
+void
+nsNativeThemeCocoa::DrawMenuBackground(CGContextRef cgContext,
+ const CGRect& inBoxRect,
+ const MenuBackgroundParams& aParams)
+{
+ if (aParams.vibrancyColor) {
+ DrawVibrancyBackground(cgContext, inBoxRect, *aParams.vibrancyColor, 4);
+ } else {
+ HIThemeMenuDrawInfo mdi;
+ memset(&mdi, 0, sizeof(mdi));
+ mdi.version = 0;
+ mdi.menuType = aParams.disabled ?
+ static_cast<ThemeMenuType>(kThemeMenuTypeInactive) :
+ static_cast<ThemeMenuType>(kThemeMenuTypePopUp);
+
+ if (aParams.submenuRightOfParent) {
+ mdi.menuType = kThemeMenuTypeHierarchical;
+ }
+
+ // The rounded corners draw outside the frame.
+ CGRect deflatedRect =
+ CGRectMake(inBoxRect.origin.x, inBoxRect.origin.y + 4,
+ inBoxRect.size.width, inBoxRect.size.height - 8);
+ HIThemeDrawMenuBackground(&deflatedRect, &mdi, cgContext,
+ HITHEME_ORIENTATION);
+ }
+}
+
static const NSSize kCheckmarkSize = NSMakeSize(11, 11);
static const NSSize kMenuarrowSize = NSMakeSize(9, 10);
static const NSSize kMenuScrollArrowSize = NSMakeSize(10, 8);
static NSString* kCheckmarkImage = @"MenuOnState";
static NSString* kMenuarrowRightImage = @"MenuSubmenu";
static NSString* kMenuarrowLeftImage = @"MenuSubmenuLeft";
static NSString* kMenuDownScrollArrowImage = @"MenuScrollDown";
static NSString* kMenuUpScrollArrowImage = @"MenuScrollUp";
@@ -2324,70 +2427,22 @@ nsNativeThemeCocoa::DrawResizer(CGContex
drawInfo.size = kHIThemeGrowBoxSizeNormal;
RenderTransformedHIThemeControl(cgContext, aRect, RenderResizer, &drawInfo,
IsFrameRTL(aFrame));
NS_OBJC_END_TRY_ABORT_BLOCK;
}
-static Color
-NSColorToColor(NSColor* aColor)
-{
- NSColor* deviceColor = [aColor colorUsingColorSpaceName:NSDeviceRGBColorSpace];
- return Color([deviceColor redComponent],
- [deviceColor greenComponent],
- [deviceColor blueComponent],
- [deviceColor alphaComponent]);
-}
-
-static Color
-VibrancyFillColor(nsIFrame* aFrame, nsITheme::ThemeGeometryType aThemeGeometryType)
-{
- ChildView* childView = ChildViewForFrame(aFrame);
- if (childView) {
- return NSColorToColor([childView vibrancyFillColorForThemeGeometryType:aThemeGeometryType]);
- }
- return Color();
-}
-
static void
DrawVibrancyBackground(CGContextRef cgContext, CGRect inBoxRect,
- nsIFrame* aFrame, nsITheme::ThemeGeometryType aThemeGeometryType,
- int aCornerRadiusIfOpaque = 0)
+ nsIFrame* aFrame, nsITheme::ThemeGeometryType aThemeGeometryType)
{
- ChildView* childView = ChildViewForFrame(aFrame);
- if (childView) {
- NSRect rect = NSRectFromCGRect(inBoxRect);
- NSGraphicsContext* savedContext = [NSGraphicsContext currentContext];
- [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithGraphicsPort:cgContext flipped:YES]];
- [NSGraphicsContext saveGraphicsState];
-
- NSColor* fillColor = [childView vibrancyFillColorForThemeGeometryType:aThemeGeometryType];
- if ([fillColor alphaComponent] == 1.0 && aCornerRadiusIfOpaque > 0) {
- // The fillColor being opaque means that the system-wide pref "reduce
- // transparency" is set. In that scenario, we still go through all the
- // vibrancy rendering paths (VibrancyManager::SystemSupportsVibrancy()
- // will still return true), but the result just won't look "vibrant".
- // However, there's one unfortunate change of behavior that this pref
- // has: It stops the window server from applying window masks. We use
- // a window mask to get rounded corners on menus. So since the mask
- // doesn't work in "reduce vibrancy" mode, we need to do our own rounded
- // corner clipping here.
- [[NSBezierPath bezierPathWithRoundedRect:rect
- xRadius:aCornerRadiusIfOpaque
- yRadius:aCornerRadiusIfOpaque] addClip];
- }
-
- [fillColor set];
- NSRectFill(rect);
-
- [NSGraphicsContext restoreGraphicsState];
- [NSGraphicsContext setCurrentContext:savedContext];
- }
+ DrawVibrancyBackground(cgContext, inBoxRect,
+ VibrancyFillColor(aFrame, aThemeGeometryType), 0);
}
bool
nsNativeThemeCocoa::IsParentScrollbarRolledOver(nsIFrame* aFrame)
{
nsIFrame* scrollbarFrame = GetParentScrollbarFrame(aFrame);
return nsLookAndFeel::UseOverlayScrollbars()
? CheckBooleanAttr(scrollbarFrame, nsGkAtoms::hover)
@@ -2506,36 +2561,18 @@ nsNativeThemeCocoa::DrawWidgetBackground
HIThemeSetFill(kThemeBrushDialogBackgroundActive, NULL, cgContext, HITHEME_ORIENTATION);
CGContextFillRect(cgContext, macRect);
}
}
break;
case NS_THEME_MENUPOPUP:
- if (VibrancyManager::SystemSupportsVibrancy()) {
- 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);
-
- bool isLeftOfParent = false;
- if (IsSubmenu(aFrame, &isLeftOfParent) && !isLeftOfParent) {
- mdi.menuType = kThemeMenuTypeHierarchical;
- }
-
- // The rounded corners draw outside the frame.
- CGRect deflatedRect = CGRectMake(macRect.origin.x, macRect.origin.y + 4,
- macRect.size.width, macRect.size.height - 8);
- HIThemeDrawMenuBackground(&deflatedRect, &mdi, cgContext, HITHEME_ORIENTATION);
- }
+ DrawMenuBackground(cgContext, macRect,
+ ComputeMenuBackgroundParams(aFrame, eventState));
break;
case NS_THEME_MENUARROW: {
bool isRTL = IsFrameRTL(aFrame);
DrawMenuIcon(cgContext, macRect, eventState, aFrame, kMenuarrowSize,
isRTL ? kMenuarrowLeftImage : kMenuarrowRightImage, true);
}
break;