bug 1343802 draw trough centered instead of filling the scrollbar r?jhorak
to follow the behavior of version 3.20 GtkRange's contents_gadget.
MozReview-Commit-ID: BQE6mQqsan8
--- a/widget/gtk/gtk3drawing.cpp
+++ b/widget/gtk/gtk3drawing.cpp
@@ -34,16 +34,19 @@ static ScrollbarGTKMetrics sScrollbarMet
static gint
moz_gtk_get_tab_thickness(GtkStyleContext *style);
static gint
moz_gtk_menu_item_paint(WidgetNodeType widget, cairo_t *cr, GdkRectangle* rect,
GtkWidgetState* state, GtkTextDirection direction);
+static GtkBorder
+GetMarginBorderPadding(GtkStyleContext* aStyle);
+
// GetStateFlagsFromGtkWidgetState() can be safely used for the specific
// GtkWidgets that set both prelight and active flags. For other widgets,
// either the GtkStateFlags or Gecko's GtkWidgetState need to be carefully
// adjusted to match GTK behavior. Although GTK sets insensitive and focus
// flags in the generic GtkWidget base class, GTK adds prelight and active
// flags only to widgets that are expected to demonstrate prelight or active
// states. This contrasts with HTML where any element may have :active and
// :hover states, and so Gecko's GtkStateFlags do not necessarily map to GTK
@@ -646,22 +649,47 @@ moz_gtk_draw_styled_frame(GtkStyleContex
if (drawFocus) {
gtk_render_focus(style, cr,
rect.x, rect.y, rect.width, rect.height);
}
}
static gint
moz_gtk_scrollbar_trough_paint(WidgetNodeType widget,
- cairo_t *cr, const GdkRectangle* rect,
+ cairo_t *cr, const GdkRectangle* aRect,
GtkWidgetState* state,
GtkTextDirection direction)
{
- GtkStyleContext* style = ClaimStyleContext(widget, direction);
- moz_gtk_draw_styled_frame(style, cr, rect, state->focused);
+ GdkRectangle rect = *aRect;
+ GtkStyleContext* style;
+
+ if (gtk_get_minor_version() >= 20) {
+ WidgetNodeType thumb = widget == MOZ_GTK_SCROLLBAR_TROUGH_VERTICAL ?
+ MOZ_GTK_SCROLLBAR_THUMB_VERTICAL :
+ MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL;
+ MozGtkSize thumbSize = GetMinMarginBox(thumb);
+ style = ClaimStyleContext(widget, direction);
+ MozGtkSize trackSize = GetMinContentBox(style);
+ trackSize.Include(thumbSize);
+ trackSize += GetMarginBorderPadding(style);
+ // Gecko's trough |aRect| fills available breadth, but GTK's trough is
+ // centered in the contents_gadget. The centering here round left
+ // and up, like gtk_box_gadget_allocate_child().
+ if (widget == MOZ_GTK_SCROLLBAR_TROUGH_VERTICAL) {
+ rect.x += (rect.width - trackSize.width)/2;
+ rect.width = trackSize.width;
+ } else {
+ rect.y += (rect.height - trackSize.height)/2;
+ rect.height = trackSize.height;
+ }
+ } else {
+ style = ClaimStyleContext(widget, direction);
+ }
+
+ moz_gtk_draw_styled_frame(style, cr, &rect, state->focused);
ReleaseStyleContext(style);
return MOZ_GTK_SUCCESS;
}
static gint
moz_gtk_scrollbar_paint(WidgetNodeType widget,
cairo_t *cr, const GdkRectangle* rect,
--- a/widget/gtk/gtkdrawing.h
+++ b/widget/gtk/gtkdrawing.h
@@ -41,21 +41,31 @@ typedef struct {
/**
* A size in the same GTK pixel units as GtkBorder and GdkRectangle.
*/
struct MozGtkSize {
gint width;
gint height;
+ MozGtkSize& operator+=(const GtkBorder& aBorder)
+ {
+ width += aBorder.left + aBorder.right;
+ height += aBorder.top + aBorder.bottom;
+ return *this;
+ }
MozGtkSize operator+(const GtkBorder& aBorder) const
{
- gint resultWidth = width + aBorder.left + aBorder.right;
- gint resultHeight = height + aBorder.top + aBorder.bottom;
- return {resultWidth, resultHeight};
+ MozGtkSize result = *this;
+ return result += aBorder;
+ }
+ void Include(MozGtkSize aOther)
+ {
+ width = std::max(width, aOther.width);
+ height = std::max(height, aOther.height);
}
void Rotate()
{
gint tmp = width;
width = height;
height = tmp;
}
};