Bug 865806 - Use the proper Lion style scrollbar on content with a dark background color; r=roc a=lsblakk
authorEhsan Akhgari <ehsan@mozilla.com>
Thu, 23 May 2013 08:47:03 +0200
changeset 142718 ebb8f343fea6688e61cd746d155a74eb8dc81560
parent 142717 2f1807160e28d823440e61370de5138d65b603e4
child 142719 88f70ea0b7548710944887e2874b99e8c430cd08
push id2579
push userakeybl@mozilla.com
push dateMon, 24 Jun 2013 18:52:47 +0000
treeherdermozilla-beta@b69b7de8a05a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc, lsblakk
bugs865806
milestone23.0a2
Bug 865806 - Use the proper Lion style scrollbar on content with a dark background color; r=roc a=lsblakk
widget/cocoa/nsNativeThemeCocoa.mm
widget/xpwidgets/Makefile.in
widget/xpwidgets/nsNativeTheme.cpp
widget/xpwidgets/nsNativeTheme.h
--- a/widget/cocoa/nsNativeThemeCocoa.mm
+++ b/widget/cocoa/nsNativeThemeCocoa.mm
@@ -2302,24 +2302,24 @@ nsNativeThemeCocoa::DrawWidgetBackground
           if (isHorizontal) {
             macRect.origin.y += 4;
             macRect.size.height -= 4;
           } else {
             macRect.origin.x += 4;
             macRect.size.width -= 4;
           }
         }
-        const BOOL isOnTopOfBrightBackground = YES; // TODO: detect this properly
+        const BOOL isOnTopOfDarkBackground = IsDarkBackground(aFrame);
         CUIDraw([NSWindow coreUIRenderer], macRect, cgContext,
                 (CFDictionaryRef)[NSDictionary dictionaryWithObjectsAndKeys:
                   @"kCUIWidgetOverlayScrollBar", @"widget",
                   @"regular", @"size",
                   (isRolledOver ? @"rollover" : @""), @"state",
                   (isHorizontal ? @"kCUIOrientHorizontal" : @"kCUIOrientVertical"), @"kCUIOrientationKey",
-                  (isOnTopOfBrightBackground ? @"" : @"kCUIVariantWhite"), @"kCUIVariantKey",
+                  (isOnTopOfDarkBackground ? @"kCUIVariantWhite" : @""), @"kCUIVariantKey",
                   [NSNumber numberWithBool:YES], @"indiconly",
                   [NSNumber numberWithBool:YES], @"kCUIThumbProportionKey",
                   [NSNumber numberWithBool:YES], @"is.flipped",
                   nil],
                 nil);
       }
       break;
     case NS_THEME_SCROLLBAR_BUTTON_UP:
@@ -2337,23 +2337,23 @@ nsNativeThemeCocoa::DrawWidgetBackground
 #endif
     break;
     case NS_THEME_SCROLLBAR_TRACK_HORIZONTAL:
     case NS_THEME_SCROLLBAR_TRACK_VERTICAL:
       if (nsLookAndFeel::GetInt(
             nsLookAndFeel::eIntID_UseOverlayScrollbars) != 0 &&
           CheckBooleanAttr(GetParentScrollbarFrame(aFrame), nsGkAtoms::hover)) {
         BOOL isHorizontal = (aWidgetType == NS_THEME_SCROLLBAR_TRACK_HORIZONTAL);
-        const BOOL isOnTopOfBrightBackground = YES; // TODO: detect this properly
+        const BOOL isOnTopOfDarkBackground = IsDarkBackground(aFrame);
         CUIDraw([NSWindow coreUIRenderer], macRect, cgContext,
                 (CFDictionaryRef)[NSDictionary dictionaryWithObjectsAndKeys:
                   @"kCUIWidgetOverlayScrollBar", @"widget",
                   @"regular", @"size",
                   (isHorizontal ? @"kCUIOrientHorizontal" : @"kCUIOrientVertical"), @"kCUIOrientationKey",
-                  (isOnTopOfBrightBackground ? @"" : @"kCUIVariantWhite"), @"kCUIVariantKey",
+                  (isOnTopOfDarkBackground ? @"kCUIVariantWhite" : @""), @"kCUIVariantKey",
                   [NSNumber numberWithBool:YES], @"noindicator",
                   [NSNumber numberWithBool:YES], @"kCUIThumbProportionKey",
                   [NSNumber numberWithBool:YES], @"is.flipped",
                   nil],
                 nil);
       }
       break;
 
