From 58712ea44cb52f893d2c2f01cf3300493f7b015d Mon Sep 17 00:00:00 2001 From: Mike Conley Date: Fri, 1 Mar 2013 13:48:18 -0500 Subject: [PATCH] Bug 625989 - Always draw in the titlebar on OSX. r=josh,dao f=mstange --- browser/base/content/browser.js | 6 -- browser/base/content/browser.xul | 1 + browser/themes/osx/browser.css | 7 ++- toolkit/content/LightweightThemeConsumer.jsm | 22 +++++-- widget/cocoa/nsChildView.h | 3 + widget/cocoa/nsChildView.mm | 22 ++++--- widget/cocoa/nsCocoaWindow.h | 1 + widget/cocoa/nsCocoaWindow.mm | 23 ++++++-- widget/cocoa/nsNativeThemeCocoa.h | 2 + widget/cocoa/nsNativeThemeCocoa.mm | 60 ++++++++++++++++---- 10 files changed, 110 insertions(+), 37 deletions(-) diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index a1c4fdf9b670..be357a9a2e6a 100644 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -6721,12 +6721,6 @@ let gPrivateBrowsingUI = { document.getElementById("Tools:Sanitize").setAttribute("disabled", "true"); if (window.location.href == getBrowserURL()) { -#ifdef XP_MACOSX - if (!PrivateBrowsingUtils.permanentPrivateBrowsing) { - document.documentElement.setAttribute("drawintitlebar", true); - } -#endif - // Adjust the window's title let docElement = document.documentElement; if (!PrivateBrowsingUtils.permanentPrivateBrowsing) { diff --git a/browser/base/content/browser.xul b/browser/base/content/browser.xul index ac4b39138af7..f538a06663f9 100644 --- a/browser/base/content/browser.xul +++ b/browser/base/content/browser.xul @@ -32,6 +32,7 @@ titlemodifier="" titlemodifier_normal="" titlemodifier_privatebrowsing="&mainWindow.titlePrivateBrowsingSuffix;" + chromemargin="0,-1,-1,-1" #else title_privatebrowsing="&mainWindow.titlemodifier;@PRE_RELEASE_SUFFIX@ &mainWindow.titlePrivateBrowsingSuffix;" titlemodifier="&mainWindow.titlemodifier;@PRE_RELEASE_SUFFIX@" diff --git a/browser/themes/osx/browser.css b/browser/themes/osx/browser.css index 6c0ddf75cb7e..aee73ac01d85 100644 --- a/browser/themes/osx/browser.css +++ b/browser/themes/osx/browser.css @@ -40,8 +40,7 @@ background-color: #eeeeee; } -#titlebar-buttonbox-container, -#main-window:not([drawintitlebar=true]) > #titlebar { +#titlebar-buttonbox-container { display: none; } @@ -49,6 +48,10 @@ height: 22px; } +#main-window:not(:-moz-lwtheme):not([privatebrowsingmode=temporary]) > #titlebar { + -moz-appearance: -moz-window-titlebar; +} + #main-window[chromehidden~="toolbar"][chromehidden~="location"][chromehidden~="directories"] { border-top: 1px solid rgba(0,0,0,0.65); } diff --git a/toolkit/content/LightweightThemeConsumer.jsm b/toolkit/content/LightweightThemeConsumer.jsm index 3fa4f42d3b21..608c6f0a9bbb 100644 --- a/toolkit/content/LightweightThemeConsumer.jsm +++ b/toolkit/content/LightweightThemeConsumer.jsm @@ -41,6 +41,9 @@ LightweightThemeConsumer.prototype = { _lastData: null, _lastScreenWidth: null, _lastScreenHeight: null, +#ifdef XP_MACOSX + _chromemarginDefault: undefined, +#endif observe: function (aSubject, aTopic, aData) { if (aTopic != "lightweight-theme-styling-update") @@ -108,10 +111,21 @@ LightweightThemeConsumer.prototype = { } #ifdef XP_MACOSX - if (active) - root.setAttribute("drawintitlebar", "true"); - else - root.removeAttribute("drawintitlebar"); + // Sample whether or not we draw in the titlebar by default the first time we update. + // If the root has no chromemargin attribute, getAttribute will return null, and + // we'll remove the attribute when the lw-theme is deactivated. + if (this._chromemarginDefault === undefined) + this._chromemarginDefault = root.getAttribute("chromemargin"); + + if (active) { + root.setAttribute("chromemargin", "0,-1,-1,-1"); + } + else { + if (this._chromemarginDefault) + root.setAttribute("chromemargin", this._chromemarginDefault); + else + root.removeAttribute("chromemargin"); + } #endif } } diff --git a/widget/cocoa/nsChildView.h b/widget/cocoa/nsChildView.h index 0439b93e2afa..56a20b826757 100644 --- a/widget/cocoa/nsChildView.h +++ b/widget/cocoa/nsChildView.h @@ -540,6 +540,9 @@ public: } // unit conversion convenience functions + int32_t CocoaPointsToDevPixels(CGFloat aPts) { + return nsCocoaUtils::CocoaPointsToDevPixels(aPts, BackingScaleFactor()); + } nsIntPoint CocoaPointsToDevPixels(const NSPoint& aPt) { return nsCocoaUtils::CocoaPointsToDevPixels(aPt, BackingScaleFactor()); } diff --git a/widget/cocoa/nsChildView.mm b/widget/cocoa/nsChildView.mm index 91ccf9566c80..530c88497332 100644 --- a/widget/cocoa/nsChildView.mm +++ b/widget/cocoa/nsChildView.mm @@ -2053,23 +2053,29 @@ nsChildView::MaybeDrawRoundedBottomCorners(GLManager* aManager, nsIntRect aRect) void nsChildView::UpdateThemeGeometries(const nsTArray& aThemeGeometries) { - NSWindow* win = [mView window]; - if (!win || ![win isKindOfClass:[ToolbarWindow class]]) + if (![mView window] || ![[mView window] isKindOfClass:[ToolbarWindow class]]) return; - float unifiedToolbarHeight = 0; - nsIntRect topPixelStrip(0, 0, [win frame].size.width, 1); + ToolbarWindow* win = (ToolbarWindow*)[mView window]; + bool drawsContentsIntoWindowFrame = [win drawsContentsIntoWindowFrame]; + int32_t windowWidth = mBounds.width; + int32_t titlebarHeight = CocoaPointsToDevPixels([win titlebarHeight]); + int32_t underTitlebarPos = drawsContentsIntoWindowFrame ? titlebarHeight : 0; + int32_t unifiedToolbarBottom = 0; for (uint32_t i = 0; i < aThemeGeometries.Length(); ++i) { const ThemeGeometry& g = aThemeGeometries[i]; if ((g.mWidgetType == NS_THEME_MOZ_MAC_UNIFIED_TOOLBAR || g.mWidgetType == NS_THEME_TOOLBAR) && - g.mRect.Contains(topPixelStrip)) { - unifiedToolbarHeight = g.mRect.YMost(); + g.mRect.X() <= 0 && + g.mRect.XMost() >= windowWidth && + g.mRect.Y() <= underTitlebarPos) { + unifiedToolbarBottom = g.mRect.YMost(); } } - [(ToolbarWindow*)win - setUnifiedToolbarHeight:DevPixelsToCocoaPoints(unifiedToolbarHeight)]; + + CGFloat unifiedHeight = DevPixelsToCocoaPoints(titlebarHeight + unifiedToolbarBottom - underTitlebarPos); + [win setUnifiedToolbarHeight:unifiedHeight]; } NS_IMETHODIMP diff --git a/widget/cocoa/nsCocoaWindow.h b/widget/cocoa/nsCocoaWindow.h index fe8ade980b16..3767d9a91d8e 100644 --- a/widget/cocoa/nsCocoaWindow.h +++ b/widget/cocoa/nsCocoaWindow.h @@ -269,6 +269,7 @@ public: virtual void SetShowsToolbarButton(bool aShow); virtual void SetShowsFullScreenButton(bool aShow); virtual void SetWindowAnimationType(WindowAnimationType aType); + NS_IMETHOD SetNonClientMargins(nsIntMargin &margins); NS_IMETHOD SetWindowTitlebarColor(nscolor aColor, bool aActive); virtual void SetDrawsInTitlebar(bool aState); virtual nsresult SynthesizeNativeMouseEvent(nsIntPoint aPoint, diff --git a/widget/cocoa/nsCocoaWindow.mm b/widget/cocoa/nsCocoaWindow.mm index 13ffabbff557..a136e71ddbb2 100644 --- a/widget/cocoa/nsCocoaWindow.mm +++ b/widget/cocoa/nsCocoaWindow.mm @@ -1954,6 +1954,15 @@ void nsCocoaWindow::SetWindowAnimationType(nsIWidget::WindowAnimationType aType) mAnimationType = aType; } +NS_IMETHODIMP nsCocoaWindow::SetNonClientMargins(nsIntMargin &margins) +{ + NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT; + + SetDrawsInTitlebar(margins.top == 0); + + NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT; +} + NS_IMETHODIMP nsCocoaWindow::SetWindowTitlebarColor(nscolor aColor, bool aActive) { NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT; @@ -2835,7 +2844,7 @@ static const NSString* kStateShowsToolbarButton = @"showsToolbarButton"; [super setBackgroundColor:mColor]; mBackgroundColor = [[NSColor whiteColor] retain]; - mUnifiedToolbarHeight = 0.0f; + mUnifiedToolbarHeight = 22.0f; // setBottomCornerRounded: is a private API call, so we check to make sure // we respond to it just in case. @@ -2909,6 +2918,7 @@ static const NSString* kStateShowsToolbarButton = @"showsToolbarButton"; [self frame].size.width, [self titlebarHeight]); } +// Returns the unified height of titlebar + toolbar. - (float)unifiedToolbarHeight { return mUnifiedToolbarHeight; @@ -2920,15 +2930,16 @@ static const NSString* kStateShowsToolbarButton = @"showsToolbarButton"; return frameRect.size.height - [self contentRectForFrameRect:frameRect].size.height; } +// Stores the complete height of titlebar + toolbar. - (void)setUnifiedToolbarHeight:(float)aHeight { - if ([self drawsContentsIntoWindowFrame] || aHeight == mUnifiedToolbarHeight) + if (aHeight == mUnifiedToolbarHeight) return; mUnifiedToolbarHeight = aHeight; // Update sheet positioning hint. - [self setContentBorderThickness:mUnifiedToolbarHeight forEdge:NSMaxYEdge]; + [self setContentBorderThickness:mUnifiedToolbarHeight - [self titlebarHeight] forEdge:NSMaxYEdge]; // Redraw the title bar. If we're inside painting, we'll do it right now, // otherwise we'll just invalidate it. @@ -3123,18 +3134,18 @@ static const NSString* kStateShowsToolbarButton = @"showsToolbarButton"; static void DrawNativeTitlebar(CGContextRef aContext, CGRect aTitlebarRect, - float aToolbarHeight, BOOL aIsMain) + float aUnifiedToolbarHeight, BOOL aIsMain) { if (aTitlebarRect.size.width * aTitlebarRect.size.height > CUIDRAW_MAX_AREA) { return; } - int unifiedHeight = aTitlebarRect.size.height + aToolbarHeight; + CUIDraw([NSWindow coreUIRenderer], aTitlebarRect, aContext, (CFDictionaryRef)[NSDictionary dictionaryWithObjectsAndKeys: @"kCUIWidgetWindowFrame", @"widget", @"regularwin", @"windowtype", (aIsMain ? @"normal" : @"inactive"), @"state", - [NSNumber numberWithInt:unifiedHeight], @"kCUIWindowFrameUnifiedTitleBarHeightKey", + [NSNumber numberWithInt:aUnifiedToolbarHeight], @"kCUIWindowFrameUnifiedTitleBarHeightKey", [NSNumber numberWithBool:YES], @"kCUIWindowFrameDrawTitleSeparatorKey", nil], nil); diff --git a/widget/cocoa/nsNativeThemeCocoa.h b/widget/cocoa/nsNativeThemeCocoa.h index 88b6e43b0f40..a0b695637f04 100644 --- a/widget/cocoa/nsNativeThemeCocoa.h +++ b/widget/cocoa/nsNativeThemeCocoa.h @@ -107,6 +107,8 @@ protected: NSWindow* aWindow); void DrawStatusBar(CGContextRef cgContext, const HIRect& inBoxRect, nsIFrame *aFrame); + void DrawNativeTitlebar(CGContextRef aContext, CGRect aTitlebarRect, + float aUnifiedHeight, BOOL aIsMain); void DrawResizer(CGContextRef cgContext, const HIRect& aRect, nsIFrame *aFrame); // Scrollbars diff --git a/widget/cocoa/nsNativeThemeCocoa.mm b/widget/cocoa/nsNativeThemeCocoa.mm index cba01e5a5bb8..b1de27df3cfd 100644 --- a/widget/cocoa/nsNativeThemeCocoa.mm +++ b/widget/cocoa/nsNativeThemeCocoa.mm @@ -1781,7 +1781,7 @@ nsNativeThemeCocoa::GetParentScrollbarFrame(nsIFrame *aFrame) do { if (scrollbarFrame->GetType() == nsGkAtoms::scrollbarFrame) break; } while ((scrollbarFrame = scrollbarFrame->GetParent())); - + // We return null if we can't find a parent scrollbar frame return scrollbarFrame; } @@ -1789,16 +1789,18 @@ nsNativeThemeCocoa::GetParentScrollbarFrame(nsIFrame *aFrame) static bool ToolbarCanBeUnified(CGContextRef cgContext, const HIRect& inBoxRect, NSWindow* aWindow) { - if (![aWindow isKindOfClass:[ToolbarWindow class]] || - [(ToolbarWindow*)aWindow drawsContentsIntoWindowFrame]) + if (![aWindow isKindOfClass:[ToolbarWindow class]]) return false; - float unifiedToolbarHeight = [(ToolbarWindow*)aWindow unifiedToolbarHeight]; - CGAffineTransform ctm = CGContextGetUserSpaceToDeviceSpaceTransform(cgContext); - CGRect deviceRect = CGRectApplyAffineTransform(inBoxRect, ctm); + ToolbarWindow* win = (ToolbarWindow*)aWindow; + float unifiedToolbarHeight = [win unifiedToolbarHeight]; + float titlebarHeight = [win titlebarHeight]; + bool drawsContentsIntoWindowFrame = [win drawsContentsIntoWindowFrame]; + float underTitlebarPos = drawsContentsIntoWindowFrame ? titlebarHeight : 0; + return inBoxRect.origin.x == 0 && - deviceRect.size.width >= [aWindow frame].size.width && - inBoxRect.origin.y <= 0.0 && + inBoxRect.size.width >= [win frame].size.width && + inBoxRect.origin.y <= underTitlebarPos && floor(inBoxRect.origin.y + inBoxRect.size.height) <= unifiedToolbarHeight; } @@ -1808,15 +1810,14 @@ nsNativeThemeCocoa::DrawUnifiedToolbar(CGContextRef cgContext, const HIRect& inB { NS_OBJC_BEGIN_TRY_ABORT_BLOCK; - float titlebarHeight = [(ToolbarWindow*)aWindow titlebarHeight]; - float unifiedHeight = titlebarHeight + inBoxRect.size.height; + float unifiedHeight = [(ToolbarWindow*)aWindow unifiedToolbarHeight]; BOOL isMain = [aWindow isMainWindow]; CGContextSaveGState(cgContext); CGContextClipToRect(cgContext, inBoxRect); - CGRect drawRect = CGRectOffset(inBoxRect, 0, -titlebarHeight); + CGRect drawRect = CGRectOffset(inBoxRect, 0, inBoxRect.size.height - unifiedHeight); if (drawRect.size.width * drawRect.size.height <= CUIDRAW_MAX_AREA) { CUIDraw([NSWindow coreUIRenderer], drawRect, cgContext, (CFDictionaryRef)[NSDictionary dictionaryWithObjectsAndKeys: @@ -1872,6 +1873,34 @@ nsNativeThemeCocoa::DrawStatusBar(CGContextRef cgContext, const HIRect& inBoxRec NS_OBJC_END_TRY_ABORT_BLOCK; } +void +nsNativeThemeCocoa::DrawNativeTitlebar(CGContextRef aContext, CGRect aTitlebarRect, + float aUnifiedHeight, BOOL aIsMain) +{ + NS_OBJC_BEGIN_TRY_ABORT_BLOCK; + + if (aTitlebarRect.size.width * aTitlebarRect.size.height > CUIDRAW_MAX_AREA) { + return; + } + + CGContextSaveGState(aContext); + + CUIDraw([NSWindow coreUIRenderer], aTitlebarRect, aContext, + (CFDictionaryRef)[NSDictionary dictionaryWithObjectsAndKeys: + @"kCUIWidgetWindowFrame", @"widget", + @"regularwin", @"windowtype", + (aIsMain ? @"normal" : @"inactive"), @"state", + [NSNumber numberWithInt:aUnifiedHeight], @"kCUIWindowFrameUnifiedTitleBarHeightKey", + [NSNumber numberWithBool:NO], @"kCUIWindowFrameDrawTitleSeparatorKey", + [NSNumber numberWithBool:YES], @"is.flipped", + nil], + nil); + + CGContextRestoreGState(aContext); + + NS_OBJC_END_TRY_ABORT_BLOCK; +} + static void RenderResizer(CGContextRef cgContext, const HIRect& aRenderRect, void* aData) { @@ -2134,6 +2163,14 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsRenderingContext* aContext, } break; + case NS_THEME_WINDOW_TITLEBAR: { + NSWindow* win = NativeWindowForFrame(aFrame); + BOOL isMain = [win isMainWindow]; + float unifiedToolbarHeight = [(ToolbarWindow*)win unifiedToolbarHeight]; + DrawNativeTitlebar(cgContext, macRect, unifiedToolbarHeight, isMain); + } + break; + case NS_THEME_TOOLBOX: { HIThemeHeaderDrawInfo hdi = { 0, kThemeStateActive, kHIThemeHeaderKindWindow }; HIThemeDrawHeader(&macRect, &hdi, cgContext, HITHEME_ORIENTATION); @@ -2910,6 +2947,7 @@ nsNativeThemeCocoa::ThemeSupportsWidget(nsPresContext* aPresContext, nsIFrame* a case NS_THEME_DIALOG: case NS_THEME_WINDOW: + case NS_THEME_WINDOW_TITLEBAR: case NS_THEME_MENUPOPUP: case NS_THEME_MENUITEM: case NS_THEME_MENUSEPARATOR: