diff -up firefox-52.0/widget/gtk/gtk3drawing.cpp.widget-rebase firefox-52.0/widget/gtk/gtk3drawing.cpp --- firefox-52.0/widget/gtk/gtk3drawing.cpp.widget-rebase 2017-02-27 17:11:05.000000000 +0100 +++ firefox-52.0/widget/gtk/gtk3drawing.cpp 2017-03-10 12:20:30.232205991 +0100 @@ -36,6 +36,10 @@ static gboolean is_initialized; 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); + // 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 @@ -167,7 +171,7 @@ moz_gtk_menuitem_get_horizontal_padding( gint moz_gtk_checkmenuitem_get_horizontal_padding(gint* horizontal_padding) { - GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_CHECKMENUITEM_CONTAINER); + GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_CHECKMENUITEM); gtk_style_context_get_style(style, "horizontal-padding", horizontal_padding, nullptr); @@ -463,7 +467,7 @@ moz_gtk_get_widget_min_size(WidgetNodeTy } static void -moz_gtk_rectangle_inset(GdkRectangle* rect, GtkBorder& aBorder) +Inset(GdkRectangle* rect, GtkBorder& aBorder) { MOZ_ASSERT(rect); rect->x += aBorder.left; @@ -472,17 +476,29 @@ moz_gtk_rectangle_inset(GdkRectangle* re rect->height -= aBorder.top + aBorder.bottom; } -/* Subtracting margin is used to inset drawing of element which can have margins, - * like scrollbar, scrollbar's trough, thumb and scrollbar's button */ +// Inset a rectangle by the margins specified in a style context. static void -moz_gtk_subtract_margin(GtkStyleContext* style, GdkRectangle* rect) +InsetByMargin(GdkRectangle* rect, GtkStyleContext* style) { MOZ_ASSERT(rect); GtkBorder margin; gtk_style_context_get_margin(style, gtk_style_context_get_state(style), &margin); - moz_gtk_rectangle_inset(rect, margin); + Inset(rect, margin); +} + +// Inset a rectangle by the border and padding specified in a style context. +static void +InsetByBorderPadding(GdkRectangle* rect, GtkStyleContext* style) +{ + GtkStateFlags state = gtk_style_context_get_state(style); + GtkBorder padding, border; + + gtk_style_context_get_padding(style, state, &padding); + Inset(rect, padding); + gtk_style_context_get_border(style, state, &border); + Inset(rect, border); } static gint @@ -528,7 +544,7 @@ moz_gtk_scrollbar_button_paint(cairo_t * if (gtk_check_version(3,20,0) == nullptr) { // The "trough-border" is not used since GTK 3.20. The stepper margin // box occupies the full width of the "contents" gadget content box. - moz_gtk_subtract_margin(style, &rect); + InsetByMargin(&rect, style); } else { // Scrollbar button has to be inset by trough_border because its DOM // element is filling width of vertical scrollbar's track (or height @@ -601,7 +617,7 @@ moz_gtk_draw_styled_frame(GtkStyleContex { GdkRectangle rect = *aRect; if (gtk_check_version(3, 6, 0) == nullptr) { - moz_gtk_subtract_margin(style, &rect); + InsetByMargin(&rect, style); } gtk_render_background(style, cr, rect.x, rect.y, rect.width, rect.height); gtk_render_frame(style, cr, rect.x, rect.y, rect.width, rect.height); @@ -664,7 +680,7 @@ moz_gtk_scrollbar_thumb_paint(WidgetNode GdkRectangle rect = *aRect; GtkStyleContext* style = ClaimStyleContext(widget, direction, state_flags); - moz_gtk_subtract_margin(style, &rect); + InsetByMargin(&rect, style); gtk_render_slider(style, cr, rect.x, @@ -865,7 +881,7 @@ moz_gtk_entry_paint(cairo_t *cr, GdkRect } static gint -moz_gtk_text_view_paint(cairo_t *cr, GdkRectangle* rect, +moz_gtk_text_view_paint(cairo_t *cr, GdkRectangle* aRect, GtkWidgetState* state, GtkTextDirection direction) { @@ -882,24 +898,24 @@ moz_gtk_text_view_paint(cairo_t *cr, Gdk GtkStyleContext* style_frame = ClaimStyleContext(MOZ_GTK_SCROLLED_WINDOW, direction, state_flags); - gtk_render_frame(style_frame, cr, rect->x, rect->y, rect->width, rect->height); + gtk_render_frame(style_frame, cr, + aRect->x, aRect->y, aRect->width, aRect->height); + + GdkRectangle rect = *aRect; + InsetByBorderPadding(&rect, style_frame); - GtkBorder border, padding; - gtk_style_context_get_border(style_frame, state_flags, &border); - gtk_style_context_get_padding(style_frame, state_flags, &padding); ReleaseStyleContext(style_frame); GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_TEXT_VIEW, direction, state_flags); - - gint xthickness = border.left + padding.left; - gint ythickness = border.top + padding.top; - - gtk_render_background(style, cr, - rect->x + xthickness, rect->y + ythickness, - rect->width - 2 * xthickness, - rect->height - 2 * ythickness); - + gtk_render_background(style, cr, rect.x, rect.y, rect.width, rect.height); + ReleaseStyleContext(style); + // There is a separate "text" window, which usually provides the + // background behind the text. However, this is transparent in Ambiance + // for GTK 3.20, in which case the MOZ_GTK_TEXT_VIEW background is + // visible. + style = ClaimStyleContext(MOZ_GTK_TEXT_VIEW_TEXT, direction, state_flags); + gtk_render_background(style, cr, rect.x, rect.y, rect.width, rect.height); ReleaseStyleContext(style); return MOZ_GTK_SUCCESS; @@ -1291,6 +1307,7 @@ moz_gtk_tooltip_paint(cairo_t *cr, const GdkRectangle rect = *aRect; gtk_render_background(style, cr, rect.x, rect.y, rect.width, rect.height); gtk_render_frame(style, cr, rect.x, rect.y, rect.width, rect.height); + ReleaseStyleContext(style); // Horizontal Box drawing // @@ -1300,33 +1317,26 @@ moz_gtk_tooltip_paint(cairo_t *cr, const // 6px margin. // For drawing Horizontal Box we have to inset drawing area by that 6px // plus its CSS margin. - GtkStyleContext* boxStyle = - CreateStyleForWidget(gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0), style); + GtkStyleContext* boxStyle = ClaimStyleContext(MOZ_GTK_TOOLTIP_BOX, direction); rect.x += 6; rect.y += 6; rect.width -= 12; rect.height -= 12; - moz_gtk_subtract_margin(boxStyle, &rect); + InsetByMargin(&rect, boxStyle); gtk_render_background(boxStyle, cr, rect.x, rect.y, rect.width, rect.height); gtk_render_frame(boxStyle, cr, rect.x, rect.y, rect.width, rect.height); // Label drawing - GtkBorder padding, border; - gtk_style_context_get_padding(boxStyle, GTK_STATE_FLAG_NORMAL, &padding); - moz_gtk_rectangle_inset(&rect, padding); - gtk_style_context_get_border(boxStyle, GTK_STATE_FLAG_NORMAL, &border); - moz_gtk_rectangle_inset(&rect, border); + InsetByBorderPadding(&rect, boxStyle); + ReleaseStyleContext(boxStyle); GtkStyleContext* labelStyle = - CreateStyleForWidget(gtk_label_new(nullptr), boxStyle); + ClaimStyleContext(MOZ_GTK_TOOLTIP_BOX_LABEL, direction); moz_gtk_draw_styled_frame(labelStyle, cr, &rect, false); - g_object_unref(labelStyle); + ReleaseStyleContext(labelStyle); - g_object_unref(boxStyle); - - ReleaseStyleContext(style); return MOZ_GTK_SUCCESS; } @@ -1335,17 +1345,9 @@ moz_gtk_resizer_paint(cairo_t *cr, GdkRe GtkWidgetState* state, GtkTextDirection direction) { - GtkStyleContext* style; - - // gtk_render_handle() draws a background, so use GtkTextView and its - // GTK_STYLE_CLASS_VIEW to match the background with textarea elements. - // The resizer is drawn with shaded variants of the background color, and - // so a transparent background would lead to a transparent resizer. - style = ClaimStyleContext(MOZ_GTK_TEXT_VIEW, GTK_TEXT_DIR_LTR, - GetStateFlagsFromGtkWidgetState(state)); - // TODO - we need to save/restore style when gtk 3.20 CSS node path - // is used - gtk_style_context_add_class(style, GTK_STYLE_CLASS_GRIP); + GtkStyleContext* style = + ClaimStyleContext(MOZ_GTK_RESIZER, GTK_TEXT_DIR_LTR, + GetStateFlagsFromGtkWidgetState(state)); // Workaround unico not respecting the text direction for resizers. // See bug 1174248. @@ -1392,17 +1394,8 @@ moz_gtk_progress_chunk_paint(cairo_t *cr GtkTextDirection direction, WidgetNodeType widget) { - GtkStyleContext* style; - - if (gtk_check_version(3, 20, 0) != nullptr) { - /* Ask for MOZ_GTK_PROGRESS_TROUGH instead of MOZ_GTK_PROGRESSBAR - * because ClaimStyleContext() saves/restores that style */ - style = ClaimStyleContext(MOZ_GTK_PROGRESS_TROUGH, direction); - gtk_style_context_remove_class(style, GTK_STYLE_CLASS_TROUGH); - gtk_style_context_add_class(style, GTK_STYLE_CLASS_PROGRESSBAR); - } else { - style = ClaimStyleContext(MOZ_GTK_PROGRESS_CHUNK, direction); - } + GtkStyleContext* style = + ClaimStyleContext(MOZ_GTK_PROGRESS_CHUNK, direction); if (widget == MOZ_GTK_PROGRESS_CHUNK_INDETERMINATE || widget == MOZ_GTK_PROGRESS_CHUNK_VERTICAL_INDETERMINATE) { @@ -1786,6 +1779,13 @@ static gint moz_gtk_menu_separator_paint(cairo_t *cr, GdkRectangle* rect, GtkTextDirection direction) { + GtkWidgetState defaultState = { 0 }; + moz_gtk_menu_item_paint(MOZ_GTK_MENUSEPARATOR, cr, rect, + &defaultState, direction); + + if (gtk_get_minor_version() >= 20) + return MOZ_GTK_SUCCESS; + GtkStyleContext* style; gboolean wide_separators; gint separator_height; @@ -1833,36 +1833,39 @@ moz_gtk_menu_item_paint(WidgetNodeType w GtkWidgetState* state, GtkTextDirection direction) { gint x, y, w, h; + guint minorVersion = gtk_get_minor_version(); + GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state); - if (state->inHover && !state->disabled) { - GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state); - GtkStyleContext* style = - ClaimStyleContext(widget, direction, state_flags); - - bool pre_3_6 = gtk_check_version(3, 6, 0) != nullptr; - if (pre_3_6) { - // GTK+ 3.4 saves the style context and adds the menubar class to - // menubar children, but does each of these only when drawing, not - // during layout. - gtk_style_context_save(style); - if (widget == MOZ_GTK_MENUBARITEM) { - gtk_style_context_add_class(style, GTK_STYLE_CLASS_MENUBAR); - } + // GTK versions prior to 3.8 render the background and frame only when not + // a separator and in hover prelight. + if (minorVersion < 8 && (widget == MOZ_GTK_MENUSEPARATOR || + !(state_flags & GTK_STATE_FLAG_PRELIGHT))) + return MOZ_GTK_SUCCESS; + + GtkStyleContext* style = ClaimStyleContext(widget, direction, state_flags); + + if (minorVersion < 6) { + // GTK+ 3.4 saves the style context and adds the menubar class to + // menubar children, but does each of these only when drawing, not + // during layout. + gtk_style_context_save(style); + if (widget == MOZ_GTK_MENUBARITEM) { + gtk_style_context_add_class(style, GTK_STYLE_CLASS_MENUBAR); } + } - x = rect->x; - y = rect->y; - w = rect->width; - h = rect->height; + x = rect->x; + y = rect->y; + w = rect->width; + h = rect->height; - gtk_render_background(style, cr, x, y, w, h); - gtk_render_frame(style, cr, x, y, w, h); + gtk_render_background(style, cr, x, y, w, h); + gtk_render_frame(style, cr, x, y, w, h); - if (pre_3_6) { - gtk_style_context_restore(style); - } - ReleaseStyleContext(style); + if (minorVersion < 6) { + gtk_style_context_restore(style); } + ReleaseStyleContext(style); return MOZ_GTK_SUCCESS; } @@ -1882,16 +1885,16 @@ moz_gtk_menu_arrow_paint(cairo_t *cr, Gd return MOZ_GTK_SUCCESS; } -// See gtk_real_check_menu_item_draw_indicator() for reference. +// For reference, see gtk_check_menu_item_size_allocate() in GTK versions after +// 3.20 and gtk_real_check_menu_item_draw_indicator() in earlier versions. static gint -moz_gtk_check_menu_item_paint(cairo_t *cr, GdkRectangle* rect, +moz_gtk_check_menu_item_paint(WidgetNodeType widgetType, + cairo_t *cr, GdkRectangle* rect, GtkWidgetState* state, - gboolean checked, gboolean isradio, - GtkTextDirection direction) + gboolean checked, GtkTextDirection direction) { GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state); GtkStyleContext* style; - GtkBorder padding; gint indicator_size, horizontal_padding; gint x, y; @@ -1901,35 +1904,44 @@ moz_gtk_check_menu_item_paint(cairo_t *c state_flags = static_cast(state_flags|checkbox_check_state); } - style = ClaimStyleContext(isradio ? MOZ_GTK_RADIOMENUITEM_CONTAINER : - MOZ_GTK_CHECKMENUITEM_CONTAINER, - direction); + bool pre_3_20 = gtk_get_minor_version() < 20; + gint offset; + style = ClaimStyleContext(widgetType, direction); gtk_style_context_get_style(style, "indicator-size", &indicator_size, "horizontal-padding", &horizontal_padding, NULL); + if (pre_3_20) { + GtkBorder padding; + gtk_style_context_get_padding(style, state_flags, &padding); + offset = horizontal_padding + padding.left + 2; + } else { + GdkRectangle r = { 0 }; + InsetByMargin(&r, style); + InsetByBorderPadding(&r, style); + offset = r.x; + } ReleaseStyleContext(style); - style = ClaimStyleContext(isradio ? MOZ_GTK_RADIOMENUITEM : - MOZ_GTK_CHECKMENUITEM, - direction, state_flags); - gtk_style_context_get_padding(style, state_flags, &padding); - gint offset = padding.left + 2; + bool isRadio = (widgetType == MOZ_GTK_RADIOMENUITEM); + WidgetNodeType indicatorType = isRadio ? MOZ_GTK_RADIOMENUITEM_INDICATOR + : MOZ_GTK_CHECKMENUITEM_INDICATOR; + style = ClaimStyleContext(indicatorType, direction, state_flags); if (direction == GTK_TEXT_DIR_RTL) { - x = rect->width - indicator_size - offset - horizontal_padding; + x = rect->width - indicator_size - offset; } else { - x = rect->x + offset + horizontal_padding; + x = rect->x + offset; } y = rect->y + (rect->height - indicator_size) / 2; - if (gtk_check_version(3, 20, 0) == nullptr) { + if (!pre_3_20) { gtk_render_background(style, cr, x, y, indicator_size, indicator_size); gtk_render_frame(style, cr, x, y, indicator_size, indicator_size); } - if (isradio) { + if (isRadio) { gtk_render_option(style, cr, x, y, indicator_size, indicator_size); } else { gtk_render_check(style, cr, x, y, indicator_size, indicator_size); @@ -2033,9 +2045,6 @@ moz_gtk_get_widget_border(WidgetNodeType if (widget == MOZ_GTK_TOOLBAR_BUTTON) gtk_style_context_restore(style); - // XXX: Subtract 1 pixel from the border to account for the added - // -moz-focus-inner border (Bug 1228281). - *left -= 1; *top -= 1; *right -= 1; *bottom -= 1; moz_gtk_add_style_border(style, left, top, right, bottom); ReleaseStyleContext(style); @@ -2174,12 +2183,15 @@ moz_gtk_get_widget_border(WidgetNodeType { // Bug 1274143 for MOZ_GTK_MENUBARITEM WidgetNodeType type = - widget == MOZ_GTK_MENUBARITEM || widget == MOZ_GTK_MENUITEM ? - MOZ_GTK_MENUITEM : MOZ_GTK_CHECKMENUITEM_CONTAINER; + widget == MOZ_GTK_MENUBARITEM ? MOZ_GTK_MENUITEM : widget; style = ClaimStyleContext(type); - moz_gtk_add_style_padding(style, left, top, right, bottom); - + if (gtk_get_minor_version() < 20) { + moz_gtk_add_style_padding(style, left, top, right, bottom); + } else { + moz_gtk_add_margin_border_padding(style, + left, top, right, bottom); + } ReleaseStyleContext(style); return MOZ_GTK_SUCCESS; } @@ -2188,7 +2200,6 @@ moz_gtk_get_widget_border(WidgetNodeType break; case MOZ_GTK_TOOLTIP: { - style = ClaimStyleContext(MOZ_GTK_TOOLTIP); // In GTK 3 there are 6 pixels of additional margin around the box. // See details there: // https://github.com/GNOME/gtk/blob/5ea69a136bd7e4970b3a800390e20314665aaed2/gtk/ui/gtktooltipwindow.ui#L11 @@ -2197,21 +2208,16 @@ moz_gtk_get_widget_border(WidgetNodeType // We also need to add margin/padding/borders from Tooltip content. // Tooltip contains horizontal box, where icon and label is put. // We ignore icon as long as we don't have support for it. - GtkStyleContext* boxStyle = - CreateStyleForWidget(gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0), - style); + GtkStyleContext* boxStyle = ClaimStyleContext(MOZ_GTK_TOOLTIP_BOX); moz_gtk_add_margin_border_padding(boxStyle, left, top, right, bottom); + ReleaseStyleContext(boxStyle); - GtkStyleContext* labelStyle = - CreateStyleForWidget(gtk_label_new(nullptr), boxStyle); + GtkStyleContext* labelStyle = ClaimStyleContext(MOZ_GTK_TOOLTIP_BOX_LABEL); moz_gtk_add_margin_border_padding(labelStyle, left, top, right, bottom); + ReleaseStyleContext(labelStyle); - g_object_unref(labelStyle); - g_object_unref(boxStyle); - - ReleaseStyleContext(style); return MOZ_GTK_SUCCESS; } case MOZ_GTK_SCROLLBAR_VERTICAL: @@ -2500,11 +2506,11 @@ void moz_gtk_get_scale_metrics(GtkOrientation orient, gint* scale_width, gint* scale_height) { - WidgetNodeType widget = (orient == GTK_ORIENTATION_HORIZONTAL) ? - MOZ_GTK_SCALE_HORIZONTAL : - MOZ_GTK_SCALE_VERTICAL; - if (gtk_check_version(3, 20, 0) != nullptr) { + WidgetNodeType widget = (orient == GTK_ORIENTATION_HORIZONTAL) ? + MOZ_GTK_SCALE_HORIZONTAL : + MOZ_GTK_SCALE_VERTICAL; + gint thumb_length, thumb_height, trough_border; moz_gtk_get_scalethumb_metrics(orient, &thumb_length, &thumb_height); @@ -2520,12 +2526,10 @@ moz_gtk_get_scale_metrics(GtkOrientation } ReleaseStyleContext(style); } else { - GtkStyleContext* style = ClaimStyleContext(widget); - gtk_style_context_get(style, gtk_style_context_get_state(style), - "min-width", scale_width, - "min-height", scale_height, - nullptr); - ReleaseStyleContext(style); + WidgetNodeType widget = (orient == GTK_ORIENTATION_HORIZONTAL) ? + MOZ_GTK_SCALE_TROUGH_HORIZONTAL : + MOZ_GTK_SCALE_TROUGH_VERTICAL; + moz_gtk_get_widget_min_size(widget, scale_width, scale_height); } } @@ -2548,10 +2552,28 @@ moz_gtk_get_scalethumb_metrics(GtkOrient MOZ_GTK_SCALE_THUMB_HORIZONTAL: MOZ_GTK_SCALE_THUMB_VERTICAL; GtkStyleContext* style = ClaimStyleContext(widget); - gtk_style_context_get(style, gtk_style_context_get_state(style), - "min-width", thumb_length, - "min-height", thumb_height, + + gint min_width, min_height; + GtkStateFlags state = gtk_style_context_get_state(style); + gtk_style_context_get(style, state, + "min-width", &min_width, + "min-height", &min_height, nullptr); + GtkBorder margin; + gtk_style_context_get_margin(style, state, &margin); + gint margin_width = margin.left + margin.right; + gint margin_height = margin.top + margin.bottom; + + // Negative margin of slider element also determines its minimal size + // so use bigger of those two values. + if (min_width < -margin_width) + min_width = -margin_width; + if (min_height < -margin_height) + min_height = -margin_height; + + *thumb_length = min_width; + *thumb_height = min_height; + ReleaseStyleContext(style); } @@ -2791,10 +2813,8 @@ moz_gtk_widget_paint(WidgetNodeType widg break; case MOZ_GTK_CHECKMENUITEM: case MOZ_GTK_RADIOMENUITEM: - return moz_gtk_check_menu_item_paint(cr, rect, state, - (gboolean) flags, - (widget == MOZ_GTK_RADIOMENUITEM), - direction); + return moz_gtk_check_menu_item_paint(widget, cr, rect, state, + (gboolean) flags, direction); break; case MOZ_GTK_SPLITTER_HORIZONTAL: return moz_gtk_vpaned_paint(cr, rect, state); diff -up firefox-52.0/widget/gtk/gtkdrawing.h.widget-rebase firefox-52.0/widget/gtk/gtkdrawing.h --- firefox-52.0/widget/gtk/gtkdrawing.h.widget-rebase 2017-02-27 17:11:05.000000000 +0100 +++ firefox-52.0/widget/gtk/gtkdrawing.h 2017-03-10 12:20:30.233205986 +0100 @@ -145,8 +145,11 @@ typedef enum { MOZ_GTK_ENTRY, /* Paints a GtkExpander. */ MOZ_GTK_EXPANDER, - /* Paints a GtkTextView. */ + /* Paints a GtkTextView or gets the style context corresponding to the + root node of a GtkTextView. */ MOZ_GTK_TEXT_VIEW, + /* The "text" window or node of a GtkTextView */ + MOZ_GTK_TEXT_VIEW_TEXT, /* Paints a GtkOptionMenu. */ MOZ_GTK_DROPDOWN, /* Paints a dropdown arrow (a GtkButton containing a down GtkArrow). */ @@ -160,11 +163,15 @@ typedef enum { MOZ_GTK_TOOLBAR_SEPARATOR, /* Paints a GtkToolTip */ MOZ_GTK_TOOLTIP, + /* Paints a GtkBox from GtkToolTip */ + MOZ_GTK_TOOLTIP_BOX, + /* Paints a GtkLabel of GtkToolTip */ + MOZ_GTK_TOOLTIP_BOX_LABEL, /* Paints a GtkFrame (e.g. a status bar panel). */ MOZ_GTK_FRAME, /* Paints the border of a GtkFrame */ MOZ_GTK_FRAME_BORDER, - /* Paints a resize grip for a GtkWindow */ + /* Paints a resize grip for a GtkTextView */ MOZ_GTK_RESIZER, /* Paints a GtkProgressBar. */ MOZ_GTK_PROGRESSBAR, @@ -210,11 +217,13 @@ typedef enum { MOZ_GTK_MENUBARITEM, /* Paints items of popup menus. */ MOZ_GTK_MENUITEM, - MOZ_GTK_IMAGEMENUITEM, - MOZ_GTK_CHECKMENUITEM_CONTAINER, - MOZ_GTK_RADIOMENUITEM_CONTAINER, + /* Paints a menuitem with check indicator, or the gets the style context for + a menuitem that contains a checkbox. */ MOZ_GTK_CHECKMENUITEM, + /* Gets the style context for a checkbox in a check menuitem. */ + MOZ_GTK_CHECKMENUITEM_INDICATOR, MOZ_GTK_RADIOMENUITEM, + MOZ_GTK_RADIOMENUITEM_INDICATOR, MOZ_GTK_MENUSEPARATOR, /* GtkVPaned base class */ MOZ_GTK_SPLITTER_HORIZONTAL, diff -up firefox-52.0/widget/gtk/mozgtk/mozgtk.c.widget-rebase firefox-52.0/widget/gtk/mozgtk/mozgtk.c --- firefox-52.0/widget/gtk/mozgtk/mozgtk.c.widget-rebase 2017-02-27 17:11:05.000000000 +0100 +++ firefox-52.0/widget/gtk/mozgtk/mozgtk.c 2017-03-10 12:20:30.233205986 +0100 @@ -245,7 +245,6 @@ STUB(gtk_icon_theme_get_icon_sizes) STUB(gtk_icon_theme_lookup_by_gicon) STUB(gtk_icon_theme_lookup_icon) STUB(gtk_image_get_type) -STUB(gtk_image_menu_item_new) STUB(gtk_image_new) STUB(gtk_image_new_from_stock) STUB(gtk_image_set_from_pixbuf) diff -up firefox-52.0/widget/gtk/nsLookAndFeel.cpp.widget-rebase firefox-52.0/widget/gtk/nsLookAndFeel.cpp --- firefox-52.0/widget/gtk/nsLookAndFeel.cpp.widget-rebase 2017-02-27 17:11:05.000000000 +0100 +++ firefox-52.0/widget/gtk/nsLookAndFeel.cpp 2017-03-10 13:54:36.918205357 +0100 @@ -24,6 +24,7 @@ #include "nsStyleConsts.h" #include "gfxFontConstants.h" #include "WidgetUtils.h" +#include "nsIXULRuntime.h" #include @@ -47,9 +48,6 @@ nsLookAndFeel::nsLookAndFeel() : nsXPLookAndFeel(), #if (MOZ_WIDGET_GTK == 2) mStyle(nullptr), -#else - mBackgroundStyle(nullptr), - mButtonStyle(nullptr), #endif mDefaultFontCached(false), mButtonFontCached(false), mFieldFontCached(false), mMenuFontCached(false) @@ -61,13 +59,27 @@ nsLookAndFeel::~nsLookAndFeel() { #if (MOZ_WIDGET_GTK == 2) g_object_unref(mStyle); -#else - g_object_unref(mBackgroundStyle); - g_object_unref(mButtonStyle); #endif } #if MOZ_WIDGET_GTK != 2 +// Modifies color |*aDest| as if a pattern of color |aSource| was painted with +// CAIRO_OPERATOR_OVER to a surface with color |*aDest|. +static void +ApplyColorOver(const GdkRGBA& aSource, GdkRGBA* aDest) { + gdouble sourceCoef = aSource.alpha; + gdouble destCoef = aDest->alpha * (1.0 - sourceCoef); + gdouble resultAlpha = sourceCoef + destCoef; + if (resultAlpha != 0.0) { // don't divide by zero + destCoef /= resultAlpha; + sourceCoef /= resultAlpha; + aDest->red = sourceCoef * aSource.red + destCoef * aDest->red; + aDest->green = sourceCoef * aSource.green + destCoef * aDest->green; + aDest->blue = sourceCoef * aSource.blue + destCoef * aDest->blue; + aDest->alpha = resultAlpha; + } +} + static void GetLightAndDarkness(const GdkRGBA& aColor, double* aLightness, double* aDarkness) @@ -377,30 +389,39 @@ nsLookAndFeel::NativeGetColor(ColorID aI break; #else // css2 http://www.w3.org/TR/REC-CSS2/ui.html#system-colors - case eColorID_activeborder: + case eColorID_activeborder: { // active window border - gtk_style_context_get_border_color(mBackgroundStyle, + GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_WINDOW); + gtk_style_context_get_border_color(style, GTK_STATE_FLAG_NORMAL, &gdk_color); aColor = GDK_RGBA_TO_NS_RGBA(gdk_color); + ReleaseStyleContext(style); break; - case eColorID_inactiveborder: + } + case eColorID_inactiveborder: { // inactive window border - gtk_style_context_get_border_color(mBackgroundStyle, - GTK_STATE_FLAG_INSENSITIVE, + GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_WINDOW); + gtk_style_context_get_border_color(style, + GTK_STATE_FLAG_INSENSITIVE, &gdk_color); aColor = GDK_RGBA_TO_NS_RGBA(gdk_color); + ReleaseStyleContext(style); break; + } case eColorID_graytext: // disabled text in windows, menus, etc. case eColorID_inactivecaptiontext: // text in inactive window caption aColor = sMenuTextInactive; break; - case eColorID_inactivecaption: + case eColorID_inactivecaption: { // inactive window caption - gtk_style_context_get_background_color(mBackgroundStyle, + GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_WINDOW); + gtk_style_context_get_background_color(style, GTK_STATE_FLAG_INSENSITIVE, &gdk_color); aColor = GDK_RGBA_TO_NS_RGBA(gdk_color); + ReleaseStyleContext(style); break; + } #endif case eColorID_infobackground: // tooltip background color @@ -521,18 +542,24 @@ nsLookAndFeel::NativeGetColor(ColorID aI case eColorID__moz_fieldtext: aColor = sMozFieldText; break; - case eColorID__moz_buttondefault: - // default button border color - gtk_style_context_get_border_color(mButtonStyle, + case eColorID__moz_buttondefault: { + // default button border color + GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_BUTTON); + gtk_style_context_get_border_color(style, GTK_STATE_FLAG_NORMAL, &gdk_color); aColor = GDK_RGBA_TO_NS_RGBA(gdk_color); + ReleaseStyleContext(style); break; - case eColorID__moz_buttonhoverface: - gtk_style_context_get_background_color(mButtonStyle, + } + case eColorID__moz_buttonhoverface: { + GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_BUTTON); + gtk_style_context_get_background_color(style, GTK_STATE_FLAG_PRELIGHT, &gdk_color); aColor = GDK_RGBA_TO_NS_RGBA(gdk_color); + ReleaseStyleContext(style); break; + } case eColorID__moz_buttonhovertext: aColor = sButtonHoverText; break; @@ -1029,16 +1056,6 @@ nsLookAndFeel::GetFontImpl(FontID aID, n return true; } -#if (MOZ_WIDGET_GTK == 3) -static GtkStyleContext* -create_context(GtkWidgetPath *path) -{ - GtkStyleContext *style = gtk_style_context_new(); - gtk_style_context_set_path(style, path); - return(style); -} -#endif - void nsLookAndFeel::Init() { @@ -1129,78 +1146,54 @@ nsLookAndFeel::Init() g_object_set(settings, dark_setting, FALSE, nullptr); } - GtkWidgetPath *path = gtk_widget_path_new(); - gtk_widget_path_append_type(path, GTK_TYPE_WINDOW); - - mBackgroundStyle = create_context(path); - gtk_style_context_add_class(mBackgroundStyle, GTK_STYLE_CLASS_BACKGROUND); - - mButtonStyle = create_context(path); - gtk_style_context_add_class(mButtonStyle, GTK_STYLE_CLASS_BUTTON); - // Scrollbar colors - style = create_context(path); - gtk_style_context_add_class(style, GTK_STYLE_CLASS_SCROLLBAR); - gtk_style_context_add_class(style, GTK_STYLE_CLASS_TROUGH); + style = ClaimStyleContext(MOZ_GTK_SCROLLBAR_TROUGH_VERTICAL); gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color); sMozScrollbar = GDK_RGBA_TO_NS_RGBA(color); - g_object_unref(style); + ReleaseStyleContext(style); // Window colors - style = create_context(path); - gtk_style_context_save(style); - gtk_style_context_add_class(style, GTK_STYLE_CLASS_BACKGROUND); + style = ClaimStyleContext(MOZ_GTK_WINDOW); gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color); sMozWindowBackground = GDK_RGBA_TO_NS_RGBA(color); gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color); sMozWindowText = GDK_RGBA_TO_NS_RGBA(color); - gtk_style_context_restore(style); - g_object_unref(style); + ReleaseStyleContext(style); // tooltip foreground and background style = ClaimStyleContext(MOZ_GTK_TOOLTIP); gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color); sInfoBackground = GDK_RGBA_TO_NS_RGBA(color); - { - GtkStyleContext* boxStyle = - CreateStyleForWidget(gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0), - style); - GtkStyleContext* labelStyle = - CreateStyleForWidget(gtk_label_new(nullptr), boxStyle); - gtk_style_context_get_color(labelStyle, GTK_STATE_FLAG_NORMAL, &color); - g_object_unref(labelStyle); - g_object_unref(boxStyle); - } - sInfoText = GDK_RGBA_TO_NS_RGBA(color); ReleaseStyleContext(style); - // menu foreground & menu background - GtkWidget *accel_label = gtk_accel_label_new("M"); - GtkWidget *menuitem = gtk_menu_item_new(); - GtkWidget *menu = gtk_menu_new(); - - g_object_ref_sink(menu); - - gtk_container_add(GTK_CONTAINER(menuitem), accel_label); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); - - style = gtk_widget_get_style_context(accel_label); + style = ClaimStyleContext(MOZ_GTK_TOOLTIP_BOX_LABEL); gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color); - sMenuText = GDK_RGBA_TO_NS_RGBA(color); - gtk_style_context_get_color(style, GTK_STATE_FLAG_INSENSITIVE, &color); - sMenuTextInactive = GDK_RGBA_TO_NS_RGBA(color); + sInfoText = GDK_RGBA_TO_NS_RGBA(color); + ReleaseStyleContext(style); - style = gtk_widget_get_style_context(menu); + style = ClaimStyleContext(MOZ_GTK_MENUITEM); + { + GtkStyleContext* accelStyle = + CreateStyleForWidget(gtk_accel_label_new("M"), style); + gtk_style_context_get_color(accelStyle, GTK_STATE_FLAG_NORMAL, &color); + sMenuText = GDK_RGBA_TO_NS_RGBA(color); + gtk_style_context_get_color(accelStyle, GTK_STATE_FLAG_INSENSITIVE, &color); + sMenuTextInactive = GDK_RGBA_TO_NS_RGBA(color); + g_object_unref(accelStyle); + } + ReleaseStyleContext(style); + + style = ClaimStyleContext(MOZ_GTK_MENUPOPUP); gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color); sMenuBackground = GDK_RGBA_TO_NS_RGBA(color); + ReleaseStyleContext(style); - style = gtk_widget_get_style_context(menuitem); + style = ClaimStyleContext(MOZ_GTK_MENUITEM); gtk_style_context_get_background_color(style, GTK_STATE_FLAG_PRELIGHT, &color); sMenuHover = GDK_RGBA_TO_NS_RGBA(color); gtk_style_context_get_color(style, GTK_STATE_FLAG_PRELIGHT, &color); sMenuHoverText = GDK_RGBA_TO_NS_RGBA(color); - - g_object_unref(menu); + ReleaseStyleContext(style); #endif // button styles @@ -1211,9 +1204,6 @@ nsLookAndFeel::Init() GtkWidget *combobox = gtk_combo_box_new(); GtkWidget *comboboxLabel = gtk_label_new("M"); gtk_container_add(GTK_CONTAINER(combobox), comboboxLabel); -#else - GtkWidget *combobox = gtk_combo_box_new_with_entry(); - GtkWidget *comboboxLabel = gtk_bin_get_child(GTK_BIN(combobox)); #endif GtkWidget *window = gtk_window_new(GTK_WINDOW_POPUP); GtkWidget *treeView = gtk_tree_view_new(); @@ -1227,7 +1217,9 @@ nsLookAndFeel::Init() gtk_container_add(GTK_CONTAINER(parent), button); gtk_container_add(GTK_CONTAINER(parent), treeView); gtk_container_add(GTK_CONTAINER(parent), linkButton); +#if (MOZ_WIDGET_GTK == 2) gtk_container_add(GTK_CONTAINER(parent), combobox); +#endif gtk_container_add(GTK_CONTAINER(parent), menuBar); gtk_menu_shell_append(GTK_MENU_SHELL(menuBar), menuBarItem); gtk_container_add(GTK_CONTAINER(window), parent); @@ -1310,11 +1302,19 @@ nsLookAndFeel::Init() } #else // Text colors - style = gtk_widget_get_style_context(textView); - gtk_style_context_save(style); - gtk_style_context_add_class(style, GTK_STYLE_CLASS_VIEW); - gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color); - sMozFieldBackground = GDK_RGBA_TO_NS_RGBA(color); + GdkRGBA bgColor; + // If the text window background is translucent, then the background of + // the textview root node is visible. + style = ClaimStyleContext(MOZ_GTK_TEXT_VIEW); + gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, + &bgColor); + ReleaseStyleContext(style); + + style = ClaimStyleContext(MOZ_GTK_TEXT_VIEW_TEXT); + gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, + &color); + ApplyColorOver(color, &bgColor); + sMozFieldBackground = GDK_RGBA_TO_NS_RGBA(bgColor); gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color); sMozFieldText = GDK_RGBA_TO_NS_RGBA(color); @@ -1327,26 +1327,34 @@ nsLookAndFeel::Init() static_cast(GTK_STATE_FLAG_FOCUSED|GTK_STATE_FLAG_SELECTED), &color); sTextSelectedText = GDK_RGBA_TO_NS_RGBA(color); - gtk_style_context_restore(style); + ReleaseStyleContext(style); - // Button text, background, border - style = gtk_widget_get_style_context(label); - gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color); - sButtonText = GDK_RGBA_TO_NS_RGBA(color); - gtk_style_context_get_color(style, GTK_STATE_FLAG_PRELIGHT, &color); - sButtonHoverText = GDK_RGBA_TO_NS_RGBA(color); + // Button text color + style = ClaimStyleContext(MOZ_GTK_BUTTON); + { + GtkStyleContext* labelStyle = + CreateStyleForWidget(gtk_label_new("M"), style); + gtk_style_context_get_color(labelStyle, GTK_STATE_FLAG_NORMAL, &color); + sButtonText = GDK_RGBA_TO_NS_RGBA(color); + gtk_style_context_get_color(labelStyle, GTK_STATE_FLAG_PRELIGHT, &color); + sButtonHoverText = GDK_RGBA_TO_NS_RGBA(color); + g_object_unref(labelStyle); + } + ReleaseStyleContext(style); // Combobox text color - style = gtk_widget_get_style_context(comboboxLabel); + style = ClaimStyleContext(MOZ_GTK_COMBOBOX_ENTRY_TEXTAREA); gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color); sComboBoxText = GDK_RGBA_TO_NS_RGBA(color); + ReleaseStyleContext(style); // Menubar text and hover text colors - style = gtk_widget_get_style_context(menuBarItem); + style = ClaimStyleContext(MOZ_GTK_MENUBARITEM); gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color); sMenuBarText = GDK_RGBA_TO_NS_RGBA(color); gtk_style_context_get_color(style, GTK_STATE_FLAG_PRELIGHT, &color); sMenuBarHoverText = GDK_RGBA_TO_NS_RGBA(color); + ReleaseStyleContext(style); // GTK's guide to fancy odd row background colors: // 1) Check if a theme explicitly defines an odd row color @@ -1354,7 +1362,7 @@ nsLookAndFeel::Init() // slightly by a hardcoded value (gtkstyle.c) // 3) If neither are defined, take the base background color and // darken that by a hardcoded value - style = gtk_widget_get_style_context(treeView); + style = ClaimStyleContext(MOZ_GTK_TREEVIEW); // Get odd row background color gtk_style_context_save(style); @@ -1362,8 +1370,7 @@ nsLookAndFeel::Init() gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color); sOddCellBackground = GDK_RGBA_TO_NS_RGBA(color); gtk_style_context_restore(style); - - gtk_widget_path_free(path); + ReleaseStyleContext(style); // GtkFrame has a "border" subnode on which Adwaita draws the border. // Some themes do not draw on this node but draw a border on the widget @@ -1448,12 +1455,6 @@ nsLookAndFeel::RefreshImpl() #if (MOZ_WIDGET_GTK == 2) g_object_unref(mStyle); mStyle = nullptr; -#else - g_object_unref(mBackgroundStyle); - g_object_unref(mButtonStyle); - - mBackgroundStyle = nullptr; - mButtonStyle = nullptr; #endif Init(); diff -up firefox-52.0/widget/gtk/WidgetStyleCache.cpp.widget-rebase firefox-52.0/widget/gtk/WidgetStyleCache.cpp --- firefox-52.0/widget/gtk/WidgetStyleCache.cpp.widget-rebase 2017-02-27 17:11:05.000000000 +0100 +++ firefox-52.0/widget/gtk/WidgetStyleCache.cpp 2017-03-10 12:20:30.235205976 +0100 @@ -434,15 +434,6 @@ CreateScrolledWindowWidget() } static GtkWidget* -CreateTextViewWidget() -{ - GtkWidget* widget = gtk_text_view_new(); - gtk_container_add(GTK_CONTAINER(GetWidget(MOZ_GTK_SCROLLED_WINDOW)), - widget); - return widget; -} - -static GtkWidget* CreateMenuSeparatorWidget() { GtkWidget* widget = gtk_separator_menu_item_new(); @@ -591,8 +582,6 @@ CreateWidget(WidgetNodeType aWidgetType) return CreateEntryWidget(); case MOZ_GTK_SCROLLED_WINDOW: return CreateScrolledWindowWidget(); - case MOZ_GTK_TEXT_VIEW: - return CreateTextViewWidget(); case MOZ_GTK_TREEVIEW: return CreateTreeViewWidget(); case MOZ_GTK_TREE_HEADER_CELL: @@ -744,16 +733,38 @@ GetWidgetRootStyle(WidgetNodeType aNodeT case MOZ_GTK_MENUITEM: style = CreateStyleForWidget(gtk_menu_item_new(), MOZ_GTK_MENUPOPUP); break; - case MOZ_GTK_IMAGEMENUITEM: - style = CreateStyleForWidget(gtk_image_menu_item_new(), MOZ_GTK_MENUPOPUP); - break; - case MOZ_GTK_CHECKMENUITEM_CONTAINER: + case MOZ_GTK_CHECKMENUITEM: style = CreateStyleForWidget(gtk_check_menu_item_new(), MOZ_GTK_MENUPOPUP); break; - case MOZ_GTK_RADIOMENUITEM_CONTAINER: + case MOZ_GTK_RADIOMENUITEM: style = CreateStyleForWidget(gtk_radio_menu_item_new(nullptr), MOZ_GTK_MENUPOPUP); break; + case MOZ_GTK_TEXT_VIEW: + style = CreateStyleForWidget(gtk_text_view_new(), + MOZ_GTK_SCROLLED_WINDOW); + break; + case MOZ_GTK_TOOLTIP: + if (gtk_check_version(3, 20, 0) != nullptr) { + // The tooltip style class is added first in CreateTooltipWidget() + // and transfered to style in CreateStyleForWidget(). + GtkWidget* tooltipWindow = CreateTooltipWidget(); + style = CreateStyleForWidget(tooltipWindow, nullptr); + gtk_widget_destroy(tooltipWindow); // Release GtkWindow self-reference. + } else { + // We create this from the path because GtkTooltipWindow is not public. + style = CreateCSSNode("tooltip", nullptr, GTK_TYPE_TOOLTIP); + gtk_style_context_add_class(style, GTK_STYLE_CLASS_BACKGROUND); + } + break; + case MOZ_GTK_TOOLTIP_BOX: + style = CreateStyleForWidget(gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0), + MOZ_GTK_TOOLTIP); + break; + case MOZ_GTK_TOOLTIP_BOX_LABEL: + style = CreateStyleForWidget(gtk_label_new(nullptr), + MOZ_GTK_TOOLTIP_BOX); + break; default: GtkWidget* widget = GetWidget(aNodeType); MOZ_ASSERT(widget); @@ -827,13 +838,13 @@ GetCssNodeStyleInternal(WidgetNodeType a style = CreateChildCSSNode(GTK_STYLE_CLASS_CHECK, MOZ_GTK_CHECKBUTTON_CONTAINER); break; - case MOZ_GTK_RADIOMENUITEM: + case MOZ_GTK_RADIOMENUITEM_INDICATOR: style = CreateChildCSSNode(GTK_STYLE_CLASS_RADIO, - MOZ_GTK_RADIOMENUITEM_CONTAINER); + MOZ_GTK_RADIOMENUITEM); break; - case MOZ_GTK_CHECKMENUITEM: + case MOZ_GTK_CHECKMENUITEM_INDICATOR: style = CreateChildCSSNode(GTK_STYLE_CLASS_CHECK, - MOZ_GTK_CHECKMENUITEM_CONTAINER); + MOZ_GTK_CHECKMENUITEM); break; case MOZ_GTK_PROGRESS_TROUGH: /* Progress bar background (trough) */ @@ -844,11 +855,6 @@ GetCssNodeStyleInternal(WidgetNodeType a style = CreateChildCSSNode("progress", MOZ_GTK_PROGRESS_TROUGH); break; - case MOZ_GTK_TOOLTIP: - // We create this from the path because GtkTooltipWindow is not public. - style = CreateCSSNode("tooltip", nullptr, GTK_TYPE_TOOLTIP); - gtk_style_context_add_class(style, GTK_STYLE_CLASS_BACKGROUND); - break; case MOZ_GTK_GRIPPER: // TODO - create from CSS node return GetWidgetStyleWithClass(MOZ_GTK_GRIPPER, @@ -865,10 +871,28 @@ GetCssNodeStyleInternal(WidgetNodeType a // TODO - create from CSS node return GetWidgetStyleWithClass(MOZ_GTK_SCROLLED_WINDOW, GTK_STYLE_CLASS_FRAME); - case MOZ_GTK_TEXT_VIEW: - // TODO - create from CSS node - return GetWidgetStyleWithClass(MOZ_GTK_TEXT_VIEW, - GTK_STYLE_CLASS_VIEW); + case MOZ_GTK_TEXT_VIEW_TEXT: + case MOZ_GTK_RESIZER: + style = CreateChildCSSNode("text", MOZ_GTK_TEXT_VIEW); + if (aNodeType == MOZ_GTK_RESIZER) { + // The "grip" class provides the correct builtin icon from + // gtk_render_handle(). The icon is drawn with shaded variants of + // the background color, and so a transparent background would lead to + // a transparent resizer. gtk_render_handle() also uses the + // background color to draw a background, and so this style otherwise + // matches what is used in GtkTextView to match the background with + // textarea elements. + GdkRGBA color; + gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, + &color); + if (color.alpha == 0.0) { + g_object_unref(style); + style = CreateStyleForWidget(gtk_text_view_new(), + MOZ_GTK_SCROLLED_WINDOW); + } + gtk_style_context_add_class(style, GTK_STYLE_CLASS_GRIP); + } + break; case MOZ_GTK_FRAME_BORDER: style = CreateChildCSSNode("border", MOZ_GTK_FRAME); break; @@ -971,27 +995,20 @@ GetWidgetStyleInternal(WidgetNodeType aN case MOZ_GTK_CHECKBUTTON: return GetWidgetStyleWithClass(MOZ_GTK_CHECKBUTTON_CONTAINER, GTK_STYLE_CLASS_CHECK); - case MOZ_GTK_RADIOMENUITEM: - return GetWidgetStyleWithClass(MOZ_GTK_RADIOMENUITEM_CONTAINER, + case MOZ_GTK_RADIOMENUITEM_INDICATOR: + return GetWidgetStyleWithClass(MOZ_GTK_RADIOMENUITEM, GTK_STYLE_CLASS_RADIO); - case MOZ_GTK_CHECKMENUITEM: - return GetWidgetStyleWithClass(MOZ_GTK_CHECKMENUITEM_CONTAINER, + case MOZ_GTK_CHECKMENUITEM_INDICATOR: + return GetWidgetStyleWithClass(MOZ_GTK_CHECKMENUITEM, GTK_STYLE_CLASS_CHECK); case MOZ_GTK_PROGRESS_TROUGH: return GetWidgetStyleWithClass(MOZ_GTK_PROGRESSBAR, GTK_STYLE_CLASS_TROUGH); - case MOZ_GTK_TOOLTIP: { - GtkStyleContext* style = sStyleStorage[aNodeType]; - if (style) - return style; - - // The tooltip style class is added first in CreateTooltipWidget() so - // that gtk_widget_path_append_for_widget() in CreateStyleForWidget() - // will find it. - GtkWidget* tooltipWindow = CreateTooltipWidget(); - style = CreateStyleForWidget(tooltipWindow, nullptr); - gtk_widget_destroy(tooltipWindow); // Release GtkWindow self-reference. - sStyleStorage[aNodeType] = style; + case MOZ_GTK_PROGRESS_CHUNK: { + GtkStyleContext* style = + GetWidgetStyleWithClass(MOZ_GTK_PROGRESSBAR, + GTK_STYLE_CLASS_PROGRESSBAR); + gtk_style_context_remove_class(style, GTK_STYLE_CLASS_TROUGH); return style; } case MOZ_GTK_GRIPPER: @@ -1006,9 +1023,25 @@ GetWidgetStyleInternal(WidgetNodeType aN case MOZ_GTK_SCROLLED_WINDOW: return GetWidgetStyleWithClass(MOZ_GTK_SCROLLED_WINDOW, GTK_STYLE_CLASS_FRAME); - case MOZ_GTK_TEXT_VIEW: - return GetWidgetStyleWithClass(MOZ_GTK_TEXT_VIEW, - GTK_STYLE_CLASS_VIEW); + case MOZ_GTK_TEXT_VIEW_TEXT: + case MOZ_GTK_RESIZER: { + // GTK versions prior to 3.20 do not have the view class on the root + // node, but add this to determine the background for the text window. + GtkStyleContext* style = + GetWidgetStyleWithClass(MOZ_GTK_TEXT_VIEW, GTK_STYLE_CLASS_VIEW); + if (aNodeType == MOZ_GTK_RESIZER) { + // The "grip" class provides the correct builtin icon from + // gtk_render_handle(). The icon is drawn with shaded variants of + // the background color, and so a transparent background would lead to + // a transparent resizer. gtk_render_handle() also uses the + // background color to draw a background, and so this style otherwise + // matches MOZ_GTK_TEXT_VIEW_TEXT to match the background with + // textarea elements. GtkTextView creates a separate text window and + // so the background should not be transparent. + gtk_style_context_add_class(style, GTK_STYLE_CLASS_GRIP); + } + return style; + } case MOZ_GTK_FRAME_BORDER: return GetWidgetRootStyle(MOZ_GTK_FRAME); case MOZ_GTK_TREEVIEW_VIEW: