Bug 1690700 - Make non-native GTK scrollbars more configurable. r=mstange
authorEmilio Cobos Álvarez <emilio@crisal.io>
Thu, 04 Feb 2021 16:22:35 +0000
changeset 566013 8529f7bef5b95ec28712fc89c9f2748a87361e14
parent 566012 d4bd35d3c25ddbdb94e99c7aaeea6d238f8fa61f
child 566014 0f49cded2ff868b4a4048f07d4cf892db8e542ab
push id38173
push userbtara@mozilla.com
push dateFri, 05 Feb 2021 09:34:54 +0000
treeherdermozilla-central@48895a7f84a6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmstange
bugs1690700, 1690494
milestone87.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1690700 - Make non-native GTK scrollbars more configurable. r=mstange This makes it easier to play with different appearances, and it shouldn't be significantly slower. This was useful for my investigation in bug 1690494. Differential Revision: https://phabricator.services.mozilla.com/D103968
modules/libpref/init/StaticPrefList.yaml
widget/gtk/nsNativeBasicThemeGTK.cpp
--- a/modules/libpref/init/StaticPrefList.yaml
+++ b/modules/libpref/init/StaticPrefList.yaml
@@ -10477,16 +10477,47 @@
   type: RelaxedAtomicBool
 #if defined(XP_LINUX) && defined(NIGHTLY_BUILD) && !defined(ANDROID)
   value: true
 #else
   value: false
 #endif
   mirror: always
 
+# The size in CSS pixels at full zoom of the minimum scrollbar width.
+- name: widget.gtk.non-native.scrollbar.normal-size
+  type: uint32_t
+  value: 12
+  mirror: always
+
+# The size in CSS pixels at full zoom of the "thin" scrollbars.
+- name: widget.gtk.non-native.scrollbar.thin-size
+  type: uint32_t
+  value: 6
+  mirror: always
+
+# The amount of space that the thumb should fill the scrollbar, from zero to
+# one.
+- name: widget.gtk.non-native.scrollbar.thumb-size
+  type: float
+  value: 0.75
+  mirror: always
+
+# The minimum size of the scroll thumb, in the scrollbar direction.
+- name: widget.gtk.non-native.scrollbar.thumb-cross-size
+  type: uint32_t
+  value: 40
+  mirror: always
+
+# Whether the thumb should be rounded for the non-native scrollbars.
+- name: widget.gtk.non-native.round-thumb
+  type: bool
+  value: true
+  mirror: always
+
 # Preference to disable dark scrollbar implementation.
 # This is mainly for testing because dark scrollbars have to be semi-
 # transparent, but many reftests expect scrollbars to look identical
 # among different backgrounds.
 # However, some users may want to disable this as well.
 - name: widget.disable-dark-scrollbar
   type: bool
   value: false
--- a/widget/gtk/nsNativeBasicThemeGTK.cpp
+++ b/widget/gtk/nsNativeBasicThemeGTK.cpp
@@ -2,25 +2,22 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsNativeBasicThemeGTK.h"
 
 #include "nsLayoutUtils.h"
 #include "mozilla/dom/Document.h"
+#include "mozilla/StaticPrefs_widget.h"
 
 using namespace mozilla;
 
