mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 13:21:05 +00:00
Bug 1055018 - Draw CoreUI widgets through -[NSAppearance _drawInRect:context:options:] on 10.10 in order to pick up the 10.10 look. r=smichaud
This commit is contained in:
parent
11375e15fd
commit
318cce364d
@ -20,9 +20,6 @@ class nsChildView;
|
||||
class nsMenuBarX;
|
||||
@class ChildView;
|
||||
|
||||
// Value copied from BITMAP_MAX_AREA, used in nsNativeThemeCocoa.mm
|
||||
#define CUIDRAW_MAX_AREA 500000
|
||||
|
||||
// If we are using an SDK older than 10.7, define bits we need that are missing
|
||||
// from it.
|
||||
#if !defined(MAC_OS_X_VERSION_10_7) || \
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "nsMenuUtilsX.h"
|
||||
#include "nsStyleConsts.h"
|
||||
#include "nsNativeThemeColors.h"
|
||||
#include "nsNativeThemeCocoa.h"
|
||||
#include "nsChildView.h"
|
||||
#include "nsCocoaFeatures.h"
|
||||
#include "nsIScreenManager.h"
|
||||
@ -3304,19 +3305,7 @@ static void
|
||||
DrawNativeTitlebar(CGContextRef aContext, CGRect aTitlebarRect,
|
||||
CGFloat aUnifiedToolbarHeight, BOOL aIsMain)
|
||||
{
|
||||
if (aTitlebarRect.size.width * aTitlebarRect.size.height > CUIDRAW_MAX_AREA) {
|
||||
return;
|
||||
}
|
||||
|
||||
CUIDraw([NSWindow coreUIRenderer], aTitlebarRect, aContext,
|
||||
(CFDictionaryRef)[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
@"kCUIWidgetWindowFrame", @"widget",
|
||||
@"regularwin", @"windowtype",
|
||||
(aIsMain ? @"normal" : @"inactive"), @"state",
|
||||
[NSNumber numberWithDouble:aUnifiedToolbarHeight], @"kCUIWindowFrameUnifiedTitleBarHeightKey",
|
||||
[NSNumber numberWithBool:YES], @"kCUIWindowFrameDrawTitleSeparatorKey",
|
||||
nil],
|
||||
nil);
|
||||
nsNativeThemeCocoa::DrawNativeTitlebar(aContext, aTitlebarRect, aUnifiedToolbarHeight, aIsMain, NO);
|
||||
|
||||
if (nsCocoaFeatures::OnLionOrLater()) {
|
||||
// On Lion the call to CUIDraw doesn't draw the top pixel strip at some
|
||||
|
@ -68,6 +68,9 @@ public:
|
||||
bool inIsIndeterminate, bool inIsHorizontal,
|
||||
double inValue, double inMaxValue, nsIFrame* aFrame);
|
||||
|
||||
static void DrawNativeTitlebar(CGContextRef aContext, CGRect aTitlebarRect,
|
||||
CGFloat aUnifiedHeight, BOOL aIsMain, BOOL aIsFlipped);
|
||||
|
||||
protected:
|
||||
virtual ~nsNativeThemeCocoa();
|
||||
|
||||
@ -124,8 +127,6 @@ protected:
|
||||
NSWindow* aWindow);
|
||||
void DrawStatusBar(CGContextRef cgContext, const HIRect& inBoxRect,
|
||||
nsIFrame *aFrame);
|
||||
void DrawNativeTitlebar(CGContextRef aContext, CGRect aTitlebarRect,
|
||||
CGFloat aUnifiedHeight, BOOL aIsMain);
|
||||
void DrawResizer(CGContextRef cgContext, const HIRect& aRect, nsIFrame *aFrame);
|
||||
|
||||
// Scrollbars
|
||||
|
@ -44,6 +44,8 @@ using mozilla::dom::HTMLMeterElement;
|
||||
// private Quartz routines needed here
|
||||
extern "C" {
|
||||
CG_EXTERN void CGContextSetCTM(CGContextRef, CGAffineTransform);
|
||||
typedef CFTypeRef CUIRendererRef;
|
||||
void CUIDraw(CUIRendererRef r, CGRect rect, CGContextRef ctx, CFDictionaryRef options, CFDictionaryRef* result);
|
||||
}
|
||||
|
||||
// Workaround for NSCell control tint drawing
|
||||
@ -822,6 +824,60 @@ static void DrawCellWithSnapping(NSCell *cell,
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
@interface NSWindow(CoreUIRendererPrivate)
|
||||
+ (CUIRendererRef)coreUIRenderer;
|
||||
@end
|
||||
|
||||
static void
|
||||
RenderWithCoreUILegacy(CGRect aRect, CGContextRef cgContext, NSDictionary* aOptions)
|
||||
{
|
||||
if (aRect.size.width * aRect.size.height <= BITMAP_MAX_AREA) {
|
||||
CUIRendererRef renderer = [NSWindow respondsToSelector:@selector(coreUIRenderer)]
|
||||
? [NSWindow coreUIRenderer] : nil;
|
||||
CUIDraw(renderer, aRect, cgContext, (CFDictionaryRef)aOptions, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static id
|
||||
GetAquaAppearance()
|
||||
{
|
||||
// We only need NSAppearance on 10.10 and up.
|
||||
if (nsCocoaFeatures::OnYosemiteOrLater()) {
|
||||
Class NSAppearanceClass = NSClassFromString(@"NSAppearance");
|
||||
if (NSAppearanceClass &&
|
||||
[NSAppearanceClass respondsToSelector:@selector(appearanceNamed:)]) {
|
||||
return [NSAppearanceClass performSelector:@selector(appearanceNamed:)
|
||||
withObject:@"NSAppearanceNameAqua"];
|
||||
}
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
@interface NSObject(NSAppearanceCoreUIRendering)
|
||||
- (void)_drawInRect:(CGRect)rect context:(CGContextRef)cgContext options:(id)options;
|
||||
@end
|
||||
|
||||
static void
|
||||
RenderWithCoreUI(CGRect aRect, CGContextRef cgContext, NSDictionary* aOptions)
|
||||
{
|
||||
static id appearance = GetAquaAppearance();
|
||||
|
||||
if (aRect.size.width * aRect.size.height > BITMAP_MAX_AREA) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (appearance && [appearance respondsToSelector:@selector(_drawInRect:context:options:)]) {
|
||||
// Render through NSAppearance on Mac OS 10.10 and up. This will call
|
||||
// CUIDraw with a CoreUI renderer that will give us the correct 10.10
|
||||
// style. Calling CUIDraw directly with [NSWindow coreUIRenderer] still
|
||||
// renders 10.9-style widgets on 10.10.
|
||||
[appearance _drawInRect:aRect context:cgContext options:aOptions];
|
||||
} else {
|
||||
// 10.9 and below
|
||||
RenderWithCoreUILegacy(aRect, cgContext, aOptions);
|
||||
}
|
||||
}
|
||||
|
||||
static float VerticalAlignFactor(nsIFrame *aFrame)
|
||||
{
|
||||
if (!aFrame)
|
||||
@ -1014,9 +1070,9 @@ nsNativeThemeCocoa::DrawMenuIcon(CGContextRef cgContext, const CGRect& aRect,
|
||||
[values insertObject:[NSNumber numberWithBool:YES] atIndex:1];
|
||||
}
|
||||
|
||||
CUIDraw([NSWindow coreUIRenderer], drawRect, cgContext,
|
||||
(CFDictionaryRef)[NSDictionary dictionaryWithObjects:values
|
||||
forKeys:keys], nil);
|
||||
RenderWithCoreUI(drawRect, cgContext,
|
||||
[NSDictionary dictionaryWithObjects:values
|
||||
forKeys:keys]);
|
||||
|
||||
#if DRAW_IN_FRAME_DEBUG
|
||||
CGContextSetRGBFillColor(cgContext, 0.0, 0.0, 0.5, 0.25);
|
||||
@ -1840,16 +1896,13 @@ nsNativeThemeCocoa::DrawSegment(CGContextRef cgContext, const HIRect& inBoxRect,
|
||||
nsIFrame* left = GetAdjacentSiblingFrameWithSameAppearance(aFrame, isRTL);
|
||||
nsIFrame* right = GetAdjacentSiblingFrameWithSameAppearance(aFrame, !isRTL);
|
||||
CGRect drawRect = SeparatorAdjustedRect(inBoxRect, left, aFrame, right);
|
||||
if (drawRect.size.width * drawRect.size.height > CUIDRAW_MAX_AREA) {
|
||||
return;
|
||||
}
|
||||
BOOL drawLeftSeparator = SeparatorResponsibility(left, aFrame) == aFrame;
|
||||
BOOL drawRightSeparator = SeparatorResponsibility(aFrame, right) == aFrame;
|
||||
NSControlSize controlSize = FindControlSize(drawRect.size.height, aSettings.heights, 4.0f);
|
||||
|
||||
CUIDraw([NSWindow coreUIRenderer], drawRect, cgContext,
|
||||
(CFDictionaryRef)[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
RenderWithCoreUI(drawRect, cgContext, [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
aSettings.widgetName, @"widget",
|
||||
(isActive ? @"kCUIPresentationStateActiveKey" : @"kCUIPresentationStateInactive"), @"kCUIPresentationStateKey",
|
||||
ToolbarButtonPosition(!left, !right), @"kCUIPositionKey",
|
||||
[NSNumber numberWithBool:drawLeftSeparator], @"kCUISegmentLeadingSeparatorKey",
|
||||
[NSNumber numberWithBool:drawRightSeparator], @"kCUISegmentTrailingSeparatorKey",
|
||||
@ -1859,8 +1912,7 @@ nsNativeThemeCocoa::DrawSegment(CGContextRef cgContext, const HIRect& inBoxRect,
|
||||
CUIControlSizeForCocoaSize(controlSize), @"size",
|
||||
[NSNumber numberWithBool:YES], @"is.flipped",
|
||||
@"up", @"direction",
|
||||
nil],
|
||||
nil);
|
||||
nil]);
|
||||
}
|
||||
|
||||
static inline UInt8
|
||||
@ -2035,28 +2087,25 @@ ToolbarCanBeUnified(CGContextRef cgContext, const HIRect& inBoxRect, NSWindow* a
|
||||
// So we draw square corners.
|
||||
static void
|
||||
DrawNativeTitlebarToolbarWithSquareCorners(CGContextRef aContext, const CGRect& aRect,
|
||||
CGFloat aUnifiedHeight, BOOL aIsMain)
|
||||
CGFloat aUnifiedHeight, BOOL aIsMain, BOOL aIsFlipped)
|
||||
{
|
||||
// We extend the draw rect horizontally and clip away the rounded corners.
|
||||
const CGFloat extendHorizontal = 10;
|
||||
CGRect drawRect = CGRectInset(aRect, -extendHorizontal, 0);
|
||||
if (drawRect.size.width * drawRect.size.height <= CUIDRAW_MAX_AREA) {
|
||||
CGContextSaveGState(aContext);
|
||||
CGContextClipToRect(aContext, aRect);
|
||||
CGContextSaveGState(aContext);
|
||||
CGContextClipToRect(aContext, aRect);
|
||||
|
||||
CUIDraw([NSWindow coreUIRenderer], drawRect, aContext,
|
||||
(CFDictionaryRef)[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
@"kCUIWidgetWindowFrame", @"widget",
|
||||
@"regularwin", @"windowtype",
|
||||
(aIsMain ? @"normal" : @"inactive"), @"state",
|
||||
[NSNumber numberWithDouble:aUnifiedHeight], @"kCUIWindowFrameUnifiedTitleBarHeightKey",
|
||||
[NSNumber numberWithBool:YES], @"kCUIWindowFrameDrawTitleSeparatorKey",
|
||||
[NSNumber numberWithBool:YES], @"is.flipped",
|
||||
nil],
|
||||
nil);
|
||||
RenderWithCoreUI(drawRect, aContext,
|
||||
[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
@"kCUIWidgetWindowFrame", @"widget",
|
||||
@"regularwin", @"windowtype",
|
||||
(aIsMain ? @"normal" : @"inactive"), @"state",
|
||||
[NSNumber numberWithDouble:aUnifiedHeight], @"kCUIWindowFrameUnifiedTitleBarHeightKey",
|
||||
[NSNumber numberWithBool:YES], @"kCUIWindowFrameDrawTitleSeparatorKey",
|
||||
[NSNumber numberWithBool:aIsFlipped], @"is.flipped",
|
||||
nil]);
|
||||
|
||||
CGContextRestoreGState(aContext);
|
||||
}
|
||||
CGContextRestoreGState(aContext);
|
||||
}
|
||||
|
||||
void
|
||||
@ -2074,7 +2123,7 @@ nsNativeThemeCocoa::DrawUnifiedToolbar(CGContextRef cgContext, const HIRect& inB
|
||||
CGFloat titlebarHeight = unifiedHeight - inBoxRect.size.height;
|
||||
CGRect drawRect = CGRectMake(inBoxRect.origin.x, inBoxRect.origin.y - titlebarHeight,
|
||||
inBoxRect.size.width, inBoxRect.size.height + titlebarHeight);
|
||||
DrawNativeTitlebarToolbarWithSquareCorners(cgContext, drawRect, unifiedHeight, isMain);
|
||||
DrawNativeTitlebarToolbarWithSquareCorners(cgContext, drawRect, unifiedHeight, isMain, YES);
|
||||
|
||||
CGContextRestoreGState(cgContext);
|
||||
|
||||
@ -2100,18 +2149,15 @@ nsNativeThemeCocoa::DrawStatusBar(CGContextRef cgContext, const HIRect& inBoxRec
|
||||
const int extendUpwards = 40;
|
||||
drawRect.origin.y -= extendUpwards;
|
||||
drawRect.size.height += extendUpwards;
|
||||
if (drawRect.size.width * drawRect.size.height <= CUIDRAW_MAX_AREA) {
|
||||
CUIDraw([NSWindow coreUIRenderer], drawRect, cgContext,
|
||||
(CFDictionaryRef)[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
@"kCUIWidgetWindowFrame", @"widget",
|
||||
@"regularwin", @"windowtype",
|
||||
(IsActive(aFrame, YES) ? @"normal" : @"inactive"), @"state",
|
||||
[NSNumber numberWithInt:inBoxRect.size.height], @"kCUIWindowFrameBottomBarHeightKey",
|
||||
[NSNumber numberWithBool:YES], @"kCUIWindowFrameDrawBottomBarSeparatorKey",
|
||||
[NSNumber numberWithBool:YES], @"is.flipped",
|
||||
nil],
|
||||
nil);
|
||||
}
|
||||
RenderWithCoreUI(drawRect, cgContext,
|
||||
[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
@"kCUIWidgetWindowFrame", @"widget",
|
||||
@"regularwin", @"windowtype",
|
||||
(IsActive(aFrame, YES) ? @"normal" : @"inactive"), @"state",
|
||||
[NSNumber numberWithInt:inBoxRect.size.height], @"kCUIWindowFrameBottomBarHeightKey",
|
||||
[NSNumber numberWithBool:YES], @"kCUIWindowFrameDrawBottomBarSeparatorKey",
|
||||
[NSNumber numberWithBool:YES], @"is.flipped",
|
||||
nil]);
|
||||
|
||||
CGContextRestoreGState(cgContext);
|
||||
|
||||
@ -2120,10 +2166,10 @@ nsNativeThemeCocoa::DrawStatusBar(CGContextRef cgContext, const HIRect& inBoxRec
|
||||
|
||||
void
|
||||
nsNativeThemeCocoa::DrawNativeTitlebar(CGContextRef aContext, CGRect aTitlebarRect,
|
||||
CGFloat aUnifiedHeight, BOOL aIsMain)
|
||||
CGFloat aUnifiedHeight, BOOL aIsMain, BOOL aIsFlipped)
|
||||
{
|
||||
CGFloat unifiedHeight = std::max(aUnifiedHeight, aTitlebarRect.size.height);
|
||||
DrawNativeTitlebarToolbarWithSquareCorners(aContext, aTitlebarRect, unifiedHeight, aIsMain);
|
||||
DrawNativeTitlebarToolbarWithSquareCorners(aContext, aTitlebarRect, unifiedHeight, aIsMain, aIsFlipped);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2447,7 +2493,7 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsRenderingContext* aContext,
|
||||
BOOL isMain = [win isMainWindow];
|
||||
float unifiedToolbarHeight = [win isKindOfClass:[ToolbarWindow class]] ?
|
||||
[(ToolbarWindow*)win unifiedToolbarHeight] : macRect.size.height;
|
||||
DrawNativeTitlebar(cgContext, macRect, unifiedToolbarHeight, isMain);
|
||||
DrawNativeTitlebar(cgContext, macRect, unifiedToolbarHeight, isMain, YES);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -2633,8 +2679,10 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsRenderingContext* aContext,
|
||||
}
|
||||
}
|
||||
const BOOL isOnTopOfDarkBackground = IsDarkBackground(aFrame);
|
||||
CUIDraw([NSWindow coreUIRenderer], macRect, cgContext,
|
||||
(CFDictionaryRef)[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
// Scrollbar thumbs have a too high minimum width when rendered through
|
||||
// NSAppearance on 10.10, so we call RenderWithCoreUILegacy here.
|
||||
RenderWithCoreUILegacy(macRect, cgContext,
|
||||
[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
(isOverlay ? @"kCUIWidgetOverlayScrollBar" : @"scrollbar"), @"widget",
|
||||
@"regular", @"size",
|
||||
(isRolledOver ? @"rollover" : @"normal"), @"state",
|
||||
@ -2643,8 +2691,7 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsRenderingContext* aContext,
|
||||
[NSNumber numberWithBool:YES], @"indiconly",
|
||||
[NSNumber numberWithBool:YES], @"kCUIThumbProportionKey",
|
||||
[NSNumber numberWithBool:YES], @"is.flipped",
|
||||
nil],
|
||||
nil);
|
||||
nil]);
|
||||
}
|
||||
break;
|
||||
case NS_THEME_SCROLLBAR_BUTTON_UP:
|
||||
@ -2682,8 +2729,8 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsRenderingContext* aContext,
|
||||
}
|
||||
}
|
||||
const BOOL isOnTopOfDarkBackground = IsDarkBackground(aFrame);
|
||||
CUIDraw([NSWindow coreUIRenderer], macRect, cgContext,
|
||||
(CFDictionaryRef)[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
RenderWithCoreUILegacy(macRect, cgContext,
|
||||
[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
(isOverlay ? @"kCUIWidgetOverlayScrollBar" : @"scrollbar"), @"widget",
|
||||
@"regular", @"size",
|
||||
(isHorizontal ? @"kCUIOrientHorizontal" : @"kCUIOrientVertical"), @"kCUIOrientationKey",
|
||||
@ -2691,8 +2738,7 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsRenderingContext* aContext,
|
||||
[NSNumber numberWithBool:YES], @"noindicator",
|
||||
[NSNumber numberWithBool:YES], @"kCUIThumbProportionKey",
|
||||
[NSNumber numberWithBool:YES], @"is.flipped",
|
||||
nil],
|
||||
nil);
|
||||
nil]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -9,15 +9,6 @@
|
||||
#include "nsCocoaFeatures.h"
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
extern "C" {
|
||||
typedef CFTypeRef CUIRendererRef;
|
||||
void CUIDraw(CUIRendererRef r, CGRect rect, CGContextRef ctx, CFDictionaryRef options, CFDictionaryRef* result);
|
||||
}
|
||||
|
||||
@interface NSWindow(CoreUIRendererPrivate)
|
||||
+ (CUIRendererRef)coreUIRenderer;
|
||||
@end
|
||||
|
||||
enum ColorName {
|
||||
toolbarTopBorderGrey,
|
||||
toolbarFillGrey,
|
||||
|
Loading…
Reference in New Issue
Block a user