Changeset 193896 in webkit


Ignore:
Timestamp:
Dec 10, 2015 2:15:36 AM (8 years ago)
Author:
Michael Catanzaro
Message:

[GTK] RenderThemeGtk::platformActiveSelectionBackgroundColor, et. al. should not clobber state of cached GtkStyleContexts
https://bugs.webkit.org/show_bug.cgi?id=151533

Reviewed by Carlos Garcia Campos.

Remove the style context cache to simplify the code, drastically reduce the number of
expensive save/restore operations performed on style contexts, and avoid unwanted
side-effects in RenderThemeGtk::styleColor. This is also a speculative fix for improper
button rendering with certain custom themes, and a simplification that will make it easier
to fix bug #150550.

This change does have performance implications, which I intend to check on the perf bot
after landing to ensure that removing the cache does not have a significant negative impact
on performance; I have no clue whether this will be a net performance win or loss. However,
this is a bit tricky, because the bot is running GTK+ 3.16, whereas I expect save/restore
might be much more expensive in GTK+ 3.20, and I do not want to make performance decisions
except based on the latest GTK+ due to large changes in the implementation of
GtkStyleContext.

  • rendering/RenderThemeGtk.cpp:

(WebCore::createStyleContext):
(WebCore::getStockIconForWidgetType):
(WebCore::getStockSymbolicIconForWidgetType):
(WebCore::RenderThemeGtk::initMediaColors):
(WebCore::RenderThemeGtk::adjustRepaintRect):
(WebCore::setToggleSize):
(WebCore::paintToggle):
(WebCore::RenderThemeGtk::setCheckboxSize):
(WebCore::RenderThemeGtk::setRadioSize):
(WebCore::RenderThemeGtk::paintButton):
(WebCore::getComboBoxMetrics):
(WebCore::RenderThemeGtk::paintMenuList):
(WebCore::RenderThemeGtk::paintTextField):
(WebCore::RenderThemeGtk::paintSliderTrack):
(WebCore::RenderThemeGtk::paintSliderThumb):
(WebCore::RenderThemeGtk::adjustSliderThumbSize):
(WebCore::RenderThemeGtk::paintProgressBar):
(WebCore::RenderThemeGtk::adjustInnerSpinButtonStyle):
(WebCore::RenderThemeGtk::paintInnerSpinButton):
(WebCore::styleColor):
(WebCore::gtkStyleChangedCallback): Deleted.
(WebCore::styleContextMap): Deleted.
(WebCore::getStyleContext): Deleted.

