Title: [197250] releases/WebKitGTK/webkit-2.4/Source/WebCore
Revision
197250
Author
[email protected]
Date
2016-02-27 07:09:16 -0800 (Sat, 27 Feb 2016)

Log Message

Merge r173110, r193896 - [GTK] ScrollbarThemeGtk should not depend on RenderThemeGtk
https://bugs.webkit.org/show_bug.cgi?id=136338

Reviewed by Philippe Normand.

Remove the dependency by creating the GtkStyleContext for the
scrollbars in ScrollbarThemeGtk.

* platform/gtk/RenderThemeGtk.cpp:
(WebCore::gtkStyleChangedCallback): Call ScrollbarThemeGtk::themeChanged().
(WebCore::getStyleContext): Remove the scrollbar style context support.
* platform/gtk/RenderThemeGtk.h: Remove gtkScrollbarStyle().
* platform/gtk/ScrollbarThemeGtk.cpp:
(WebCore::ScrollbarStyleContext::ScrollbarStyleContext): Helper
class to create the global GtkStyleContext for scrollbars.
(WebCore::ScrollbarStyleContext::~ScrollbarStyleContext):
(WebCore::ScrollbarStyleContext::context):
(WebCore::gtkScrollbarStyleContext):
(WebCore::ScrollbarThemeGtk::ScrollbarThemeGtk): Remove m_context initialization.
(WebCore::ScrollbarThemeGtk::themeChanged): Invalidate the
GtkStylecontext and call updateThemeProperties().
(WebCore::ScrollbarThemeGtk::updateThemeProperties): Use the
global style context.
(WebCore::ScrollbarThemeGtk::paintTrackBackground): Ditto.
(WebCore::ScrollbarThemeGtk::paintScrollbarBackground): Ditto.
(WebCore::ScrollbarThemeGtk::paintThumb): Ditto.
(WebCore::ScrollbarThemeGtk::paintButton): Ditto.
* platform/gtk/ScrollbarThemeGtk.h:

