Bug 1370757 - Improve widget overflow calculation. r?mattwoodrow draft
authorMarkus Stange <mstange@themasta.com>
Wed, 07 Jun 2017 15:05:31 -0400
changeset 592155 1a4f0e6bc57372b42e8d60cfbf0008fa99df55b7
parent 592154 f6473095261e82fc679219e0caf75e6ac2abb5cd
child 592156 df5ac8d4082b5357bac9f7bf866186c8620ffd4e
child 592157 51838032f328d7f32802cea01b84b485256bd8b1
child 592158 7a75a8d5354c2a9001d926befd6e2d87a04eb8e1
push id63299
push userbmo:mstange@themasta.com
push dateSat, 10 Jun 2017 19:30:58 +0000
reviewersmattwoodrow
bugs1370757
milestone55.0a1
Bug 1370757 - Improve widget overflow calculation. r?mattwoodrow This fixes HiDPI and adds overflow for meter bars. Meter bars should probably have their intrinsic size fixed instead, but keeping the existing behavior for them is less risky. MozReview-Commit-ID: xF83bqdDlz
widget/cocoa/nsNativeThemeCocoa.mm
--- a/widget/cocoa/nsNativeThemeCocoa.mm
+++ b/widget/cocoa/nsNativeThemeCocoa.mm
@@ -2268,20 +2268,20 @@ nsNativeThemeCocoa::IsParentScrollbarRol
 {
   nsIFrame* scrollbarFrame = GetParentScrollbarFrame(aFrame);
   return nsLookAndFeel::UseOverlayScrollbars()
     ? CheckBooleanAttr(scrollbarFrame, nsGkAtoms::hover)
     : GetContentState(scrollbarFrame, NS_THEME_NONE).HasState(NS_EVENT_STATE_HOVER);
 }
 
 static bool
-IsHiDPIContext(nsPresContext* aContext)
+IsHiDPIContext(nsDeviceContext* aContext)
 {
   return nsPresContext::AppUnitsPerCSSPixel() >=
-    2 * aContext->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom();
+    2 * aContext->AppUnitsPerDevPixelAtUnitFullZoom();
 }
 
 NS_IMETHODIMP
 nsNativeThemeCocoa::DrawWidgetBackground(nsRenderingContext* aContext,
                                          nsIFrame* aFrame,
                                          uint8_t aWidgetType,
                                          const nsRect& aRect,
                                          const nsRect& aDirtyRect)
@@ -2306,17 +2306,17 @@ nsNativeThemeCocoa::DrawWidgetBackground
   // sure our surface is big enough for that.
   // For example, DrawCellWithSnapping snaps the drawing rect, and that can
   // result in us drawing outside of what we thought the bounds were.
   // The 5 is just a guess of how much margin we need to handle that.
   nativeDirtyRect.Inflate(5);
 
   AutoRestoreTransform autoRestoreTransform(&aDrawTarget);
 
-  bool hidpi = IsHiDPIContext(aFrame->PresContext());
+  bool hidpi = IsHiDPIContext(aFrame->PresContext()->DeviceContext());
   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));
   }
 
@@ -3088,17 +3088,17 @@ nsNativeThemeCocoa::GetWidgetBorder(nsDe
       break;
     }
 
     case NS_THEME_STATUSBAR:
       aResult->SizeTo(1, 0, 0, 0);
       break;
   }
 
-  if (IsHiDPIContext(aFrame->PresContext())) {
+  if (IsHiDPIContext(aContext)) {
     *aResult = *aResult + *aResult; // doubled
   }
 
   return NS_OK;
 
   NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
 }
 
