--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -3894,26 +3894,20 @@ nsContentUtils::TriggerLink(nsIContent *
handler->OnLinkClick(aContent, aLinkURI, aTargetSpec.get());
}
}
/* static */
nsIWidget*
nsContentUtils::GetTopLevelWidget(nsIWidget* aWidget)
{
- if (!aWidget) {
+ if (!aWidget)
return nsnull;
- }
-
- nsIWidget* currWidget = aWidget;
- nsIWidget* parentWidget;
- while ((parentWidget = currWidget->GetParent()) != nsnull) {
- currWidget = parentWidget;
- }
- return currWidget;
+
+ return aWidget->GetTopLevelWidget();
}
/* static */
const nsDependentString
nsContentUtils::GetLocalizedEllipsis()
{
static PRUnichar sBuf[4] = { 0, 0, 0, 0 };
if (!sBuf[0]) {
--- a/gfx/public/nsThemeConstants.h
+++ b/gfx/public/nsThemeConstants.h
@@ -230,10 +230,13 @@
// For text on non-iconic menuitems only
#define NS_THEME_MENUITEMTEXT 220
// Vista Rebars
#define NS_THEME_WIN_COMMUNICATIONS_TOOLBOX 221
#define NS_THEME_WIN_MEDIA_TOOLBOX 222
#define NS_THEME_WIN_BROWSER_TAB_BAR_TOOLBOX 223
+// Unified toolbar on the Mac
+#define NS_THEME_MOZ_MAC_UNIFIED_TOOLBAR 224
+
// Vista glass
#define NS_THEME_WIN_GLASS 230
--- a/layout/style/nsCSSKeywordList.h
+++ b/layout/style/nsCSSKeywordList.h
@@ -574,16 +574,17 @@ CSS_KEY(checkbox-label, checkboxlabel)
CSS_KEY(radio-label, radiolabel)
CSS_KEY(button-focus, buttonfocus)
CSS_KEY(-moz-win-media-toolbox, _moz_win_media_toolbox)
CSS_KEY(-moz-win-communications-toolbox, _moz_win_communications_toolbox)
CSS_KEY(-moz-win-browsertabbar-toolbox, _moz_win_browsertabbar_toolbox)
CSS_KEY(-moz-win-mediatext, _moz_win_mediatext)
CSS_KEY(-moz-win-communicationstext, _moz_win_communicationstext)
CSS_KEY(-moz-win-glass, _moz_win_glass)
+CSS_KEY(-moz-mac-unified-toolbar, _moz_mac_unified_toolbar)
#ifdef MOZ_SVG
//CSS_KEY(all, all)
CSS_KEY(alphabetic, alphabetic)
//CSS_KEY(auto, auto)
CSS_KEY(bevel, bevel)
CSS_KEY(butt, butt)
CSS_KEY(central, central)
--- a/layout/style/nsCSSProps.cpp
+++ b/layout/style/nsCSSProps.cpp
@@ -323,16 +323,17 @@ const PRInt32 nsCSSProps::kAppearanceKTa
eCSSKeyword_menuseparator, NS_THEME_MENUSEPARATOR,
eCSSKeyword_menuarrow, NS_THEME_MENUARROW,
eCSSKeyword_menuimage, NS_THEME_MENUIMAGE,
eCSSKeyword_menuitemtext, NS_THEME_MENUITEMTEXT,
eCSSKeyword__moz_win_media_toolbox, NS_THEME_WIN_MEDIA_TOOLBOX,
eCSSKeyword__moz_win_communications_toolbox, NS_THEME_WIN_COMMUNICATIONS_TOOLBOX,
eCSSKeyword__moz_win_browsertabbar_toolbox, NS_THEME_WIN_BROWSER_TAB_BAR_TOOLBOX,
eCSSKeyword__moz_win_glass, NS_THEME_WIN_GLASS,
+ eCSSKeyword__moz_mac_unified_toolbar, NS_THEME_MOZ_MAC_UNIFIED_TOOLBAR,
eCSSKeyword_UNKNOWN,-1
};
// Keyword id tables for variant/enum parsing
const PRInt32 nsCSSProps::kAzimuthKTable[] = {
eCSSKeyword_left_side, NS_STYLE_AZIMUTH_LEFT_SIDE,
eCSSKeyword_far_left, NS_STYLE_AZIMUTH_FAR_LEFT,
eCSSKeyword_left, NS_STYLE_AZIMUTH_LEFT,
--- a/widget/public/nsIWidget.h
+++ b/widget/public/nsIWidget.h
@@ -88,20 +88,20 @@ typedef nsEventStatus (*PR_CALLBACK EVEN
#define NS_NATIVE_PLUGIN_PORT 8
#define NS_NATIVE_SCREEN 9
#define NS_NATIVE_SHELLWIDGET 10 // Get the shell GtkWidget
#ifdef XP_MACOSX
#define NS_NATIVE_PLUGIN_PORT_QD 100
#define NS_NATIVE_PLUGIN_PORT_CG 101
#endif
-// AE42543F-BF61-4164-96BA-AF8F4EDCEEAD
+// 0e64821f-00a2-4adc-ac3b-3439d61f4491
#define NS_IWIDGET_IID \
-{ 0xae42543f, 0xbf61, 0x4164, \
- { 0x96, 0xba, 0xaf, 0x8f, 0x4e, 0xdc, 0xee, 0xad } }
+{ 0x0e64821f, 0x00a2, 0x4adc, \
+ { 0xac, 0x3b, 0x34, 0x39, 0xd6, 0x1f, 0x44, 0x91 } }
// Hide the native window systems real window type so as to avoid
// including native window system types and APIs. This is necessary
// to ensure cross-platform code.
typedef void* nsNativeWidget;
/**
* Border styles
@@ -379,16 +379,25 @@ class nsIWidget : public nsISupports {
* top level window
*
* @return the parent widget or nsnull if it does not have a parent
*
*/
virtual nsIWidget* GetParent(void) = 0;
/**
+ * Return the top level Widget of this Widget
+ *
+ * @param aLevelsUp returns the number of GetParent() calls that
+ * were necessary to get to the top level widget
+ * @return the top level widget
+ */
+ virtual nsIWidget* GetTopLevelWidget(PRInt32* aLevelsUp = NULL) = 0;
+
+ /**
* Return the top (non-sheet) parent of this Widget if it's a sheet,
* or nsnull if this isn't a sheet (or some other error occurred).
* Sheets are only supported on some platforms (currently only OS X).
*
* @return the top (non-sheet) parent widget or nsnull
*
*/
virtual nsIWidget* GetSheetWindowParent(void) = 0;
--- a/widget/src/cocoa/nsChildView.h
+++ b/widget/src/cocoa/nsChildView.h
@@ -270,17 +270,16 @@ public:
nsNativeWidget aNativeParent = nsnull);
NS_IMETHOD Destroy();
NS_IMETHOD Show(PRBool aState);
NS_IMETHOD IsVisible(PRBool& outState);
virtual nsIWidget* GetParent(void);
- nsIWidget* GetTopLevelWidget();
NS_IMETHOD ModalEventFilter(PRBool aRealEvent, void *aEvent,
PRBool *aForWindow);
NS_IMETHOD ConstrainPosition(PRBool aAllowSlop,
PRInt32 *aX, PRInt32 *aY);
NS_IMETHOD Move(PRInt32 aX, PRInt32 aY);
NS_IMETHOD Resize(PRInt32 aWidth,PRInt32 aHeight, PRBool aRepaint);
--- a/widget/src/cocoa/nsChildView.mm
+++ b/widget/src/cocoa/nsChildView.mm
@@ -872,24 +872,16 @@ NS_IMETHODIMP nsChildView::Show(PRBool a
nsIWidget*
nsChildView::GetParent(void)
{
return mParentWidget;
}
-nsIWidget*
-nsChildView::GetTopLevelWidget()
-{
- nsIWidget* current = this;
- for (nsIWidget* parent = GetParent(); parent ; parent = parent->GetParent())
- current = parent;
- return current;
-}
NS_IMETHODIMP nsChildView::ModalEventFilter(PRBool aRealEvent, void *aEvent,
PRBool *aForWindow)
{
if (aForWindow)
*aForWindow = PR_FALSE;
return NS_ERROR_NOT_IMPLEMENTED;
}
@@ -2716,24 +2708,34 @@ NSEvent* gLastDragEvent = nil;
// It will set the port back to this port on destruction.
::SetPort(NULL); // todo: only do if a Quickdraw plugin is present in the hierarchy!
[super lockFocus];
NS_OBJC_END_TRY_ABORT_BLOCK;
}
+static BOOL IsPaintingSuppressed(nsIWidget* aWidget)
+{
+ nsIWidget* topLevelWidget = aWidget->GetTopLevelWidget();
+ NSWindow* win = (NSWindow*)topLevelWidget->GetNativeData(NS_NATIVE_WINDOW);
+ return ([win isKindOfClass:[ToolbarWindow class]] &&
+ [(ToolbarWindow*)win isPaintingSuppressed]);
+}
+
+
// The display system has told us that a portion of our view is dirty. Tell
// gecko to paint it
- (void)drawRect:(NSRect)aRect
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
PRBool isVisible;
- if (!mGeckoChild || NS_FAILED(mGeckoChild->IsVisible(isVisible)) || !isVisible)
+ if (!mGeckoChild || NS_FAILED(mGeckoChild->IsVisible(isVisible)) ||
+ !isVisible || IsPaintingSuppressed(mGeckoChild))
return;
CGContextRef cgContext = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
nsRect geckoBounds;
mGeckoChild->GetBounds(geckoBounds);
NSRect bounds = [self bounds];
--- a/widget/src/cocoa/nsCocoaWindow.h
+++ b/widget/src/cocoa/nsCocoaWindow.h
@@ -113,53 +113,90 @@ typedef struct _nsCocoaWindowList {
- (void)windowDidResize:(NSNotification*)aNotification;
- (void)sendFocusEvent:(PRUint32)eventType;
- (nsCocoaWindow*)geckoWidget;
- (PRBool)toplevelActiveState;
- (void)sendToplevelActivateEvents;
- (void)sendToplevelDeactivateEvents;
@end
+// These are the start and end greys for the unified titlebar and toolbar gradient.
+static const float sLeopardHeaderStartGrey = 197/255.0f;
+static const float sLeopardHeaderEndGrey = 150/255.0f;
+static const float sLeopardHeaderBackgroundStartGrey = 233/255.0f;
+static const float sLeopardHeaderBackgroundEndGrey = 207/255.0f;
+
+// This is the grey for the border at the bottom of the titlebar / toolbar.
+static const float sLeopardTitlebarBorderGrey = 64/255.0f;
+static const float sLeopardTitlebarBackgroundBorderGrey = 135/255.0f;
+
+struct UnifiedGradientInfo {
+ float titlebarHeight;
+ float toolbarHeight;
+ BOOL windowIsMain;
+ BOOL drawTitlebar; // NO for toolbar, YES for titlebar
+};
+
+// Callback used by the default titlebar and toolbar shading.
+// *aIn == 0 at the top of the titlebar/toolbar, *aIn == 1 at the bottom
+static void unifiedShading(void* aInfo, const float* aIn, float* aOut)
+{
+ UnifiedGradientInfo* info = (UnifiedGradientInfo*)aInfo;
+ // The gradient percentage at the bottom of the titlebar / top of the toolbar
+ float start = info->titlebarHeight / (info->titlebarHeight + info->toolbarHeight - 1);
+ const float startGrey = info->windowIsMain ? sLeopardHeaderStartGrey : sLeopardHeaderBackgroundStartGrey;
+ const float endGrey = info->windowIsMain ? sLeopardHeaderEndGrey : sLeopardHeaderBackgroundEndGrey;
+ // *aIn is the gradient percentage of the titlebar or toolbar gradient,
+ // a is the gradient percentage of the whole unified gradient.
+ float a = info->drawTitlebar ? *aIn * start : start + *aIn * (1 - start);
+ float result = (1.0f - a) * startGrey + a * endGrey;
+ aOut[0] = result;
+ aOut[1] = result;
+ aOut[2] = result;
+ aOut[3] = 1.0f;
+}
// NSColor subclass that allows us to draw separate colors both in the titlebar
// and for background of the window.
@interface TitlebarAndBackgroundColor : NSColor
{
NSColor *mActiveTitlebarColor;
NSColor *mInactiveTitlebarColor;
NSColor *mBackgroundColor;
NSWindow *mWindow; // [WEAK] (we are owned by the window)
- float mTitlebarHeight;
}
- (id)initWithActiveTitlebarColor:(NSColor*)aActiveTitlebarColor
inactiveTitlebarColor:(NSColor*)aInactiveTitlebarColor
backgroundColor:(NSColor*)aBackgroundColor
forWindow:(NSWindow*)aWindow;
// Pass nil here to get the default appearance.
- (void)setTitlebarColor:(NSColor*)aColor forActiveWindow:(BOOL)aActive;
- (NSColor*)activeTitlebarColor;
- (NSColor*)inactiveTitlebarColor;
- (void)setBackgroundColor:(NSColor*)aColor;
- (NSColor*)backgroundColor;
- (NSWindow*)window;
-- (float)titlebarHeight;
@end
// NSWindow subclass for handling windows with toolbars.
@interface ToolbarWindow : NSWindow
{
TitlebarAndBackgroundColor *mColor;
+ float mUnifiedToolbarHeight;
+ BOOL mSuppressPainting;
}
- (void)setTitlebarColor:(NSColor*)aColor forActiveWindow:(BOOL)aActive;
-- (NSColor*)activeTitlebarColor;
-- (NSColor*)inactiveTitlebarColor;
+- (void)setUnifiedToolbarHeight:(float)aToolbarHeight;
+- (float)unifiedToolbarHeight;
+- (float)titlebarHeight;
+- (BOOL)isPaintingSuppressed;
// This method is also available on NSWindows (via a category), and is the
// preferred way to check the background color of a window.
- (NSColor*)windowBackgroundColor;
@end
class nsCocoaWindow : public nsBaseWidget, public nsPIWidgetCocoa
{
private:
--- a/widget/src/cocoa/nsCocoaWindow.mm
+++ b/widget/src/cocoa/nsCocoaWindow.mm
@@ -1670,42 +1670,73 @@ NS_IMETHODIMP nsCocoaWindow::EndSecureKe
return [self backgroundColor];
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
@end
+@interface ToolbarWindow(Private)
+
+- (void)redrawTitlebar;
+
+@end
+
+
// This class allows us to have a "unified toolbar" style window. It works like this:
// 1) We set the window's style to textured.
// 2) Because of this, the background color applies to the entire window, including
// the titlebar area. For normal textured windows, the default pattern is a
-// "brushed metal" image.
+// "brushed metal" image on Tiger and a unified gradient on Leopard.
// 3) We set the background color to a custom NSColor subclass that knows how tall the window is.
// When -set is called on it, it sets a pattern (with a draw callback) as the fill. In that callback,
-// it paints the the titlebar and background colrs in the correct areas of the context its given,
+// it paints the the titlebar and background colors in the correct areas of the context it's given,
// which will fill the entire window (CG will tile it horizontally for us).
+// 4) Whenever the window's main state changes and when [window display] is called,
+// Cocoa redraws the titlebar using the patternDraw callback function.
//
// This class also provides us with a pill button to show/hide the toolbar.
+//
+// Drawing the unified gradient in the titlebar and the toolbar works like this:
+// 1) In the style sheet we set the toolbar's -moz-appearance to -moz-mac-unified-toolbar.
+// 2) When the toolbar is drawn, Gecko calls nsNativeThemeCocoa::DrawWidgetBackground
+// for the widget type NS_THEME_MOZ_MAC_UNIFIED_TOOLBAR.
+// 3) This calls DrawUnifiedToolbar which finds the toolbar frame's ToolbarWindow
+// and passes the toolbar frame's height to setUnifiedToolbarHeight.
+// 4) If the toolbar height has changed, a titlebar redraw is triggered by
+// [self display] and the upper part of the unified gradient is drawn in the
+// titlebar.
+// 5) DrawUnifiedToolbar draws the lower part of the unified gradient in the toolbar.
+//
+// Whenever the unified gradient is drawn in the titlebar or the toolbar, both
+// titlebar height and toolbar height must be known in order to construct the
+// correct gradient (which is a linear gradient with the length
+// titlebarHeight + toolbarHeight - 1). But you can only get from the toolbar frame
+// to the containing window - the other direction doesn't work. That's why the
+// toolbar height is cached in the ToolbarWindow but nsNativeThemeCocoa can simply
+// query the window for its titlebar height when drawing the toolbar.
@implementation ToolbarWindow
- (id)initWithContentRect:(NSRect)aContentRect styleMask:(unsigned int)aStyle backing:(NSBackingStoreType)aBufferingType defer:(BOOL)aFlag
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
aStyle = aStyle | NSTexturedBackgroundWindowMask;
if ((self = [super initWithContentRect:aContentRect styleMask:aStyle backing:aBufferingType defer:aFlag])) {
mColor = [[TitlebarAndBackgroundColor alloc] initWithActiveTitlebarColor:nil
inactiveTitlebarColor:nil
backgroundColor:[NSColor whiteColor]
forWindow:self];
// Call the superclass's implementation, to avoid our guard method below.
[super setBackgroundColor:mColor];
+ mUnifiedToolbarHeight = 0.0f;
+ mSuppressPainting = NO;
+
// setBottomCornerRounded: is a private API call, so we check to make sure
// we respond to it just in case.
if ([self respondsToSelector:@selector(setBottomCornerRounded:)])
[self setBottomCornerRounded:NO];
}
return self;
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
@@ -1753,36 +1784,43 @@ NS_IMETHODIMP nsCocoaWindow::EndSecureKe
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
[mColor setTitlebarColor:aColor forActiveWindow:aActive];
NS_OBJC_END_TRY_ABORT_BLOCK;
}
-
-- (NSColor*)activeTitlebarColor
+// This is called by nsNativeThemeCocoa.mm's DrawUnifiedToolbar.
+// We need to know the toolbar's height in order to draw the correct
+// unified gradient in the titlebar.
+- (void)setUnifiedToolbarHeight:(float)aToolbarHeight
{
- NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
-
- return [mColor activeTitlebarColor];
-
- NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
+ if (mUnifiedToolbarHeight == aToolbarHeight)
+ return;
+ mUnifiedToolbarHeight = aToolbarHeight;
+ [self redrawTitlebar];
}
-- (NSColor*)inactiveTitlebarColor
+- (float)unifiedToolbarHeight
+{
+ return mUnifiedToolbarHeight;
+}
+
+- (float)titlebarHeight
{
- NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
-
- return [mColor inactiveTitlebarColor];
-
- NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
+ NSRect frameRect = [self frame];
+ return frameRect.size.height - [self contentRectForFrameRect:frameRect].size.height;
}
+- (BOOL)isPaintingSuppressed
+{
+ return mSuppressPainting;
+}
// Always show the toolbar pill button.
- (BOOL)_hasToolbar
{
return YES;
}
@@ -1854,16 +1892,29 @@ NS_IMETHODIMP nsCocoaWindow::EndSecureKe
break;
}
[super sendEvent:anEvent];
}
@end
+@implementation ToolbarWindow(Private)
+
+// [self display] seems to be the only way to repaint a window's titlebar.
+// The bad thing about it is that it repaints all the window's subviews as well.
+// So we use a guard to prevent unnecessary redrawing.
+- (void)redrawTitlebar
+{
+ mSuppressPainting = YES;
+ [self display];
+ mSuppressPainting = NO;
+}
+
+@end
// Custom NSColor subclass where most of the work takes place for drawing in
// the titlebar area.
@implementation TitlebarAndBackgroundColor
- (id)initWithActiveTitlebarColor:(NSColor*)aActiveTitlebarColor
inactiveTitlebarColor:(NSColor*)aInactiveTitlebarColor
backgroundColor:(NSColor*)aBackgroundColor
@@ -1871,21 +1922,16 @@ NS_IMETHODIMP nsCocoaWindow::EndSecureKe
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
if ((self = [super init])) {
mActiveTitlebarColor = [aActiveTitlebarColor retain];
mInactiveTitlebarColor = [aInactiveTitlebarColor retain];
mBackgroundColor = [aBackgroundColor retain];
mWindow = aWindow; // weak ref to avoid a cycle
- NSRect frameRect = [aWindow frame];
-
- // We cant just use a static because the height can vary by window, and we don't
- // want to recalculate this every time we draw. A member is the best solution.
- mTitlebarHeight = frameRect.size.height - [aWindow contentRectForFrameRect:frameRect].size.height;
}
return self;
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
}
- (void)dealloc
@@ -1898,93 +1944,58 @@ NS_IMETHODIMP nsCocoaWindow::EndSecureKe
[super dealloc];
NS_OBJC_END_TRY_ABORT_BLOCK;
}
// Our pattern width is 1 pixel. CoreGraphics can cache and tile for us.
static const float sPatternWidth = 1.0f;
-// These are the start and end greys for the default titlebar gradient.
-static const float sLeopardHeaderStartGrey = 196/255.0f;
-static const float sLeopardHeaderEndGrey = 149/255.0f;
-static const float sLeopardHeaderBackgroundStartGrey = 232/255.0f;
-static const float sLeopardHeaderBackgroundEndGrey = 207/255.0f;
-static const float sTigerHeaderStartGrey = 239/255.0f;
-static const float sTigerHeaderEndGrey = 202/255.0f;
-
-// This is the grey for the border at the bottom of the titlebar.
-static const float sLeopardTitlebarBorderGrey = 64/255.0f;
-static const float sLeopardTitlebarBackgroundBorderGrey = 134/255.0f;
-static const float sTigerTitlebarBorderGrey = 140/255.0f;
-
-// Callback used by the default titlebar shading.
-static void headerShading(void* aInfo, const float* aIn, float* aOut)
-{
- float startGrey, endGrey;
- BOOL isMain = *(BOOL*)aInfo;
- if (nsToolkit::OnLeopardOrLater()) {
- startGrey = isMain ? sLeopardHeaderStartGrey : sLeopardHeaderBackgroundStartGrey;
- endGrey = isMain ? sLeopardHeaderEndGrey : sLeopardHeaderBackgroundEndGrey;
- }
- else {
- startGrey = sTigerHeaderStartGrey;
- endGrey = sTigerHeaderEndGrey;
- }
- float result = (*aIn) * startGrey + (1.0f - *aIn) * endGrey;
- aOut[0] = result;
- aOut[1] = result;
- aOut[2] = result;
- aOut[3] = 1.0f;
-}
-
-
// Callback where all of the drawing for this color takes place.
void patternDraw(void* aInfo, CGContextRef aContext)
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
TitlebarAndBackgroundColor *color = (TitlebarAndBackgroundColor*)aInfo;
NSColor *backgroundColor = [color backgroundColor];
- NSWindow *window = [color window];
+ ToolbarWindow *window = (ToolbarWindow*)[color window];
BOOL isMain = [window isMainWindow];
NSColor *titlebarColor = isMain ? [color activeTitlebarColor] : [color inactiveTitlebarColor];
// Remember: this context is NOT flipped, so the origin is in the bottom left.
- float titlebarHeight = [color titlebarHeight];
+ float titlebarHeight = [window titlebarHeight];
float titlebarOrigin = [window frame].size.height - titlebarHeight;
+ UnifiedGradientInfo info = { titlebarHeight, [window unifiedToolbarHeight], isMain, YES };
+
[NSGraphicsContext saveGraphicsState];
[NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithGraphicsPort:aContext flipped:NO]];
// If the titlebar color is nil, draw the default titlebar shading.
if (!titlebarColor) {
- // On Tiger when the window is not main, we want to draw a pinstripe pattern instead.
- if (!nsToolkit::OnLeopardOrLater() && !isMain) {
- [[NSColor windowBackgroundColor] set];
- NSRectFill(NSMakeRect(0.0f, titlebarOrigin, 1.0f, titlebarOrigin + titlebarHeight));
- } else {
- // Otherwise, create and draw a CGShading that uses headerShading() as its callback.
- CGFunctionCallbacks callbacks = {0, headerShading, NULL};
- CGFunctionRef function = CGFunctionCreate(&isMain, 1, NULL, 4, NULL, &callbacks);
- CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
- CGShadingRef shading = CGShadingCreateAxial(colorSpace, CGPointMake(0.0f, titlebarOrigin),
- CGPointMake(0.0f, titlebarOrigin + titlebarHeight),
- function, NO, NO);
- CGColorSpaceRelease(colorSpace);
- CGFunctionRelease(function);
- CGContextDrawShading(aContext, shading);
- CGShadingRelease(shading);
- }
+ // Create and draw a CGShading that uses unifiedShading() as its callback.
+ CGFunctionCallbacks callbacks = {0, unifiedShading, NULL};
+ CGFunctionRef function = CGFunctionCreate(&info, 1, NULL, 4, NULL, &callbacks);
+ CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
+ CGShadingRef shading = CGShadingCreateAxial(colorSpace,
+ CGPointMake(0.0f, titlebarOrigin + titlebarHeight),
+ CGPointMake(0.0f, titlebarOrigin),
+ function, NO, NO);
+ CGColorSpaceRelease(colorSpace);
+ CGFunctionRelease(function);
+ CGContextDrawShading(aContext, shading);
+ CGShadingRelease(shading);
// Draw the one pixel border at the bottom of the titlebar.
- float borderGrey = !nsToolkit::OnLeopardOrLater() ? sTigerTitlebarBorderGrey :
- (isMain ? sLeopardTitlebarBorderGrey : sLeopardTitlebarBackgroundBorderGrey);
- [[NSColor colorWithDeviceWhite:borderGrey alpha:1.0f] set];
- NSRectFill(NSMakeRect(0.0f, titlebarOrigin, sPatternWidth, 1.0f));
+ if ([window unifiedToolbarHeight] == 0) {
+ float borderGrey = isMain ? sLeopardTitlebarBorderGrey :
+ sLeopardTitlebarBackgroundBorderGrey;
+ [[NSColor colorWithDeviceWhite:borderGrey alpha:1.0f] set];
+ NSRectFill(NSMakeRect(0.0f, titlebarOrigin, sPatternWidth, 1.0f));
+ }
} else {
// if the titlebar color is not nil, just set and draw it normally.
[titlebarColor set];
NSRectFill(NSMakeRect(0.0f, titlebarOrigin, sPatternWidth, titlebarHeight));
}
// Draw the background color of the window everywhere but where the titlebar is.
[backgroundColor set];
@@ -2084,22 +2095,16 @@ void patternDraw(void* aInfo, CGContextR
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
[self setFill];
NS_OBJC_END_TRY_ABORT_BLOCK;
}
-
-- (float)titlebarHeight
-{
- return mTitlebarHeight;
-}
-
@end
// This is an internal Apple class, which we need to work around a bug in. It is
// the class responsible for drawing the titlebar for metal windows. It actually
// is a few levels deep in the inhertiance graph, but we don't need to know about
// all its superclasses.
@interface NSGrayFrame : NSObject
--- a/widget/src/cocoa/nsNativeThemeCocoa.h
+++ b/widget/src/cocoa/nsNativeThemeCocoa.h
@@ -121,16 +121,19 @@ protected:
ThemeButtonAdornment inAdornment, PRInt32 inState);
void DrawSpinButtons (CGContextRef context, ThemeButtonKind inKind,
const HIRect& inBoxRect,
PRBool inDisabled, ThemeDrawState inDrawState,
ThemeButtonAdornment inAdornment, PRInt32 inState);
void DrawCheckbox(CGContextRef context, ThemeButtonKind inKind,
const HIRect& inBoxRect, PRBool inChecked,
PRBool inDisabled, PRInt32 inState);
+ void DrawUnifiedToolbar(CGContextRef cgContext, const HIRect& inBoxRect,
+ nsIFrame *aFrame);
+
// Scrollbars
void DrawScrollbar(CGContextRef aCGContext, const HIRect& aBoxRect, nsIFrame *aFrame);
void GetScrollbarPressStates (nsIFrame *aFrame, PRInt32 aButtonStates[]);
void GetScrollbarDrawInfo (HIThemeTrackDrawInfo& aTdi, nsIFrame *aFrame,
const HIRect& aRect, PRBool aShouldGetButtonStates);
nsIFrame* GetParentScrollbarFrame(nsIFrame *aFrame);
void DrawCellWithScaling(NSCell *cell,
--- a/widget/src/cocoa/nsNativeThemeCocoa.mm
+++ b/widget/src/cocoa/nsNativeThemeCocoa.mm
@@ -52,16 +52,17 @@
#include "nsIFrame.h"
#include "nsIAtom.h"
#include "nsIEventStateManager.h"
#include "nsINameSpaceManager.h"
#include "nsPresContext.h"
#include "nsILookAndFeel.h"
#include "nsWidgetAtoms.h"
#include "nsToolkit.h"
+#include "nsCocoaWindow.h"
#include "gfxContext.h"
#include "gfxQuartzSurface.h"
#include "gfxQuartzNativeDrawing.h"
#define DRAW_IN_FRAME_DEBUG 0
#define SCROLLBARS_VISUAL_DEBUG 0
@@ -111,16 +112,29 @@ static void InflateControlRect(NSRect* r
int controlSize = EnumSizeForCocoaSize(cocoaControlSize);
const float* buttonMargins = marginSet[osIndex][controlSize];
rect->origin.x -= buttonMargins[leftMargin];
rect->origin.y -= buttonMargins[bottomMargin];
rect->size.width += buttonMargins[leftMargin] + buttonMargins[rightMargin];
rect->size.height += buttonMargins[bottomMargin] + buttonMargins[topMargin];
}
+static NSWindow* NativeWindowForFrame(nsIFrame* aFrame, int* aLevelsUp = NULL)
+{
+ if (!aFrame)
+ return nil;
+
+ nsIWidget* widget = aFrame->GetWindow();
+ if (!widget)
+ return nil;
+
+ nsIWidget* topLevelWidget = widget->GetTopLevelWidget(aLevelsUp);
+
+ return (NSWindow*)topLevelWidget->GetNativeData(NS_NATIVE_WINDOW);
+}
NS_IMPL_ISUPPORTS1(nsNativeThemeCocoa, nsITheme)
nsNativeThemeCocoa::nsNativeThemeCocoa()
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
@@ -976,16 +990,66 @@ nsNativeThemeCocoa::GetParentScrollbarFr
if (scrollbarFrame->GetType() == nsWidgetAtoms::scrollbarFrame) break;
} while ((scrollbarFrame = scrollbarFrame->GetParent()));
// We return null if we can't find a parent scrollbar frame
return scrollbarFrame;
}
+void
+nsNativeThemeCocoa::DrawUnifiedToolbar(CGContextRef cgContext, const HIRect& inBoxRect,
+ nsIFrame *aFrame)
+{
+ NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
+
+ float titlebarHeight = 0;
+ int levelsUp = 0;
+ NSWindow* win = NativeWindowForFrame(aFrame, &levelsUp);
+
+ // If the toolbar is directly below the titlebar in the top level view of a ToolbarWindow
+ if ([win isKindOfClass:[ToolbarWindow class]] && levelsUp == 0 &&
+ inBoxRect.origin.y <= 0) {
+ // Consider the titlebar height when calculating the gradient.
+ titlebarHeight = [(ToolbarWindow*)win titlebarHeight];
+ // Notify the window about the toolbar's height so that it can draw the
+ // correct gradient in the titlebar.
+ [(ToolbarWindow*)win setUnifiedToolbarHeight:inBoxRect.size.height];
+ }
+
+ BOOL isMain = win ? [win isMainWindow] : YES;
+
+ // Draw the gradient
+ UnifiedGradientInfo info = { titlebarHeight, inBoxRect.size.height, isMain, NO };
+ struct CGFunctionCallbacks callbacks = { 0, unifiedShading, NULL };
+ CGFunctionRef function = CGFunctionCreate(&info, 1, NULL, 4, NULL, &callbacks);
+ float srcY = inBoxRect.origin.y;
+ float dstY = srcY + inBoxRect.size.height - 1;
+ CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
+ CGShadingRef shading = CGShadingCreateAxial(colorSpace,
+ CGPointMake(0, srcY),
+ CGPointMake(0, dstY), function,
+ NO, NO);
+ CGColorSpaceRelease(colorSpace);
+ CGFunctionRelease(function);
+ CGContextClipToRect(cgContext, inBoxRect);
+ CGContextDrawShading(cgContext, shading);
+ CGShadingRelease(shading);
+
+ // Draw the border at the bottom of the toolbar.
+ float borderGrey = isMain ? sLeopardTitlebarBorderGrey :
+ sLeopardTitlebarBackgroundBorderGrey;
+ [[NSColor colorWithDeviceWhite:borderGrey alpha:1.0f] set];
+ NSRectFill(NSMakeRect(inBoxRect.origin.x, inBoxRect.origin.y +
+ inBoxRect.size.height - 1.0f, inBoxRect.size.width, 1.0f));
+
+ NS_OBJC_END_TRY_ABORT_BLOCK;
+}
+
+
NS_IMETHODIMP
nsNativeThemeCocoa::DrawWidgetBackground(nsIRenderingContext* aContext, nsIFrame* aFrame,
PRUint8 aWidgetType, const nsRect& aRect,
const nsRect& aDirtyRect)
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
// setup to draw into the correct port
@@ -1144,16 +1208,20 @@ nsNativeThemeCocoa::DrawWidgetBackground
break;
case NS_THEME_TOOLBAR_SEPARATOR: {
HIThemeSeparatorDrawInfo sdi = { 0, kThemeStateActive };
HIThemeDrawSeparator(&macRect, &sdi, cgContext, HITHEME_ORIENTATION);
}
break;
+ case NS_THEME_MOZ_MAC_UNIFIED_TOOLBAR:
+ DrawUnifiedToolbar(cgContext, macRect, aFrame);
+ break;
+
case NS_THEME_TOOLBAR:
case NS_THEME_TOOLBOX:
case NS_THEME_STATUSBAR: {
HIThemeHeaderDrawInfo hdi = { 0, kThemeStateActive, kHIThemeHeaderKindWindow };
HIThemeDrawHeader(&macRect, &hdi, cgContext, HITHEME_ORIENTATION);
}
break;
@@ -1431,16 +1499,20 @@ nsNativeThemeCocoa::GetWidgetBorder(nsID
if (isHorizontal)
aResult->SizeTo(endcapSize, 0, 0, 0);
else
aResult->SizeTo(0, endcapSize, 0, 0);
}
break;
}
+
+ case NS_THEME_MOZ_MAC_UNIFIED_TOOLBAR:
+ aResult->SizeTo(0, 0, 1, 0);
+ break;
}
return NS_OK;
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
}
@@ -1743,16 +1815,17 @@ nsNativeThemeCocoa::GetMinimumWidgetSize
NS_IMETHODIMP
nsNativeThemeCocoa::WidgetStateChanged(nsIFrame* aFrame, PRUint8 aWidgetType,
nsIAtom* aAttribute, PRBool* aShouldRepaint)
{
// Some widget types just never change state.
switch (aWidgetType) {
case NS_THEME_TOOLBOX:
case NS_THEME_TOOLBAR:
+ case NS_THEME_MOZ_MAC_UNIFIED_TOOLBAR:
case NS_THEME_TOOLBAR_BUTTON:
case NS_THEME_SCROLLBAR_TRACK_VERTICAL:
case NS_THEME_SCROLLBAR_TRACK_HORIZONTAL:
case NS_THEME_STATUSBAR:
case NS_THEME_STATUSBAR_PANEL:
case NS_THEME_STATUSBAR_RESIZER_PANEL:
case NS_THEME_TOOLTIP:
case NS_THEME_TAB_PANELS:
@@ -1833,16 +1906,17 @@ nsNativeThemeCocoa::ThemeSupportsWidget(
case NS_THEME_RADIO:
case NS_THEME_RADIO_SMALL:
case NS_THEME_RADIO_CONTAINER:
case NS_THEME_GROUPBOX:
case NS_THEME_BUTTON:
case NS_THEME_BUTTON_BEVEL:
case NS_THEME_SPINNER:
case NS_THEME_TOOLBAR:
+ case NS_THEME_MOZ_MAC_UNIFIED_TOOLBAR:
case NS_THEME_STATUSBAR:
case NS_THEME_TEXTFIELD:
case NS_THEME_TEXTFIELD_MULTILINE:
//case NS_THEME_TOOLBOX:
//case NS_THEME_TOOLBAR_BUTTON:
case NS_THEME_PROGRESSBAR:
case NS_THEME_PROGRESSBAR_VERTICAL:
case NS_THEME_PROGRESSBAR_CHUNK:
--- a/widget/src/xpwidgets/nsBaseWidget.cpp
+++ b/widget/src/xpwidgets/nsBaseWidget.cpp
@@ -286,16 +286,35 @@ NS_IMETHODIMP nsBaseWidget::SetParent(ns
//-------------------------------------------------------------------------
nsIWidget* nsBaseWidget::GetParent(void)
{
return nsnull;
}
//-------------------------------------------------------------------------
//
+// Get this nsBaseWidget top level widget
+//
+//-------------------------------------------------------------------------
+nsIWidget* nsBaseWidget::GetTopLevelWidget(PRInt32* aLevelsUp)
+{
+ nsIWidget *topLevelWidget, *widget = this;
+ if (aLevelsUp)
+ *aLevelsUp = -1;
+ while (widget) {
+ topLevelWidget = widget;
+ widget = widget->GetParent();
+ if (aLevelsUp)
+ ++*aLevelsUp;
+ }
+ return topLevelWidget;
+}
+
+//-------------------------------------------------------------------------
+//
// Get this nsBaseWidget's top (non-sheet) parent (if it's a sheet)
//
//-------------------------------------------------------------------------
nsIWidget* nsBaseWidget::GetSheetWindowParent(void)
{
return nsnull;
}
--- a/widget/src/xpwidgets/nsBaseWidget.h
+++ b/widget/src/xpwidgets/nsBaseWidget.h
@@ -76,16 +76,17 @@ public:
NS_IMETHOD CaptureMouse(PRBool aCapture);
NS_IMETHOD Validate();
NS_IMETHOD InvalidateRegion(const nsIRegion *aRegion, PRBool aIsSynchronous);
NS_IMETHOD GetClientData(void*& aClientData);
NS_IMETHOD SetClientData(void* aClientData);
NS_IMETHOD Destroy();
NS_IMETHOD SetParent(nsIWidget* aNewParent);
virtual nsIWidget* GetParent(void);
+ virtual nsIWidget* GetTopLevelWidget(PRInt32* aLevelsUp = NULL);
virtual nsIWidget* GetSheetWindowParent(void);
virtual void AddChild(nsIWidget* aChild);
virtual void RemoveChild(nsIWidget* aChild);
NS_IMETHOD SetZIndex(PRInt32 aZIndex);
NS_IMETHOD GetZIndex(PRInt32* aZIndex);
NS_IMETHOD PlaceBehind(nsTopLevelWidgetZPlacement aPlacement,
nsIWidget *aWidget, PRBool aActivate);