Bug 1294102 - Use the original height that is not affected by the top to decide the button style on OSX. r=mstange, a=gchang
authorTooru Fujisawa <arai_a@mac.com>
Sat, 13 Aug 2016 15:34:57 +0900
changeset 342440 314849c716d7027f555283d0370f5bf3d8261be0
parent 342439 6b74a4734d1659dad98b792b1c8fca713ea1b2f3
child 342441 4169e451cbd0677090bdd648f010434b27599c94
push id1183
push userraliiev@mozilla.com
push dateMon, 05 Sep 2016 20:01:49 +0000
treeherdermozilla-release@3148731bed45 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmstange, gchang
bugs1294102
milestone49.0
Bug 1294102 - Use the original height that is not affected by the top to decide the button style on OSX. r=mstange, a=gchang
layout/reftests/bugs/1294102-1-ref.html
layout/reftests/bugs/1294102-1.html
layout/reftests/bugs/reftest.list
widget/cocoa/nsNativeThemeCocoa.h
widget/cocoa/nsNativeThemeCocoa.mm
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/1294102-1-ref.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<html>
+<body>
+<input type="button" style="position: absolute; top: 10.1px; left: 10px; width: 90px; height: 26.3px;" value="M">
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/1294102-1.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<html>
+<body>
+<input type="button" style="position: absolute; top: 10.3px; left: 10px; width: 90px; height: 26.3px;" value="M">
+</body>
+</html>
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -1952,8 +1952,13 @@ fuzzy(100,2000) == 1239564.html 1239564-
 == 1242781.html 1242781-ref.html
 == 1263845.html 1263845-ref.html
 == 1260543-1.html 1260543-1-ref.html
 == 1272997-1.html 1272997-1-ref.html
 random-if(!winWidget) == 1273154-1.html 1273154-1-ref.html # depends on Windows font
 random-if(!winWidget) == 1273154-2.html 1273154-2-ref.html # depends on Windows font
 == 1274368-1.html 1274368-1-ref.html
 == 1275411-1.html 1275411-1-ref.html
+# Buttons in 2 pages have different position and the rendering result can be
+# different, but they should use the same button style and the background color
+# should be same.  |fuzzy()| here allows the difference in border, but not
+# background color.
+fuzzy(255,1000) skip-if(!cocoaWidget) == 1294102-1.html 1294102-1-ref.html
--- a/widget/cocoa/nsNativeThemeCocoa.h
+++ b/widget/cocoa/nsNativeThemeCocoa.h
@@ -118,17 +118,17 @@ protected:
                  int32_t inMaxValue, nsIFrame* aFrame);
   void DrawCheckboxOrRadio(CGContextRef cgContext, bool inCheckbox,
                            const HIRect& inBoxRect, bool inSelected,
                            mozilla::EventStates inState, nsIFrame* aFrame);
   void DrawSearchField(CGContextRef cgContext, const HIRect& inBoxRect,
                        nsIFrame* aFrame, mozilla::EventStates inState);
   void DrawPushButton(CGContextRef cgContext, const HIRect& inBoxRect,
                       mozilla::EventStates inState, uint8_t aWidgetType,
-                      nsIFrame* aFrame);
+                      nsIFrame* aFrame, float aOriginalHeight);
   void DrawMenuIcon(CGContextRef cgContext, const CGRect& aRect,
                     mozilla::EventStates inState, nsIFrame* aFrame,
                     const NSSize& aIconSize, NSString* aImageName,
                     bool aCenterHorizontally);
   void DrawButton(CGContextRef context, ThemeButtonKind inKind,
                   const HIRect& inBoxRect, bool inIsDefault, 
                   ThemeButtonValue inValue, ThemeButtonAdornment inAdornment,
                   mozilla::EventStates inState, nsIFrame* aFrame);
--- a/widget/cocoa/nsNativeThemeCocoa.mm
+++ b/widget/cocoa/nsNativeThemeCocoa.mm
@@ -1209,17 +1209,17 @@ static const CellRenderSettings pushButt
 // The height at which we start doing square buttons instead of rounded buttons
 // Rounded buttons look bad if drawn at a height greater than 26, so at that point
 // we switch over to doing square buttons which looks fine at any size.
 #define DO_SQUARE_BUTTON_HEIGHT 26
 
 void
 nsNativeThemeCocoa::DrawPushButton(CGContextRef cgContext, const HIRect& inBoxRect,
                                    EventStates inState, uint8_t aWidgetType,
-                                   nsIFrame* aFrame)
+                                   nsIFrame* aFrame, float aOriginalHeight)
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
 
   BOOL isActive = FrameIsInActiveWindow(aFrame);
   BOOL isDisabled = IsDisabled(aFrame, inState);
 
   NSButtonCell* cell = (aWidgetType == NS_THEME_BUTTON) ? mPushButtonCell :
     (aWidgetType == NS_THEME_MAC_HELP_BUTTON) ? mHelpButtonCell : mDisclosureButtonCell;
