diff --git a/widget/gtk/gtk3drawing.cpp b/widget/gtk/gtk3drawing.cpp index 2a481d70b587..e079d46f1a84 100644 --- a/widget/gtk/gtk3drawing.cpp +++ b/widget/gtk/gtk3drawing.cpp @@ -437,6 +437,18 @@ calculate_arrow_rect(GtkWidget* arrow, GdkRectangle* rect, return MOZ_GTK_SUCCESS; } +static MozGtkSize +GetMinContentBox(GtkStyleContext* style) +{ + GtkStateFlags state_flags = gtk_style_context_get_state(style); + gint width, height; + gtk_style_context_get(style, state_flags, + "min-width", &width, + "min-height", &height, + nullptr); + return {width, height}; +} + /** * Get minimum widget size as sum of margin, padding, border and * min-width/min-height. @@ -2639,34 +2651,42 @@ GetScrollbarMetrics(GtkOrientation aOrientation) // track style = ClaimStyleContext(track); metrics->border.track = GetMarginBorderPadding(style); + MozGtkSize trackMinSize = GetMinContentBox(style) + metrics->border.track; ReleaseStyleContext(style); MozGtkSize trackSizeForThumb = metrics->size.thumb + metrics->border.track; // button if (hasButtons) { metrics->size.button = GetMinMarginBox(MOZ_GTK_SCROLLBAR_BUTTON); - if (aOrientation == GTK_ORIENTATION_HORIZONTAL) { - metrics->size.button.Rotate(); - // 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. - 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; - } + } else { + metrics->size.button = {0, 0}; + } + if (aOrientation == GTK_ORIENTATION_HORIZONTAL) { + metrics->size.button.Rotate(); + // If the track is wider than necessary for the thumb, including when + // 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. + gint extra = + std::max(trackMinSize.height, + 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 = + std::max(trackMinSize.width, + 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; } }