bug 1343802 adjust scrollbar track border to prevent thumb expanding to fill available breadth r?jhorak+328198 draft
authorKarl Tomlinson <karlt+@karlt.net>
Thu, 23 Mar 2017 18:31:16 +1300
changeset 503435 b6c60aa5be6fe3f1c84b897aed40df3260f465aa
parent 503434 3a02aff5a74a4f217b332ec08085e78bdbf287ce
child 503436 e4c70da301998f5afcf46cca7ae0e2d9dc73f89e
push id50576
push userktomlinson@mozilla.com
push dateThu, 23 Mar 2017 06:19:17 +0000
reviewersjhorak
bugs1343802, 328198
milestone55.0a1
bug 1343802 adjust scrollbar track border to prevent thumb expanding to fill available breadth r?jhorak+328198 MozReview-Commit-ID: 7KJGnds0ngL
widget/gtk/gtk3drawing.cpp
--- a/widget/gtk/gtk3drawing.cpp
+++ b/widget/gtk/gtk3drawing.cpp
@@ -2559,43 +2559,46 @@ GetScrollbarMetrics(GtkOrientation aOrie
     if (metrics->initialized)
         return metrics;
 
     metrics->initialized = true;
 
     WidgetNodeType scrollbar = aOrientation == GTK_ORIENTATION_HORIZONTAL ?
         MOZ_GTK_SCROLLBAR_HORIZONTAL : MOZ_GTK_SCROLLBAR_VERTICAL;
 
+    gboolean backward, forward, secondary_backward, secondary_forward;
+    GtkStyleContext* style = ClaimStyleContext(scrollbar);
+    gtk_style_context_get_style(style,
+                                "has-backward-stepper", &backward,
+                                "has-forward-stepper", &forward,
+                                "has-secondary-backward-stepper",
+                                &secondary_backward,
+                                "has-secondary-forward-stepper",
+                                &secondary_forward, nullptr);
+    bool hasButtons =
+        backward || forward || secondary_backward || secondary_forward;
+
     if (gtk_get_minor_version() < 20) {
         gint slider_width, trough_border, stepper_size, min_slider_size;
-        gboolean backward, forward, secondary_backward, secondary_forward;
-
-        GtkStyleContext* style = ClaimStyleContext(scrollbar);
+
         gtk_style_context_get_style(style,
                                     "slider-width", &slider_width,
                                     "trough-border", &trough_border,
                                     "stepper-size", &stepper_size,
                                     "min-slider-length", &min_slider_size,
-                                    "has-backward-stepper", &backward,
-                                    "has-forward-stepper", &forward,
-                                    "has-secondary-backward-stepper",
-                                    &secondary_backward,
-                                    "has-secondary-forward-stepper",
-                                    &secondary_forward, nullptr);
+                                    nullptr);
         ReleaseStyleContext(style);
 
         metrics->size.thumb =
             SizeFromLengthAndBreadth(aOrientation, min_slider_size, slider_width);
         metrics->size.button =
             SizeFromLengthAndBreadth(aOrientation, stepper_size, slider_width);
         // overall scrollbar
         gint breadth = slider_width + 2 * trough_border;
         // Require room for the slider in the track if we don't have buttons.
-        bool hasButtons = backward || forward ||
-            secondary_backward || secondary_forward;
         gint length = hasButtons ? 0 : min_slider_size + 2 * trough_border;
         metrics->size.scrollbar =
             SizeFromLengthAndBreadth(aOrientation, length, breadth);
 
         // Borders on the major axis are set on the outermost scrollbar
         // element to correctly position the buttons when
         // trough-under-steppers is true.
         // Borders on the minor axis are set on the track element so that it
@@ -2612,43 +2615,71 @@ GetScrollbarMetrics(GtkOrientation aOrie
                 metrics->border.track.left =
                 metrics->border.track.right = trough_border;
         }
 
         return metrics;
     }
 
     // GTK version > 3.20
+    // scrollbar
+    metrics->border.scrollbar = GetMarginBorderPadding(style);
+    ReleaseStyleContext(style);
+
     WidgetNodeType contents, track, thumb;
     if (aOrientation == GTK_ORIENTATION_HORIZONTAL) {
         contents = MOZ_GTK_SCROLLBAR_CONTENTS_HORIZONTAL;
         track = MOZ_GTK_SCROLLBAR_TROUGH_HORIZONTAL;
         thumb = MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL;
     } else {
         contents = MOZ_GTK_SCROLLBAR_CONTENTS_VERTICAL;
         track = MOZ_GTK_SCROLLBAR_TROUGH_VERTICAL;
         thumb = MOZ_GTK_SCROLLBAR_THUMB_VERTICAL;
     }
     // thumb
     metrics->size.thumb = GetMinMarginBox(thumb);
     // track
-    GtkStyleContext* style = ClaimStyleContext(track);
+    style = ClaimStyleContext(track);
     metrics->border.track = GetMarginBorderPadding(style);
     ReleaseStyleContext(style);
+    MozGtkSize trackSizeForThumb = metrics->size.thumb + metrics->border.track;
     // button
-    metrics->size.button = GetMinMarginBox(MOZ_GTK_SCROLLBAR_BUTTON);
-    // scrollbar
-    style = ClaimStyleContext(scrollbar);
-    metrics->border.scrollbar = GetMarginBorderPadding(style);
-    ReleaseStyleContext(style);
+    if (hasButtons) {
+        metrics->size.button = GetMinMarginBox(MOZ_GTK_SCROLLBAR_BUTTON);
+        // If the buttons will cause Gecko to expand the track to fill
+        // available breadth, then add to the track border to prevent Gecko
+        // from expanding the thumb to fill available breadth.
+        if (aOrientation == GTK_ORIENTATION_HORIZONTAL) {
+            gint extra = metrics->size.button.height - trackSizeForThumb.height;
+            if (extra > 0) {
+                // If extra is odd, then the thumb is 0.5 pixels above
+                // center as in gtk_range_compute_slider_position().
+                metrics->border.track.top += extra / 2;
+                metrics->border.track.bottom += extra - extra / 2;
+                // Update size for change in border.
+                trackSizeForThumb.height += extra;
+            }
+        } else {
+            gint extra = metrics->size.button.width - trackSizeForThumb.width;
+            if (extra > 0) {
+                // If extra is odd, then the thumb is 0.5 pixels to the left
+                // of center as in gtk_range_compute_slider_position().
+                metrics->border.track.left += extra / 2;
+                metrics->border.track.right += extra - extra / 2;
+                trackSizeForThumb.width += extra;
+            }
+        }
+    }
+
     style = ClaimStyleContext(contents);
     GtkBorder contentsBorder = GetMarginBorderPadding(style);
     ReleaseStyleContext(style);
-    metrics->size.scrollbar = metrics->size.thumb + metrics->border.track +
-        contentsBorder + metrics->border.scrollbar;
+
+    metrics->size.scrollbar =
+        trackSizeForThumb + contentsBorder + metrics->border.scrollbar;
 
     return metrics;
 }
 
 /* cairo_t *cr argument has to be a system-cairo. */
 gint
 moz_gtk_widget_paint(WidgetNodeType widget, cairo_t *cr,
                      GdkRectangle* rect,