[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

Modified Paths

Diff

Modified: releases/WebKitGTK/webkit-2.4/Source/WebCore/ChangeLog (197249 => 197250)


--- releases/WebKitGTK/webkit-2.4/Source/WebCore/ChangeLog	2016-02-27 15:08:56 UTC (rev 197249)
+++ releases/WebKitGTK/webkit-2.4/Source/WebCore/ChangeLog	2016-02-27 15:09:16 UTC (rev 197250)
@@ -1,3 +1,80 @@
+2015-12-10  Michael Catanzaro  <[email protected]>
+
+        [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.
+
+2014-08-29  Carlos Garcia Campos  <[email protected]>
+
+        [GTK] ScrollbarThemeGtk should not depend on RenderThemeGtk
+        https://bugs.webkit.org/show_bug.cgi?id=136338
+
+        Reviewed by Philippe Normand.
+
+        Remove the dependency by creating the GtkStyleContext for the
+        scrollbars in ScrollbarThemeGtk.
+
+        * platform/gtk/RenderThemeGtk.cpp:
+        (WebCore::gtkStyleChangedCallback): Call ScrollbarThemeGtk::themeChanged().
+        (WebCore::getStyleContext): Remove the scrollbar style context support.
+        * platform/gtk/RenderThemeGtk.h: Remove gtkScrollbarStyle().
+        * platform/gtk/ScrollbarThemeGtk.cpp:
+        (WebCore::ScrollbarStyleContext::ScrollbarStyleContext): Helper
+        class to create the global GtkStyleContext for scrollbars.
+        (WebCore::ScrollbarStyleContext::~ScrollbarStyleContext):
+        (WebCore::ScrollbarStyleContext::context):
+        (WebCore::gtkScrollbarStyleContext):
+        (WebCore::ScrollbarThemeGtk::ScrollbarThemeGtk): Remove m_context initialization.
+        (WebCore::ScrollbarThemeGtk::themeChanged): Invalidate the
+        GtkStylecontext and call updateThemeProperties().
+        (WebCore::ScrollbarThemeGtk::updateThemeProperties): Use the
+        global style context.
+        (WebCore::ScrollbarThemeGtk::paintTrackBackground): Ditto.
+        (WebCore::ScrollbarThemeGtk::paintScrollbarBackground): Ditto.
+        (WebCore::ScrollbarThemeGtk::paintThumb): Ditto.
+        (WebCore::ScrollbarThemeGtk::paintButton): Ditto.
+        * platform/gtk/ScrollbarThemeGtk.h:
+
 2015-11-21  Michael Catanzaro  <[email protected]>
 
         [GTK] Off-by-one error in getStyleContext()

Modified: releases/WebKitGTK/webkit-2.4/Source/WebCore/platform/gtk/RenderThemeGtk.h (197249 => 197250)


--- releases/WebKitGTK/webkit-2.4/Source/WebCore/platform/gtk/RenderThemeGtk.h	2016-02-27 15:08:56 UTC (rev 197249)
+++ releases/WebKitGTK/webkit-2.4/Source/WebCore/platform/gtk/RenderThemeGtk.h	2016-02-27 15:09:16 UTC (rev 197250)
@@ -108,8 +108,6 @@
     GtkWidget* gtkVScrollbar() const;
     GtkWidget* gtkHScrollbar() const;
     static void getIndicatorMetrics(ControlPart, int& indicatorSize, int& indicatorSpacing);
-#else
-    GtkStyleContext* gtkScrollbarStyle();
 #endif
 
 protected:

Modified: releases/WebKitGTK/webkit-2.4/Source/WebCore/platform/gtk/RenderThemeGtk3.cpp (197249 => 197250)


--- releases/WebKitGTK/webkit-2.4/Source/WebCore/platform/gtk/RenderThemeGtk3.cpp	2016-02-27 15:08:56 UTC (rev 197249)
+++ releases/WebKitGTK/webkit-2.4/Source/WebCore/platform/gtk/RenderThemeGtk3.cpp	2016-02-27 15:09:16 UTC (rev 197250)
@@ -36,6 +36,7 @@
 #include "PaintInfo.h"
 #include "PlatformContextCairo.h"
 #include "RenderElement.h"
+#include "ScrollbarThemeGtk.h"
 #include "TextDirection.h"
 #include "UserAgentStyleSheets.h"
 #include <cmath>
@@ -49,22 +50,14 @@
 // This is the default value defined by GTK+, where it was defined as MIN_ARROW_WIDTH in gtkspinbutton.c.
 static const int minSpinButtonArrowSize = 6;
 
-typedef HashMap<GType, GRefPtr<GtkStyleContext> > StyleContextMap;
-static StyleContextMap& styleContextMap();
-
 static void gtkStyleChangedCallback(GObject*, GParamSpec*)
 {
-    StyleContextMap::const_iterator end = styleContextMap().end();
-    for (StyleContextMap::const_iterator iter = styleContextMap().begin(); iter != end; ++iter)
-        gtk_style_context_invalidate(iter->value.get());
-
+    static_cast<ScrollbarThemeGtk*>(ScrollbarTheme::theme())->themeChanged();
     Page::updateStyleForAllPagesAfterGlobalChangeInEnvironment();
 }
 
-static StyleContextMap& styleContextMap()
+static GRefPtr<GtkStyleContext> createStyleContext(GType widgetType)
 {
-    DEFINE_STATIC_LOCAL(StyleContextMap, map, ());
-
     static bool initialized = false;
     if (!initialized) {
         GtkSettings* settings = gtk_settings_get_default();
@@ -72,21 +65,11 @@
         g_signal_connect(settings, "notify::gtk-color-scheme", G_CALLBACK(gtkStyleChangedCallback), 0);
         initialized = true;
     }
-    return map;
-}
 
-static GtkStyleContext* getStyleContext(GType widgetType)
-{
-    StyleContextMap::AddResult result = styleContextMap().add(widgetType, nullptr);
-    if (!result.isNewEntry)
-        return result.iterator->value.get();
-
     GtkWidgetPath* path = gtk_widget_path_new();
     gtk_widget_path_append_type(path, widgetType);
 
-    if (widgetType == GTK_TYPE_SCROLLBAR)
-        gtk_widget_path_iter_add_class(path, 0, GTK_STYLE_CLASS_SCROLLBAR);
-    else if (widgetType == GTK_TYPE_ENTRY)
+    if (widgetType == GTK_TYPE_ENTRY)
         gtk_widget_path_iter_add_class(path, 0, GTK_STYLE_CLASS_ENTRY);
     else if (widgetType == GTK_TYPE_ARROW)
         gtk_widget_path_iter_add_class(path, 0, "arrow");
@@ -113,15 +96,9 @@
     gtk_style_context_set_path(context.get(), path);
     gtk_widget_path_free(path);
 
-    result.iterator->value = context;
-    return context.get();
+    return context;
 }
 
-GtkStyleContext* RenderThemeGtk::gtkScrollbarStyle()
-{
-    return getStyleContext(GTK_TYPE_SCROLLBAR);
-}
-
 // This is not a static method, because we want to avoid having GTK+ headers in RenderThemeGtk.h.
 extern GtkTextDirection gtkTextDirection(TextDirection);
 
@@ -137,21 +114,17 @@
 void RenderThemeGtk::initMediaColors()
 {
     GdkRGBA color;
-    GtkStyleContext* containerContext = getStyleContext(GTK_TYPE_CONTAINER);
+    GRefPtr<GtkStyleContext> containerContext = createStyleContext(GTK_TYPE_CONTAINER);
 
-    gtk_style_context_save(containerContext);
-
-    gtk_style_context_set_state(containerContext, GTK_STATE_FLAG_NORMAL);
-    gtk_style_context_get_background_color(containerContext, gtk_style_context_get_state(containerContext), &color);
+    gtk_style_context_set_state(containerContext.get(), GTK_STATE_FLAG_NORMAL);
+    gtk_style_context_get_background_color(containerContext.get(), gtk_style_context_get_state(containerContext.get()), &color);
     m_panelColor = color;
-    gtk_style_context_set_state(containerContext, GTK_STATE_FLAG_ACTIVE);
-    gtk_style_context_get_background_color(containerContext, gtk_style_context_get_state(containerContext), &color);
+    gtk_style_context_set_state(containerContext.get(), GTK_STATE_FLAG_ACTIVE);
+    gtk_style_context_get_background_color(containerContext.get(), gtk_style_context_get_state(containerContext.get()), &color);
     m_sliderColor = color;
-    gtk_style_context_set_state(containerContext, GTK_STATE_FLAG_SELECTED);
-    gtk_style_context_get_background_color(containerContext, gtk_style_context_get_state(containerContext), &color);
+    gtk_style_context_set_state(containerContext.get(), GTK_STATE_FLAG_SELECTED);
+    gtk_style_context_get_background_color(containerContext.get(), gtk_style_context_get_state(containerContext.get()), &color);
     m_sliderThumbColor = color;
-
-    gtk_style_context_restore(containerContext);
 }
 #endif
 
@@ -166,32 +139,32 @@
 
 void RenderThemeGtk::adjustRepaintRect(const RenderObject* renderObject, IntRect& rect)
 {
-    GtkStyleContext* context = 0;
+    GRefPtr<GtkStyleContext> context;
     bool checkInteriorFocus = false;
     ControlPart part = renderObject->style().appearance();
     switch (part) {
     case CheckboxPart:
     case RadioPart:
-        context = getStyleContext(part == CheckboxPart ? GTK_TYPE_CHECK_BUTTON : GTK_TYPE_RADIO_BUTTON);
+        context = createStyleContext(part == CheckboxPart ? GTK_TYPE_CHECK_BUTTON : GTK_TYPE_RADIO_BUTTON);
 
         gint indicatorSpacing;
-        gtk_style_context_get_style(context, "indicator-spacing", &indicatorSpacing, NULL);
+        gtk_style_context_get_style(context.get(), "indicator-spacing", &indicatorSpacing, nullptr);
         rect.inflate(indicatorSpacing);
 
         return;
     case SliderVerticalPart:
     case SliderHorizontalPart:
-        context = getStyleContext(GTK_TYPE_SCALE);
+        context = createStyleContext(GTK_TYPE_SCALE);
         break;
     case ButtonPart:
     case MenulistButtonPart:
     case MenulistPart:
-        context = getStyleContext(GTK_TYPE_BUTTON);
+        context = createStyleContext(GTK_TYPE_BUTTON);
         checkInteriorFocus = true;
         break;
     case TextFieldPart:
     case TextAreaPart:
-        context = getStyleContext(GTK_TYPE_ENTRY);
+        context = createStyleContext(GTK_TYPE_ENTRY);
         checkInteriorFocus = true;
         break;
     default:
@@ -201,15 +174,17 @@
     ASSERT(context);
     if (checkInteriorFocus) {
         gboolean interiorFocus;
-        gtk_style_context_get_style(context, "interior-focus", &interiorFocus, NULL);
+        gtk_style_context_get_style(context.get(), "interior-focus", &interiorFocus, nullptr);
         if (interiorFocus)
             return;
     }
-    adjustRectForFocus(context, rect);
+    adjustRectForFocus(context.get(), rect);
 }
 
-static void setToggleSize(GtkStyleContext* context, RenderStyle* style)
+static void setToggleSize(GType widgetType, RenderStyle& style)
 {
+    GRefPtr<GtkStyleContext> context = createStyleContext(widgetType);
+
     // The width and height are both specified, so we shouldn't change them.
     if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto())
         return;
@@ -218,7 +193,7 @@
     // GTK+ users tend to demand the native look.
     // It could be made a configuration option values other than 13 actually break site compatibility.
     gint indicatorSize;
-    gtk_style_context_get_style(context, "indicator-size", &indicatorSize, NULL);
+    gtk_style_context_get_style(context.get(), "indicator-size", &indicatorSize, nullptr);
 
     if (style->width().isIntrinsicOrAuto())
         style->setWidth(Length(indicatorSize, Fixed));
@@ -229,15 +204,14 @@
 
 static void paintToggle(const RenderThemeGtk* theme, GType widgetType, RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& fullRect)
 {
-    GtkStyleContext* context = getStyleContext(widgetType);
-    gtk_style_context_save(context);
+    GRefPtr<GtkStyleContext> context = createStyleContext(widgetType);
 
     // Some themes do not render large toggle buttons properly, so we simply
     // shrink the rectangle back down to the default size and then center it
     // in the full toggle button region. The reason for not simply forcing toggle
     // buttons to be a smaller size is that we don't want to break site layouts.
     gint indicatorSize;
-    gtk_style_context_get_style(context, "indicator-size", &indicatorSize, NULL);
+    gtk_style_context_get_style(context.get(), "indicator-size", &indicatorSize, nullptr);
     IntRect rect(fullRect);
     if (rect.width() > indicatorSize) {
         rect.inflateX(-(rect.width() - indicatorSize) / 2);
@@ -249,8 +223,8 @@
         rect.setHeight(indicatorSize); // In case rect.height() was equal to indicatorSize + 1.
     }
 
-    gtk_style_context_set_direction(context, static_cast<GtkTextDirection>(gtkTextDirection(renderObject->style().direction())));
-    gtk_style_context_add_class(context, widgetType == GTK_TYPE_CHECK_BUTTON ? GTK_STYLE_CLASS_CHECK : GTK_STYLE_CLASS_RADIO);
+    gtk_style_context_set_direction(context.get(), static_cast<GtkTextDirection>(gtkTextDirection(renderObject->style().direction())));
+    gtk_style_context_add_class(context.get(), widgetType == GTK_TYPE_CHECK_BUTTON ? GTK_STYLE_CLASS_CHECK : GTK_STYLE_CLASS_RADIO);
 
     guint flags = 0;
     if (!theme->isEnabled(renderObject) || theme->isReadOnlyControl(renderObject))
@@ -267,28 +241,26 @@
 #endif
     if (theme->isPressed(renderObject))
         flags |= GTK_STATE_FLAG_SELECTED;
-    gtk_style_context_set_state(context, static_cast<GtkStateFlags>(flags));
+    gtk_style_context_set_state(context.get(), static_cast<GtkStateFlags>(flags));
 
     if (widgetType == GTK_TYPE_CHECK_BUTTON)
-        gtk_render_check(context, paintInfo.context->platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height());
+        gtk_render_check(context.get(), paintInfo.context->platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height());
     else
-        gtk_render_option(context, paintInfo.context->platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height());
+        gtk_render_option(context.get(), paintInfo.context->platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height());
 
     if (theme->isFocused(renderObject)) {
         IntRect indicatorRect(rect);
         gint indicatorSpacing;
-        gtk_style_context_get_style(context, "indicator-spacing", &indicatorSpacing, NULL);
+        gtk_style_context_get_style(context.get(), "indicator-spacing", &indicatorSpacing, nullptr);
         indicatorRect.inflate(indicatorSpacing);
-        gtk_render_focus(context, paintInfo.context->platformContext()->cr(), indicatorRect.x(), indicatorRect.y(),
+        gtk_render_focus(context.get(), paintInfo.context->platformContext()->cr(), indicatorRect.x(), indicatorRect.y(),
                          indicatorRect.width(), indicatorRect.height());
     }
-
-    gtk_style_context_restore(context);
 }
 
 void RenderThemeGtk::setCheckboxSize(RenderStyle* style) const
 {
-    setToggleSize(getStyleContext(GTK_TYPE_CHECK_BUTTON), style);
+    setToggleSize(GTK_TYPE_CHECK_BUTTON, style);
 }
 
 bool RenderThemeGtk::paintCheckbox(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect)
@@ -299,7 +271,7 @@
 
 void RenderThemeGtk::setRadioSize(RenderStyle* style) const
 {
-    setToggleSize(getStyleContext(GTK_TYPE_RADIO_BUTTON), style);
+    setToggleSize(GTK_TYPE_RADIO_BUTTON, style);
 }
 
 bool RenderThemeGtk::paintRadio(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect)
@@ -376,16 +348,13 @@
 }
 bool RenderThemeGtk::paintButton(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect)
 {
-    GtkStyleContext* context = getStyleContext(GTK_TYPE_BUTTON);
-    gtk_style_context_save(context);
+    GRefPtr<GtkStyleContext> context = createStyleContext(GTK_TYPE_BUTTON);
 
-    gtk_style_context_set_direction(context, static_cast<GtkTextDirection>(gtkTextDirection(renderObject->style().direction())));
-    gtk_style_context_add_class(context, GTK_STYLE_CLASS_BUTTON);
+    gtk_style_context_set_direction(context.get(), static_cast<GtkTextDirection>(gtkTextDirection(renderObject->style().direction())));
+    gtk_style_context_add_class(context.get(), GTK_STYLE_CLASS_BUTTON);
 
-    renderButton(this, context, renderObject, paintInfo, rect);
+    renderButton(this, context.get(), renderObject, paintInfo, rect);
 
-    gtk_style_context_restore(context);
-
     return false;
 }
 
@@ -396,46 +365,34 @@
     if (style->appearance() == NoControlPart)
         return;
 
-    GtkStyleContext* context = getStyleContext(GTK_TYPE_COMBO_BOX);
-    gtk_style_context_save(context);
+    GRefPtr<GtkStyleContext> context = createStyleContext(GTK_TYPE_COMBO_BOX);
 
-    gtk_style_context_add_class(context, GTK_STYLE_CLASS_BUTTON);
-    gtk_style_context_set_direction(context, static_cast<GtkTextDirection>(gtkTextDirection(style->direction())));
+    gtk_style_context_add_class(context.get(), GTK_STYLE_CLASS_BUTTON);
+    gtk_style_context_set_direction(context.get(), static_cast<GtkTextDirection>(gtkTextDirection(style->direction())));
 
-    gtk_style_context_set_state(context, static_cast<GtkStateFlags>(0));
-    gtk_style_context_get_border(context, gtk_style_context_get_state(context), &border);
+    gtk_style_context_set_state(context.get(), static_cast<GtkStateFlags>(0));
+    gtk_style_context_get_border(context.get(), gtk_style_context_get_state(context.get()), &border);
 
     gboolean interiorFocus;
     gint focusWidth, focusPad;
-    gtk_style_context_get_style(context,
-                                "interior-focus", &interiorFocus,
-                                "focus-line-width", &focusWidth,
-                                "focus-padding", &focusPad, NULL);
+    gtk_style_context_get_style(context.get(), "interior-focus", &interiorFocus, "focus-line-width", &focusWidth, "focus-padding", &focusPad, nullptr);
     focus = interiorFocus ? focusWidth + focusPad : 0;
 
-    gtk_style_context_restore(context);
+    context = createStyleContext(GTK_TYPE_SEPARATOR);
 
-    context = getStyleContext(GTK_TYPE_SEPARATOR);
-    gtk_style_context_save(context);
-
     GtkTextDirection direction = static_cast<GtkTextDirection>(gtkTextDirection(style->direction()));
-    gtk_style_context_set_direction(context, direction);
-    gtk_style_context_add_class(context, "separator");
+    gtk_style_context_set_direction(context.get(), direction);
+    gtk_style_context_add_class(context.get(), "separator");
 
     gboolean wideSeparators;
     gint separatorWidth;
-    gtk_style_context_get_style(context,
-                                "wide-separators", &wideSeparators,
-                                "separator-width", &separatorWidth,
-                                NULL);
+    gtk_style_context_get_style(context.get(), "wide-separators", &wideSeparators, "separator-width", &separatorWidth, nullptr);
 
     // GTK+ always uses border.left, regardless of text direction. See gtkseperator.c.
     if (!wideSeparators)
         separatorWidth = border.left;
 
     separator = separatorWidth;
-
-    gtk_style_context_restore(context);
 }
 
 int RenderThemeGtk::popupInternalPaddingLeft(RenderStyle* style) const
@@ -482,29 +439,24 @@
     GtkTextDirection direction = static_cast<GtkTextDirection>(gtkTextDirection(renderObject->style().direction()));
 
     // Paint the button.
-    GtkStyleContext* buttonStyleContext = getStyleContext(GTK_TYPE_BUTTON);
-    gtk_style_context_save(buttonStyleContext);
-    gtk_style_context_set_direction(buttonStyleContext, direction);
-    gtk_style_context_add_class(buttonStyleContext, GTK_STYLE_CLASS_BUTTON);
-    renderButton(this, buttonStyleContext, renderObject, paintInfo, rect);
+    GRefPtr<GtkStyleContext> buttonStyleContext = createStyleContext(GTK_TYPE_BUTTON);
+    gtk_style_context_set_direction(buttonStyleContext.get(), direction);
+    gtk_style_context_add_class(buttonStyleContext.get(), GTK_STYLE_CLASS_BUTTON);
+    renderButton(this, buttonStyleContext.get(), renderObject, paintInfo, rect);
 
     // Get the inner rectangle.
     gint focusWidth, focusPad;
     GtkBorder* innerBorderPtr = 0;
     GtkBorder innerBorder = { 1, 1, 1, 1 };
-    gtk_style_context_get_style(buttonStyleContext,
-                                "inner-border", &innerBorderPtr,
-                                "focus-line-width", &focusWidth,
-                                "focus-padding", &focusPad,
-                                NULL);
+    gtk_style_context_get_style(buttonStyleContext.get(), "inner-border", &innerBorderPtr, "focus-line-width", &focusWidth, "focus-padding", &focusPad, nullptr);
     if (innerBorderPtr) {
         innerBorder = *innerBorderPtr;
         gtk_border_free(innerBorderPtr);
     }
 
     GtkBorder borderWidth;
-    GtkStateFlags state = gtk_style_context_get_state(buttonStyleContext);
-    gtk_style_context_get_border(buttonStyleContext, state, &borderWidth);
+    GtkStateFlags state = gtk_style_context_get_state(buttonStyleContext.get());
+    gtk_style_context_get_border(buttonStyleContext.get(), state, &borderWidth);
 
     focusWidth += focusPad;
     IntRect innerRect(rect.x() + innerBorder.left + borderWidth.left + focusWidth,
@@ -515,27 +467,21 @@
     if (isPressed(renderObject)) {
         gint childDisplacementX;
         gint childDisplacementY;
-        gtk_style_context_get_style(buttonStyleContext,
-                                    "child-displacement-x", &childDisplacementX,
-                                    "child-displacement-y", &childDisplacementY,
-                                    NULL);
+        gtk_style_context_get_style(buttonStyleContext.get(), "child-displacement-x", &childDisplacementX, "child-displacement-y", &childDisplacementY, nullptr);
         innerRect.move(childDisplacementX, childDisplacementY);
     }
     innerRect.setWidth(std::max(1, innerRect.width()));
     innerRect.setHeight(std::max(1, innerRect.height()));
 
-    gtk_style_context_restore(buttonStyleContext);
-
     // Paint the arrow.
-    GtkStyleContext* arrowStyleContext = getStyleContext(GTK_TYPE_ARROW);
-    gtk_style_context_save(arrowStyleContext);
+    GRefPtr<GtkStyleContext> arrowStyleContext = createStyleContext(GTK_TYPE_ARROW);
 
-    gtk_style_context_set_direction(arrowStyleContext, direction);
-    gtk_style_context_add_class(arrowStyleContext, "arrow");
-    gtk_style_context_add_class(arrowStyleContext, GTK_STYLE_CLASS_BUTTON);
+    gtk_style_context_set_direction(arrowStyleContext.get(), direction);
+    gtk_style_context_add_class(arrowStyleContext.get(), "arrow");
+    gtk_style_context_add_class(arrowStyleContext.get(), GTK_STYLE_CLASS_BUTTON);
 
     gfloat arrowScaling;
-    gtk_style_context_get_style(arrowStyleContext, "arrow-scaling", &arrowScaling, NULL);
+    gtk_style_context_get_style(arrowStyleContext.get(), "arrow-scaling", &arrowScaling, nullptr);
 
     IntSize arrowSize(minArrowSize, innerRect.height());
     FloatPoint arrowPosition(innerRect.location());
@@ -547,30 +493,22 @@
     gint extent = std::min(arrowSize.width(), arrowSize.height()) * arrowScaling;
     arrowPosition.move((arrowSize.width() - extent) / 2, (arrowSize.height() - extent) / 2);
 
-    gtk_style_context_set_state(arrowStyleContext, state);
-    gtk_render_arrow(arrowStyleContext, cairoContext, G_PI, arrowPosition.x(), arrowPosition.y(), extent);
+    gtk_style_context_set_state(arrowStyleContext.get(), state);
+    gtk_render_arrow(arrowStyleContext.get(), cairoContext, G_PI, arrowPosition.x(), arrowPosition.y(), extent);
 
-    gtk_style_context_restore(arrowStyleContext);
-
     // Paint the separator if needed.
-    GtkStyleContext* separatorStyleContext = getStyleContext(GTK_TYPE_COMBO_BOX);
-    gtk_style_context_save(separatorStyleContext);
+    GRefPtr<GtkStyleContext> separatorStyleContext = createStyleContext(GTK_TYPE_COMBO_BOX);
 
-    gtk_style_context_set_direction(separatorStyleContext, direction);
-    gtk_style_context_add_class(separatorStyleContext, "separator");
+    gtk_style_context_set_direction(separatorStyleContext.get(), direction);
+    gtk_style_context_add_class(separatorStyleContext.get(), "separator");
 
     gboolean wideSeparators;
     gint separatorWidth;
-    gtk_style_context_get_style(separatorStyleContext,
-                                "wide-separators", &wideSeparators,
-                                "separator-width", &separatorWidth,
-                                NULL);
-    if (wideSeparators && !separatorWidth) {
-        gtk_style_context_restore(separatorStyleContext);
+    gtk_style_context_get_style(separatorStyleContext.get(), "wide-separators", &wideSeparators, "separator-width", &separatorWidth, nullptr);
+    if (wideSeparators && !separatorWidth)
         return false;
-    }
 
-    gtk_style_context_set_state(separatorStyleContext, state);
+    gtk_style_context_set_state(separatorStyleContext.get(), state);
     IntPoint separatorPosition(arrowPosition.x(), innerRect.y());
     if (wideSeparators) {
         if (direction == GTK_TEXT_DIR_LTR)
@@ -578,14 +516,12 @@
         else
             separatorPosition.move(arrowSize.width(), 0);
 
-        gtk_render_frame(separatorStyleContext, cairoContext,
-                         separatorPosition.x(), separatorPosition.y(),
-                         separatorWidth, innerRect.height());
+        gtk_render_frame(separatorStyleContext.get(), cairoContext, separatorPosition.x(), separatorPosition.y(), separatorWidth, innerRect.height());
     } else {
         GtkBorder padding;
-        gtk_style_context_get_padding(separatorStyleContext, gtk_style_context_get_state(separatorStyleContext), &padding);
+        gtk_style_context_get_padding(separatorStyleContext.get(), gtk_style_context_get_state(separatorStyleContext.get()), &padding);
         GtkBorder border;
-        gtk_style_context_get_border(separatorStyleContext, gtk_style_context_get_state(separatorStyleContext), &border);
+        gtk_style_context_get_border(separatorStyleContext.get(), gtk_style_context_get_state(separatorStyleContext.get()), &border);
 
         if (direction == GTK_TEXT_DIR_LTR)
             separatorPosition.move(-(padding.left + border.left), 0);
@@ -597,52 +533,41 @@
         // An extra clip prevents the separator bleeding outside of the specified rectangle because of subpixel positioning.
         cairo_rectangle(cairoContext, separatorPosition.x(), separatorPosition.y(), border.left, innerRect.height());
         cairo_clip(cairoContext);
-        gtk_render_line(separatorStyleContext, cairoContext,
-                        separatorPosition.x(), separatorPosition.y(),
-                        separatorPosition.x(), innerRect.maxY());
+        gtk_render_line(separatorStyleContext.get(), cairoContext, separatorPosition.x(), separatorPosition.y(), separatorPosition.x(), innerRect.maxY());
         cairo_restore(cairoContext);
     }
 
-    gtk_style_context_restore(separatorStyleContext);
     return false;
 }
 
 bool RenderThemeGtk::paintTextField(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect)
 {
-    GtkStyleContext* context = getStyleContext(GTK_TYPE_ENTRY);
-    gtk_style_context_save(context);
+    GRefPtr<GtkStyleContext> context = createStyleContext(GTK_TYPE_ENTRY);
 
-    gtk_style_context_set_direction(context, static_cast<GtkTextDirection>(gtkTextDirection(renderObject->style().direction())));
-    gtk_style_context_add_class(context, GTK_STYLE_CLASS_ENTRY);
+    gtk_style_context_set_direction(context.get(), static_cast<GtkTextDirection>(gtkTextDirection(renderObject->style().direction())));
+    gtk_style_context_add_class(context.get(), GTK_STYLE_CLASS_ENTRY);
 
     guint flags = 0;
     if (!isEnabled(renderObject) || isReadOnlyControl(renderObject))
         flags |= GTK_STATE_FLAG_INSENSITIVE;
     else if (isFocused(renderObject))
         flags |= GTK_STATE_FLAG_FOCUSED;
-    gtk_style_context_set_state(context, static_cast<GtkStateFlags>(flags));
+    gtk_style_context_set_state(context.get(), static_cast<GtkStateFlags>(flags));
 
-    gtk_render_background(context, paintInfo.context->platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height());
-    gtk_render_frame(context, paintInfo.context->platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height());
+    gtk_render_background(context.get(), paintInfo.context->platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height());
+    gtk_render_frame(context.get(), paintInfo.context->platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height());
 
     if (isFocused(renderObject) && isEnabled(renderObject)) {
         gboolean interiorFocus;
         gint focusWidth, focusPad;
-        gtk_style_context_get_style(context,
-                                    "interior-focus", &interiorFocus,
-                                    "focus-line-width", &focusWidth,
-                                    "focus-padding", &focusPad,
-                                    NULL);
+        gtk_style_context_get_style(context.get(), "interior-focus", &interiorFocus, "focus-line-width", &focusWidth, "focus-padding", &focusPad, nullptr);
         if (!interiorFocus) {
             IntRect focusRect(rect);
             focusRect.inflate(focusWidth + focusPad);
-            gtk_render_focus(context, paintInfo.context->platformContext()->cr(),
-                             focusRect.x(), focusRect.y(), focusRect.width(), focusRect.height());
+            gtk_render_focus(context.get(), paintInfo.context->platformContext()->cr(), focusRect.x(), focusRect.y(), focusRect.width(), focusRect.height());
         }
     }
 
-    gtk_style_context_restore(context);
-
     return false;
 }
 
@@ -660,33 +585,26 @@
     ControlPart part = renderObject->style().appearance();
     ASSERT_UNUSED(part, part == SliderHorizontalPart || part == SliderVerticalPart || part == MediaVolumeSliderPart);
 
-    GtkStyleContext* context = getStyleContext(GTK_TYPE_SCALE);
-    gtk_style_context_save(context);
+    GRefPtr<GtkStyleContext> context = createStyleContext(GTK_TYPE_SCALE);
 
-    gtk_style_context_set_direction(context, gtkTextDirection(renderObject->style().direction()));
-    applySliderStyleContextClasses(context, part);
-    gtk_style_context_add_class(context, GTK_STYLE_CLASS_TROUGH);
+    gtk_style_context_set_direction(context.get(), gtkTextDirection(renderObject->style().direction()));
+    applySliderStyleContextClasses(context.get(), part);
+    gtk_style_context_add_class(context.get(), GTK_STYLE_CLASS_TROUGH);
 
     if (!isEnabled(renderObject) || isReadOnlyControl(renderObject))
-        gtk_style_context_set_state(context, GTK_STATE_FLAG_INSENSITIVE);
+        gtk_style_context_set_state(context.get(), GTK_STATE_FLAG_INSENSITIVE);
 
-    gtk_render_background(context, paintInfo.context->platformContext()->cr(),
-                          rect.x(), rect.y(), rect.width(), rect.height());
-    gtk_render_frame(context, paintInfo.context->platformContext()->cr(),
-                     rect.x(), rect.y(), rect.width(), rect.height());
+    gtk_render_background(context.get(), paintInfo.context->platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height());
+    gtk_render_frame(context.get(), paintInfo.context->platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height());
 
     if (isFocused(renderObject)) {
         gint focusWidth, focusPad;
-        gtk_style_context_get_style(context,
-                                    "focus-line-width", &focusWidth,
-                                    "focus-padding", &focusPad, NULL);
+        gtk_style_context_get_style(context.get(), "focus-line-width", &focusWidth, "focus-padding", &focusPad, nullptr);
         IntRect focusRect(rect);
         focusRect.inflate(focusWidth + focusPad);
-        gtk_render_focus(context, paintInfo.context->platformContext()->cr(),
-                         focusRect.x(), focusRect.y(), focusRect.width(), focusRect.height());
+        gtk_render_focus(context.get(), paintInfo.context->platformContext()->cr(), focusRect.x(), focusRect.y(), focusRect.width(), focusRect.height());
     }
 
-    gtk_style_context_restore(context);
     return false;
 }
 
@@ -695,12 +613,11 @@
     ControlPart part = renderObject->style().appearance();
     ASSERT(part == SliderThumbHorizontalPart || part == SliderThumbVerticalPart || part == MediaVolumeSliderThumbPart);
 
-    GtkStyleContext* context = getStyleContext(GTK_TYPE_SCALE);
-    gtk_style_context_save(context);
+    GRefPtr<GtkStyleContext> context = createStyleContext(GTK_TYPE_SCALE);
 
-    gtk_style_context_set_direction(context, gtkTextDirection(renderObject->style().direction()));
-    applySliderStyleContextClasses(context, part);
-    gtk_style_context_add_class(context, GTK_STYLE_CLASS_SLIDER);
+    gtk_style_context_set_direction(context.get(), gtkTextDirection(renderObject->style().direction()));
+    applySliderStyleContextClasses(context.get(), part);
+    gtk_style_context_add_class(context.get(), GTK_STYLE_CLASS_SLIDER);
 
     guint flags = 0;
     if (!isEnabled(renderObject) || isReadOnlyControl(renderObject))
@@ -709,13 +626,11 @@
         flags |= GTK_STATE_FLAG_PRELIGHT;
     if (isPressed(renderObject))
         flags |= GTK_STATE_FLAG_ACTIVE;
-    gtk_style_context_set_state(context, static_cast<GtkStateFlags>(flags));
+    gtk_style_context_set_state(context.get(), static_cast<GtkStateFlags>(flags));
 
-    gtk_render_slider(context, paintInfo.context->platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height(),
-                      part == SliderThumbHorizontalPart ? GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL);
+    gtk_render_slider(context.get(), paintInfo.context->platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height(),
+        part == SliderThumbHorizontalPart ? GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL);
 
-    gtk_style_context_restore(context);
-
     return false;
 }
 