@@ -1239,17 +1239,20 @@ nsNativeThemeCocoa::DrawPushButton(CGCon
 
     DrawCellWithScaling(cell, cgContext, inBoxRect, NSRegularControlSize,
                         NSZeroSize, buttonSize, NULL, mCellDrawView,
                         false); // Don't mirror icon in RTL.
   } else {
     // If the button is tall enough, draw the square button style so that
     // buttons with non-standard content look good. Otherwise draw normal
     // rounded aqua buttons.
-    if (inBoxRect.size.height > DO_SQUARE_BUTTON_HEIGHT) {
+    // This comparison is done based on the height that is calculated without
+    // the top, because the snapped height can be affected by the top of the
+    // rect and that may result in different height depending on the top value.
+    if (aOriginalHeight > DO_SQUARE_BUTTON_HEIGHT) {
       [cell setBezelStyle:NSShadowlessSquareBezelStyle];
       DrawCellWithScaling(cell, cgContext, inBoxRect, NSRegularControlSize,
                           NSZeroSize, NSMakeSize(14, 0), NULL, mCellDrawView,
                           IsFrameRTL(aFrame));
     } else {
       [cell setBezelStyle:NSRoundedBezelStyle];
       DrawCellWithSnapping(cell, cgContext, inBoxRect, pushButtonSettings, 0.5f,
                            mCellDrawView, IsFrameRTL(aFrame), 1.0f);
@@ -2414,26 +2417,28 @@ nsNativeThemeCocoa::DrawWidgetBackground
   DrawTarget& aDrawTarget = *aContext->GetDrawTarget();
 
   // setup to draw into the correct port
   int32_t p2a = aFrame->PresContext()->AppUnitsPerDevPixel();
 
   gfx::Rect nativeDirtyRect = NSRectToRect(aDirtyRect, p2a);
   gfxRect nativeWidgetRect(aRect.x, aRect.y, aRect.width, aRect.height);
   nativeWidgetRect.ScaleInverse(gfxFloat(p2a));
+  float nativeWidgetHeight = round(nativeWidgetRect.Height());
   nativeWidgetRect.Round();
   if (nativeWidgetRect.IsEmpty())
     return NS_OK; // Don't attempt to draw invisible widgets.
 
   AutoRestoreTransform autoRestoreTransform(&aDrawTarget);
 
   bool hidpi = IsHiDPIContext(aFrame->PresContext());
   if (hidpi) {
     // Use high-resolution drawing.
     nativeWidgetRect.Scale(0.5f);
+    nativeWidgetHeight *= 0.5f;
     nativeDirtyRect.Scale(0.5f);
     aDrawTarget.SetTransform(aDrawTarget.GetTransform().PreScale(2.0f, 2.0f));
   }
 
   gfxQuartzNativeDrawing nativeDrawing(aDrawTarget, nativeDirtyRect);
 
   CGContextRef cgContext = nativeDrawing.BeginNativeDrawing();
   if (cgContext == nullptr) {
@@ -2602,28 +2607,30 @@ nsNativeThemeCocoa::DrawWidgetBackground
             !QueueAnimatedContentForRefresh(aFrame->GetContent(), 10)) {
           NS_WARNING("Unable to animate button!");
         }
         DrawButton(cgContext, kThemePushButton, macRect, true,
                    kThemeButtonOff, kThemeAdornmentNone, eventState, aFrame);
       } else if (IsButtonTypeMenu(aFrame)) {
         DrawDropdown(cgContext, macRect, eventState, aWidgetType, aFrame);
       } else {
-        DrawPushButton(cgContext, macRect, eventState, aWidgetType, aFrame);
+        DrawPushButton(cgContext, macRect, eventState, aWidgetType, aFrame,
+                       nativeWidgetHeight);
       }
       break;
 
     case NS_THEME_FOCUS_OUTLINE:
       DrawFocusOutline(cgContext, macRect, eventState, aWidgetType, aFrame);
       break;
 
     case NS_THEME_MAC_HELP_BUTTON:
     case NS_THEME_MAC_DISCLOSURE_BUTTON_OPEN:
     case NS_THEME_MAC_DISCLOSURE_BUTTON_CLOSED:
-      DrawPushButton(cgContext, macRect, eventState, aWidgetType, aFrame);
+      DrawPushButton(cgContext, macRect, eventState, aWidgetType, aFrame,
+                     nativeWidgetHeight);
       break;
 
     case NS_THEME_BUTTON_BEVEL:
       DrawButton(cgContext, kThemeMediumBevelButton, macRect,
                  IsDefaultButton(aFrame), kThemeButtonOff, kThemeAdornmentNone,
                  eventState, aFrame);
       break;