@@ -3125,17 +3125,17 @@ nsNativeThemeCocoa::GetWidgetPadding(nsD
   }
   return false;
 }
 
 bool
 nsNativeThemeCocoa::GetWidgetOverflow(nsDeviceContext* aContext, nsIFrame* aFrame,
                                       uint8_t aWidgetType, nsRect* aOverflowRect)
 {
-  int32_t p2a = aFrame->PresContext()->AppUnitsPerDevPixel();
+  nsIntMargin overflow;
   switch (aWidgetType) {
     case NS_THEME_BUTTON:
     case NS_THEME_MAC_DISCLOSURE_BUTTON_OPEN:
     case NS_THEME_MAC_DISCLOSURE_BUTTON_CLOSED:
     case NS_THEME_MAC_HELP_BUTTON:
     case NS_THEME_TOOLBARBUTTON:
     case NS_THEME_NUMBER_INPUT:
     case NS_THEME_TEXTFIELD:
@@ -3143,42 +3143,50 @@ nsNativeThemeCocoa::GetWidgetOverflow(ns
     case NS_THEME_SEARCHFIELD:
     case NS_THEME_LISTBOX:
     case NS_THEME_MENULIST:
     case NS_THEME_MENULIST_BUTTON:
     case NS_THEME_MENULIST_TEXTFIELD:
     case NS_THEME_CHECKBOX:
     case NS_THEME_RADIO:
     case NS_THEME_TAB:
+    case NS_THEME_FOCUS_OUTLINE:
     {
-      // We assume that the above widgets can draw a focus ring that will be less than
-      // or equal to 4 pixels thick.
-      nsIntMargin extraSize = nsIntMargin(kMaxFocusRingWidth,
-                                          kMaxFocusRingWidth,
-                                          kMaxFocusRingWidth,
-                                          kMaxFocusRingWidth);
-      nsMargin m(NSIntPixelsToAppUnits(extraSize.top, p2a),
-                 NSIntPixelsToAppUnits(extraSize.right, p2a),
-                 NSIntPixelsToAppUnits(extraSize.bottom, p2a),
-                 NSIntPixelsToAppUnits(extraSize.left, p2a));
-      aOverflowRect->Inflate(m);
-      return true;
+      overflow.SizeTo(kMaxFocusRingWidth,
+                      kMaxFocusRingWidth,
+                      kMaxFocusRingWidth,
+                      kMaxFocusRingWidth);
+      break;
     }
     case NS_THEME_PROGRESSBAR:
     {
-      // Progress bars draw a 2 pixel white shadow under their progress indicators
-      nsMargin m(0, 0, NSIntPixelsToAppUnits(2, p2a), 0);
-      aOverflowRect->Inflate(m);
-      return true;
+      // Progress bars draw a 2 pixel white shadow under their progress indicators.
+      overflow.bottom = 2;
+      break;
+    }
+    case NS_THEME_METERBAR:
+    {
+      // Meter bars overflow their boxes by about 2 pixels.
+      overflow.SizeTo(2, 2, 2, 2);
+      break;
     }
-    case NS_THEME_FOCUS_OUTLINE:
-    {
-      aOverflowRect->Inflate(NSIntPixelsToAppUnits(2, p2a));
-      return true;
-    }
+  }
+
+  if (IsHiDPIContext(aContext)) {
+    // Double the number of device pixels.
+    overflow += overflow;
+  }
+
+  if (overflow != nsIntMargin()) {
+    int32_t p2a = aFrame->PresContext()->AppUnitsPerDevPixel();
+    aOverflowRect->Inflate(nsMargin(NSIntPixelsToAppUnits(overflow.top, p2a),
+                                    NSIntPixelsToAppUnits(overflow.right, p2a),
+                                    NSIntPixelsToAppUnits(overflow.bottom, p2a),
+                                    NSIntPixelsToAppUnits(overflow.left, p2a)));
+    return true;
   }
 
   return false;
 }
 
 static const int32_t kRegularScrollbarThumbMinSize = 26;
 static const int32_t kSmallScrollbarThumbMinSize = 26;
 
@@ -3492,17 +3500,17 @@ nsNativeThemeCocoa::GetMinimumWidgetSize
       HIPoint pnt = { 0, 0 };
       HIRect bounds;
       HIThemeGetGrowBoxBounds(&pnt, &drawInfo, &bounds);
       aResult->SizeTo(bounds.size.width, bounds.size.height);
       *aIsOverridable = false;
     }
   }
 
-  if (IsHiDPIContext(aPresContext)) {
+  if (IsHiDPIContext(aPresContext->DeviceContext())) {
     *aResult = *aResult * 2;
   }
 
   return NS_OK;
 
   NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
 }