@@ -725,11 +640,9 @@
     if (part != SliderThumbHorizontalPart && part != SliderThumbVerticalPart)
         return;
 
+    GRefPtr<GtkStyleContext> context = createStyleContext(GTK_TYPE_SCALE);
     gint sliderWidth, sliderLength;
-    gtk_style_context_get_style(getStyleContext(GTK_TYPE_SCALE),
-                                "slider-width", &sliderWidth,
-                                "slider-length", &sliderLength,
-                                NULL);
+    gtk_style_context_get_style(context.get(), "slider-width", &sliderWidth, "slider-length", &sliderLength, nullptr);
     if (part == SliderThumbHorizontalPart) {
         style->setWidth(Length(sliderLength, Fixed));
         style->setHeight(Length(sliderWidth, Fixed));
@@ -746,23 +659,21 @@
     if (!renderObject->isProgress())
         return true;
 
-    GtkStyleContext* context = getStyleContext(GTK_TYPE_PROGRESS_BAR);
-    gtk_style_context_save(context);
+    GRefPtr<GtkStyleContext> context = createStyleContext(GTK_TYPE_PROGRESS_BAR);
+    gtk_style_context_save(context.get());
 
-    gtk_style_context_add_class(context, GTK_STYLE_CLASS_TROUGH);
+    gtk_style_context_add_class(context.get(), GTK_STYLE_CLASS_TROUGH);
 
-    gtk_render_background(context, paintInfo.context->platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height());
-    gtk_render_frame(context, paintInfo.context->platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height());
+    gtk_render_background(context.get(), paintInfo.context->platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height());
+    gtk_render_frame(context.get(), paintInfo.context->platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height());
 
-    gtk_style_context_restore(context);
+    gtk_style_context_restore(context.get());
 
-    gtk_style_context_save(context);
-    gtk_style_context_add_class(context, GTK_STYLE_CLASS_PROGRESSBAR);
+    gtk_style_context_add_class(context.get(), GTK_STYLE_CLASS_PROGRESSBAR);
+    gtk_style_context_set_state(context.get(), static_cast<GtkStateFlags>(0));
 
-    gtk_style_context_set_state(context, static_cast<GtkStateFlags>(0));
-
     GtkBorder padding;
-    gtk_style_context_get_padding(context, gtk_style_context_get_state(context), &padding);
+    gtk_style_context_get_padding(context.get(), gtk_style_context_get_state(context.get()), &padding);
     IntRect progressRect(rect.x() + padding.left, rect.y() + padding.top,
                          rect.width() - (padding.left + padding.right),
                          rect.height() - (padding.top + padding.bottom));
@@ -770,13 +681,13 @@
 
     if (!progressRect.isEmpty()) {
 #if GTK_CHECK_VERSION(3, 13, 7)
-        gtk_render_background(context, paintInfo.context->platformContext()->cr(), progressRect.x(), progressRect.y(), progressRect.width(), progressRect.height());
-        gtk_render_frame(context, paintInfo.context->platformContext()->cr(), progressRect.x(), progressRect.y(), progressRect.width(), progressRect.height());
+        gtk_render_background(context.get(), paintInfo.context->platformContext()->cr(), progressRect.x(), progressRect.y(), progressRect.width(), progressRect.height());
+        gtk_render_frame(context.get(), paintInfo.context->platformContext()->cr(), progressRect.x(), progressRect.y(), progressRect.width(), progressRect.height());
 #else
-        gtk_render_activity(context, paintInfo.context->platformContext()->cr(), progressRect.x(), progressRect.y(), progressRect.width(), progressRect.height());
+        gtk_render_activity(context.get(), paintInfo.context->platformContext()->cr(), progressRect.x(), progressRect.y(), progressRect.width(), progressRect.height());
 #endif
     }
-    gtk_style_context_restore(context);
+
     return false;
 }
 #endif