--- a/widget/xpwidgets/Makefile.in
+++ b/widget/xpwidgets/Makefile.in
@@ -65,16 +65,17 @@ endif
 
 ifdef MOZ_ENABLE_D3D10_LAYER
 DEFINES		+= -DMOZ_ENABLE_D3D10_LAYER
 endif
 
 LOCAL_INCLUDES	+= \
 		-I$(srcdir)/../$(MOZ_WIDGET_TOOLKIT) \
 		-I$(srcdir)/../shared \
+		-I$(topsrcdir)/layout/base \
 		-I$(topsrcdir)/layout/forms \
 		-I$(topsrcdir)/layout/generic \
 		-I$(topsrcdir)/layout/xul/base/src \
 		-I$(topsrcdir)/view/src \
 		-I$(srcdir) \
 		$(NULL)
 
 # we don't want the shared lib, but we want to force the creation of a static lib.
--- a/widget/xpwidgets/nsNativeTheme.cpp
+++ b/widget/xpwidgets/nsNativeTheme.cpp
@@ -18,16 +18,17 @@
 #include "nsIDOMXULMenuListElement.h"
 #include "nsThemeConstants.h"
 #include "nsIComponentManager.h"
 #include "nsPIDOMWindow.h"
 #include "nsProgressFrame.h"
 #include "nsMeterFrame.h"
 #include "nsMenuFrame.h"
 #include "nsRangeFrame.h"
+#include "nsCSSRendering.h"
 #include "mozilla/dom/Element.h"
 #include <algorithm>
 
 nsNativeTheme::nsNativeTheme()
 : mAnimatedContentTimeout(UINT32_MAX)
 {
 }
 
@@ -672,8 +673,32 @@ nsNativeTheme::IsRangeHorizontal(nsIFram
   nsIFrame* rangeFrame = aFrame;
   if (rangeFrame->GetType() != nsGkAtoms::rangeFrame) {
     rangeFrame = aFrame->GetParent();
   }
   MOZ_ASSERT(rangeFrame->GetType() == nsGkAtoms::rangeFrame);
 
   return static_cast<nsRangeFrame*>(rangeFrame)->IsHorizontal();
 }
+
+bool
+nsNativeTheme::IsDarkBackground(nsIFrame* aFrame)
+{
+  nsIScrollableFrame* scrollFrame = nullptr;
+  while (!scrollFrame && aFrame) {
+    scrollFrame = aFrame->GetScrollTargetFrame();
+    aFrame = aFrame->GetParent();
+  }
+  if (!scrollFrame)
+    return false;
+
+  nsIFrame* frame = scrollFrame->GetScrolledFrame();
+  nsStyleContext* bgSC;
+  if (nsCSSRendering::FindBackground(frame, &bgSC)) {
+    nscolor bgColor = bgSC->StyleBackground()->mBackgroundColor;
+    // Consider the background color dark if the sum of the r, g and b values is
+    // less than 384 in a semi-transparent docement.  This heuristic matches what
+    // WebKit does, and we can improve it later if needed.
+    return NS_GET_A(bgColor) > 127 &&
+           NS_GET_R(bgColor) + NS_GET_G(bgColor) + NS_GET_B(bgColor) < 384;
+  }
+  return false;
+}
--- a/widget/xpwidgets/nsNativeTheme.h
+++ b/widget/xpwidgets/nsNativeTheme.h
@@ -168,13 +168,16 @@ class nsNativeTheme : public nsITimerCal
   bool QueueAnimatedContentForRefresh(nsIContent* aContent,
                                         uint32_t aMinimumFrameRate);
 
   nsIFrame* GetAdjacentSiblingFrameWithSameAppearance(nsIFrame* aFrame,
                                                       bool aNextSibling);
 
   bool IsRangeHorizontal(nsIFrame* aFrame);
 
+  // scrollbar
+  bool IsDarkBackground(nsIFrame* aFrame);
+
  private:
   uint32_t mAnimatedContentTimeout;
   nsCOMPtr<nsITimer> mAnimatedContentTimer;
   nsAutoTArray<nsCOMPtr<nsIContent>, 20> mAnimatedContentList;
 };