Location:
trunk/Source/WebCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r193894 r193896  
     12015-12-10  Michael Catanzaro  <mcatanzaro@igalia.com>
     2
     3        [GTK] RenderThemeGtk::platformActiveSelectionBackgroundColor, et. al. should not clobber state of cached GtkStyleContexts
     4        https://bugs.webkit.org/show_bug.cgi?id=151533
     5
     6        Reviewed by Carlos Garcia Campos.
     7
     8        Remove the style context cache to simplify the code, drastically reduce the number of
     9        expensive save/restore operations performed on style contexts, and avoid unwanted
     10        side-effects in RenderThemeGtk::styleColor. This is also a speculative fix for improper
     11        button rendering with certain custom themes, and a simplification that will make it easier
     12        to fix bug #150550.
     13
     14        This change does have performance implications, which I intend to check on the perf bot
     15        after landing to ensure that removing the cache does not have a significant negative impact
     16        on performance; I have no clue whether this will be a net performance win or loss. However,
     17        this is a bit tricky, because the bot is running GTK+ 3.16, whereas I expect save/restore
     18        might be much more expensive in GTK+ 3.20, and I do not want to make performance decisions
     19        except based on the latest GTK+ due to large changes in the implementation of
     20        GtkStyleContext.
     21
     22        * rendering/RenderThemeGtk.cpp:
     23        (WebCore::createStyleContext):
     24        (WebCore::getStockIconForWidgetType):
     25        (WebCore::getStockSymbolicIconForWidgetType):
     26        (WebCore::RenderThemeGtk::initMediaColors):
     27        (WebCore::RenderThemeGtk::adjustRepaintRect):
     28        (WebCore::setToggleSize):
     29        (WebCore::paintToggle):
     30        (WebCore::RenderThemeGtk::setCheckboxSize):
     31        (WebCore::RenderThemeGtk::setRadioSize):
     32        (WebCore::RenderThemeGtk::paintButton):
     33        (WebCore::getComboBoxMetrics):
     34        (WebCore::RenderThemeGtk::paintMenuList):
     35        (WebCore::RenderThemeGtk::paintTextField):
     36        (WebCore::RenderThemeGtk::paintSliderTrack):
     37        (WebCore::RenderThemeGtk::paintSliderThumb):
     38        (WebCore::RenderThemeGtk::adjustSliderThumbSize):
     39        (WebCore::RenderThemeGtk::paintProgressBar):
     40        (WebCore::RenderThemeGtk::adjustInnerSpinButtonStyle):
     41        (WebCore::RenderThemeGtk::paintInnerSpinButton):
     42        (WebCore::styleColor):
     43        (WebCore::gtkStyleChangedCallback): Deleted.
     44        (WebCore::styleContextMap): Deleted.
     45        (WebCore::getStyleContext): Deleted.
     46
    1472015-12-10  Myles C. Maxfield  <mmaxfield@apple.com>
    248
  • trunk/Source/WebCore/rendering/RenderThemeGtk.cpp

    r192731 r193896  
    137137static const int minSpinButtonArrowSize = 6;
    138138
    139 typedef HashMap<GType, GRefPtr<GtkStyleContext>> StyleContextMap;
    140 static StyleContextMap& styleContextMap();
    141 
    142139static void gtkStyleChangedCallback(GObject*, GParamSpec*)
    143140{
    144     for (const auto& styleContext : styleContextMap())
    145         gtk_style_context_invalidate(styleContext.value.get());
    146141    static_cast<ScrollbarThemeGtk&>(ScrollbarTheme::theme()).themeChanged();
    147142    Page::updateStyleForAllPagesAfterGlobalChangeInEnvironment();
    148143}
    149144
    150 static StyleContextMap& styleContextMap()
    151 {
    152     static NeverDestroyed<StyleContextMap> map;
     145static GRefPtr<GtkStyleContext> createStyleContext(GType widgetType)
     146{
    153147    static bool initialized = false;
    154148    if (!initialized) {
     
    158152        initialized = true;
    159153    }
    160     return map;
    161 }
    162 
    163 static GtkStyleContext* getStyleContext(GType widgetType)
    164 {
    165     StyleContextMap::AddResult result = styleContextMap().add(widgetType, nullptr);
    166     if (!result.isNewEntry)
    167         return result.iterator->value.get();
    168154
    169155    GtkWidgetPath* path = gtk_widget_path_new();
     
    196182    gtk_widget_path_free(path);
    197183
    198     result.iterator->value = context;
    199     return context.get();
     184    return context;
    200185}
    201186
     
    204189    ASSERT(iconName);
    205190
    206     GtkStyleContext* context = getStyleContext(widgetType);
    207     GtkIconSet* iconSet = gtk_style_context_lookup_icon_set(context, iconName);
    208 
    209     gtk_style_context_save(context);
     191    GRefPtr<GtkStyleContext> context = createStyleContext(widgetType);
     192    GtkIconSet* iconSet = gtk_style_context_lookup_icon_set(context.get(), iconName);
    210193
    211194    guint flags = 0;
     
    215198        flags |= GTK_STATE_FLAG_INSENSITIVE;
    216199
    217     gtk_style_context_set_state(context, static_cast<GtkStateFlags>(flags));
    218     gtk_style_context_set_direction(context, static_cast<GtkTextDirection>(direction));
    219     GdkPixbuf* icon = gtk_icon_set_render_icon_pixbuf(iconSet, context, static_cast<GtkIconSize>(iconSize));
    220 
    221     gtk_style_context_restore(context);
     200    gtk_style_context_set_state(context.get(), static_cast<GtkStateFlags>(flags));
     201    gtk_style_context_set_direction(context.get(), static_cast<GtkTextDirection>(direction));
     202    GdkPixbuf* icon = gtk_icon_set_render_icon_pixbuf(iconSet, context.get(), static_cast<GtkIconSize>(iconSize));
    222203
    223204    return adoptGRef(icon);
     
    226207static GRefPtr<GdkPixbuf> getStockSymbolicIconForWidgetType(GType widgetType, const char* symbolicIconName, const char* fallbackStockIconName, gint direction, gint state, gint iconSize)
    227208{
    228     GtkStyleContext* context = getStyleContext(widgetType);
    229 
    230     gtk_style_context_save(context);
     209    GRefPtr<GtkStyleContext> context = createStyleContext(widgetType);
    231210
    232211    guint flags = 0;
     
    236215        flags |= GTK_STATE_FLAG_INSENSITIVE;
    237216
    238     gtk_style_context_set_state(context, static_cast<GtkStateFlags>(flags));
    239     gtk_style_context_set_direction(context, static_cast<GtkTextDirection>(direction));
     217    gtk_style_context_set_state(context.get(), static_cast<GtkStateFlags>(flags));
     218    gtk_style_context_set_direction(context.get(), static_cast<GtkTextDirection>(direction));
    240219
    241220    GUniquePtr<GtkIconInfo> info(gtk_icon_theme_lookup_icon(gtk_icon_theme_get_default(), symbolicIconName, iconSize,
     
    243222    GdkPixbuf* icon = nullptr;
    244223    if (info)
    245         icon = gtk_icon_info_load_symbolic_for_context(info.get(), context, nullptr, nullptr);
    246 
    247     gtk_style_context_restore(context);
     224        icon = gtk_icon_info_load_symbolic_for_context(info.get(), context.get(), nullptr, nullptr);
    248225
    249226    if (!icon) {
     
    272249{
    273250    GdkRGBA color;
    274     GtkStyleContext* containerContext = getStyleContext(GTK_TYPE_CONTAINER);
    275 
    276     gtk_style_context_save(containerContext);
    277 
    278     gtk_style_context_set_state(containerContext, GTK_STATE_FLAG_NORMAL);
    279     gtk_style_context_get_background_color(containerContext, gtk_style_context_get_state(containerContext), &color);
     251    GRefPtr<GtkStyleContext> containerContext = createStyleContext(GTK_TYPE_CONTAINER);
     252
     253    gtk_style_context_set_state(containerContext.get(), GTK_STATE_FLAG_NORMAL);
     254    gtk_style_context_get_background_color(containerContext.get(), gtk_style_context_get_state(containerContext.get()), &color);
    280255    m_panelColor = color;
    281     gtk_style_context_set_state(containerContext, GTK_STATE_FLAG_ACTIVE);
    282     gtk_style_context_get_background_color(containerContext, gtk_style_context_get_state(containerContext), &color);
     256    gtk_style_context_set_state(containerContext.get(), GTK_STATE_FLAG_ACTIVE);
     257    gtk_style_context_get_background_color(containerContext.get(), gtk_style_context_get_state(containerContext.get()), &color);
    283258    m_sliderColor = color;
    284     gtk_style_context_set_state(containerContext, GTK_STATE_FLAG_SELECTED);
    285     gtk_style_context_get_background_color(containerContext, gtk_style_context_get_state(containerContext), &color);
     259    gtk_style_context_set_state(containerContext.get(), GTK_STATE_FLAG_SELECTED);
     260    gtk_style_context_get_background_color(containerContext.get(), gtk_style_context_get_state(containerContext.get()), &color);
    286261    m_sliderThumbColor = color;
    287 
    288     gtk_style_context_restore(containerContext);
    289262}
    290263
     
    423396void RenderThemeGtk::adjustRepaintRect(const RenderObject& renderObject, FloatRect& rect)
    424397{
    425     GtkStyleContext* context = 0;
     398    GRefPtr<GtkStyleContext> context;
    426399    bool checkInteriorFocus = false;
    427400    ControlPart part = renderObject.style().appearance();
     
    429402    case CheckboxPart:
    430403    case RadioPart:
    431         context = getStyleContext(part == CheckboxPart ? GTK_TYPE_CHECK_BUTTON : GTK_TYPE_RADIO_BUTTON);
     404        context = createStyleContext(part == CheckboxPart ? GTK_TYPE_CHECK_BUTTON : GTK_TYPE_RADIO_BUTTON);
    432405
    433406        gint indicatorSpacing;
    434         gtk_style_context_get_style(context, "indicator-spacing", &indicatorSpacing, nullptr);
     407        gtk_style_context_get_style(context.get(), "indicator-spacing", &indicatorSpacing, nullptr);
    435408        rect.inflate(indicatorSpacing);
    436409
     
    438411    case SliderVerticalPart:
    439412    case SliderHorizontalPart:
    440         context = getStyleContext(GTK_TYPE_SCALE);
     413        context = createStyleContext(GTK_TYPE_SCALE);
    441414        break;
    442415    case ButtonPart:
    443416    case MenulistButtonPart:
    444417    case MenulistPart:
    445         context = getStyleContext(GTK_TYPE_BUTTON);
     418        context = createStyleContext(GTK_TYPE_BUTTON);
    446419        checkInteriorFocus = true;
    447420        break;
    448421    case TextFieldPart:
    449422    case TextAreaPart:
    450         context = getStyleContext(GTK_TYPE_ENTRY);
     423        context = createStyleContext(GTK_TYPE_ENTRY);
    451424        checkInteriorFocus = true;
    452425        break;
     
    458431    if (checkInteriorFocus) {
    459432        gboolean interiorFocus;
    460         gtk_style_context_get_style(context, "interior-focus", &interiorFocus, nullptr);
     433        gtk_style_context_get_style(context.get(), "interior-focus", &interiorFocus, nullptr);
    461434        if (interiorFocus)
    462435            return;
    463436    }
    464     adjustRectForFocus(context, rect);
     437    adjustRectForFocus(context.get(), rect);
    465438}
    466439
     
    472445}
    473446
    474 static void setToggleSize(GtkStyleContext* context, RenderStyle& style)
    475 {
     447static void setToggleSize(GType widgetType, RenderStyle& style)
     448{
     449    GRefPtr<GtkStyleContext> context = createStyleContext(widgetType);
     450
    476451    // The width and height are both specified, so we shouldn't change them.
    477452    if (!style.width().isIntrinsicOrAuto() && !style.height().isAuto())
     
    482457    // It could be made a configuration option values other than 13 actually break site compatibility.
    483458    gint indicatorSize;
    484     gtk_style_context_get_style(context, "indicator-size", &indicatorSize, nullptr);
     459    gtk_style_context_get_style(context.get(), "indicator-size", &indicatorSize, nullptr);
    485460
    486461    if (style.width().isIntrinsicOrAuto())
     
    493468static void paintToggle(const RenderThemeGtk* theme, GType widgetType, const RenderObject& renderObject, const PaintInfo& paintInfo, const IntRect& fullRect)
    494469{
    495     GtkStyleContext* context = getStyleContext(widgetType);
    496     gtk_style_context_save(context);
     470    GRefPtr<GtkStyleContext> context = createStyleContext(widgetType);
    497471
    498472    // Some themes do not render large toggle buttons properly, so we simply
     
    501475    // buttons to be a smaller size is that we don't want to break site layouts.
    502476    gint indicatorSize;
    503     gtk_style_context_get_style(context, "indicator-size", &indicatorSize, nullptr);
     477    gtk_style_context_get_style(context.get(), "indicator-size", &indicatorSize, nullptr);
    504478    IntRect rect(fullRect);
    505479    if (rect.width() > indicatorSize) {
     
    513487    }
    514488
    515     gtk_style_context_set_direction(context, static_cast<GtkTextDirection>(gtkTextDirection(renderObject.style().direction())));
    516     gtk_style_context_add_class(context, widgetType == GTK_TYPE_CHECK_BUTTON ? GTK_STYLE_CLASS_CHECK : GTK_STYLE_CLASS_RADIO);
     489    gtk_style_context_set_direction(context.get(), static_cast<GtkTextDirection>(gtkTextDirection(renderObject.style().direction())));
     490    gtk_style_context_add_class(context.get(), widgetType == GTK_TYPE_CHECK_BUTTON ? GTK_STYLE_CLASS_CHECK : GTK_STYLE_CLASS_RADIO);
    517491
    518492    guint flags = 0;
     
    531505    if (theme->isPressed(renderObject))
    532506        flags |= GTK_STATE_FLAG_SELECTED;
    533     gtk_style_context_set_state(context, static_cast<GtkStateFlags>(flags));
     507    gtk_style_context_set_state(context.get(), static_cast<GtkStateFlags>(flags));
    534508
    535509    if (widgetType == GTK_TYPE_CHECK_BUTTON)
    536         gtk_render_check(context, paintInfo.context().platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height());
     510        gtk_render_check(context.get(), paintInfo.context().platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height());
    537511    else
    538         gtk_render_option(context, paintInfo.context().platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height());
     512        gtk_render_option(context.get(), paintInfo.context().platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height());
    539513
    540514    if (theme->isFocused(renderObject)) {
    541515        IntRect indicatorRect(rect);
    542516        gint indicatorSpacing;
    543         gtk_style_context_get_style(context, "indicator-spacing", &indicatorSpacing, nullptr);
     517        gtk_style_context_get_style(context.get(), "indicator-spacing", &indicatorSpacing, nullptr);
    544518        indicatorRect.inflate(indicatorSpacing);
    545         gtk_render_focus(context, paintInfo.context().platformContext()->cr(), indicatorRect.x(), indicatorRect.y(),
     519        gtk_render_focus(context.get(), paintInfo.context().platformContext()->cr(), indicatorRect.x(), indicatorRect.y(),
    546520            indicatorRect.width(), indicatorRect.height());
    547521    }
    548 
    549     gtk_style_context_restore(context);
    550522}
    551523
    552524void RenderThemeGtk::setCheckboxSize(RenderStyle& style) const
    553525{
    554     setToggleSize(getStyleContext(GTK_TYPE_CHECK_BUTTON), style);
     526    setToggleSize(GTK_TYPE_CHECK_BUTTON, style);
    555527}
    556528
     
    563535void RenderThemeGtk::setRadioSize(RenderStyle& style) const
    564536{
    565     setToggleSize(getStyleContext(GTK_TYPE_RADIO_BUTTON), style);
     537    setToggleSize(GTK_TYPE_RADIO_BUTTON, style);
    566538}
    567539
     
    640612bool RenderThemeGtk::paintButton(const RenderObject& renderObject, const PaintInfo& paintInfo, const IntRect& rect)
    641613{
    642     GtkStyleContext* context = getStyleContext(GTK_TYPE_BUTTON);
    643     gtk_style_context_save(context);
    644 
    645     gtk_style_context_set_direction(context, static_cast<GtkTextDirection>(gtkTextDirection(renderObject.style().direction())));
    646     gtk_style_context_add_class(context, GTK_STYLE_CLASS_BUTTON);
    647 
    648     renderButton(this, context, renderObject, paintInfo, rect);
    649 
    650     gtk_style_context_restore(context);
     614    GRefPtr<GtkStyleContext> context = createStyleContext(GTK_TYPE_BUTTON);
     615
     616    gtk_style_context_set_direction(context.get(), static_cast<GtkTextDirection>(gtkTextDirection(renderObject.style().direction())));
     617    gtk_style_context_add_class(context.get(), GTK_STYLE_CLASS_BUTTON);
     618
     619    renderButton(this, context.get(), renderObject, paintInfo, rect);
    651620
    652621    return false;
     
    674643        return;
    675644
    676     GtkStyleContext* context = getStyleContext(GTK_TYPE_COMBO_BOX);
    677     gtk_style_context_save(context);
    678 
    679     gtk_style_context_add_class(context, GTK_STYLE_CLASS_BUTTON);
    680     gtk_style_context_set_direction(context, static_cast<GtkTextDirection>(gtkTextDirection(style.direction())));
    681 
    682     gtk_style_context_set_state(context, static_cast<GtkStateFlags>(0));
    683     gtk_style_context_get_border(context, gtk_style_context_get_state(context), &border);
     645    GRefPtr<GtkStyleContext> context = createStyleContext(GTK_TYPE_COMBO_BOX);
     646
     647    gtk_style_context_add_class(context.get(), GTK_STYLE_CLASS_BUTTON);
     648    gtk_style_context_set_direction(context.get(), static_cast<GtkTextDirection>(gtkTextDirection(style.direction())));
     649
     650    gtk_style_context_set_state(context.get(), static_cast<GtkStateFlags>(0));
     651    gtk_style_context_get_border(context.get(), gtk_style_context_get_state(context.get()), &border);
    684652
    685653    gboolean interiorFocus;
    686654    gint focusWidth, focusPad;
    687     gtk_style_context_get_style(context, "interior-focus", &interiorFocus, "focus-line-width", &focusWidth, "focus-padding", &focusPad, nullptr);
     655    gtk_style_context_get_style(context.get(), "interior-focus", &interiorFocus, "focus-line-width", &focusWidth, "focus-padding", &focusPad, nullptr);
    688656    focus = interiorFocus ? focusWidth + focusPad : 0;
    689657
    690     gtk_style_context_restore(context);
    691 
    692     context = getStyleContext(GTK_TYPE_SEPARATOR);
    693     gtk_style_context_save(context);
     658    context = createStyleContext(GTK_TYPE_SEPARATOR);
    694659
    695660    GtkTextDirection direction = static_cast<GtkTextDirection>(gtkTextDirection(style.direction()));
    696     gtk_style_context_set_direction(context, direction);
    697     gtk_style_context_add_class(context, "separator");
     661    gtk_style_context_set_direction(context.get(), direction);
     662    gtk_style_context_add_class(context.get(), "separator");
    698663
    699664    gboolean wideSeparators;
    700665    gint separatorWidth;
    701     gtk_style_context_get_style(context, "wide-separators", &wideSeparators, "separator-width", &separatorWidth, nullptr);
     666    gtk_style_context_get_style(context.get(), "wide-separators", &wideSeparators, "separator-width", &separatorWidth, nullptr);
    702667
    703668    // GTK+ always uses border.left, regardless of text direction. See gtkseperator.c.
     
    706671
    707672    separator = separatorWidth;
    708 
    709     gtk_style_context_restore(context);
    710673}
    711674
     
    757720
    758721    // Paint the button.
    759     GtkStyleContext* buttonStyleContext = getStyleContext(GTK_TYPE_BUTTON);
    760     gtk_style_context_save(buttonStyleContext);
    761     gtk_style_context_set_direction(buttonStyleContext, direction);
    762     gtk_style_context_add_class(buttonStyleContext, GTK_STYLE_CLASS_BUTTON);
    763     renderButton(this, buttonStyleContext, renderObject, paintInfo, rect);
     722    GRefPtr<GtkStyleContext> buttonStyleContext = createStyleContext(GTK_TYPE_BUTTON);
     723    gtk_style_context_set_direction(buttonStyleContext.get(), direction);
     724    gtk_style_context_add_class(buttonStyleContext.get(), GTK_STYLE_CLASS_BUTTON);
     725    renderButton(this, buttonStyleContext.get(), renderObject, paintInfo, rect);
    764726
    765727    // Get the inner rectangle.
     
    767729    GtkBorder* innerBorderPtr = 0;
    768730    GtkBorder innerBorder = { 1, 1, 1, 1 };
    769     gtk_style_context_get_style(buttonStyleContext, "inner-border", &innerBorderPtr, "focus-line-width", &focusWidth, "focus-padding", &focusPad, nullptr);
     731    gtk_style_context_get_style(buttonStyleContext.get(), "inner-border", &innerBorderPtr, "focus-line-width", &focusWidth, "focus-padding", &focusPad, nullptr);
    770732    if (innerBorderPtr) {
    771733        innerBorder = *innerBorderPtr;
     
    774736
    775737    GtkBorder borderWidth;
    776     GtkStateFlags state = gtk_style_context_get_state(buttonStyleContext);
    777     gtk_style_context_get_border(buttonStyleContext, state, &borderWidth);
     738    GtkStateFlags state = gtk_style_context_get_state(buttonStyleContext.get());
     739    gtk_style_context_get_border(buttonStyleContext.get(), state, &borderWidth);
    778740
    779741    focusWidth += focusPad;
     
    787749        gint childDisplacementX;
    788750        gint childDisplacementY;
    789         gtk_style_context_get_style(buttonStyleContext, "child-displacement-x", &childDisplacementX, "child-displacement-y", &childDisplacementY, nullptr);
     751        gtk_style_context_get_style(buttonStyleContext.get(), "child-displacement-x", &childDisplacementX, "child-displacement-y", &childDisplacementY, nullptr);
    790752        innerRect.move(childDisplacementX, childDisplacementY);
    791753    }
     
    793755    innerRect.setHeight(std::max(1, innerRect.height()));
    794756
    795     gtk_style_context_restore(buttonStyleContext);
    796 
    797757    // Paint the arrow.
    798     GtkStyleContext* arrowStyleContext = getStyleContext(GTK_TYPE_ARROW);
    799     gtk_style_context_save(arrowStyleContext);
    800 
    801     gtk_style_context_set_direction(arrowStyleContext, direction);
    802     gtk_style_context_add_class(arrowStyleContext, "arrow");
    803     gtk_style_context_add_class(arrowStyleContext, GTK_STYLE_CLASS_BUTTON);
     758    GRefPtr<GtkStyleContext> arrowStyleContext = createStyleContext(GTK_TYPE_ARROW);
     759
     760    gtk_style_context_set_direction(arrowStyleContext.get(), direction);
     761    gtk_style_context_add_class(arrowStyleContext.get(), "arrow");
     762    gtk_style_context_add_class(arrowStyleContext.get(), GTK_STYLE_CLASS_BUTTON);
    804763
    805764    gfloat arrowScaling;
    806     gtk_style_context_get_style(arrowStyleContext, "arrow-scaling", &arrowScaling, nullptr);
     765    gtk_style_context_get_style(arrowStyleContext.get(), "arrow-scaling", &arrowScaling, nullptr);
    807766
    808767    IntSize arrowSize(minArrowSize, innerRect.height());
     
    816775    arrowPosition.move((arrowSize.width() - extent) / 2, (arrowSize.height() - extent) / 2);
    817776
    818     gtk_style_context_set_state(arrowStyleContext, state);
    819     gtk_render_arrow(arrowStyleContext, cairoContext, G_PI, arrowPosition.x(), arrowPosition.y(), extent);
    820 
    821     gtk_style_context_restore(arrowStyleContext);
     777    gtk_style_context_set_state(arrowStyleContext.get(), state);
     778    gtk_render_arrow(arrowStyleContext.get(), cairoContext, G_PI, arrowPosition.x(), arrowPosition.y(), extent);
    822779
    823780    // Paint the separator if needed.
    824     GtkStyleContext* separatorStyleContext = getStyleContext(GTK_TYPE_COMBO_BOX);
    825     gtk_style_context_save(separatorStyleContext);
    826 
    827     gtk_style_context_set_direction(separatorStyleContext, direction);
    828     gtk_style_context_add_class(separatorStyleContext, "separator");
     781    GRefPtr<GtkStyleContext> separatorStyleContext = createStyleContext(GTK_TYPE_COMBO_BOX);
     782
     783    gtk_style_context_set_direction(separatorStyleContext.get(), direction);
     784    gtk_style_context_add_class(separatorStyleContext.get(), "separator");
    829785
    830786    gboolean wideSeparators;
    831787    gint separatorWidth;
    832     gtk_style_context_get_style(separatorStyleContext, "wide-separators", &wideSeparators, "separator-width", &separatorWidth, nullptr);
    833     if (wideSeparators && !separatorWidth) {
    834         gtk_style_context_restore(separatorStyleContext);
     788    gtk_style_context_get_style(separatorStyleContext.get(), "wide-separators", &wideSeparators, "separator-width", &separatorWidth, nullptr);
     789    if (wideSeparators && !separatorWidth)
    835790        return false;
    836     }
    837 
    838     gtk_style_context_set_state(separatorStyleContext, state);
     791
     792    gtk_style_context_set_state(separatorStyleContext.get(), state);
    839793    IntPoint separatorPosition(arrowPosition.x(), innerRect.y());
    840794    if (wideSeparators) {
     
    844798            separatorPosition.move(arrowSize.width(), 0);
    845799
    846         gtk_render_frame(separatorStyleContext, cairoContext, separatorPosition.x(), separatorPosition.y(), separatorWidth, innerRect.height());
     800        gtk_render_frame(separatorStyleContext.get(), cairoContext, separatorPosition.x(), separatorPosition.y(), separatorWidth, innerRect.height());
    847801    } else {
    848802        GtkBorder padding;
    849         gtk_style_context_get_padding(separatorStyleContext, gtk_style_context_get_state(separatorStyleContext), &padding);
     803        gtk_style_context_get_padding(separatorStyleContext.get(), gtk_style_context_get_state(separatorStyleContext.get()), &padding);
    850804        GtkBorder border;
    851         gtk_style_context_get_border(separatorStyleContext, gtk_style_context_get_state(separatorStyleContext), &border);
     805        gtk_style_context_get_border(separatorStyleContext.get(), gtk_style_context_get_state(separatorStyleContext.get()), &border);
    852806
    853807        if (direction == GTK_TEXT_DIR_LTR)
     
    861815        cairo_rectangle(cairoContext, separatorPosition.x(), separatorPosition.y(), border.left, innerRect.height());
    862816        cairo_clip(cairoContext);
    863         gtk_render_line(separatorStyleContext, cairoContext, separatorPosition.x(), separatorPosition.y(), separatorPosition.x(), innerRect.maxY());
     817        gtk_render_line(separatorStyleContext.get(), cairoContext, separatorPosition.x(), separatorPosition.y(), separatorPosition.x(), innerRect.maxY());
    864818        cairo_restore(cairoContext);
    865819    }
    866820
    867     gtk_style_context_restore(separatorStyleContext);
    868821    return false;
    869822}
     
    876829bool RenderThemeGtk::paintTextField(const RenderObject& renderObject, const PaintInfo& paintInfo, const FloatRect& rect)
    877830{
    878     GtkStyleContext* context = getStyleContext(GTK_TYPE_ENTRY);
    879     gtk_style_context_save(context);
    880 
    881     gtk_style_context_set_direction(context, static_cast<GtkTextDirection>(gtkTextDirection(renderObject.style().direction())));
    882     gtk_style_context_add_class(context, GTK_STYLE_CLASS_ENTRY);
     831    GRefPtr<GtkStyleContext> context = createStyleContext(GTK_TYPE_ENTRY);
     832
     833    gtk_style_context_set_direction(context.get(), static_cast<GtkTextDirection>(gtkTextDirection(renderObject.style().direction())));
     834    gtk_style_context_add_class(context.get(), GTK_STYLE_CLASS_ENTRY);
    883835
    884836    guint flags = 0;
     
    887839    else if (isFocused(renderObject))
    888840        flags |= GTK_STATE_FLAG_FOCUSED;
    889     gtk_style_context_set_state(context, static_cast<GtkStateFlags>(flags));
    890 
    891     gtk_render_background(context, paintInfo.context().platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height());
    892     gtk_render_frame(context, paintInfo.context().platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height());
     841    gtk_style_context_set_state(context.get(), static_cast<GtkStateFlags>(flags));
     842
     843    gtk_render_background(context.get(), paintInfo.context().platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height());
     844    gtk_render_frame(context.get(), paintInfo.context().platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height());
    893845
    894846    if (isFocused(renderObject) && isEnabled(renderObject)) {
    895847        gboolean interiorFocus;
    896848        gint focusWidth, focusPad;
    897         gtk_style_context_get_style(context, "interior-focus", &interiorFocus, "focus-line-width", &focusWidth, "focus-padding", &focusPad, nullptr);
     849        gtk_style_context_get_style(context.get(), "interior-focus", &interiorFocus, "focus-line-width", &focusWidth, "focus-padding", &focusPad, nullptr);
    898850        if (!interiorFocus) {
    899851            IntRect focusRect(rect);
    900852            focusRect.inflate(focusWidth + focusPad);
    901             gtk_render_focus(context, paintInfo.context().platformContext()->cr(), focusRect.x(), focusRect.y(), focusRect.width(), focusRect.height());
     853            gtk_render_focus(context.get(), paintInfo.context().platformContext()->cr(), focusRect.x(), focusRect.y(), focusRect.width(), focusRect.height());
    902854        }
    903855    }
    904 
    905     gtk_style_context_restore(context);
    906856
    907857    return false;
     
    11041054    ASSERT_UNUSED(part, part == SliderHorizontalPart || part == SliderVerticalPart || part == MediaVolumeSliderPart);
    11051055
    1106     GtkStyleContext* context = getStyleContext(GTK_TYPE_SCALE);
    1107     gtk_style_context_save(context);
    1108 
    1109     gtk_style_context_set_direction(context, gtkTextDirection(renderObject.style().direction()));
    1110     applySliderStyleContextClasses(context, part);
    1111     gtk_style_context_add_class(context, GTK_STYLE_CLASS_TROUGH);
     1056    GRefPtr<GtkStyleContext> context = createStyleContext(GTK_TYPE_SCALE);
     1057
     1058    gtk_style_context_set_direction(context.get(), gtkTextDirection(renderObject.style().direction()));
     1059    applySliderStyleContextClasses(context.get(), part);
     1060    gtk_style_context_add_class(context.get(), GTK_STYLE_CLASS_TROUGH);
    11121061
    11131062    if (!isEnabled(renderObject))
    1114         gtk_style_context_set_state(context, GTK_STATE_FLAG_INSENSITIVE);
    1115 
    1116     gtk_render_background(context, paintInfo.context().platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height());
    1117     gtk_render_frame(context, paintInfo.context().platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height());
     1063        gtk_style_context_set_state(context.get(), GTK_STATE_FLAG_INSENSITIVE);
     1064
     1065    gtk_render_background(context.get(), paintInfo.context().platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height());
     1066    gtk_render_frame(context.get(), paintInfo.context().platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height());
    11181067
    11191068    if (isFocused(renderObject)) {
    11201069        gint focusWidth, focusPad;
    1121         gtk_style_context_get_style(context, "focus-line-width", &focusWidth, "focus-padding", &focusPad, nullptr);
     1070        gtk_style_context_get_style(context.get(), "focus-line-width", &focusWidth, "focus-padding", &focusPad, nullptr);
    11221071        IntRect focusRect(rect);
    11231072        focusRect.inflate(focusWidth + focusPad);
    1124         gtk_render_focus(context, paintInfo.context().platformContext()->cr(), focusRect.x(), focusRect.y(), focusRect.width(), focusRect.height());
    1125     }
    1126 
    1127     gtk_style_context_restore(context);
     1073        gtk_render_focus(context.get(), paintInfo.context().platformContext()->cr(), focusRect.x(), focusRect.y(), focusRect.width(), focusRect.height());
     1074    }
     1075
    11281076    return false;
    11291077}
     
    11341082    ASSERT(part == SliderThumbHorizontalPart || part == SliderThumbVerticalPart || part == MediaVolumeSliderThumbPart);
    11351083
    1136     GtkStyleContext* context = getStyleContext(GTK_TYPE_SCALE);
    1137     gtk_style_context_save(context);
    1138 
    1139     gtk_style_context_set_direction(context, gtkTextDirection(renderObject.style().direction()));
    1140     applySliderStyleContextClasses(context, part);
    1141     gtk_style_context_add_class(context, GTK_STYLE_CLASS_SLIDER);
     1084    GRefPtr<GtkStyleContext> context = createStyleContext(GTK_TYPE_SCALE);
     1085
     1086    gtk_style_context_set_direction(context.get(), gtkTextDirection(renderObject.style().direction()));
     1087    applySliderStyleContextClasses(context.get(), part);
     1088    gtk_style_context_add_class(context.get(), GTK_STYLE_CLASS_SLIDER);
    11421089
    11431090    guint flags = 0;
     
    11481095    if (isPressed(renderObject))
    11491096        flags |= GTK_STATE_FLAG_ACTIVE;
    1150     gtk_style_context_set_state(context, static_cast<GtkStateFlags>(flags));
    1151 
    1152     gtk_render_slider(context, paintInfo.context().platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height(),
     1097    gtk_style_context_set_state(context.get(), static_cast<GtkStateFlags>(flags));
     1098
     1099    gtk_render_slider(context.get(), paintInfo.context().platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height(),
    11531100        part == SliderThumbHorizontalPart ? GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL);
    1154 
    1155     gtk_style_context_restore(context);
    11561101
    11571102    return false;
     
    11641109        return;
    11651110
     1111    GRefPtr<GtkStyleContext> context = createStyleContext(GTK_TYPE_SCALE);
    11661112    gint sliderWidth, sliderLength;
    1167     gtk_style_context_get_style(getStyleContext(GTK_TYPE_SCALE), "slider-width", &sliderWidth, "slider-length", &sliderLength, nullptr);
     1113    gtk_style_context_get_style(context.get(), "slider-width", &sliderWidth, "slider-length", &sliderLength, nullptr);
    11681114    if (part == SliderThumbHorizontalPart) {
    11691115        style.setWidth(Length(sliderLength, Fixed));
     
    11811127        return true;
    11821128
    1183     GtkStyleContext* context = getStyleContext(GTK_TYPE_PROGRESS_BAR);
    1184     gtk_style_context_save(context);
    1185 
    1186     gtk_style_context_add_class(context, GTK_STYLE_CLASS_TROUGH);
    1187 
    1188     gtk_render_background(context, paintInfo.context().platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height());
    1189     gtk_render_frame(context, paintInfo.context().platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height());
    1190 
    1191     gtk_style_context_restore(context);
    1192 
    1193     gtk_style_context_save(context);
    1194     gtk_style_context_add_class(context, GTK_STYLE_CLASS_PROGRESSBAR);
    1195     gtk_style_context_set_state(context, static_cast<GtkStateFlags>(0));
     1129    GRefPtr<GtkStyleContext> context = createStyleContext(GTK_TYPE_PROGRESS_BAR);
     1130    gtk_style_context_save(context.get());
     1131
     1132    gtk_style_context_add_class(context.get(), GTK_STYLE_CLASS_TROUGH);
     1133
     1134    gtk_render_background(context.get(), paintInfo.context().platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height());
     1135    gtk_render_frame(context.get(), paintInfo.context().platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height());
     1136
     1137    gtk_style_context_restore(context.get());
     1138
     1139    gtk_style_context_add_class(context.get(), GTK_STYLE_CLASS_PROGRESSBAR);
     1140    gtk_style_context_set_state(context.get(), static_cast<GtkStateFlags>(0));
    11961141
    11971142    GtkBorder padding;
    1198     gtk_style_context_get_padding(context, gtk_style_context_get_state(context), &padding);
     1143    gtk_style_context_get_padding(context.get(), gtk_style_context_get_state(context.get()), &padding);
    11991144    IntRect progressRect(
    12001145        rect.x() + padding.left,
     
    12061151    if (!progressRect.isEmpty()) {
    12071152#if GTK_CHECK_VERSION(3, 13, 7)
    1208         gtk_render_background(context, paintInfo.context().platformContext()->cr(), progressRect.x(), progressRect.y(), progressRect.width(), progressRect.height());
    1209         gtk_render_frame(context, paintInfo.context().platformContext()->cr(), progressRect.x(), progressRect.y(), progressRect.width(), progressRect.height());
     1153        gtk_render_background(context.get(), paintInfo.context().platformContext()->cr(), progressRect.x(), progressRect.y(), progressRect.width(), progressRect.height());
     1154        gtk_render_frame(context.get(), paintInfo.context().platformContext()->cr(), progressRect.x(), progressRect.y(), progressRect.width(), progressRect.height());
    12101155#else
    1211         gtk_render_activity(context, paintInfo.context().platformContext()->cr(), progressRect.x(), progressRect.y(), progressRect.width(), progressRect.height());
     1156        gtk_render_activity(context.get(), paintInfo.context().platformContext()->cr(), progressRect.x(), progressRect.y(), progressRect.width(), progressRect.height());
    12121157#endif
    12131158    }
    12141159
    1215     gtk_style_context_restore(context);
    12161160    return false;
    12171161}
     
    12301174void RenderThemeGtk::adjustInnerSpinButtonStyle(StyleResolver&, RenderStyle& style, Element*) const
    12311175{
    1232     GtkStyleContext* context = getStyleContext(GTK_TYPE_SPIN_BUTTON);
     1176    GRefPtr<GtkStyleContext> context = createStyleContext(GTK_TYPE_SPIN_BUTTON);
    12331177
    12341178    GtkBorder padding;
    1235     gtk_style_context_get_padding(context, gtk_style_context_get_state(context), &padding);
    1236 
    1237     int width = spinButtonArrowSize(context) + padding.left + padding.right;
     1179    gtk_style_context_get_padding(context.get(), gtk_style_context_get_state(context.get()), &padding);
     1180
     1181    int width = spinButtonArrowSize(context.get()) + padding.left + padding.right;
    12381182    style.setWidth(Length(width, Fixed));
    12391183    style.setMinWidth(Length(width, Fixed));
     
    13081252bool RenderThemeGtk::paintInnerSpinButton(const RenderObject& renderObject, const PaintInfo& paintInfo, const IntRect& rect)
    13091253{
    1310     GtkStyleContext* context = getStyleContext(GTK_TYPE_SPIN_BUTTON);
    1311     gtk_style_context_save(context);
     1254    GRefPtr<GtkStyleContext> context = createStyleContext(GTK_TYPE_SPIN_BUTTON);
    13121255
    13131256    GtkTextDirection direction = static_cast<GtkTextDirection>(gtkTextDirection(renderObject.style().direction()));
    1314     gtk_style_context_set_direction(context, direction);
     1257    gtk_style_context_set_direction(context.get(), direction);
    13151258
    13161259    guint flags = 0;
     
    13191262    else if (isFocused(renderObject))
    13201263        flags |= GTK_STATE_FLAG_FOCUSED;
    1321     gtk_style_context_set_state(context, static_cast<GtkStateFlags>(flags));
    1322     gtk_style_context_remove_class(context, GTK_STYLE_CLASS_ENTRY);
    1323 
    1324     paintSpinArrowButton(this, context, renderObject, paintInfo, rect, GTK_ARROW_UP);
    1325     paintSpinArrowButton(this, context, renderObject, paintInfo, rect, GTK_ARROW_DOWN);
    1326 
    1327     gtk_style_context_restore(context);
     1264    gtk_style_context_set_state(context.get(), static_cast<GtkStateFlags>(flags));
     1265    gtk_style_context_remove_class(context.get(), GTK_STYLE_CLASS_ENTRY);
     1266
     1267    paintSpinArrowButton(this, context.get(), renderObject, paintInfo, rect, GTK_ARROW_UP);
     1268    paintSpinArrowButton(this, context.get(), renderObject, paintInfo, rect, GTK_ARROW_DOWN);
    13281269
    13291270    return false;
     
    13501291{
    13511292
    1352     GtkStyleContext* context = getStyleContext(widgetType);
     1293    GRefPtr<GtkStyleContext> context = createStyleContext(widgetType);
    13531294    // Recent GTK+ versions (> 3.14) require to explicitly set the state before getting the color.
    1354     gtk_style_context_set_state(context, state);
     1295    gtk_style_context_set_state(context.get(), state);
    13551296
    13561297    GdkRGBA gdkRGBAColor;
    13571298    if (colorType == StyleColorBackground)
    1358         gtk_style_context_get_background_color(context, gtk_style_context_get_state(context), &gdkRGBAColor);
     1299        gtk_style_context_get_background_color(context.get(), gtk_style_context_get_state(context.get()), &gdkRGBAColor);
    13591300    else
    1360         gtk_style_context_get_color(context, gtk_style_context_get_state(context), &gdkRGBAColor);
     1301        gtk_style_context_get_color(context.get(), gtk_style_context_get_state(context.get()), &gdkRGBAColor);
    13611302    return gdkRGBAColor;
    13621303}
Note: See TracChangeset for help on using the changeset viewer.