@@ -794,12 +705,12 @@
 
 void RenderThemeGtk::adjustInnerSpinButtonStyle(StyleResolver*, RenderStyle* style, Element*) const
 {
-    GtkStyleContext* context = getStyleContext(GTK_TYPE_SPIN_BUTTON);
+    GRefPtr<GtkStyleContext> context = createStyleContext(GTK_TYPE_SPIN_BUTTON);
 
     GtkBorder padding;
-    gtk_style_context_get_padding(context, gtk_style_context_get_state(context), &padding);
+    gtk_style_context_get_padding(context.get(), gtk_style_context_get_state(context.get()), &padding);
 
-    int width = spinButtonArrowSize(context) + padding.left + padding.right;
+    int width = spinButtonArrowSize(context.get()) + padding.left + padding.right;
     style->setWidth(Length(width, Fixed));
     style->setMinWidth(Length(width, Fixed));
 }
@@ -872,74 +783,63 @@
 
 bool RenderThemeGtk::paintInnerSpinButton(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect)
 {
-    GtkStyleContext* context = getStyleContext(GTK_TYPE_SPIN_BUTTON);
-    gtk_style_context_save(context);
+    GRefPtr<GtkStyleContext> context = createStyleContext(GTK_TYPE_SPIN_BUTTON);
 
     GtkTextDirection direction = static_cast<GtkTextDirection>(gtkTextDirection(renderObject->style().direction()));
-    gtk_style_context_set_direction(context, direction);
+    gtk_style_context_set_direction(context.get(), direction);
 
     guint flags = 0;
     if (!isEnabled(renderObject) || isReadOnlyControl(renderObject))
         flags |= GTK_STATE_FLAG_INSENSITIVE;
     else if (isFocused(renderObject))
         flags |= GTK_STATE_FLAG_FOCUSED;
-    gtk_style_context_set_state(context, static_cast<GtkStateFlags>(flags));
-    gtk_style_context_remove_class(context, GTK_STYLE_CLASS_ENTRY);
+    gtk_style_context_set_state(context.get(), static_cast<GtkStateFlags>(flags));
+    gtk_style_context_remove_class(context.get(), GTK_STYLE_CLASS_ENTRY);
 
-    paintSpinArrowButton(this, context, renderObject, paintInfo, rect, GTK_ARROW_UP);
-    paintSpinArrowButton(this, context, renderObject, paintInfo, rect, GTK_ARROW_DOWN);
+    paintSpinArrowButton(this, context.get(), renderObject, paintInfo, rect, GTK_ARROW_UP);
+    paintSpinArrowButton(this, context.get(), renderObject, paintInfo, rect, GTK_ARROW_DOWN);
 
-    gtk_style_context_restore(context);
-
     return false;
 }
 
 GRefPtr<GdkPixbuf> getStockIconForWidgetType(GType widgetType, const char* iconName, gint direction, gint state, gint iconSize)
 {
-    GtkStyleContext* context = getStyleContext(widgetType);
-    GtkIconSet* iconSet = gtk_style_context_lookup_icon_set(context, iconName);
+    GRefPtr<GtkStyleContext> context = createStyleContext(widgetType);
+    GtkIconSet* iconSet = gtk_style_context_lookup_icon_set(context.get(), iconName);
 
-    gtk_style_context_save(context);
-
     guint flags = 0;
     if (state == GTK_STATE_PRELIGHT)
         flags |= GTK_STATE_FLAG_PRELIGHT;
     else if (state == GTK_STATE_INSENSITIVE)
         flags |= GTK_STATE_FLAG_INSENSITIVE;
 
-    gtk_style_context_set_state(context, static_cast<GtkStateFlags>(flags));
-    gtk_style_context_set_direction(context, static_cast<GtkTextDirection>(direction));
-    GdkPixbuf* icon = gtk_icon_set_render_icon_pixbuf(iconSet, context, static_cast<GtkIconSize>(iconSize));
+    gtk_style_context_set_state(context.get(), static_cast<GtkStateFlags>(flags));
+    gtk_style_context_set_direction(context.get(), static_cast<GtkTextDirection>(direction));
+    GdkPixbuf* icon = gtk_icon_set_render_icon_pixbuf(iconSet, context.get(), static_cast<GtkIconSize>(iconSize));
 
-    gtk_style_context_restore(context);
-
     return adoptGRef(icon);
 }
 
 GRefPtr<GdkPixbuf> getStockSymbolicIconForWidgetType(GType widgetType, const char* symbolicIconName, const char *fallbackStockIconName, gint direction, gint state, gint iconSize)
 {
-    GtkStyleContext* context = getStyleContext(widgetType);
+    GRefPtr<GtkStyleContext> context = createStyleContext(widgetType);
 
-    gtk_style_context_save(context);
-
     guint flags = 0;
     if (state == GTK_STATE_PRELIGHT)
         flags |= GTK_STATE_FLAG_PRELIGHT;
     else if (state == GTK_STATE_INSENSITIVE)
         flags |= GTK_STATE_FLAG_INSENSITIVE;
 
-    gtk_style_context_set_state(context, static_cast<GtkStateFlags>(flags));
-    gtk_style_context_set_direction(context, static_cast<GtkTextDirection>(direction));
+    gtk_style_context_set_state(context.get(), static_cast<GtkStateFlags>(flags));
+    gtk_style_context_set_direction(context.get(), static_cast<GtkTextDirection>(direction));
     GtkIconInfo* info = gtk_icon_theme_lookup_icon(gtk_icon_theme_get_default(), symbolicIconName, iconSize,
         static_cast<GtkIconLookupFlags>(GTK_ICON_LOOKUP_FORCE_SVG | GTK_ICON_LOOKUP_FORCE_SIZE));
     GdkPixbuf* icon = 0;
     if (info) {
-        icon = gtk_icon_info_load_symbolic_for_context(info, context, 0, 0);
+        icon = gtk_icon_info_load_symbolic_for_context(info, context.get(), nullptr, nullptr);
         gtk_icon_info_free(info);
     }
 
-    gtk_style_context_restore(context);
-
     if (!icon)
         return getStockIconForWidgetType(widgetType, fallbackStockIconName, direction, state, iconSize);
 
@@ -950,15 +850,15 @@
 
 static Color styleColor(GType widgetType, GtkStateFlags state, StyleColorType colorType)
 {
-    GtkStyleContext* context = getStyleContext(widgetType);
+    GRefPtr<GtkStyleContext> context = createStyleContext(widgetType);
     // Recent GTK+ versions (> 3.14) require to explicitly set the state before getting the color.
-    gtk_style_context_set_state(context, state);
+    gtk_style_context_set_state(context.get(), state);
 
     GdkRGBA gdkRGBAColor;
     if (colorType == StyleColorBackground)
-        gtk_style_context_get_background_color(context, gtk_style_context_get_state(context), &gdkRGBAColor);
+        gtk_style_context_get_background_color(context.get(), gtk_style_context_get_state(context.get()), &gdkRGBAColor);
     else
-        gtk_style_context_get_color(context, gtk_style_context_get_state(context), &gdkRGBAColor);
+        gtk_style_context_get_color(context.get(), gtk_style_context_get_state(context.get()), &gdkRGBAColor);
     return gdkRGBAColor;
 }
 

Modified: releases/WebKitGTK/webkit-2.4/Source/WebCore/platform/gtk/ScrollbarThemeGtk.h (197249 => 197250)


--- releases/WebKitGTK/webkit-2.4/Source/WebCore/platform/gtk/ScrollbarThemeGtk.h	2016-02-27 15:08:56 UTC (rev 197249)
+++ releases/WebKitGTK/webkit-2.4/Source/WebCore/platform/gtk/ScrollbarThemeGtk.h	2016-02-27 15:09:16 UTC (rev 197250)
@@ -56,15 +56,20 @@
     // TODO: These are the default GTK+ values. At some point we should pull these from the theme itself.
     virtual double initialAutoscrollTimerDelay() { return 0.20; }
     virtual double autoscrollTimerDelay() { return 0.02; }
+#ifdef GTK_API_VERSION_2
     void updateThemeProperties();
+#else
+    void themeChanged();
+#endif
     void updateScrollbarsFrameThickness();
     void registerScrollbar(ScrollbarThemeClient*);
     void unregisterScrollbar(ScrollbarThemeClient*);
 
 protected:
 #ifndef GTK_API_VERSION_2
-    GtkStyleContext* m_context;
+    void updateThemeProperties();
 #endif
+
     int m_thumbFatness;
     int m_troughBorderWidth;
     int m_stepperSize;

Modified: releases/WebKitGTK/webkit-2.4/Source/WebCore/platform/gtk/ScrollbarThemeGtk3.cpp (197249 => 197250)


--- releases/WebKitGTK/webkit-2.4/Source/WebCore/platform/gtk/ScrollbarThemeGtk3.cpp	2016-02-27 15:08:56 UTC (rev 197249)
+++ releases/WebKitGTK/webkit-2.4/Source/WebCore/platform/gtk/ScrollbarThemeGtk3.cpp	2016-02-27 15:09:16 UTC (rev 197250)
@@ -30,39 +30,68 @@
 
 #include "PlatformContextCairo.h"
 #include "PlatformMouseEvent.h"
-#include "RenderThemeGtk.h"
 #include "ScrollView.h"
 #include "Scrollbar.h"
 #include <gtk/gtk.h>
+#include <wtf/gobject/GRefPtr.h>
 
 namespace WebCore {
 
-static void gtkStyleChangedCallback(GtkWidget*, ScrollbarThemeGtk* scrollbarTheme)
+class ScrollbarStyleContext {
+    WTF_MAKE_NONCOPYABLE(ScrollbarStyleContext); WTF_MAKE_FAST_ALLOCATED;
+public:
+    ScrollbarStyleContext()
+        : m_context(adoptGRef(gtk_style_context_new()))
+    {
+        GtkWidgetPath* path = gtk_widget_path_new();
+        gtk_widget_path_append_type(path, GTK_TYPE_SCROLLBAR);
+        gtk_widget_path_iter_add_class(path, 0, GTK_STYLE_CLASS_SCROLLBAR);
+        gtk_style_context_set_path(m_context.get(), path);
+        gtk_widget_path_free(path);
+    }
+
+    ~ScrollbarStyleContext()
+    {
+    }
+
+    GtkStyleContext* context() const { return m_context.get(); }
+
+private:
+    GRefPtr<GtkStyleContext> m_context;
+};
+
+static GtkStyleContext* gtkScrollbarStyleContext()
 {
-    scrollbarTheme->updateThemeProperties();
+    DEFINE_STATIC_LOCAL(ScrollbarStyleContext, styleContext, ());
+    return styleContext.context();
 }
 
+void ScrollbarThemeGtk::themeChanged()
+{
+    gtk_style_context_invalidate(gtkScrollbarStyleContext());
+    updateThemeProperties();
+}
+
 ScrollbarThemeGtk::ScrollbarThemeGtk()
-    : m_context(static_cast<RenderThemeGtk*>(RenderTheme::defaultTheme().get())->gtkScrollbarStyle())
 {
     updateThemeProperties();
-    g_signal_connect(m_context, "changed", G_CALLBACK(gtkStyleChangedCallback), this);
 }
 
 void ScrollbarThemeGtk::updateThemeProperties()
 {
-    gtk_style_context_get_style(m_context,
-                                "min-slider-length", &m_minThumbLength,
-                                "slider-width", &m_thumbFatness,
-                                "trough-border", &m_troughBorderWidth,
-                                "stepper-size", &m_stepperSize,
-                                "stepper-spacing", &m_stepperSpacing,
-                                "trough-under-steppers", &m_troughUnderSteppers,
-                                "has-backward-stepper", &m_hasBackButtonStartPart,
-                                "has-forward-stepper", &m_hasForwardButtonEndPart,
-                                "has-secondary-backward-stepper", &m_hasBackButtonEndPart,
-                                "has-secondary-forward-stepper", &m_hasForwardButtonStartPart,
-                                NULL);
+    gtk_style_context_get_style(
+        gtkScrollbarStyleContext(),
+        "min-slider-length", &m_minThumbLength,
+        "slider-width", &m_thumbFatness,
+        "trough-border", &m_troughBorderWidth,
+        "stepper-size", &m_stepperSize,
+        "stepper-spacing", &m_stepperSpacing,
+        "trough-under-steppers", &m_troughUnderSteppers,
+        "has-backward-stepper", &m_hasBackButtonStartPart,
+        "has-forward-stepper", &m_hasForwardButtonEndPart,
+        "has-secondary-backward-stepper", &m_hasBackButtonEndPart,
+        "has-secondary-forward-stepper", &m_hasForwardButtonStartPart,
+        nullptr);
     updateScrollbarsFrameThickness();
 }
 
@@ -90,60 +119,62 @@
     if (m_troughUnderSteppers)
         fullScrollbarRect = IntRect(scrollbar->x(), scrollbar->y(), scrollbar->width(), scrollbar->height());
 
-    gtk_style_context_save(m_context);
+    GtkStyleContext* styleContext = gtkScrollbarStyleContext();
+    gtk_style_context_save(styleContext);
 
-    applyScrollbarStyleContextClasses(m_context, scrollbar->orientation());
-    gtk_style_context_add_class(m_context, GTK_STYLE_CLASS_TROUGH);
+    applyScrollbarStyleContextClasses(styleContext, scrollbar->orientation());
+    gtk_style_context_add_class(styleContext, GTK_STYLE_CLASS_TROUGH);
 
-    adjustRectAccordingToMargin(m_context, static_cast<GtkStateFlags>(0), fullScrollbarRect);
-    gtk_render_background(m_context, context->platformContext()->cr(),
-                          fullScrollbarRect.x(), fullScrollbarRect.y(), fullScrollbarRect.width(), fullScrollbarRect.height());
-    gtk_render_frame(m_context, context->platformContext()->cr(),
-                     fullScrollbarRect.x(), fullScrollbarRect.y(), fullScrollbarRect.width(), fullScrollbarRect.height());
+    adjustRectAccordingToMargin(styleContext, static_cast<GtkStateFlags>(0), fullScrollbarRect);
+    gtk_render_background(styleContext, context->platformContext()->cr(), fullScrollbarRect.x(), fullScrollbarRect.y(), fullScrollbarRect.width(), fullScrollbarRect.height());
+    gtk_render_frame(styleContext, context->platformContext()->cr(), fullScrollbarRect.x(), fullScrollbarRect.y(), fullScrollbarRect.width(), fullScrollbarRect.height());
 
-    gtk_style_context_restore(m_context);
+    gtk_style_context_restore(styleContext);
 }
 
 void ScrollbarThemeGtk::paintScrollbarBackground(GraphicsContext* context, ScrollbarThemeClient* scrollbar)
 {
-    gtk_style_context_save(m_context);
+    GtkStyleContext* styleContext = gtkScrollbarStyleContext();
+    gtk_style_context_save(styleContext);
 
-    applyScrollbarStyleContextClasses(m_context, scrollbar->orientation());
-    gtk_style_context_add_class(m_context, "scrolled-window");
-    gtk_render_frame(m_context, context->platformContext()->cr(), scrollbar->x(), scrollbar->y(), scrollbar->width(), scrollbar->height());
+    applyScrollbarStyleContextClasses(styleContext, scrollbar->orientation());
+    gtk_style_context_add_class(styleContext, "scrolled-window");
+    gtk_render_frame(styleContext, context->platformContext()->cr(), scrollbar->x(), scrollbar->y(), scrollbar->width(), scrollbar->height());
 
-    gtk_style_context_restore(m_context);
+    gtk_style_context_restore(styleContext);
 }
 
 void ScrollbarThemeGtk::paintThumb(GraphicsContext* context, ScrollbarThemeClient* scrollbar, const IntRect& rect)
 {
-    gtk_style_context_save(m_context);
+    GtkStyleContext* styleContext = gtkScrollbarStyleContext();
+    gtk_style_context_save(styleContext);
 
     ScrollbarOrientation orientation = scrollbar->orientation();
-    applyScrollbarStyleContextClasses(m_context, orientation);
-    gtk_style_context_add_class(m_context, GTK_STYLE_CLASS_SLIDER);
+    applyScrollbarStyleContextClasses(styleContext, orientation);
+    gtk_style_context_add_class(styleContext, GTK_STYLE_CLASS_SLIDER);
 
     guint flags = 0;
     if (scrollbar->pressedPart() == ThumbPart)
         flags |= GTK_STATE_FLAG_ACTIVE;
     if (scrollbar->hoveredPart() == ThumbPart)
         flags |= GTK_STATE_FLAG_PRELIGHT;
-    gtk_style_context_set_state(m_context, static_cast<GtkStateFlags>(flags));
+    gtk_style_context_set_state(styleContext, static_cast<GtkStateFlags>(flags));
 
     IntRect thumbRect(rect);
-    adjustRectAccordingToMargin(m_context, static_cast<GtkStateFlags>(flags), thumbRect);
-    gtk_render_slider(m_context, context->platformContext()->cr(), thumbRect.x(), thumbRect.y(), thumbRect.width(), thumbRect.height(),
+    adjustRectAccordingToMargin(styleContext, static_cast<GtkStateFlags>(flags), thumbRect);
+    gtk_render_slider(styleContext, context->platformContext()->cr(), thumbRect.x(), thumbRect.y(), thumbRect.width(), thumbRect.height(),
         orientation == VerticalScrollbar ? GTK_ORIENTATION_VERTICAL : GTK_ORIENTATION_HORIZONTAL);
 
-    gtk_style_context_restore(m_context);
+    gtk_style_context_restore(styleContext);
 }
 
 void ScrollbarThemeGtk::paintButton(GraphicsContext* context, ScrollbarThemeClient* scrollbar, const IntRect& rect, ScrollbarPart part)
 {
-    gtk_style_context_save(m_context);
+    GtkStyleContext* styleContext = gtkScrollbarStyleContext();
+    gtk_style_context_save(styleContext);
 
     ScrollbarOrientation orientation = scrollbar->orientation();
-    applyScrollbarStyleContextClasses(m_context, orientation);
+    applyScrollbarStyleContextClasses(styleContext, orientation);
 
     guint flags = 0;
     if ((BackButtonStartPart == part && scrollbar->currentPos())
@@ -156,14 +187,14 @@
             flags |= GTK_STATE_FLAG_PRELIGHT;
     } else
         flags |= GTK_STATE_FLAG_INSENSITIVE;
-    gtk_style_context_set_state(m_context, static_cast<GtkStateFlags>(flags));
+    gtk_style_context_set_state(styleContext, static_cast<GtkStateFlags>(flags));
 
-    gtk_style_context_add_class(m_context, GTK_STYLE_CLASS_BUTTON);
-    gtk_render_background(m_context, context->platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height());
-    gtk_render_frame(m_context, context->platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height());
+    gtk_style_context_add_class(styleContext, GTK_STYLE_CLASS_BUTTON);
+    gtk_render_background(styleContext, context->platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height());
+    gtk_render_frame(styleContext, context->platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height());
 
     gfloat arrowScaling;
-    gtk_style_context_get_style(m_context, "arrow-scaling", &arrowScaling, NULL);
+    gtk_style_context_get_style(styleContext, "arrow-scaling", &arrowScaling, NULL);
 
     double arrowSize = std::min(rect.width(), rect.height()) * arrowScaling;
     FloatPoint arrowPoint(rect.x() + (rect.width() - arrowSize) / 2,
@@ -171,10 +202,7 @@
 
     if (flags & GTK_STATE_FLAG_ACTIVE) {
         gint arrowDisplacementX, arrowDisplacementY;
-        gtk_style_context_get_style(m_context,
-                                    "arrow-displacement-x", &arrowDisplacementX,
-                                    "arrow-displacement-y", &arrowDisplacementY,
-                                    NULL);
+        gtk_style_context_get_style(styleContext, "arrow-displacement-x", &arrowDisplacementX, "arrow-displacement-y", &arrowDisplacementY, nullptr);
         arrowPoint.move(arrowDisplacementX, arrowDisplacementY);
     }
 
@@ -185,9 +213,9 @@
         angle = (part == ForwardButtonEndPart || part == ForwardButtonStartPart) ? G_PI / 2 : 3 * (G_PI / 2);
     }
 
-    gtk_render_arrow(m_context, context->platformContext()->cr(), angle, arrowPoint.x(), arrowPoint.y(), arrowSize);
+    gtk_render_arrow(styleContext, context->platformContext()->cr(), angle, arrowPoint.x(), arrowPoint.y(), arrowSize);
 
-    gtk_style_context_restore(m_context);
+    gtk_style_context_restore(styleContext);
 }
 
 } // namespace WebCore
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to