-static constexpr CSSCoord kGtkMinimumScrollbarSize = 12;
-static constexpr CSSCoord kGtkMinimumThinScrollbarSize = 6;
-static constexpr CSSCoord kGtkMinimumScrollbarThumbSize = 40;
-
 already_AddRefed<nsITheme> do_GetBasicNativeThemeDoNotUseDirectly() {
-  static mozilla::StaticRefPtr<nsITheme> gInstance;
+  static StaticRefPtr<nsITheme> gInstance;
   if (MOZ_UNLIKELY(!gInstance)) {
     gInstance = new nsNativeBasicThemeGTK();
     ClearOnShutdown(&gInstance);
   }
   return do_AddRef(gInstance);
 }
 
 nsITheme::Transparency nsNativeBasicThemeGTK::GetWidgetTransparency(
@@ -36,19 +33,20 @@ nsITheme::Transparency nsNativeBasicThem
   }
   return nsNativeBasicTheme::GetWidgetTransparency(aFrame, aAppearance);
 }
 
 auto nsNativeBasicThemeGTK::GetScrollbarSizes(nsPresContext* aPresContext,
                                               StyleScrollbarWidth aWidth,
                                               Overlay) -> ScrollbarSizes {
   DPIRatio dpiRatio = GetDPIRatioForScrollbarPart(aPresContext);
-  CSSCoord size = aWidth == StyleScrollbarWidth::Thin
-                      ? kGtkMinimumThinScrollbarSize
-                      : kGtkMinimumScrollbarSize;
+  CSSCoord size =
+      aWidth == StyleScrollbarWidth::Thin
+          ? StaticPrefs::widget_gtk_non_native_scrollbar_thin_size()
+          : StaticPrefs::widget_gtk_non_native_scrollbar_normal_size();
   LayoutDeviceIntCoord s = (size * dpiRatio).Truncated();
   return {s, s};
 }
 
 NS_IMETHODIMP
 nsNativeBasicThemeGTK::GetMinimumWidgetSize(nsPresContext* aPresContext,
                                             nsIFrame* aFrame,
                                             StyleAppearance aAppearance,
@@ -61,44 +59,57 @@ nsNativeBasicThemeGTK::GetMinimumWidgetS
 
   DPIRatio dpiRatio = GetDPIRatioForScrollbarPart(aPresContext);
   ComputedStyle* style = nsLayoutUtils::StyleForScrollbar(aFrame);
   auto sizes = GetScrollbarSizes(
       aPresContext, style->StyleUIReset()->mScrollbarWidth, Overlay::No);
   MOZ_ASSERT(sizes.mHorizontal == sizes.mVertical);
   aResult->SizeTo(sizes.mHorizontal, sizes.mHorizontal);
 
-  switch (aAppearance) {
-    case StyleAppearance::ScrollbarHorizontal:
-    case StyleAppearance::ScrollbarthumbHorizontal:
-      aResult->width = kGtkMinimumScrollbarThumbSize * dpiRatio;
-      break;
-    case StyleAppearance::ScrollbarVertical:
-    case StyleAppearance::ScrollbarthumbVertical:
-      aResult->height = kGtkMinimumScrollbarThumbSize * dpiRatio;
-      break;
-    default:
-      break;
+  if (aAppearance == StyleAppearance::ScrollbarHorizontal ||
+      aAppearance == StyleAppearance::ScrollbarVertical ||
+      aAppearance == StyleAppearance::ScrollbarthumbHorizontal ||
+      aAppearance == StyleAppearance::ScrollbarthumbVertical) {
+    CSSCoord thumbSize(
+        StaticPrefs::widget_gtk_non_native_scrollbar_thumb_cross_size());
+    const bool isVertical =
+        aAppearance == StyleAppearance::ScrollbarVertical ||
+        aAppearance == StyleAppearance::ScrollbarthumbVertical;
+    if (isVertical) {
+      aResult->height = thumbSize * dpiRatio;
+    } else {
+      aResult->width = thumbSize * dpiRatio;
+    }
   }
 
   *aIsOverridable = true;
   return NS_OK;
 }
 
 void nsNativeBasicThemeGTK::PaintScrollbarThumb(
     DrawTarget* aDrawTarget, const LayoutDeviceRect& aRect, bool aHorizontal,
     nsIFrame* aFrame, const ComputedStyle& aStyle,
     const EventStates& aElementState, const EventStates& aDocumentState,
     DPIRatio aDpiRatio) {
   sRGBColor thumbColor =
       ComputeScrollbarThumbColor(aFrame, aStyle, aElementState, aDocumentState);
+
   LayoutDeviceRect thumbRect(aRect);
-  thumbRect.Deflate(floorf((aHorizontal ? aRect.height : aRect.width) / 4.0f));
+
+  {
+    float factor = std::max(
+        0.0f, 1.0f - StaticPrefs::widget_gtk_non_native_scrollbar_thumb_size());
+    thumbRect.Deflate((aHorizontal ? aRect.height : aRect.width) * factor);
+  }
+
   LayoutDeviceCoord radius =
-      (aHorizontal ? thumbRect.height : thumbRect.width) / 2.0f;
+      StaticPrefs::widget_gtk_non_native_round_thumb()
+          ? (aHorizontal ? thumbRect.height : thumbRect.width) / 2.0f
+          : 0.0f;
+
   PaintRoundedRectWithRadius(aDrawTarget, thumbRect, thumbColor, sRGBColor(), 0,
                              radius / aDpiRatio, aDpiRatio);
 }
 
 void nsNativeBasicThemeGTK::PaintScrollbar(DrawTarget* aDrawTarget,
                                            const LayoutDeviceRect& aRect,
                                            bool aHorizontal, nsIFrame* aFrame,
                                            const ComputedStyle& aStyle,
@@ -106,18 +117,20 @@ void nsNativeBasicThemeGTK::PaintScrollb
                                            DPIRatio aDpiRatio) {
   auto [trackColor, borderColor] =
       ComputeScrollbarColors(aFrame, aStyle, aDocumentState);
   Unused << borderColor;
   aDrawTarget->FillRect(aRect.ToUnknownRect(),
                         gfx::ColorPattern(ToDeviceColor(trackColor)));
 }
 
-void nsNativeBasicThemeGTK::PaintScrollCorner(
-    DrawTarget* aDrawTarget, const LayoutDeviceRect& aRect, nsIFrame* aFrame,
-    const ComputedStyle& aStyle, const EventStates& aDocumentState,
-    DPIRatio aDpiRatio) {
+void nsNativeBasicThemeGTK::PaintScrollCorner(DrawTarget* aDrawTarget,
+                                              const LayoutDeviceRect& aRect,
+                                              nsIFrame* aFrame,
+                                              const ComputedStyle& aStyle,
+                                              const EventStates& aDocumentState,
+                                              DPIRatio aDpiRatio) {
   auto [trackColor, borderColor] =
       ComputeScrollbarColors(aFrame, aStyle, aDocumentState);
   Unused << borderColor;
   aDrawTarget->FillRect(aRect.ToUnknownRect(),
                         gfx::ColorPattern(ToDeviceColor(trackColor)));
 }