Bug 1045213 - Use vibrancy effect for context menus. r=smichaud

This commit is contained in:
Markus Stange 2015-02-04 17:25:18 -05:00
parent b87e5450c9
commit 22c821bf28
5 changed files with 75 additions and 43 deletions

View File

@ -2796,6 +2796,9 @@ nsDisplayThemedBackground::nsDisplayThemedBackground(nsDisplayListBuilder* aBuil
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:

View File

@ -24,7 +24,8 @@ namespace mozilla {
enum class VibrancyType {
LIGHT,
DARK,
TOOLTIP
TOOLTIP,
MENU
};
/**

View File

@ -162,6 +162,7 @@ AppearanceForVibrancyType(VibrancyType aType)
switch (aType) {
case VibrancyType::LIGHT:
case VibrancyType::TOOLTIP:
case VibrancyType::MENU:
return [NSAppearanceClass performSelector:@selector(appearanceNamed:)
withObject:@"NSAppearanceNameVibrantLight"];
case VibrancyType::DARK:
@ -189,9 +190,9 @@ VibrancyManager::CreateEffectView(VibrancyType aType, NSRect aRect)
NSView* effectView = [[EffectViewClass alloc] initWithFrame:aRect];
[effectView performSelector:@selector(setAppearance:)
withObject:AppearanceForVibrancyType(aType)];
if (aType == VibrancyType::TOOLTIP) {
// Tooltip windows never become active, so we need to tell the vibrancy
// effect to look active regardless of window state.
if (aType == VibrancyType::TOOLTIP || aType == VibrancyType::MENU) {
// Tooltip and menu windows never become active, so we need to tell the
// vibrancy effect to look active regardless of window state.
[effectView setState:NSVisualEffectStateActive];
}
return effectView;

View File

@ -2373,16 +2373,24 @@ nsChildView::UpdateVibrancy(const nsTArray<ThemeGeometry>& aThemeGeometries)
GatherThemeGeometryRegion(aThemeGeometries, NS_THEME_MAC_VIBRANCY_LIGHT);
nsIntRegion vibrantDarkRegion =
GatherThemeGeometryRegion(aThemeGeometries, NS_THEME_MAC_VIBRANCY_DARK);
nsIntRegion menuRegion =
GatherThemeGeometryRegion(aThemeGeometries, NS_THEME_MENUPOPUP).OrWith(
GatherThemeGeometryRegion(aThemeGeometries, NS_THEME_MENUITEM).OrWith(
GatherThemeGeometryRegion(aThemeGeometries, NS_THEME_CHECKMENUITEM)));
nsIntRegion tooltipRegion =
GatherThemeGeometryRegion(aThemeGeometries, NS_THEME_TOOLTIP);
vibrantDarkRegion.SubOut(vibrantLightRegion);
vibrantDarkRegion.SubOut(menuRegion);
vibrantDarkRegion.SubOut(tooltipRegion);
vibrantLightRegion.SubOut(menuRegion);
vibrantLightRegion.SubOut(tooltipRegion);
menuRegion.SubOut(tooltipRegion);
auto& vm = EnsureVibrancyManager();
vm.UpdateVibrantRegion(VibrancyType::LIGHT, vibrantLightRegion);
vm.UpdateVibrantRegion(VibrancyType::TOOLTIP, tooltipRegion);
vm.UpdateVibrantRegion(VibrancyType::MENU, menuRegion);
vm.UpdateVibrantRegion(VibrancyType::DARK, vibrantDarkRegion);
}
@ -2404,6 +2412,10 @@ WidgetTypeToVibrancyType(uint8_t aWidgetType)
return VibrancyType::DARK;
case NS_THEME_TOOLTIP:
return VibrancyType::TOOLTIP;
case NS_THEME_MENUPOPUP:
case NS_THEME_MENUITEM:
case NS_THEME_CHECKMENUITEM:
return VibrancyType::MENU;
default:
MOZ_CRASH();
}

View File

@ -2256,16 +2256,24 @@ nsNativeThemeCocoa::DrawResizer(CGContextRef cgContext, const HIRect& aRect,
static void
DrawVibrancyBackground(CGContextRef cgContext, CGRect inBoxRect,
nsIFrame* aFrame, uint8_t aWidgetType)
nsIFrame* aFrame, uint8_t aWidgetType,
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];
NSRectFill(NSRectFromCGRect(inBoxRect));
NSRectFill(rect);
[NSGraphicsContext restoreGraphicsState];
[NSGraphicsContext setCurrentContext:savedContext];
}
}
@ -2381,24 +2389,27 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsRenderingContext* aContext,
}
break;
case NS_THEME_MENUPOPUP: {
HIThemeMenuDrawInfo mdi;
memset(&mdi, 0, sizeof(mdi));
mdi.version = 0;
mdi.menuType = IsDisabled(aFrame, eventState) ?
static_cast<ThemeMenuType>(kThemeMenuTypeInactive) :
static_cast<ThemeMenuType>(kThemeMenuTypePopUp);
case NS_THEME_MENUPOPUP:
if (VibrancyManager::SystemSupportsVibrancy()) {
DrawVibrancyBackground(cgContext, macRect, aFrame, aWidgetType, 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;
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);
}
// 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);
}
break;
case NS_THEME_MENUARROW: {
@ -2410,29 +2421,27 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsRenderingContext* aContext,
case NS_THEME_MENUITEM:
case NS_THEME_CHECKMENUITEM: {
SurfaceFormat format = thebesCtx->GetDrawTarget()->GetFormat();
bool isTransparent = (format == SurfaceFormat::R8G8B8A8) ||
(format == SurfaceFormat::B8G8R8A8);
if (isTransparent) {
// Clear the background to get correct transparency.
CGContextClearRect(cgContext, macRect);
bool isDisabled = IsDisabled(aFrame, eventState);
bool isSelected = !isDisabled && CheckBooleanAttr(aFrame, nsGkAtoms::menuactive);
if (!isSelected && VibrancyManager::SystemSupportsVibrancy()) {
DrawVibrancyBackground(cgContext, macRect, aFrame, aWidgetType);
} 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) :
isSelected ?
static_cast<ThemeMenuState>(kThemeMenuSelected) :
static_cast<ThemeMenuState>(kThemeMenuActive));
// XXX pass in the menu rect instead of always using the item rect
HIRect ignored;
HIThemeDrawMenuItem(&macRect, &macRect, &drawInfo, cgContext, HITHEME_ORIENTATION, &ignored);
}
// 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(aFrame, eventState) ?
static_cast<ThemeMenuState>(kThemeMenuDisabled) :
CheckBooleanAttr(aFrame, nsGkAtoms::menuactive) ?
static_cast<ThemeMenuState>(kThemeMenuSelected) :
static_cast<ThemeMenuState>(kThemeMenuActive));
// XXX pass in the menu rect instead of always using the item rect
HIRect ignored;
HIThemeDrawMenuItem(&macRect, &macRect, &drawInfo, cgContext, HITHEME_ORIENTATION, &ignored);
if (aWidgetType == NS_THEME_CHECKMENUITEM) {
DrawMenuIcon(cgContext, macRect, eventState, aFrame, kCheckmarkSize, kCheckmarkImage, false);
}
@ -3751,6 +3760,9 @@ nsNativeThemeCocoa::NeedToClearBackgroundBehindWidget(uint8_t aWidgetType)
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;
default:
return false;
@ -3775,6 +3787,9 @@ nsNativeThemeCocoa::WidgetProvidesFontSmoothingBackgroundColor(nsIFrame* aFrame,
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:
{
ChildView* childView = ChildViewForFrame(aFrame);
if (childView) {