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

Log Message

Merge r194847 - [GTK] Cleanup RenderThemeGtk
https://bugs.webkit.org/show_bug.cgi?id=152888

Reviewed by Michael Catanzaro.

Use a common path for GTK+ 3.19 and previous versions, simplifying
the code and removing a lot of ifdefs.

 - createStyleContext() now receives a theme part enum value, and
   an optional parent GtkStyleContext. It encapsulates all the
   differences between GTK+ 3.19 and previous version leaving the
   rendering code common and free of ifdefs.
 - Stock icons support have been removed, simplifying the code
   that now always renders symbolic icons, updating the colors
   depending on the current state.
 - Media button and colors have been removed, because they are
   unused now that we render the media controls with CSS.
 - ComboBox separators support has also been removed. In GTK+ 3.19
   combo boxes no longer have separators and most of the GTK+
   themes don't use the either, so it's better to simple not render
   them anymore in WebKit either.
 - Code to paint caps lock indicator has been removed too, since
   caps lock indicator is now shadow dom and automatically
   rendered by WebCore.

* rendering/RenderThemeGtk.cpp:
(WebCore::createStyleContext):
(WebCore::loadThemedIcon):
(WebCore::gtkIconStateFlags):
(WebCore::RenderThemeGtk::adjustRepaintRect):
(WebCore::setToggleSize):
(WebCore::paintToggle):
(WebCore::RenderThemeGtk::setCheckboxSize):
(WebCore::RenderThemeGtk::paintCheckbox):
(WebCore::RenderThemeGtk::setRadioSize):
(WebCore::RenderThemeGtk::paintRadio):
(WebCore::RenderThemeGtk::paintButton):
(WebCore::getComboBoxMetrics):
(WebCore::RenderThemeGtk::popupInternalPaddingLeft):
(WebCore::RenderThemeGtk::popupInternalPaddingRight):
(WebCore::RenderThemeGtk::popupInternalPaddingTop):
(WebCore::RenderThemeGtk::popupInternalPaddingBottom):
(WebCore::RenderThemeGtk::paintMenuList):
(WebCore::RenderThemeGtk::paintTextField):
(WebCore::adjustSearchFieldIconStyle):
(WebCore::RenderThemeGtk::adjustSearchFieldResultsDecorationPartStyle):
(WebCore::paintIcon):
(WebCore::paintEntryIcon):
(WebCore::RenderThemeGtk::paintSearchFieldResultsDecorationPart):
(WebCore::RenderThemeGtk::adjustSearchFieldCancelButtonStyle):
(WebCore::RenderThemeGtk::paintSearchFieldCancelButton):
(WebCore::RenderThemeGtk::shouldHaveCapsLockIndicator):
(WebCore::RenderThemeGtk::paintSliderTrack):
(WebCore::RenderThemeGtk::paintSliderThumb):
(WebCore::RenderThemeGtk::adjustSliderThumbSize):
(WebCore::RenderThemeGtk::paintProgressBar):
(WebCore::RenderThemeGtk::adjustInnerSpinButtonStyle):
(WebCore::paintSpinArrowButton):
(WebCore::RenderThemeGtk::paintInnerSpinButton):
(WebCore::styleColor):
(WebCore::RenderThemeGtk::platformActiveSelectionBackgroundColor):
(WebCore::RenderThemeGtk::platformInactiveSelectionBackgroundColor):
(WebCore::RenderThemeGtk::platformActiveSelectionForegroundColor):
(WebCore::RenderThemeGtk::platformInactiveSelectionForegroundColor):
(WebCore::RenderThemeGtk::platformActiveListBoxSelectionBackgroundColor):
(WebCore::RenderThemeGtk::platformInactiveListBoxSelectionBackgroundColor):
(WebCore::RenderThemeGtk::platformActiveListBoxSelectionForegroundColor):
(WebCore::RenderThemeGtk::platformInactiveListBoxSelectionForegroundColor):
(WebCore::RenderThemeGtk::systemColor):
(WebCore::RenderThemeGtk::paintMediaButton):
(WebCore::RenderThemeGtk::paintMediaFullscreenButton):
(WebCore::RenderThemeGtk::paintMediaMuteButton):
(WebCore::RenderThemeGtk::paintMediaPlayButton):
(WebCore::RenderThemeGtk::paintMediaSeekBackButton):
(WebCore::RenderThemeGtk::paintMediaSeekForwardButton):
(WebCore::RenderThemeGtk::paintMediaToggleClosedCaptionsButton):
* rendering/RenderThemeGtk.h:

Modified Paths

Diff

Modified: releases/WebKitGTK/webkit-2.4/Source/WebCore/ChangeLog (197251 => 197252)


--- releases/WebKitGTK/webkit-2.4/Source/WebCore/ChangeLog	2016-02-27 15:09:36 UTC (rev 197251)
+++ releases/WebKitGTK/webkit-2.4/Source/WebCore/ChangeLog	2016-02-27 15:09:57 UTC (rev 197252)
@@ -1,3 +1,83 @@
+2016-01-11  Carlos Garcia Campos  <[email protected]>
+
+        [GTK] Cleanup RenderThemeGtk
+        https://bugs.webkit.org/show_bug.cgi?id=152888
+
+        Reviewed by Michael Catanzaro.
+
+        Use a common path for GTK+ 3.19 and previous versions, simplifying
+        the code and removing a lot of ifdefs.
+
+         - createStyleContext() now receives a theme part enum value, and
+           an optional parent GtkStyleContext. It encapsulates all the
+           differences between GTK+ 3.19 and previous version leaving the
+           rendering code common and free of ifdefs.
+         - Stock icons support have been removed, simplifying the code
+           that now always renders symbolic icons, updating the colors
+           depending on the current state.
+         - Media button and colors have been removed, because they are
+           unused now that we render the media controls with CSS.
+         - ComboBox separators support has also been removed. In GTK+ 3.19
+           combo boxes no longer have separators and most of the GTK+
+           themes don't use the either, so it's better to simple not render
+           them anymore in WebKit either.
+         - Code to paint caps lock indicator has been removed too, since
+           caps lock indicator is now shadow dom and automatically
+           rendered by WebCore.
+
+        * rendering/RenderThemeGtk.cpp:
+        (WebCore::createStyleContext):
+        (WebCore::loadThemedIcon):
+        (WebCore::gtkIconStateFlags):
+        (WebCore::RenderThemeGtk::adjustRepaintRect):
+        (WebCore::setToggleSize):
+        (WebCore::paintToggle):
+        (WebCore::RenderThemeGtk::setCheckboxSize):
+        (WebCore::RenderThemeGtk::paintCheckbox):
+        (WebCore::RenderThemeGtk::setRadioSize):
+        (WebCore::RenderThemeGtk::paintRadio):
+        (WebCore::RenderThemeGtk::paintButton):
+        (WebCore::getComboBoxMetrics):
+        (WebCore::RenderThemeGtk::popupInternalPaddingLeft):
+        (WebCore::RenderThemeGtk::popupInternalPaddingRight):
+        (WebCore::RenderThemeGtk::popupInternalPaddingTop):
+        (WebCore::RenderThemeGtk::popupInternalPaddingBottom):
+        (WebCore::RenderThemeGtk::paintMenuList):
+        (WebCore::RenderThemeGtk::paintTextField):
+        (WebCore::adjustSearchFieldIconStyle):
+        (WebCore::RenderThemeGtk::adjustSearchFieldResultsDecorationPartStyle):
+        (WebCore::paintIcon):
+        (WebCore::paintEntryIcon):
+        (WebCore::RenderThemeGtk::paintSearchFieldResultsDecorationPart):
+        (WebCore::RenderThemeGtk::adjustSearchFieldCancelButtonStyle):
+        (WebCore::RenderThemeGtk::paintSearchFieldCancelButton):
+        (WebCore::RenderThemeGtk::shouldHaveCapsLockIndicator):
+        (WebCore::RenderThemeGtk::paintSliderTrack):
+        (WebCore::RenderThemeGtk::paintSliderThumb):
+        (WebCore::RenderThemeGtk::adjustSliderThumbSize):
+        (WebCore::RenderThemeGtk::paintProgressBar):
+        (WebCore::RenderThemeGtk::adjustInnerSpinButtonStyle):
+        (WebCore::paintSpinArrowButton):
+        (WebCore::RenderThemeGtk::paintInnerSpinButton):
+        (WebCore::styleColor):
+        (WebCore::RenderThemeGtk::platformActiveSelectionBackgroundColor):
+        (WebCore::RenderThemeGtk::platformInactiveSelectionBackgroundColor):
+        (WebCore::RenderThemeGtk::platformActiveSelectionForegroundColor):
+        (WebCore::RenderThemeGtk::platformInactiveSelectionForegroundColor):
+        (WebCore::RenderThemeGtk::platformActiveListBoxSelectionBackgroundColor):
+        (WebCore::RenderThemeGtk::platformInactiveListBoxSelectionBackgroundColor):
+        (WebCore::RenderThemeGtk::platformActiveListBoxSelectionForegroundColor):
+        (WebCore::RenderThemeGtk::platformInactiveListBoxSelectionForegroundColor):
+        (WebCore::RenderThemeGtk::systemColor):
+        (WebCore::RenderThemeGtk::paintMediaButton):
+        (WebCore::RenderThemeGtk::paintMediaFullscreenButton):
+        (WebCore::RenderThemeGtk::paintMediaMuteButton):
+        (WebCore::RenderThemeGtk::paintMediaPlayButton):
+        (WebCore::RenderThemeGtk::paintMediaSeekBackButton):
+        (WebCore::RenderThemeGtk::paintMediaSeekForwardButton):
+        (WebCore::RenderThemeGtk::paintMediaToggleClosedCaptionsButton):
+        * rendering/RenderThemeGtk.h:
+
 2015-12-22  Michael Catanzaro  <[email protected]>
 
         [GTK] Everything broken in GTK+ 3.19

Modified: releases/WebKitGTK/webkit-2.4/Source/WebCore/platform/gtk/RenderThemeGtk.cpp (197251 => 197252)


--- releases/WebKitGTK/webkit-2.4/Source/WebCore/platform/gtk/RenderThemeGtk.cpp	2016-02-27 15:09:36 UTC (rev 197251)
+++ releases/WebKitGTK/webkit-2.4/Source/WebCore/platform/gtk/RenderThemeGtk.cpp	2016-02-27 15:09:57 UTC (rev 197252)
@@ -56,11 +56,6 @@
 
 namespace WebCore {
 
-// This would be a static method, except that forward declaring GType is tricky, since its
-// definition depends on including glib.h, negating the benefit of using a forward declaration.
-extern GRefPtr<GdkPixbuf> getStockIconForWidgetType(GType, const char* iconName, gint direction, gint state, gint iconSize);
-extern GRefPtr<GdkPixbuf> getStockSymbolicIconForWidgetType(GType widgetType, const char* symbolicIconName, const char *fallbackStockIconName, gint direction, gint state, gint iconSize);
-
 #if ENABLE(VIDEO)
 static HTMLMediaElement* getMediaElementFromRenderObject(RenderObject* o)
 {
@@ -73,32 +68,6 @@
 
     return toHTMLMediaElement(mediaNode);
 }
-
-void RenderThemeGtk::initMediaButtons()
-{
-    static bool iconsInitialized = false;
-
-    if (iconsInitialized)
-        return;
-
-    GRefPtr<GtkIconFactory> iconFactory = adoptGRef(gtk_icon_factory_new());
-    GtkIconSource* iconSource = gtk_icon_source_new();
-    const char* icons[] = { "audio-volume-high", "audio-volume-muted" };
-
-    gtk_icon_factory_add_default(iconFactory.get());
-
-    for (size_t i = 0; i < G_N_ELEMENTS(icons); ++i) {
-        gtk_icon_source_set_icon_name(iconSource, icons[i]);
-        GtkIconSet* iconSet = gtk_icon_set_new();
-        gtk_icon_set_add_source(iconSet, iconSource);
-        gtk_icon_factory_add(iconFactory.get(), icons[i], iconSet);
-        gtk_icon_set_unref(iconSet);
-    }
-
-    gtk_icon_source_free(iconSource);
-
-    iconsInitialized = true;
-}
 #endif
 
 PassRefPtr<RenderTheme> RenderThemeGtk::create()
@@ -113,17 +82,8 @@
 }
 
 RenderThemeGtk::RenderThemeGtk()
-    : m_panelColor(Color::white)
-    , m_sliderColor(Color::white)
-    , m_sliderThumbColor(Color::white)
-    , m_mediaIconSize(16)
-    , m_mediaSliderHeight(14)
 {
     platformInit();
-#if ENABLE(VIDEO)
-    initMediaColors();
-    initMediaButtons();
-#endif
 }
 
 static bool supportsFocus(ControlPart appearance)
@@ -190,18 +150,6 @@
     }
 }
 
-static GtkStateType gtkIconState(RenderTheme* theme, RenderObject* renderObject)
-{
-    if (!theme->isEnabled(renderObject))
-        return GTK_STATE_INSENSITIVE;
-    if (theme->isPressed(renderObject))
-        return GTK_STATE_ACTIVE;
-    if (theme->isHovered(renderObject))
-        return GTK_STATE_PRELIGHT;
-
-    return GTK_STATE_NORMAL;
-}
-
 void RenderThemeGtk::adjustButtonStyle(StyleResolver*, RenderStyle* style, WebCore::Element*) const
 {
     // Some layout tests check explicitly that buttons ignore line-height.
@@ -233,48 +181,6 @@
     return paintTextField(o, i, r);
 }
 
-static void paintGdkPixbuf(GraphicsContext* context, const GdkPixbuf* icon, const IntRect& iconRect)
-{
-    IntSize iconSize(gdk_pixbuf_get_width(icon), gdk_pixbuf_get_height(icon));
-    GRefPtr<GdkPixbuf> scaledIcon;
-    if (iconRect.size() != iconSize) {
-        // We could use cairo_scale() here but cairo/pixman downscale quality is quite bad.
-        scaledIcon = adoptGRef(gdk_pixbuf_scale_simple(icon, iconRect.width(), iconRect.height(),
-                                                       GDK_INTERP_BILINEAR));
-        icon = scaledIcon.get();
-    }
-
-    cairo_t* cr = context->platformContext()->cr();
-    cairo_save(cr);
-    gdk_cairo_set_source_pixbuf(cr, icon, iconRect.x(), iconRect.y());
-    cairo_paint(cr);
-    cairo_restore(cr);
-}
-
-// Defined in GTK+ (gtk/gtkiconfactory.c)
-static const gint gtkIconSizeMenu = 16;
-static const gint gtkIconSizeSmallToolbar = 18;
-static const gint gtkIconSizeButton = 20;
-static const gint gtkIconSizeLargeToolbar = 24;
-static const gint gtkIconSizeDnd = 32;
-static const gint gtkIconSizeDialog = 48;
-
-static GtkIconSize getIconSizeForPixelSize(gint pixelSize)
-{
-    if (pixelSize < gtkIconSizeSmallToolbar)
-        return GTK_ICON_SIZE_MENU;
-    if (pixelSize >= gtkIconSizeSmallToolbar && pixelSize < gtkIconSizeButton)
-        return GTK_ICON_SIZE_SMALL_TOOLBAR;
-    if (pixelSize >= gtkIconSizeButton && pixelSize < gtkIconSizeLargeToolbar)
-        return GTK_ICON_SIZE_BUTTON;
-    if (pixelSize >= gtkIconSizeLargeToolbar && pixelSize < gtkIconSizeDnd)
-        return GTK_ICON_SIZE_LARGE_TOOLBAR;
-    if (pixelSize >= gtkIconSizeDnd && pixelSize < gtkIconSizeDialog)
-        return GTK_ICON_SIZE_DND;
-
-    return GTK_ICON_SIZE_DIALOG;
-}
-
 void RenderThemeGtk::adjustSearchFieldResultsButtonStyle(StyleResolver* styleResolver, RenderStyle* style, Element* e) const
 {
     adjustSearchFieldCancelButtonStyle(styleResolver, style, e);
@@ -285,82 +191,6 @@
     return paintSearchFieldResultsDecorationPart(o, i, rect);
 }
 
-static void adjustSearchFieldIconStyle(RenderStyle* style)
-{
-    style->resetBorder();
-    style->resetPadding();
-
-    // Get the icon size based on the font size.
-    int fontSize = style->fontSize();
-    if (fontSize < gtkIconSizeMenu) {
-        style->setWidth(Length(fontSize, Fixed));
-        style->setHeight(Length(fontSize, Fixed));
-        return;
-    }
-    gint width = 0, height = 0;
-    gtk_icon_size_lookup(getIconSizeForPixelSize(fontSize), &width, &height);
-    style->setWidth(Length(width, Fixed));
-    style->setHeight(Length(height, Fixed));
-}
-
-void RenderThemeGtk::adjustSearchFieldResultsDecorationPartStyle(StyleResolver*, RenderStyle* style, Element*) const
-{
-    adjustSearchFieldIconStyle(style);
-}
-
-static IntRect centerRectVerticallyInParentInputElement(RenderObject* renderObject, const IntRect& rect)
-{
-    // Get the renderer of <input> element.
-    Node* input = renderObject->node()->shadowHost();
-    if (!input)
-        input = renderObject->node();
-    if (!input->renderer()->isBox())
-        return IntRect();
-
-    // If possible center the y-coordinate of the rect vertically in the parent input element.
-    // We also add one pixel here to ensure that the y coordinate is rounded up for box heights
-    // that are even, which looks in relation to the box text.
-    IntRect inputContentBox = toRenderBox(input->renderer())->absoluteContentBox();
-
-    // Make sure the scaled decoration stays square and will fit in its parent's box.
-    int iconSize = std::min(inputContentBox.width(), std::min(inputContentBox.height(), rect.height()));
-    IntRect scaledRect(rect.x(), inputContentBox.y() + (inputContentBox.height() - iconSize + 1) / 2, iconSize, iconSize);
-    return scaledRect;
-}
-
-bool RenderThemeGtk::paintSearchFieldResultsDecorationPart(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect)
-{
-    IntRect iconRect = centerRectVerticallyInParentInputElement(renderObject, rect);
-    if (iconRect.isEmpty())
-        return false;
-
-    GRefPtr<GdkPixbuf> icon = getStockIconForWidgetType(GTK_TYPE_ENTRY, GTK_STOCK_FIND,
-                                                        gtkTextDirection(renderObject->style().direction()),
-                                                        gtkIconState(this, renderObject),
-                                                        getIconSizeForPixelSize(rect.height()));
-    paintGdkPixbuf(paintInfo.context, icon.get(), iconRect);
-    return false;
-}
-
-void RenderThemeGtk::adjustSearchFieldCancelButtonStyle(StyleResolver*, RenderStyle* style, Element*) const
-{
-    adjustSearchFieldIconStyle(style);
-}
-
-bool RenderThemeGtk::paintSearchFieldCancelButton(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect)
-{
-    IntRect iconRect = centerRectVerticallyInParentInputElement(renderObject, rect);
-    if (iconRect.isEmpty())
-        return false;
-
-    GRefPtr<GdkPixbuf> icon = getStockIconForWidgetType(GTK_TYPE_ENTRY, GTK_STOCK_CLEAR,
-                                                        gtkTextDirection(renderObject->style().direction()),
-                                                        gtkIconState(this, renderObject),
-                                                        getIconSizeForPixelSize(rect.height()));
-    paintGdkPixbuf(paintInfo.context, icon.get(), iconRect);
-    return false;
-}
-
 void RenderThemeGtk::adjustSearchFieldStyle(StyleResolver*, RenderStyle* style, Element*) const
 {
     // We cannot give a proper rendering when border radius is active, unfortunately.
@@ -373,31 +203,6 @@
     return paintTextField(o, i, rect);
 }
 
-bool RenderThemeGtk::paintCapsLockIndicator(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect)
-{
-    // The other paint methods don't need to check whether painting is disabled because RenderTheme already checks it
-    // before calling them, but paintCapsLockIndicator() is called by RenderTextControlSingleLine which doesn't check it.
-    if (paintInfo.context->paintingDisabled())
-        return true;
-
-    int iconSize = std::min(rect.width(), rect.height());
-    GRefPtr<GdkPixbuf> icon = getStockIconForWidgetType(GTK_TYPE_ENTRY, GTK_STOCK_CAPS_LOCK_WARNING,
-                                                        gtkTextDirection(renderObject->style().direction()),
-                                                        0, getIconSizeForPixelSize(iconSize));
-
-    // Only re-scale the icon when it's smaller than the minimum icon size.
-    if (iconSize >= gtkIconSizeMenu)
-        iconSize = gdk_pixbuf_get_height(icon.get());
-
-    // GTK+ locates the icon right aligned in the entry. The given rectangle is already
-    // centered vertically by RenderTextControlSingleLine.
-    IntRect iconRect(rect.x() + rect.width() - iconSize,
-                     rect.y() + (rect.height() - iconSize) / 2,
-                     iconSize, iconSize);
-    paintGdkPixbuf(paintInfo.context, icon.get(), iconRect);
-    return true;
-}
-
 void RenderThemeGtk::adjustSliderTrackStyle(StyleResolver*, RenderStyle* style, Element*) const
 {
     style->setBoxShadow(nullptr);
@@ -468,9 +273,6 @@
 
 void RenderThemeGtk::platformColorsDidChange()
 {
-#if ENABLE(VIDEO)
-    initMediaColors();
-#endif
     RenderTheme::platformColorsDidChange();
 }
 
@@ -487,17 +289,6 @@
 }
 #endif
 
-bool RenderThemeGtk::paintMediaButton(RenderObject* renderObject, GraphicsContext* context, const IntRect& rect, const char* symbolicIconName, const char* fallbackStockIconName)
-{
-    IntRect iconRect(rect.x() + (rect.width() - m_mediaIconSize) / 2,
-                     rect.y() + (rect.height() - m_mediaIconSize) / 2,
-                     m_mediaIconSize, m_mediaIconSize);
-    GRefPtr<GdkPixbuf> icon = getStockSymbolicIconForWidgetType(GTK_TYPE_CONTAINER, symbolicIconName, fallbackStockIconName,
-        gtkTextDirection(renderObject->style().direction()), gtkIconState(this, renderObject), iconRect.width());
-    paintGdkPixbuf(context, icon.get(), iconRect);
-    return false;
-}
-
 bool RenderThemeGtk::hasOwnDisabledStateHandlingFor(ControlPart part) const
 {
     return (part != MediaMuteButtonPart);
@@ -512,7 +303,7 @@
 {
     HTMLMediaElement* mediaElement = getMediaElementFromRenderObject(renderObject);
     if (!mediaElement)
-        return false;
+        return true;
 
     bool muted = mediaElement->muted();
     return paintMediaButton(renderObject, paintInfo.context, rect,
@@ -524,9 +315,9 @@
 {
     Node* node = renderObject->node();
     if (!node)
-        return false;
+        return true;
     if (!node->isMediaControlElement())
-        return false;
+        return true;
 
     bool play = mediaControlElementType(node) == MediaPlayButton;
     return paintMediaButton(renderObject, paintInfo.context, rect,
@@ -557,7 +348,7 @@
 {
     HTMLMediaElement* mediaElement = parentMediaElement(*o);
     if (!mediaElement)
-        return false;
+        return true;
 
     GraphicsContext* context = paintInfo.context;
     context->save();
@@ -593,11 +384,6 @@
     return false;
 }
 
-bool RenderThemeGtk::paintMediaVolumeSliderContainer(RenderObject*, const PaintInfo& paintInfo, const IntRect& rect)
-{
-    return true;
-}
-
 bool RenderThemeGtk::paintMediaVolumeSliderTrack(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect)
 {
     HTMLMediaElement* mediaElement = parentMediaElement(*renderObject);

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


--- releases/WebKitGTK/webkit-2.4/Source/WebCore/platform/gtk/RenderThemeGtk.h	2016-02-27 15:09:36 UTC (rev 197251)
+++ releases/WebKitGTK/webkit-2.4/Source/WebCore/platform/gtk/RenderThemeGtk.h	2016-02-27 15:09:57 UTC (rev 197252)
@@ -158,8 +158,6 @@
     virtual void adjustSliderThumbSize(RenderStyle*, Element*) const;
 
 #if ENABLE(VIDEO)
-    void initMediaColors();
-    void initMediaButtons();
     virtual bool hasOwnDisabledStateHandlingFor(ControlPart) const;
     virtual bool paintMediaFullscreenButton(RenderObject*, const PaintInfo&, const IntRect&);
     virtual bool paintMediaPlayButton(RenderObject*, const PaintInfo&, const IntRect&);
@@ -168,7 +166,6 @@
     virtual bool paintMediaSeekForwardButton(RenderObject*, const PaintInfo&, const IntRect&);
     virtual bool paintMediaSliderTrack(RenderObject*, const PaintInfo&, const IntRect&);
     virtual bool paintMediaSliderThumb(RenderObject*, const PaintInfo&, const IntRect&);
-    virtual bool paintMediaVolumeSliderContainer(RenderObject*, const PaintInfo&, const IntRect&);
     virtual bool paintMediaVolumeSliderTrack(RenderObject*, const PaintInfo&, const IntRect&);
     virtual bool paintMediaVolumeSliderThumb(RenderObject*, const PaintInfo&, const IntRect&);
     virtual bool paintMediaCurrentTime(RenderObject*, const PaintInfo&, const IntRect&);
@@ -201,12 +198,6 @@
     static IntRect calculateProgressRect(RenderObject*, const IntRect&);
 #endif
 
-    mutable Color m_panelColor;
-    mutable Color m_sliderColor;
-    mutable Color m_sliderThumbColor;
-    const int m_mediaIconSize;
-    const int m_mediaSliderHeight;
-
 #ifdef GTK_API_VERSION_2
     void setupWidgetAndAddToContainer(GtkWidget*, GtkWidget*) const;
     void refreshComboBoxChildren() const;

Modified: releases/WebKitGTK/webkit-2.4/Source/WebCore/platform/gtk/RenderThemeGtk2.cpp (197251 => 197252)


--- releases/WebKitGTK/webkit-2.4/Source/WebCore/platform/gtk/RenderThemeGtk2.cpp	2016-02-27 15:09:36 UTC (rev 197251)
+++ releases/WebKitGTK/webkit-2.4/Source/WebCore/platform/gtk/RenderThemeGtk2.cpp	2016-02-27 15:09:57 UTC (rev 197252)
@@ -38,6 +38,7 @@
 #include "HTMLNames.h"
 #include "MediaControlElements.h"
 #include "PaintInfo.h"
+#include "PlatformContextCairo.h"
 #include "RenderElement.h"
 #include "TextDirection.h"
 #include "UserAgentStyleSheets.h"
@@ -53,6 +54,34 @@
 // This is not a static method, because we want to avoid having GTK+ headers in RenderThemeGtk.h.
 extern GtkTextDirection gtkTextDirection(TextDirection);
 
+#if ENABLE(VIDEO)
+static void initMediaButtons()
+{
+    static bool iconsInitialized = false;
+
+    if (iconsInitialized)
+        return;
+
+    GRefPtr<GtkIconFactory> iconFactory = adoptGRef(gtk_icon_factory_new());
+    GtkIconSource* iconSource = gtk_icon_source_new();
+    const char* icons[] = { "audio-volume-high", "audio-volume-muted" };
+
+    gtk_icon_factory_add_default(iconFactory.get());
+
+    for (size_t i = 0; i < G_N_ELEMENTS(icons); ++i) {
+        gtk_icon_source_set_icon_name(iconSource, icons[i]);
+        GtkIconSet* iconSet = gtk_icon_set_new();
+        gtk_icon_set_add_source(iconSet, iconSource);
+        gtk_icon_factory_add(iconFactory.get(), icons[i], iconSet);
+        gtk_icon_set_unref(iconSet);
+    }
+
+    gtk_icon_source_free(iconSource);
+
+    iconsInitialized = true;
+}
+#endif
+
 void RenderThemeGtk::platformInit()
 {
     m_themePartsHaveRGBAColormap = true;
@@ -79,6 +108,9 @@
         m_themePartsHaveRGBAColormap = false;
         m_colormap = gdk_screen_get_default_colormap(gdk_screen_get_default());
     }
+#if ENABLE(VIDEO)
+    initMediaButtons();
+#endif
 }
 
 RenderThemeGtk::~RenderThemeGtk()
@@ -87,16 +119,6 @@
         gtk_widget_destroy(m_gtkWindow);
 }
 
-#if ENABLE(VIDEO)
-void RenderThemeGtk::initMediaColors()
-{
-    GtkStyle* style = gtk_widget_get_style(GTK_WIDGET(gtkContainer()));
-    m_panelColor = style->bg[GTK_STATE_NORMAL];
-    m_sliderColor = style->bg[GTK_STATE_ACTIVE];
-    m_sliderThumbColor = style->bg[GTK_STATE_SELECTED];
-}
-#endif
-
 static void adjustRectForFocus(GtkWidget* widget, IntRect& rect, bool ignoreInteriorFocusProperty = false)
 {
     gint focusWidth, focusPad;
@@ -465,6 +487,176 @@
     return false;
 }
 
+static void paintGdkPixbuf(GraphicsContext* context, const GdkPixbuf* icon, const IntRect& iconRect)
+{
+    IntSize iconSize(gdk_pixbuf_get_width(icon), gdk_pixbuf_get_height(icon));
+    GRefPtr<GdkPixbuf> scaledIcon;
+    if (iconRect.size() != iconSize) {
+        // We could use cairo_scale() here but cairo/pixman downscale quality is quite bad.
+        scaledIcon = adoptGRef(gdk_pixbuf_scale_simple(icon, iconRect.width(), iconRect.height(),
+                                                       GDK_INTERP_BILINEAR));
+        icon = scaledIcon.get();
+    }
+
+    cairo_t* cr = context->platformContext()->cr();
+    cairo_save(cr);
+    gdk_cairo_set_source_pixbuf(cr, icon, iconRect.x(), iconRect.y());
+    cairo_paint(cr);
+    cairo_restore(cr);
+}
+
+// Defined in GTK+ (gtk/gtkiconfactory.c)
+static const gint gtkIconSizeMenu = 16;
+static const gint gtkIconSizeSmallToolbar = 18;
+static const gint gtkIconSizeButton = 20;
+static const gint gtkIconSizeLargeToolbar = 24;
+static const gint gtkIconSizeDnd = 32;
+static const gint gtkIconSizeDialog = 48;
+
+static GtkIconSize getIconSizeForPixelSize(gint pixelSize)
+{
+    if (pixelSize < gtkIconSizeSmallToolbar)
+        return GTK_ICON_SIZE_MENU;
+    if (pixelSize >= gtkIconSizeSmallToolbar && pixelSize < gtkIconSizeButton)
+        return GTK_ICON_SIZE_SMALL_TOOLBAR;
+    if (pixelSize >= gtkIconSizeButton && pixelSize < gtkIconSizeLargeToolbar)
+        return GTK_ICON_SIZE_BUTTON;
+    if (pixelSize >= gtkIconSizeLargeToolbar && pixelSize < gtkIconSizeDnd)
+        return GTK_ICON_SIZE_LARGE_TOOLBAR;
+    if (pixelSize >= gtkIconSizeDnd && pixelSize < gtkIconSizeDialog)
+        return GTK_ICON_SIZE_DND;
+
+    return GTK_ICON_SIZE_DIALOG;
+}
+
+static void adjustSearchFieldIconStyle(RenderStyle* style)
+{
+    style->resetBorder();
+    style->resetPadding();
+
+    // Get the icon size based on the font size.
+    int fontSize = style->fontSize();
+    if (fontSize < gtkIconSizeMenu) {
+        style->setWidth(Length(fontSize, Fixed));
+        style->setHeight(Length(fontSize, Fixed));
+        return;
+    }
+    gint width = 0, height = 0;
+    gtk_icon_size_lookup(getIconSizeForPixelSize(fontSize), &width, &height);
+    style->setWidth(Length(width, Fixed));
+    style->setHeight(Length(height, Fixed));
+}
+
+void RenderThemeGtk::adjustSearchFieldResultsDecorationPartStyle(StyleResolver*, RenderStyle* style, Element*) const
+{
+    adjustSearchFieldIconStyle(style);
+}
+
+static IntRect centerRectVerticallyInParentInputElement(RenderObject* renderObject, const IntRect& rect)
+{
+    // Get the renderer of <input> element.
+    Node* input = renderObject->node()->shadowHost();
+    if (!input)
+        input = renderObject->node();
+    if (!input->renderer()->isBox())
+        return IntRect();
+
+    // If possible center the y-coordinate of the rect vertically in the parent input element.
+    // We also add one pixel here to ensure that the y coordinate is rounded up for box heights
+    // that are even, which looks in relation to the box text.
+    IntRect inputContentBox = toRenderBox(input->renderer())->absoluteContentBox();
+
+    // Make sure the scaled decoration stays square and will fit in its parent's box.
+    int iconSize = std::min(inputContentBox.width(), std::min(inputContentBox.height(), rect.height()));
+    IntRect scaledRect(rect.x(), inputContentBox.y() + (inputContentBox.height() - iconSize + 1) / 2, iconSize, iconSize);
+    return scaledRect;
+}
+
+GRefPtr<GdkPixbuf> getStockIconForWidgetType(GType widgetType, const char* iconName, gint direction, gint state, gint iconSize)
+{
+    ASSERT(widgetType == GTK_TYPE_CONTAINER || widgetType == GTK_TYPE_ENTRY);
+
+    RenderThemeGtk* theme = static_cast<RenderThemeGtk*>(RenderTheme::defaultTheme().get());
+    GtkWidget* widget = widgetType == GTK_TYPE_CONTAINER ? GTK_WIDGET(theme->gtkContainer()) : theme->gtkEntry();
+
+    GtkStyle* style = gtk_widget_get_style(widget);
+    GtkIconSet* iconSet = gtk_style_lookup_icon_set(style, iconName);
+    return adoptGRef(gtk_icon_set_render_icon(iconSet, style,
+                                              static_cast<GtkTextDirection>(direction),
+                                              static_cast<GtkStateType>(state),
+                                              static_cast<GtkIconSize>(iconSize), 0, 0));
+}
+
+static GtkStateType gtkIconState(RenderTheme* theme, RenderObject* renderObject)
+{
+    if (!theme->isEnabled(renderObject))
+        return GTK_STATE_INSENSITIVE;
+    if (theme->isPressed(renderObject))
+        return GTK_STATE_ACTIVE;
+    if (theme->isHovered(renderObject))
+        return GTK_STATE_PRELIGHT;
+
+    return GTK_STATE_NORMAL;
+}
+
+bool RenderThemeGtk::paintSearchFieldResultsDecorationPart(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect)
+{
+    IntRect iconRect = centerRectVerticallyInParentInputElement(renderObject, rect);
+    if (iconRect.isEmpty())
+        return false;
+
+    GRefPtr<GdkPixbuf> icon = getStockIconForWidgetType(GTK_TYPE_ENTRY, GTK_STOCK_FIND,
+                                                        gtkTextDirection(renderObject->style().direction()),
+                                                        gtkIconState(this, renderObject),
+                                                        getIconSizeForPixelSize(rect.height()));
+    paintGdkPixbuf(paintInfo.context, icon.get(), iconRect);
+    return false;
+}
+
+void RenderThemeGtk::adjustSearchFieldCancelButtonStyle(StyleResolver*, RenderStyle* style, Element*) const
+{
+    adjustSearchFieldIconStyle(style);
+}
+
+bool RenderThemeGtk::paintSearchFieldCancelButton(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect)
+{
+    IntRect iconRect = centerRectVerticallyInParentInputElement(renderObject, rect);
+    if (iconRect.isEmpty())
+        return false;
+
+    GRefPtr<GdkPixbuf> icon = getStockIconForWidgetType(GTK_TYPE_ENTRY, GTK_STOCK_CLEAR,
+                                                        gtkTextDirection(renderObject->style().direction()),
+                                                        gtkIconState(this, renderObject),
+                                                        getIconSizeForPixelSize(rect.height()));
+    paintGdkPixbuf(paintInfo.context, icon.get(), iconRect);
+    return false;
+}
+
+bool RenderThemeGtk::paintCapsLockIndicator(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect)
+{
+    // The other paint methods don't need to check whether painting is disabled because RenderTheme already checks it
+    // before calling them, but paintCapsLockIndicator() is called by RenderTextControlSingleLine which doesn't check it.
+    if (paintInfo.context->paintingDisabled())
+        return true;
+
+    int iconSize = std::min(rect.width(), rect.height());
+    GRefPtr<GdkPixbuf> icon = getStockIconForWidgetType(GTK_TYPE_ENTRY, GTK_STOCK_CAPS_LOCK_WARNING,
+                                                        gtkTextDirection(renderObject->style().direction()),
+                                                        0, getIconSizeForPixelSize(iconSize));
+
+    // Only re-scale the icon when it's smaller than the minimum icon size.
+    if (iconSize >= gtkIconSizeMenu)
+        iconSize = gdk_pixbuf_get_height(icon.get());
+
+    // GTK+ locates the icon right aligned in the entry. The given rectangle is already
+    // centered vertically by RenderTextControlSingleLine.
+    IntRect iconRect(rect.x() + rect.width() - iconSize,
+                     rect.y() + (rect.height() - iconSize) / 2,
+                     iconSize, iconSize);
+    paintGdkPixbuf(paintInfo.context, icon.get(), iconRect);
+    return true;
+}
+
 bool RenderThemeGtk::paintSliderTrack(RenderObject* object, const PaintInfo& info, const IntRect& rect)
 {
     if (info.context->paintingDisabled())
@@ -651,23 +843,8 @@
     return false;
 }
 
-GRefPtr<GdkPixbuf> getStockIconForWidgetType(GType widgetType, const char* iconName, gint direction, gint state, gint iconSize)
+static GRefPtr<GdkPixbuf> getStockSymbolicIconForWidgetType(GType widgetType, const char* symbolicIconName, const char *fallbackStockIconName, gint direction, gint state, gint iconSize)
 {
-    ASSERT(widgetType == GTK_TYPE_CONTAINER || widgetType == GTK_TYPE_ENTRY);
-
-    RenderThemeGtk* theme = static_cast<RenderThemeGtk*>(RenderTheme::defaultTheme().get());
-    GtkWidget* widget = widgetType == GTK_TYPE_CONTAINER ? GTK_WIDGET(theme->gtkContainer()) : theme->gtkEntry();
-
-    GtkStyle* style = gtk_widget_get_style(widget);
-    GtkIconSet* iconSet = gtk_style_lookup_icon_set(style, iconName);
-    return adoptGRef(gtk_icon_set_render_icon(iconSet, style,
-                                              static_cast<GtkTextDirection>(direction),
-                                              static_cast<GtkStateType>(state),
-                                              static_cast<GtkIconSize>(iconSize), 0, 0));
-}
-
-GRefPtr<GdkPixbuf> getStockSymbolicIconForWidgetType(GType widgetType, const char* symbolicIconName, const char *fallbackStockIconName, gint direction, gint state, gint iconSize)
-{
     return getStockIconForWidgetType(widgetType, fallbackStockIconName, direction, state, iconSize);
 }
 
@@ -731,6 +908,18 @@
     }
 }
 
+bool RenderThemeGtk::paintMediaButton(RenderObject* renderObject, GraphicsContext* context, const IntRect& rect, const char* symbolicIconName, const char* fallbackStockIconName)
+{
+    static const unsigned mediaIconSize = 16;
+    IntRect iconRect(rect.x() + (rect.width() - mediaIconSize) / 2,
+                     rect.y() + (rect.height() - mediaIconSize) / 2,
+                     mediaIconSize, mediaIconSize);
+    GRefPtr<GdkPixbuf> icon = getStockSymbolicIconForWidgetType(GTK_TYPE_CONTAINER, symbolicIconName, fallbackStockIconName,
+        gtkTextDirection(renderObject->style().direction()), gtkIconState(this, renderObject), iconRect.width());
+    paintGdkPixbuf(context, icon.get(), iconRect);
+    return false;
+}
+
 static void gtkStyleSetCallback(GtkWidget* widget, GtkStyle* previous, RenderTheme* renderTheme)
 {
     // FIXME: Make sure this function doesn't get called many times for a single GTK+ style change signal.

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


--- releases/WebKitGTK/webkit-2.4/Source/WebCore/platform/gtk/RenderThemeGtk3.cpp	2016-02-27 15:09:36 UTC (rev 197251)
+++ releases/WebKitGTK/webkit-2.4/Source/WebCore/platform/gtk/RenderThemeGtk3.cpp	2016-02-27 15:09:57 UTC (rev 197252)
@@ -31,6 +31,7 @@
 #include "GraphicsContext.h"
 #include "GtkVersioning.h"
 #include "GRefPtrGtk.h"
+#include "HTMLInputElement.h"
 #include "HTMLNames.h"
 #include "MediaControlElements.h"
 #include "Page.h"
@@ -51,13 +52,41 @@
 // This is the default value defined by GTK+, where it was defined as MIN_ARROW_WIDTH in gtkspinbutton.c.
 static const int minSpinButtonArrowSize = 6;
 
+enum RenderThemePart {
+    Entry,
+    EntrySelection,
+    EntryIconLeft,
+    EntryIconRight,
+    Button,
+    CheckButton,
+    CheckButtonCheck,
+    RadioButton,
+    RadioButtonRadio,
+    ComboBox,
+    ComboBoxButton,
+    ComboBoxArrow,
+    Scale,
+    ScaleTrough,
+    ScaleSlider,
+    ProgressBar,
+    ProgressBarTrough,
+    ProgressBarProgress,
+    ListBox,
+    SpinButton,
+    SpinButtonUpButton,
+    SpinButtonDownButton,
+#if ENABLE(VIDEO)
+    MediaButton,
+#endif
+};
+
 static void gtkStyleChangedCallback(GObject*, GParamSpec*)
 {
     static_cast<ScrollbarThemeGtk*>(ScrollbarTheme::theme())->themeChanged();
     Page::updateStyleForAllPagesAfterGlobalChangeInEnvironment();
 }
 
-static GRefPtr<GtkStyleContext> createStyleContext(GType widgetType)
+static GRefPtr<GtkStyleContext> createStyleContext(RenderThemePart themePart, GtkStyleContext* parent = nullptr)
 {
     static bool initialized = false;
     if (!initialized) {
@@ -67,65 +96,192 @@
         initialized = true;
     }
 
-    GRefPtr<GtkWidgetPath> path = adoptGRef(gtk_widget_path_new());
-    gtk_widget_path_append_type(path.get(), widgetType);
+    GRefPtr<GtkWidgetPath> path = adoptGRef(parent ? gtk_widget_path_copy(gtk_style_context_get_path(parent)) : gtk_widget_path_new());
 
+    switch (themePart) {
+    case Entry:
+        gtk_widget_path_append_type(path.get(), GTK_TYPE_ENTRY);
 #if GTK_CHECK_VERSION(3, 19, 2)
-    // Pick a good default object path for the style context based on the widget type. This will
-    // usually need to be overridden manually, but it doesn't hurt to have a good default.
-    if (widgetType == GTK_TYPE_ENTRY)
-        gtk_widget_path_iter_set_object_name(path.get(), 0, "entry");
-    else if (widgetType == GTK_TYPE_ARROW)
-        gtk_widget_path_iter_set_object_name(path.get(), 0, "button"); // Note: not a typo.
-    else if (widgetType == GTK_TYPE_BUTTON) {
-        gtk_widget_path_iter_set_object_name(path.get(), 0, "button");
-        gtk_widget_path_iter_add_class(path.get(), 0, "text-button");
-    }
-    else if (widgetType == GTK_TYPE_SCALE)
-        gtk_widget_path_iter_set_object_name(path.get(), 0, "scale");
-    else if (widgetType == GTK_TYPE_SEPARATOR)
-        gtk_widget_path_iter_set_object_name(path.get(), 0, "separator");
-    else if (widgetType == GTK_TYPE_PROGRESS_BAR)
-        gtk_widget_path_iter_set_object_name(path.get(), 0, "progressbar");
-    else if (widgetType == GTK_TYPE_SPIN_BUTTON)
-        gtk_widget_path_iter_set_object_name(path.get(), 0, "spinbutton");
-    else if (widgetType == GTK_TYPE_TREE_VIEW) {
-        gtk_widget_path_iter_set_object_name(path.get(), 0, "treeview");
-        gtk_widget_path_iter_add_class(path.get(), 0, "view");
-    } else if (widgetType == GTK_TYPE_CHECK_BUTTON)
-        gtk_widget_path_iter_set_object_name(path.get(), 0, "checkbutton");
-    else if (widgetType == GTK_TYPE_RADIO_BUTTON)
-        gtk_widget_path_iter_set_object_name(path.get(), 0, "radiobutton");
-    else if (widgetType == GTK_TYPE_COMBO_BOX)
-        gtk_widget_path_iter_set_object_name(path.get(), 0, "combobox");
+        gtk_widget_path_iter_set_object_name(path.get(), -1, "entry");
 #else
-    if (widgetType == GTK_TYPE_ENTRY)
-        gtk_widget_path_iter_add_class(path.get(), 0, GTK_STYLE_CLASS_ENTRY);
-    else if (widgetType == GTK_TYPE_ARROW)
-        gtk_widget_path_iter_add_class(path.get(), 0, "arrow");
-    else if (widgetType == GTK_TYPE_BUTTON) {
-        gtk_widget_path_iter_add_class(path.get(), 0, GTK_STYLE_CLASS_BUTTON);
-        gtk_widget_path_iter_add_class(path.get(), 0, "text-button");
+        gtk_widget_path_iter_add_class(path.get(), -1, GTK_STYLE_CLASS_ENTRY);
+#endif
+        break;
+    case EntrySelection:
+        gtk_widget_path_append_type(path.get(), GTK_TYPE_ENTRY);
+#if GTK_CHECK_VERSION(3, 19, 2)
+        gtk_widget_path_iter_set_object_name(path.get(), -1, "selection");
+#else
+        gtk_widget_path_iter_add_class(path.get(), -1, GTK_STYLE_CLASS_ENTRY);
+#endif
+        break;
+    case EntryIconLeft:
+    case EntryIconRight:
+        gtk_widget_path_append_type(path.get(), GTK_TYPE_ENTRY);
+#if GTK_CHECK_VERSION(3, 19, 2)
+        gtk_widget_path_iter_set_object_name(path.get(), -1, "image");
+        gtk_widget_path_iter_add_class(path.get(), -1, themePart == EntryIconLeft ? "left" : "right");
+#endif
+        break;
+    case Button:
+        gtk_widget_path_append_type(path.get(), GTK_TYPE_BUTTON);
+#if GTK_CHECK_VERSION(3, 19, 2)
+        gtk_widget_path_iter_set_object_name(path.get(), -1, "button");
+#else
+        gtk_widget_path_iter_add_class(path.get(), -1, GTK_STYLE_CLASS_BUTTON);
+#endif
+        gtk_widget_path_iter_add_class(path.get(), -1, "text-button");
+        break;
+    case CheckButton:
+        gtk_widget_path_append_type(path.get(), GTK_TYPE_CHECK_BUTTON);
+#if GTK_CHECK_VERSION(3, 19, 2)
+        gtk_widget_path_iter_set_object_name(path.get(), -1, "checkbutton");
+#else
+        gtk_widget_path_iter_add_class(path.get(), -1, GTK_STYLE_CLASS_CHECK);
+#endif
+        break;
+    case CheckButtonCheck:
+        gtk_widget_path_append_type(path.get(), GTK_TYPE_CHECK_BUTTON);
+#if GTK_CHECK_VERSION(3, 19, 2)
+        gtk_widget_path_iter_set_object_name(path.get(), -1, "check");
+#else
+        gtk_widget_path_iter_add_class(path.get(), -1, GTK_STYLE_CLASS_CHECK);
+#endif
+        break;
+    case RadioButton:
+        gtk_widget_path_append_type(path.get(), GTK_TYPE_RADIO_BUTTON);
+#if GTK_CHECK_VERSION(3, 19, 2)
+        gtk_widget_path_iter_set_object_name(path.get(), -1, "radiobutton");
+#else
+        gtk_widget_path_iter_add_class(path.get(), -1, GTK_STYLE_CLASS_RADIO);
+#endif
+        break;
+    case RadioButtonRadio:
+        gtk_widget_path_append_type(path.get(), GTK_TYPE_RADIO_BUTTON);
+#if GTK_CHECK_VERSION(3, 19, 2)
+        gtk_widget_path_iter_set_object_name(path.get(), -1, "radio");
+#else
+        gtk_widget_path_iter_add_class(path.get(), -1, GTK_STYLE_CLASS_RADIO);
+#endif
+        break;
+    case ComboBox:
+        gtk_widget_path_append_type(path.get(), GTK_TYPE_COMBO_BOX);
+#if GTK_CHECK_VERSION(3, 19, 2)
+        gtk_widget_path_iter_set_object_name(path.get(), -1, "combobox");
+#endif
+        break;
+    case ComboBoxButton:
+        gtk_widget_path_append_type(path.get(), GTK_TYPE_BUTTON);
+#if GTK_CHECK_VERSION(3, 19, 2)
+        gtk_widget_path_iter_set_object_name(path.get(), -1, "button");
+#else
+        gtk_widget_path_iter_add_class(path.get(), -1, GTK_STYLE_CLASS_BUTTON);
+#endif
+        gtk_widget_path_iter_add_class(path.get(), -1, "text-button");
+        gtk_widget_path_iter_add_class(path.get(), -1, "combo");
+        break;
+    case ComboBoxArrow:
+        gtk_widget_path_append_type(path.get(), GTK_TYPE_ARROW);
+#if GTK_CHECK_VERSION(3, 19, 2)
+        gtk_widget_path_iter_set_object_name(path.get(), -1, "arrow");
+#else
+        gtk_widget_path_iter_add_class(path.get(), -1, "arrow");
+#endif
+        break;
+    case Scale:
+        gtk_widget_path_append_type(path.get(), GTK_TYPE_SCALE);
+#if GTK_CHECK_VERSION(3, 19, 2)
+        gtk_widget_path_iter_set_object_name(path.get(), -1, "scale");
+#else
+        gtk_widget_path_iter_add_class(path.get(), -1, GTK_STYLE_CLASS_SCALE);
+#endif
+        break;
+    case ScaleTrough:
+        gtk_widget_path_append_type(path.get(), GTK_TYPE_SCALE);
+#if GTK_CHECK_VERSION(3, 19, 2)
+        gtk_widget_path_iter_set_object_name(path.get(), -1, "trough");
+#else
+        gtk_widget_path_iter_add_class(path.get(), -1, GTK_STYLE_CLASS_SCALE);
+        gtk_widget_path_iter_add_class(path.get(), -1, GTK_STYLE_CLASS_TROUGH);
+#endif
+        break;
+    case ScaleSlider:
+        gtk_widget_path_append_type(path.get(), GTK_TYPE_SCALE);
+#if GTK_CHECK_VERSION(3, 19, 2)
+        gtk_widget_path_iter_set_object_name(path.get(), -1, "slider");
+#else
+        gtk_widget_path_iter_add_class(path.get(), -1, GTK_STYLE_CLASS_SCALE);
+        gtk_widget_path_iter_add_class(path.get(), -1, GTK_STYLE_CLASS_SLIDER);
+#endif
+        break;
+    case ProgressBar:
+        gtk_widget_path_append_type(path.get(), GTK_TYPE_PROGRESS_BAR);
+#if GTK_CHECK_VERSION(3, 19, 2)
+        gtk_widget_path_iter_set_object_name(path.get(), -1, "progressbar");
+#else
+        gtk_widget_path_iter_add_class(path.get(), -1, GTK_STYLE_CLASS_PROGRESSBAR);
+#endif
+        gtk_widget_path_iter_add_class(path.get(), -1, GTK_STYLE_CLASS_HORIZONTAL);
+        break;
+    case ProgressBarTrough:
+        gtk_widget_path_append_type(path.get(), GTK_TYPE_PROGRESS_BAR);
+#if GTK_CHECK_VERSION(3, 19, 2)
+        gtk_widget_path_iter_set_object_name(path.get(), -1, "trough");
+#else
+        gtk_widget_path_iter_add_class(path.get(), -1, GTK_STYLE_CLASS_PROGRESSBAR);
+        gtk_widget_path_iter_add_class(path.get(), -1, GTK_STYLE_CLASS_TROUGH);
+#endif
+        break;
+    case ProgressBarProgress:
+        gtk_widget_path_append_type(path.get(), GTK_TYPE_PROGRESS_BAR);
+#if GTK_CHECK_VERSION(3, 19, 2)
+        gtk_widget_path_iter_set_object_name(path.get(), -1, "progress");
+#else
+        gtk_widget_path_iter_add_class(path.get(), -1, GTK_STYLE_CLASS_PROGRESSBAR);
+#endif
+        break;
+    case ListBox:
+        gtk_widget_path_append_type(path.get(), GTK_TYPE_TREE_VIEW);
+#if GTK_CHECK_VERSION(3, 19, 2)
+        gtk_widget_path_iter_set_object_name(path.get(), -1, "treeview");
+#endif
+        gtk_widget_path_iter_add_class(path.get(), -1, GTK_STYLE_CLASS_VIEW);
+        break;
+    case SpinButton:
+        gtk_widget_path_append_type(path.get(), GTK_TYPE_SPIN_BUTTON);
+#if GTK_CHECK_VERSION(3, 19, 2)
+        gtk_widget_path_iter_set_object_name(path.get(), -1, "spinbutton");
+#else
+        gtk_widget_path_iter_add_class(path.get(), -1, GTK_STYLE_CLASS_SPINBUTTON);
+#endif
+        gtk_widget_path_iter_add_class(path.get(), -1, GTK_STYLE_CLASS_HORIZONTAL);
+        break;
+    case SpinButtonUpButton:
+    case SpinButtonDownButton:
+        gtk_widget_path_append_type(path.get(), GTK_TYPE_SPIN_BUTTON);
+#if GTK_CHECK_VERSION(3, 19, 2)
+        gtk_widget_path_iter_set_object_name(path.get(), -1, "button");
+        gtk_widget_path_iter_add_class(path.get(), -1, themePart == SpinButtonUpButton ? "up" : "down");
+#else
+        gtk_widget_path_iter_add_class(path.get(), -1, GTK_STYLE_CLASS_SPINBUTTON);
+        gtk_widget_path_iter_add_class(path.get(), -1, GTK_STYLE_CLASS_BUTTON);
+#endif
+        break;
+#if ENABLE(VIDEO)
+    case MediaButton:
+        gtk_widget_path_append_type(path.get(), GTK_TYPE_IMAGE);
+#if GTK_CHECK_VERSION(3, 19, 2)
+        gtk_widget_path_iter_set_object_name(path.get(), -1, "image");
+#else
+        gtk_widget_path_iter_add_class(path.get(), -1, GTK_STYLE_CLASS_IMAGE);
+#endif
+        break;
+#endif // ENABLE(VIDEO)
     }
-    else if (widgetType == GTK_TYPE_SCALE)
-        gtk_widget_path_iter_add_class(path.get(), 0, GTK_STYLE_CLASS_SCALE);
-    else if (widgetType == GTK_TYPE_SEPARATOR)
-        gtk_widget_path_iter_add_class(path.get(), 0, GTK_STYLE_CLASS_SEPARATOR);
-    else if (widgetType == GTK_TYPE_PROGRESS_BAR)
-        gtk_widget_path_iter_add_class(path.get(), 0, GTK_STYLE_CLASS_PROGRESSBAR);
-    else if (widgetType == GTK_TYPE_SPIN_BUTTON)
-        gtk_widget_path_iter_add_class(path.get(), 0, GTK_STYLE_CLASS_SPINBUTTON);
-    else if (widgetType == GTK_TYPE_TREE_VIEW)
-        gtk_widget_path_iter_add_class(path.get(), 0, GTK_STYLE_CLASS_VIEW);
-    else if (widgetType == GTK_TYPE_CHECK_BUTTON)
-        gtk_widget_path_iter_add_class(path.get(), 0, GTK_STYLE_CLASS_CHECK);
-    else if (widgetType == GTK_TYPE_RADIO_BUTTON)
-        gtk_widget_path_iter_add_class(path.get(), 0, GTK_STYLE_CLASS_RADIO);
-#endif
 
     GRefPtr<GtkStyleContext> context = adoptGRef(gtk_style_context_new());
     gtk_style_context_set_path(context.get(), path.get());
-
+    gtk_style_context_set_parent(context.get(), parent);
     return context;
 }
 
@@ -140,23 +296,17 @@
 {
 }
 
-#if ENABLE(VIDEO)
-void RenderThemeGtk::initMediaColors()
+static GtkStateFlags gtkIconStateFlags(RenderTheme* theme, RenderObject* renderObject)
 {
-    GdkRGBA color;
-    GRefPtr<GtkStyleContext> containerContext = createStyleContext(GTK_TYPE_CONTAINER);
+    if (!theme->isEnabled(renderObject))
+        return GTK_STATE_FLAG_INSENSITIVE;
+    if (theme->isPressed(renderObject))
+        return GTK_STATE_FLAG_ACTIVE;
+    if (theme->isHovered(renderObject))
+        return GTK_STATE_FLAG_PRELIGHT;
 
-    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.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.get(), GTK_STATE_FLAG_SELECTED);
-    gtk_style_context_get_background_color(containerContext.get(), gtk_style_context_get_state(containerContext.get()), &color);
-    m_sliderThumbColor = color;
+    return GTK_STATE_FLAG_NORMAL;
 }
-#endif
 
 static void adjustRectForFocus(GtkStyleContext* context, IntRect& rect)
 {
@@ -175,7 +325,7 @@
     switch (part) {
     case CheckboxPart:
     case RadioPart:
-        context = createStyleContext(part == CheckboxPart ? GTK_TYPE_CHECK_BUTTON : GTK_TYPE_RADIO_BUTTON);
+        context = createStyleContext(part == CheckboxPart ? CheckButton : RadioButton);
 
         gint indicatorSpacing;
         gtk_style_context_get_style(context.get(), "indicator-spacing", &indicatorSpacing, nullptr);
@@ -184,17 +334,17 @@
         return;
     case SliderVerticalPart:
     case SliderHorizontalPart:
-        context = createStyleContext(GTK_TYPE_SCALE);
+        context = createStyleContext(ScaleSlider);
         break;
     case ButtonPart:
     case MenulistButtonPart:
     case MenulistPart:
-        context = createStyleContext(GTK_TYPE_BUTTON);
+        context = createStyleContext(Button);
         checkInteriorFocus = true;
         break;
     case TextFieldPart:
     case TextAreaPart:
-        context = createStyleContext(GTK_TYPE_ENTRY);
+        context = createStyleContext(Entry);
         checkInteriorFocus = true;
         break;
     default:
@@ -211,14 +361,13 @@
     adjustRectForFocus(context.get(), rect);
 }
 
-static void setToggleSize(GType widgetType, RenderStyle* style)
+static void setToggleSize(RenderThemePart themePart, 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;
 
+    GRefPtr<GtkStyleContext> context = createStyleContext(themePart);
     // Other ports hard-code this to 13. GTK+ users tend to demand the native look.
     gint indicatorSize;
     gtk_style_context_get_style(context.get(), "indicator-size", &indicatorSize, nullptr);
@@ -230,40 +379,28 @@
         style->setHeight(Length(indicatorSize, Fixed));
 }
 
-static void paintToggle(const RenderThemeGtk* theme, GType widgetType, RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& fullRect)
+static void paintToggle(const RenderThemeGtk* theme, RenderThemePart themePart, RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& fullRect)
 {
-    GRefPtr<GtkStyleContext> context = createStyleContext(widgetType);
-#if GTK_CHECK_VERSION(3, 19, 2)
-    GRefPtr<GtkWidgetPath> path = adoptGRef(gtk_widget_path_new());
+    GRefPtr<GtkStyleContext> parentContext = createStyleContext(themePart);
+    GRefPtr<GtkStyleContext> context = createStyleContext(themePart == CheckButton ? CheckButtonCheck : RadioButtonRadio, parentContext.get());
+    gtk_style_context_set_direction(context.get(), static_cast<GtkTextDirection>(gtkTextDirection(renderObject->style().direction())));
 
-    if (widgetType == GTK_TYPE_CHECK_BUTTON) {
-        if (theme->isChecked(renderObject) || theme->isIndeterminate(renderObject)) {
-            gtk_widget_path_append_type(path.get(), GTK_TYPE_CHECK_BUTTON);
-            gtk_widget_path_iter_set_object_name(path.get(), 0, "checkbutton");
-        } else {
-            gtk_widget_path_append_type(path.get(), GTK_TYPE_CHECK_BUTTON);
-            gtk_widget_path_iter_set_object_name(path.get(), 0, "button");
-            gtk_widget_path_iter_add_class(path.get(), 0, "check");
-        }
-
-        gtk_widget_path_append_type(path.get(), GTK_TYPE_CHECK_BUTTON);
-        gtk_widget_path_iter_set_object_name(path.get(), 1, "check");
-    } else if (widgetType == GTK_TYPE_RADIO_BUTTON) {
-        if (theme->isChecked(renderObject) || theme->isIndeterminate(renderObject)) {
-            gtk_widget_path_append_type(path.get(), GTK_TYPE_RADIO_BUTTON);
-            gtk_widget_path_iter_set_object_name(path.get(), 0, "radiobutton");
-        } else {
-            gtk_widget_path_append_type(path.get(), GTK_TYPE_RADIO_BUTTON);
-            gtk_widget_path_iter_set_object_name(path.get(), 0, "button");
-            gtk_widget_path_iter_add_class(path.get(), 0, "radio");
-        }
-
-        gtk_widget_path_append_type(path.get(), GTK_TYPE_RADIO_BUTTON);
-        gtk_widget_path_iter_set_object_name(path.get(), 1, "radio");
-    }
-
-    gtk_style_context_set_path(context.get(), path.get());
+    unsigned flags = 0;
+    if (!theme->isEnabled(renderObject))
+        flags |= GTK_STATE_FLAG_INSENSITIVE;
+    else if (theme->isHovered(renderObject))
+        flags |= GTK_STATE_FLAG_PRELIGHT;
+    if (theme->isIndeterminate(renderObject))
+        flags |= GTK_STATE_FLAG_INCONSISTENT;
+    else if (theme->isChecked(renderObject))
+#if GTK_CHECK_VERSION(3, 13, 7)
+        flags |= GTK_STATE_FLAG_CHECKED;
+#else
+    flags |= GTK_STATE_FLAG_ACTIVE;
 #endif
+    if (theme->isPressed(renderObject))
+        flags |= GTK_STATE_FLAG_SELECTED;
+    gtk_style_context_set_state(context.get(), static_cast<GtkStateFlags>(flags));
 
     // 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
@@ -282,32 +419,10 @@
         rect.setHeight(indicatorSize); // In case rect.height() was equal to indicatorSize + 1.
     }
 
-    gtk_style_context_set_direction(context.get(), static_cast<GtkTextDirection>(gtkTextDirection(renderObject->style().direction())));
+    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 GTK_CHECK_VERSION(3, 19, 2)
-    gtk_style_context_add_class(context.get(), "toggle");
-#else
-    gtk_style_context_add_class(context.get(), widgetType == GTK_TYPE_CHECK_BUTTON ? GTK_STYLE_CLASS_CHECK : GTK_STYLE_CLASS_RADIO);
-#endif
-
-    guint flags = 0;
-    if (!theme->isEnabled(renderObject) || theme->isReadOnlyControl(renderObject))
-        flags |= GTK_STATE_FLAG_INSENSITIVE;
-    else if (theme->isHovered(renderObject))
-        flags |= GTK_STATE_FLAG_PRELIGHT;
-    if (theme->isIndeterminate(renderObject))
-        flags |= GTK_STATE_FLAG_INCONSISTENT;
-    else if (theme->isChecked(renderObject))
-#if GTK_CHECK_VERSION(3, 13, 7)
-        flags |= GTK_STATE_FLAG_CHECKED;
-#else
-        flags |= GTK_STATE_FLAG_ACTIVE;
-#endif
-    if (theme->isPressed(renderObject))
-        flags |= GTK_STATE_FLAG_SELECTED;
-    gtk_style_context_set_state(context.get(), static_cast<GtkStateFlags>(flags));
-
-    if (widgetType == GTK_TYPE_CHECK_BUTTON)
+    if (themePart == CheckButton)
         gtk_render_check(context.get(), paintInfo.context->platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height());
     else
         gtk_render_option(context.get(), paintInfo.context->platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height());
@@ -324,23 +439,23 @@
 
 void RenderThemeGtk::setCheckboxSize(RenderStyle* style) const
 {
-    setToggleSize(GTK_TYPE_CHECK_BUTTON, style);
+    setToggleSize(CheckButton, style);
 }
 
 bool RenderThemeGtk::paintCheckbox(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect)
 {
-    paintToggle(this, GTK_TYPE_CHECK_BUTTON, renderObject, paintInfo, rect);
+    paintToggle(this, CheckButton, renderObject, paintInfo, rect);
     return false;
 }
 
 void RenderThemeGtk::setRadioSize(RenderStyle* style) const
 {
-    setToggleSize(GTK_TYPE_RADIO_BUTTON, style);
+    setToggleSize(RadioButton, style);
 }
 
 bool RenderThemeGtk::paintRadio(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect)
 {
-    paintToggle(this, GTK_TYPE_RADIO_BUTTON, renderObject, paintInfo, rect);
+    paintToggle(this, RadioButton, renderObject, paintInfo, rect);
     return false;
 }
 
@@ -412,42 +527,24 @@
 }
 bool RenderThemeGtk::paintButton(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect)
 {
-    GRefPtr<GtkStyleContext> context = createStyleContext(GTK_TYPE_BUTTON);
-
+    GRefPtr<GtkStyleContext> context = createStyleContext(Button);
     gtk_style_context_set_direction(context.get(), static_cast<GtkTextDirection>(gtkTextDirection(renderObject->style().direction())));
-#if !GTK_CHECK_VERSION(3, 19, 2)
-    gtk_style_context_add_class(context.get(), GTK_STYLE_CLASS_BUTTON);
-#endif
 
     renderButton(this, context.get(), renderObject, paintInfo, rect);
 
     return false;
 }
 
-static void getComboBoxMetrics(RenderStyle* style, GtkBorder& border, int& focus, int& separator)
+static void getComboBoxMetrics(RenderStyle* style, GtkBorder& border, int& focus)
 {
     // If this menu list button isn't drawn using the native theme, we
     // don't add any extra padding beyond what WebCore already uses.
     if (style->appearance() == NoControlPart)
         return;
 
-    GRefPtr<GtkStyleContext> context = createStyleContext(GTK_TYPE_COMBO_BOX);
-#if GTK_CHECK_VERSION(3, 19, 2)
-    GRefPtr<GtkWidgetPath> path = adoptGRef(gtk_widget_path_new());
-
-    gtk_widget_path_append_type(path.get(), GTK_TYPE_COMBO_BOX);
-    gtk_widget_path_iter_set_object_name(path.get(), 0, "combobox");
-
-    gtk_widget_path_append_type(path.get(), GTK_TYPE_COMBO_BOX);
-    gtk_widget_path_iter_set_object_name(path.get(), 1, "button");
-    gtk_widget_path_iter_add_class(path.get(), 1, "combo");
-
-    gtk_style_context_set_path(context.get(), path.get());
-#else
-    gtk_style_context_add_class(context.get(), GTK_STYLE_CLASS_BUTTON);
-#endif
+    GRefPtr<GtkStyleContext> parentContext = createStyleContext(ComboBox);
+    GRefPtr<GtkStyleContext> context = createStyleContext(ComboBoxButton, parentContext.get());
     gtk_style_context_set_direction(context.get(), static_cast<GtkTextDirection>(gtkTextDirection(style->direction())));
-
     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);
 
@@ -455,61 +552,43 @@
     gint focusWidth, focusPad;
     gtk_style_context_get_style(context.get(), "interior-focus", &interiorFocus, "focus-line-width", &focusWidth, "focus-padding", &focusPad, nullptr);
     focus = interiorFocus ? focusWidth + focusPad : 0;
-
-    context = createStyleContext(GTK_TYPE_SEPARATOR);
-
-    GtkTextDirection direction = static_cast<GtkTextDirection>(gtkTextDirection(style->direction()));
-    gtk_style_context_set_direction(context.get(), direction);
-#if !GTK_CHECK_VERSION(3, 19, 2)
-    gtk_style_context_add_class(context.get(), "separator");
-#endif
-
-    gboolean wideSeparators;
-    gint separatorWidth;
-    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;
 }
 
 int RenderThemeGtk::popupInternalPaddingLeft(RenderStyle* style) const
 {
     GtkBorder borderWidth = { 0, 0, 0, 0 };
-    int focusWidth = 0, separatorWidth = 0;
-    getComboBoxMetrics(style, borderWidth, focusWidth, separatorWidth);
+    int focusWidth = 0;
+    getComboBoxMetrics(style, borderWidth, focusWidth);
     int left = borderWidth.left + focusWidth;
     if (style->direction() == RTL)
-        left += separatorWidth + minArrowSize;
+        left += minArrowSize;
     return left;
 }
 
 int RenderThemeGtk::popupInternalPaddingRight(RenderStyle* style) const
 {
     GtkBorder borderWidth = { 0, 0, 0, 0 };
-    int focusWidth = 0, separatorWidth = 0;
-    getComboBoxMetrics(style, borderWidth, focusWidth, separatorWidth);
+    int focusWidth = 0;
+    getComboBoxMetrics(style, borderWidth, focusWidth);
     int right = borderWidth.right + focusWidth;
     if (style->direction() == LTR)
-        right += separatorWidth + minArrowSize;
+        right += minArrowSize;
     return right;
 }
 
 int RenderThemeGtk::popupInternalPaddingTop(RenderStyle* style) const
 {
     GtkBorder borderWidth = { 0, 0, 0, 0 };
-    int focusWidth = 0, separatorWidth = 0;
-    getComboBoxMetrics(style, borderWidth, focusWidth, separatorWidth);
+    int focusWidth = 0;
+    getComboBoxMetrics(style, borderWidth, focusWidth);
     return borderWidth.top + focusWidth;
 }
 
 int RenderThemeGtk::popupInternalPaddingBottom(RenderStyle* style) const
 {
     GtkBorder borderWidth = { 0, 0, 0, 0 };
-    int focusWidth = 0, separatorWidth = 0;
-    getComboBoxMetrics(style, borderWidth, focusWidth, separatorWidth);
+    int focusWidth = 0;
+    getComboBoxMetrics(style, borderWidth, focusWidth);
     return borderWidth.bottom + focusWidth;
 }
 
@@ -518,12 +597,11 @@
     cairo_t* cairoContext = paintInfo.context->platformContext()->cr();
     GtkTextDirection direction = static_cast<GtkTextDirection>(gtkTextDirection(renderObject->style().direction()));
 
+    GRefPtr<GtkStyleContext> parentStyleContext = createStyleContext(ComboBox);
+
     // Paint the button.
-    GRefPtr<GtkStyleContext> buttonStyleContext = createStyleContext(GTK_TYPE_BUTTON);
+    GRefPtr<GtkStyleContext> buttonStyleContext = createStyleContext(ComboBoxButton, parentStyleContext.get());
     gtk_style_context_set_direction(buttonStyleContext.get(), direction);
-#if !GTK_CHECK_VERSION(3, 19, 2)
-    gtk_style_context_add_class(buttonStyleContext.get(), GTK_STYLE_CLASS_BUTTON);
-#endif
     renderButton(this, buttonStyleContext.get(), renderObject, paintInfo, rect);
 
     // Get the inner rectangle.
@@ -556,16 +634,16 @@
     innerRect.setHeight(std::max(1, innerRect.height()));
 
     // Paint the arrow.
-    GRefPtr<GtkStyleContext> arrowStyleContext = createStyleContext(GTK_TYPE_ARROW);
-
+    GRefPtr<GtkStyleContext> arrowStyleContext = createStyleContext(ComboBoxArrow, buttonStyleContext.get());
     gtk_style_context_set_direction(arrowStyleContext.get(), direction);
-#if !GTK_CHECK_VERSION(3, 19, 2)
-    gtk_style_context_add_class(arrowStyleContext.get(), "arrow");
-    gtk_style_context_add_class(arrowStyleContext.get(), GTK_STYLE_CLASS_BUTTON);
-#endif
 
+#if GTK_CHECK_VERSION(3, 19, 2)
+    // arrow-scaling style property is now deprecated and ignored.
+    gfloat arrowScaling = 1.;
+#else
     gfloat arrowScaling;
-    gtk_style_context_get_style(arrowStyleContext.get(), "arrow-scaling", &arrowScaling, nullptr);
+    gtk_style_context_get_style(parentStyleContext.get(), "arrow-scaling", &arrowScaling, nullptr);
+#endif
 
     IntSize arrowSize(minArrowSize, innerRect.height());
     FloatPoint arrowPosition(innerRect.location());
@@ -580,67 +658,13 @@
     gtk_style_context_set_state(arrowStyleContext.get(), state);
     gtk_render_arrow(arrowStyleContext.get(), cairoContext, G_PI, arrowPosition.x(), arrowPosition.y(), extent);
 
-    // Paint the separator if needed.
-    GRefPtr<GtkStyleContext> separatorStyleContext = createStyleContext(GTK_TYPE_COMBO_BOX);
-#if GTK_CHECK_VERSION(3, 19, 2)
-    GRefPtr<GtkWidgetPath> path = adoptGRef(gtk_widget_path_new());
-
-    gtk_widget_path_append_type(path.get(), GTK_TYPE_SEPARATOR);
-    gtk_widget_path_iter_set_object_name(path.get(), 0, "separator");
-
-    gtk_style_context_set_path(separatorStyleContext.get(), path.get());
-#else
-    gtk_style_context_add_class(separatorStyleContext.get(), "separator");
-#endif
-
-    gtk_style_context_set_direction(separatorStyleContext.get(), direction);
-
-    gboolean wideSeparators;
-    gint separatorWidth;
-    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.get(), state);
-    IntPoint separatorPosition(arrowPosition.x(), innerRect.y());
-    if (wideSeparators) {
-        if (direction == GTK_TEXT_DIR_LTR)
-            separatorPosition.move(-separatorWidth, 0);
-        else
-            separatorPosition.move(arrowSize.width(), 0);
-
-        gtk_render_frame(separatorStyleContext.get(), cairoContext, separatorPosition.x(), separatorPosition.y(), separatorWidth, innerRect.height());
-    } else {
-        GtkBorder padding;
-        gtk_style_context_get_padding(separatorStyleContext.get(), gtk_style_context_get_state(separatorStyleContext.get()), &padding);
-        GtkBorder 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);
-        else
-            separatorPosition.move(arrowSize.width(), 0);
-
-        cairo_save(cairoContext);
-
-        // 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.get(), cairoContext, separatorPosition.x(), separatorPosition.y(), separatorPosition.x(), innerRect.maxY());
-        cairo_restore(cairoContext);
-    }
-
     return false;
 }
 
 bool RenderThemeGtk::paintTextField(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect)
 {
-    GRefPtr<GtkStyleContext> context = createStyleContext(GTK_TYPE_ENTRY);
-
+    GRefPtr<GtkStyleContext> context = createStyleContext(Entry);
     gtk_style_context_set_direction(context.get(), static_cast<GtkTextDirection>(gtkTextDirection(renderObject->style().direction())));
-#if !GTK_CHECK_VERSION(3, 19, 2)
-    gtk_style_context_add_class(context.get(), GTK_STYLE_CLASS_ENTRY);
-#endif
 
     guint flags = 0;
     if (!isEnabled(renderObject) || isReadOnlyControl(renderObject))
@@ -666,40 +690,176 @@
     return false;
 }
 
-static void applySliderStyleContextClasses(GtkStyleContext* context, ControlPart part)
+// Defined in GTK+ (gtk/gtkiconfactory.c)
+static const gint gtkIconSizeMenu = 16;
+static const gint gtkIconSizeSmallToolbar = 18;
+static const gint gtkIconSizeButton = 20;
+static const gint gtkIconSizeLargeToolbar = 24;
+static const gint gtkIconSizeDnd = 32;
+static const gint gtkIconSizeDialog = 48;
+
+static GtkIconSize getIconSizeForPixelSize(gint pixelSize)
 {
-#if !GTK_CHECK_VERSION(3, 19, 2)
-    gtk_style_context_add_class(context, GTK_STYLE_CLASS_SCALE);
-#endif
-    if (part == SliderHorizontalPart || part == SliderThumbHorizontalPart)
-        gtk_style_context_add_class(context, GTK_STYLE_CLASS_HORIZONTAL);
-    else if (part == SliderVerticalPart || part == SliderThumbVerticalPart)
-        gtk_style_context_add_class(context, GTK_STYLE_CLASS_VERTICAL);
+    if (pixelSize < gtkIconSizeSmallToolbar)
+        return GTK_ICON_SIZE_MENU;
+    if (pixelSize >= gtkIconSizeSmallToolbar && pixelSize < gtkIconSizeButton)
+        return GTK_ICON_SIZE_SMALL_TOOLBAR;
+    if (pixelSize >= gtkIconSizeButton && pixelSize < gtkIconSizeLargeToolbar)
+        return GTK_ICON_SIZE_BUTTON;
+    if (pixelSize >= gtkIconSizeLargeToolbar && pixelSize < gtkIconSizeDnd)
+        return GTK_ICON_SIZE_LARGE_TOOLBAR;
+    if (pixelSize >= gtkIconSizeDnd && pixelSize < gtkIconSizeDialog)
+        return GTK_ICON_SIZE_DND;
+
+    return GTK_ICON_SIZE_DIALOG;
 }
 
-bool RenderThemeGtk::paintSliderTrack(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect)
+static void adjustSearchFieldIconStyle(RenderThemePart themePart, RenderStyle* style)
 {
-    ControlPart part = renderObject->style().appearance();
-    ASSERT_UNUSED(part, part == SliderHorizontalPart || part == SliderVerticalPart || part == MediaVolumeSliderPart);
+    style->resetBorder();
+    style->resetPadding();
 
-    GRefPtr<GtkStyleContext> context = createStyleContext(GTK_TYPE_SCALE);
-#if GTK_CHECK_VERSION(3, 19, 2)
-    GRefPtr<GtkWidgetPath> path = adoptGRef(gtk_widget_path_new());
+    GRefPtr<GtkStyleContext> parentContext = createStyleContext(Entry);
+    GRefPtr<GtkStyleContext> context = createStyleContext(themePart, parentContext.get());
 
-    gtk_widget_path_append_type(path.get(), GTK_TYPE_SCALE);
-    gtk_widget_path_iter_set_object_name(path.get(), 0, "scale");
+    GtkBorder padding;
+    gtk_style_context_get_padding(context.get(), gtk_style_context_get_state(context.get()), &padding);
 
-    gtk_widget_path_append_type(path.get(), GTK_TYPE_SCALE);
-    gtk_widget_path_iter_set_object_name(path.get(), 1, "trough");
+    // Get the icon size based on the font size.
+    int fontSize = style->fontSize();
+    if (fontSize < gtkIconSizeMenu) {
+        style->setWidth(Length(fontSize + (padding.left + padding.right), Fixed));
+        style->setHeight(Length(fontSize + (padding.top + padding.bottom), Fixed));
+        return;
+    }
+    gint width = 0, height = 0;
+    gtk_icon_size_lookup(getIconSizeForPixelSize(fontSize), &width, &height);
+    style->setWidth(Length(width + (padding.left + padding.right), Fixed));
+    style->setHeight(Length(height + (padding.top + padding.bottom), Fixed));
+}
 
-    gtk_style_context_set_path(context.get(), path.get());
+void RenderThemeGtk::adjustSearchFieldResultsDecorationPartStyle(StyleResolver*, RenderStyle* style, Element*) const
+{
+    adjustSearchFieldIconStyle(EntryIconLeft, style);
+}
+
+static GRefPtr<GdkPixbuf> loadThemedIcon(GtkStyleContext* context, const char* iconName, GtkIconSize iconSize)
+{
+    GRefPtr<GIcon> icon = adoptGRef(g_themed_icon_new(iconName));
+    unsigned lookupFlags = GTK_ICON_LOOKUP_USE_BUILTIN | GTK_ICON_LOOKUP_FORCE_SIZE | GTK_ICON_LOOKUP_FORCE_SVG;
+#if GTK_CHECK_VERSION(3, 14, 0)
+    GtkTextDirection direction = gtk_style_context_get_direction(context);
+    if (direction & GTK_TEXT_DIR_LTR)
+        lookupFlags |= GTK_ICON_LOOKUP_DIR_LTR;
+    else if (direction & GTK_TEXT_DIR_RTL)
+        lookupFlags |= GTK_ICON_LOOKUP_DIR_RTL;
 #endif
+    int width, height;
+    gtk_icon_size_lookup(iconSize, &width, &height);
+    GtkIconInfo* iconInfo = gtk_icon_theme_lookup_by_gicon(gtk_icon_theme_get_default(), icon.get(), std::min(width, height), static_cast<GtkIconLookupFlags>(lookupFlags));
+    if (!iconInfo)
+        return nullptr;
 
+    GdkPixbuf* pixbuf = gtk_icon_info_load_symbolic_for_context(iconInfo, context, nullptr, nullptr);
+    gtk_icon_info_free(iconInfo);
+
+    return adoptGRef(pixbuf);
+}
+
+static bool paintIcon(GtkStyleContext* context, GraphicsContext& graphicsContext, const IntRect& rect, const char* iconName)
+{
+    GRefPtr<GdkPixbuf> icon = loadThemedIcon(context, iconName, getIconSizeForPixelSize(rect.height()));
+    if (!icon)
+        return false;
+
+    if (gdk_pixbuf_get_width(icon.get()) > rect.width() || gdk_pixbuf_get_height(icon.get()) > rect.height())
+        icon = adoptGRef(gdk_pixbuf_scale_simple(icon.get(), rect.width(), rect.height(), GDK_INTERP_BILINEAR));
+
+    gtk_render_icon(context, graphicsContext.platformContext()->cr(), icon.get(), rect.x(), rect.y());
+    return true;
+}
+
+static bool paintEntryIcon(RenderThemePart themePart, const char* iconName, GraphicsContext& graphicsContext, const IntRect& rect, GtkTextDirection direction, GtkStateFlags state)
+{
+    GRefPtr<GtkStyleContext> parentContext = createStyleContext(Entry);
+    GRefPtr<GtkStyleContext> context = createStyleContext(themePart, parentContext.get());
+    gtk_style_context_set_direction(context.get(), direction);
+    gtk_style_context_set_state(context.get(), state);
+    return paintIcon(context.get(), graphicsContext, rect, iconName);
+}
+
+static IntRect centerRectVerticallyInParentInputElement(RenderObject* renderObject, const IntRect& rect)
+{
+    // Get the renderer of <input> element.
+    Node* input = renderObject->node()->shadowHost();
+    if (!input)
+        input = renderObject->node();
+    if (!input->renderer()->isBox())
+        return IntRect();
+
+    // If possible center the y-coordinate of the rect vertically in the parent input element.
+    // We also add one pixel here to ensure that the y coordinate is rounded up for box heights
+    // that are even, which looks in relation to the box text.
+    IntRect inputContentBox = toRenderBox(input->renderer())->absoluteContentBox();
+
+    // Make sure the scaled decoration stays square and will fit in its parent's box.
+    int iconSize = std::min(inputContentBox.width(), std::min(inputContentBox.height(), rect.height()));
+    IntRect scaledRect(rect.x(), inputContentBox.y() + (inputContentBox.height() - iconSize + 1) / 2, iconSize, iconSize);
+    return scaledRect;
+}
+
+bool RenderThemeGtk::paintSearchFieldResultsDecorationPart(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect)
+{
+    IntRect iconRect = centerRectVerticallyInParentInputElement(renderObject, rect);
+    if (iconRect.isEmpty())
+        return true;
+
+    return !paintEntryIcon(EntryIconLeft, "edit-find-symbolic", *paintInfo.context, iconRect, gtkTextDirection(renderObject->style().direction()),
+        gtkIconStateFlags(this, renderObject));
+}
+
+void RenderThemeGtk::adjustSearchFieldCancelButtonStyle(StyleResolver*, RenderStyle* style, Element*) const
+{
+    adjustSearchFieldIconStyle(EntryIconRight, style);
+}
+
+bool RenderThemeGtk::paintSearchFieldCancelButton(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect)
+{
+    IntRect iconRect = centerRectVerticallyInParentInputElement(renderObject, rect);
+    if (iconRect.isEmpty())
+        return true;
+
+    return !paintEntryIcon(EntryIconRight, "edit-clear-symbolic", *paintInfo.context, iconRect, gtkTextDirection(renderObject->style().direction()),
+        gtkIconStateFlags(this, renderObject));
+}
+
+bool RenderThemeGtk::paintCapsLockIndicator(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect)
+{
+    // The other paint methods don't need to check whether painting is disabled because RenderTheme already checks it
+    // before calling them, but paintCapsLockIndicator() is called by RenderTextControlSingleLine which doesn't check it.
+    if (paintInfo.context->paintingDisabled())
+        return true;
+
+    int iconSize = std::min(rect.width(), rect.height());
+    // GTK+ locates the icon right aligned in the entry. The given rectangle is already
+    // centered vertically by RenderTextControlSingleLine.
+    IntRect iconRect(rect.x() + rect.width() - iconSize,
+                     rect.y() + (rect.height() - iconSize) / 2,
+                     iconSize, iconSize);
+
+    return !paintEntryIcon(EntryIconRight, "dialog-warning-symbolic", *paintInfo.context, iconRect, gtkTextDirection(renderObject->style().direction()),
+        gtkIconStateFlags(this, renderObject));
+}
+
+bool RenderThemeGtk::paintSliderTrack(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect)
+{
+    ControlPart part = renderObject->style().appearance();
+    ASSERT_UNUSED(part, part == SliderHorizontalPart || part == SliderVerticalPart);
+
+    GRefPtr<GtkStyleContext> parentContext = createStyleContext(Scale);
+    gtk_style_context_add_class(parentContext.get(), part == SliderHorizontalPart ? GTK_STYLE_CLASS_HORIZONTAL : GTK_STYLE_CLASS_VERTICAL);
+    GRefPtr<GtkStyleContext> context = createStyleContext(ScaleTrough, parentContext.get());
     gtk_style_context_set_direction(context.get(), gtkTextDirection(renderObject->style().direction()));
-    applySliderStyleContextClasses(context.get(), part);
-#if !GTK_CHECK_VERSION(3, 19, 2)
-    gtk_style_context_add_class(context.get(), GTK_STYLE_CLASS_TROUGH);
-#endif
 
     if (!isEnabled(renderObject) || isReadOnlyControl(renderObject))
         gtk_style_context_set_state(context.get(), GTK_STATE_FLAG_INSENSITIVE);
@@ -721,27 +881,13 @@
 bool RenderThemeGtk::paintSliderThumb(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect)
 {
     ControlPart part = renderObject->style().appearance();
-    ASSERT(part == SliderThumbHorizontalPart || part == SliderThumbVerticalPart || part == MediaVolumeSliderThumbPart);
+    ASSERT(part == SliderThumbHorizontalPart || part == SliderThumbVerticalPart);
 
-    GRefPtr<GtkStyleContext> context = createStyleContext(GTK_TYPE_SCALE);
-#if GTK_CHECK_VERSION(3, 19, 2)
-    // FIXME: The entire slider is too wide, stretching the thumb into an oval rather than a circle.
-    GRefPtr<GtkWidgetPath> path = adoptGRef(gtk_widget_path_new());
-
-    gtk_widget_path_append_type(path.get(), GTK_TYPE_SCALE);
-    gtk_widget_path_iter_set_object_name(path.get(), 0, "scale");
-
-    gtk_widget_path_append_type(path.get(), GTK_TYPE_SCALE);
-    gtk_widget_path_iter_set_object_name(path.get(), 1, "trough");
-
-    gtk_widget_path_append_type(path.get(), GTK_TYPE_SCALE);
-    gtk_widget_path_iter_set_object_name(path.get(), 2, "slider");
-
-    gtk_style_context_set_path(context.get(), path.get());
-#endif
-
+    GRefPtr<GtkStyleContext> parentContext = createStyleContext(Scale);
+    gtk_style_context_add_class(parentContext.get(), part == SliderThumbHorizontalPart ? GTK_STYLE_CLASS_HORIZONTAL : GTK_STYLE_CLASS_VERTICAL);
+    GRefPtr<GtkStyleContext> troughContext = createStyleContext(ScaleTrough, parentContext.get());
+    GRefPtr<GtkStyleContext> context = createStyleContext(ScaleSlider, troughContext.get());
     gtk_style_context_set_direction(context.get(), gtkTextDirection(renderObject->style().direction()));
-    applySliderStyleContextClasses(context.get(), part);
 
     guint flags = 0;
     if (!isEnabled(renderObject) || isReadOnlyControl(renderObject))
@@ -764,7 +910,7 @@
     if (part != SliderThumbHorizontalPart && part != SliderThumbVerticalPart)
         return;
 
-    GRefPtr<GtkStyleContext> context = createStyleContext(GTK_TYPE_SCALE);
+    GRefPtr<GtkStyleContext> context = createStyleContext(Scale);
     gint sliderWidth, sliderLength;
     gtk_style_context_get_style(context.get(), "slider-width", &sliderWidth, "slider-length", &sliderLength, nullptr);
     if (part == SliderThumbHorizontalPart) {
@@ -772,7 +918,7 @@
         style->setHeight(Length(sliderWidth, Fixed));
         return;
     }
-    ASSERT(part == SliderThumbVerticalPart || part == MediaVolumeSliderThumbPart);
+    ASSERT(part == SliderThumbVerticalPart);
     style->setWidth(Length(sliderWidth, Fixed));
     style->setHeight(Length(sliderLength, Fixed));
 }
@@ -783,43 +929,13 @@
     if (!renderObject->isProgress())
         return true;
 
-    GRefPtr<GtkStyleContext> context = createStyleContext(GTK_TYPE_PROGRESS_BAR);
-#if GTK_CHECK_VERSION(3, 19, 2)
-    GRefPtr<GtkWidgetPath> path = adoptGRef(gtk_widget_path_new());
+    GRefPtr<GtkStyleContext> parentContext = createStyleContext(ProgressBar);
+    GRefPtr<GtkStyleContext> troughContext = createStyleContext(ProgressBarTrough, parentContext.get());
+    GRefPtr<GtkStyleContext> context = createStyleContext(ProgressBarProgress, troughContext.get());
 
-    gtk_widget_path_append_type(path.get(), GTK_TYPE_PROGRESS_BAR);
-    gtk_widget_path_iter_set_object_name(path.get(), 0, "progressbar");
+    gtk_render_background(troughContext.get(), paintInfo.context->platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height());
+    gtk_render_frame(troughContext.get(), paintInfo.context->platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height());
 
-    gtk_widget_path_append_type(path.get(), GTK_TYPE_PROGRESS_BAR);
-    gtk_widget_path_iter_set_object_name(path.get(), 1, "trough");
-
-    gtk_style_context_set_path(context.get(), path.get());
-#else
-    gtk_style_context_save(context.get());
-    gtk_style_context_add_class(context.get(), GTK_STYLE_CLASS_TROUGH);
-#endif
-
-    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 GTK_CHECK_VERSION(3, 19, 2)
-    path = adoptGRef(gtk_widget_path_new());
-
-    gtk_widget_path_append_type(path.get(), GTK_TYPE_PROGRESS_BAR);
-    gtk_widget_path_iter_set_object_name(path.get(), 0, "progressbar");
-
-    gtk_widget_path_append_type(path.get(), GTK_TYPE_PROGRESS_BAR);
-    gtk_widget_path_iter_set_object_name(path.get(), 1, "trough");
-
-    gtk_widget_path_append_type(path.get(), GTK_TYPE_PROGRESS_BAR);
-    gtk_widget_path_iter_set_object_name(path.get(), 2, "progress");
-
-    gtk_style_context_set_path(context.get(), path.get());
-#else
-    gtk_style_context_restore(context.get());
-    gtk_style_context_add_class(context.get(), GTK_STYLE_CLASS_PROGRESSBAR);
-#endif
-
     gtk_style_context_set_state(context.get(), static_cast<GtkStateFlags>(0));
 
     GtkBorder padding;
@@ -855,7 +971,7 @@
 
 void RenderThemeGtk::adjustInnerSpinButtonStyle(StyleResolver*, RenderStyle* style, Element*) const
 {
-    GRefPtr<GtkStyleContext> context = createStyleContext(GTK_TYPE_SPIN_BUTTON);
+    GRefPtr<GtkStyleContext> context = createStyleContext(SpinButton);
 
     GtkBorder padding;
     gtk_style_context_get_padding(context.get(), gtk_style_context_get_state(context.get()), &padding);
@@ -865,29 +981,13 @@
     style->setMinWidth(Length(width, Fixed));
 }
 
-static void paintSpinArrowButton(RenderTheme* theme, GtkStyleContext* context, RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect, GtkArrowType arrowType)
+static void paintSpinArrowButton(RenderTheme* theme, GtkStyleContext* parentContext, RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect, GtkArrowType arrowType)
 {
     ASSERT(arrowType == GTK_ARROW_UP || arrowType == GTK_ARROW_DOWN);
 
-    gtk_style_context_save(context);
-
-#if GTK_CHECK_VERSION(3, 19, 2)
-    GRefPtr<GtkWidgetPath> path = adoptGRef(gtk_widget_path_new());
-
-    gtk_widget_path_append_type(path.get(), GTK_TYPE_SPIN_BUTTON);
-    gtk_widget_path_iter_set_object_name(path.get(), 0, "spinbutton");
-
-    gtk_widget_path_append_type(path.get(), GTK_TYPE_SPIN_BUTTON);
-    gtk_widget_path_iter_set_object_name(path.get(), 1, "button");
-    gtk_widget_path_iter_add_class(path.get(), 1, arrowType == GTK_ARROW_UP ? "up" : "down");
-
-    gtk_style_context_set_path(context, path.get());
-#else
-    gtk_style_context_add_class(context, GTK_STYLE_CLASS_BUTTON);
-#endif
-
-    GtkTextDirection direction = gtk_style_context_get_direction(context);
-    guint state = static_cast<guint>(gtk_style_context_get_state(context));
+    GRefPtr<GtkStyleContext> context = createStyleContext(arrowType == GTK_ARROW_UP ? SpinButtonUpButton : SpinButtonDownButton, parentContext);
+    GtkTextDirection direction = gtk_style_context_get_direction(context.get());
+    guint state = static_cast<guint>(gtk_style_context_get_state(context.get()));
     if (!(state & GTK_STATE_FLAG_INSENSITIVE)) {
         if (theme->isPressed(renderObject)) {
             if ((arrowType == GTK_ARROW_UP && theme->isSpinUpButtonPartPressed(renderObject))
@@ -899,11 +999,11 @@
                 state |= GTK_STATE_FLAG_PRELIGHT;
         }
     }
-    gtk_style_context_set_state(context, static_cast<GtkStateFlags>(state));
+    gtk_style_context_set_state(context.get(), static_cast<GtkStateFlags>(state));
 
     // Paint button.
     IntRect buttonRect(rect);
-    guint junction = gtk_style_context_get_junction_sides(context);
+    guint junction = gtk_style_context_get_junction_sides(context.get());
     if (arrowType == GTK_ARROW_UP)
         junction |= GTK_JUNCTION_BOTTOM;
     else {
@@ -911,10 +1011,10 @@
         buttonRect.move(0, rect.height() / 2);
     }
     buttonRect.setHeight(rect.height() / 2);
-    gtk_style_context_set_junction_sides(context, static_cast<GtkJunctionSides>(junction));
+    gtk_style_context_set_junction_sides(context.get(), static_cast<GtkJunctionSides>(junction));
 
-    gtk_render_background(context, paintInfo.context->platformContext()->cr(), buttonRect.x(), buttonRect.y(), buttonRect.width(), buttonRect.height());
-    gtk_render_frame(context, paintInfo.context->platformContext()->cr(), buttonRect.x(), buttonRect.y(), buttonRect.width(), buttonRect.height());
+    gtk_render_background(context.get(), paintInfo.context->platformContext()->cr(), buttonRect.x(), buttonRect.y(), buttonRect.width(), buttonRect.height());
+    gtk_render_frame(context.get(), paintInfo.context->platformContext()->cr(), buttonRect.x(), buttonRect.y(), buttonRect.width(), buttonRect.height());
 
     // Paint arrow centered inside button.
     // This code is based on gtkspinbutton.c code.
@@ -940,25 +1040,20 @@
     gint height = (width + 1) / 2;
 
     arrowRect.move((arrowRect.width() - width) / 2, (arrowRect.height() - height) / 2);
-    gtk_render_arrow(context, paintInfo.context->platformContext()->cr(), angle, arrowRect.x(), arrowRect.y(), width);
-
-    gtk_style_context_restore(context);
+    gtk_render_arrow(context.get(), paintInfo.context->platformContext()->cr(), angle, arrowRect.x(), arrowRect.y(), width);
 }
 
 bool RenderThemeGtk::paintInnerSpinButton(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect)
 {
-    GRefPtr<GtkStyleContext> context = createStyleContext(GTK_TYPE_SPIN_BUTTON);
+    GRefPtr<GtkStyleContext> context = createStyleContext(SpinButton);
+    gtk_style_context_set_direction(context.get(), gtkTextDirection(renderObject->style().direction()));
 
-    GtkTextDirection direction = static_cast<GtkTextDirection>(gtkTextDirection(renderObject->style().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.get(), static_cast<GtkStateFlags>(flags));
-    gtk_style_context_remove_class(context.get(), GTK_STYLE_CLASS_ENTRY);
 
     paintSpinArrowButton(this, context.get(), renderObject, paintInfo, rect, GTK_ARROW_UP);
     paintSpinArrowButton(this, context.get(), renderObject, paintInfo, rect, GTK_ARROW_DOWN);
@@ -966,69 +1061,18 @@
     return false;
 }
 
-GRefPtr<GdkPixbuf> getStockIconForWidgetType(GType widgetType, const char* iconName, gint direction, gint state, gint iconSize)
-{
-    GRefPtr<GtkStyleContext> context = createStyleContext(widgetType);
-    GtkIconSet* iconSet = gtk_style_context_lookup_icon_set(context.get(), iconName);
-
-    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.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));
-
-    return adoptGRef(icon);
-}
-
-GRefPtr<GdkPixbuf> getStockSymbolicIconForWidgetType(GType widgetType, const char* symbolicIconName, const char *fallbackStockIconName, gint direction, gint state, gint iconSize)
-{
-    GRefPtr<GtkStyleContext> context = createStyleContext(widgetType);
-
-    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.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.get(), nullptr, nullptr);
-        gtk_icon_info_free(info);
-    }
-
-    if (!icon)
-        return getStockIconForWidgetType(widgetType, fallbackStockIconName, direction, state, iconSize);
-
-    return adoptGRef(icon);
-}
-
 enum StyleColorType { StyleColorBackground, StyleColorForeground };
 
-static Color styleColor(GType widgetType, GtkStateFlags state, StyleColorType colorType)
+static Color styleColor(RenderThemePart themePart, GtkStateFlags state, StyleColorType colorType)
 {
-    GRefPtr<GtkStyleContext> context = createStyleContext(widgetType);
-#if GTK_CHECK_VERSION(3, 19, 2)
-    if (widgetType == GTK_TYPE_ENTRY) {
-        GRefPtr<GtkWidgetPath> path = adoptGRef(gtk_widget_path_new());
-
-        gtk_widget_path_append_type(path.get(), GTK_TYPE_ENTRY);
-        gtk_widget_path_iter_set_object_name(path.get(), 0, "entry");
-
-        gtk_widget_path_append_type(path.get(), GTK_TYPE_ENTRY);
-        gtk_widget_path_iter_set_object_name(path.get(), 1, "selection");
-
-        gtk_style_context_set_path(context.get(), path.get());
+    GRefPtr<GtkStyleContext> parentContext;
+    RenderThemePart part = themePart;
+    if (themePart == Entry && (state & GTK_STATE_FLAG_SELECTED)) {
+        parentContext = createStyleContext(Entry);
+        part = EntrySelection;
     }
-#endif
 
+    GRefPtr<GtkStyleContext> context = createStyleContext(part, parentContext.get());
     gtk_style_context_set_state(context.get(), state);
 
     GdkRGBA gdkRGBAColor;
@@ -1041,56 +1085,66 @@
 
 Color RenderThemeGtk::platformActiveSelectionBackgroundColor() const
 {
-    return styleColor(GTK_TYPE_ENTRY, static_cast<GtkStateFlags>(GTK_STATE_FLAG_SELECTED | GTK_STATE_FLAG_FOCUSED), StyleColorBackground);
+    return styleColor(Entry, static_cast<GtkStateFlags>(GTK_STATE_FLAG_SELECTED | GTK_STATE_FLAG_FOCUSED), StyleColorBackground);
 }
 
 Color RenderThemeGtk::platformInactiveSelectionBackgroundColor() const
 {
-    return styleColor(GTK_TYPE_ENTRY, GTK_STATE_FLAG_SELECTED, StyleColorBackground);
+    return styleColor(Entry, GTK_STATE_FLAG_SELECTED, StyleColorBackground);
 }
 
 Color RenderThemeGtk::platformActiveSelectionForegroundColor() const
 {
-    return styleColor(GTK_TYPE_ENTRY, static_cast<GtkStateFlags>(GTK_STATE_FLAG_SELECTED | GTK_STATE_FLAG_FOCUSED), StyleColorForeground);
+    return styleColor(Entry, static_cast<GtkStateFlags>(GTK_STATE_FLAG_SELECTED | GTK_STATE_FLAG_FOCUSED), StyleColorForeground);
 }
 
 Color RenderThemeGtk::platformInactiveSelectionForegroundColor() const
 {
-    return styleColor(GTK_TYPE_ENTRY, GTK_STATE_FLAG_SELECTED, StyleColorForeground);
+    return styleColor(Entry, GTK_STATE_FLAG_SELECTED, StyleColorForeground);
 }
 
 Color RenderThemeGtk::activeListBoxSelectionBackgroundColor() const
 {
-    return styleColor(GTK_TYPE_TREE_VIEW, static_cast<GtkStateFlags>(GTK_STATE_FLAG_SELECTED | GTK_STATE_FLAG_FOCUSED), StyleColorBackground);
+    return styleColor(ListBox, static_cast<GtkStateFlags>(GTK_STATE_FLAG_SELECTED | GTK_STATE_FLAG_FOCUSED), StyleColorBackground);
 }
 
 Color RenderThemeGtk::inactiveListBoxSelectionBackgroundColor() const
 {
-    return styleColor(GTK_TYPE_TREE_VIEW, GTK_STATE_FLAG_SELECTED, StyleColorBackground);
+    return styleColor(ListBox, GTK_STATE_FLAG_SELECTED, StyleColorBackground);
 }
 
 Color RenderThemeGtk::activeListBoxSelectionForegroundColor() const
 {
-    return styleColor(GTK_TYPE_TREE_VIEW, static_cast<GtkStateFlags>(GTK_STATE_FLAG_SELECTED | GTK_STATE_FLAG_FOCUSED), StyleColorForeground);
+    return styleColor(ListBox, static_cast<GtkStateFlags>(GTK_STATE_FLAG_SELECTED | GTK_STATE_FLAG_FOCUSED), StyleColorForeground);
 }
 
 Color RenderThemeGtk::inactiveListBoxSelectionForegroundColor() const
 {
-    return styleColor(GTK_TYPE_TREE_VIEW, GTK_STATE_FLAG_SELECTED, StyleColorForeground);
+    return styleColor(ListBox, GTK_STATE_FLAG_SELECTED, StyleColorForeground);
 }
 
 Color RenderThemeGtk::systemColor(CSSValueID cssValueId) const
 {
     switch (cssValueId) {
     case CSSValueButtontext:
-        return styleColor(GTK_TYPE_BUTTON, GTK_STATE_FLAG_ACTIVE, StyleColorForeground);
+        return styleColor(Button, GTK_STATE_FLAG_ACTIVE, StyleColorForeground);
     case CSSValueCaptiontext:
-        return styleColor(GTK_TYPE_ENTRY, GTK_STATE_FLAG_ACTIVE, StyleColorForeground);
+        return styleColor(Entry, GTK_STATE_FLAG_ACTIVE, StyleColorForeground);
     default:
         return RenderTheme::systemColor(cssValueId);
     }
 }
 
+bool RenderThemeGtk::paintMediaButton(RenderObject* renderObject, GraphicsContext* graphicsContext, const IntRect& rect, const char* iconName, const char*)
+{
+    GRefPtr<GtkStyleContext> context = createStyleContext(MediaButton);
+    gtk_style_context_set_direction(context.get(), gtkTextDirection(renderObject->style().direction()));
+    gtk_style_context_set_state(context.get(), gtkIconStateFlags(this, renderObject));
+    static const unsigned mediaIconSize = 16;
+    IntRect iconRect(rect.x() + (rect.width() - mediaIconSize) / 2, rect.y() + (rect.height() - mediaIconSize) / 2, mediaIconSize, mediaIconSize);
+    return !paintIcon(context.get(), *graphicsContext, iconRect, iconName);
+}
+
 } // namespace WebCore
 
 #endif // !GTK_API_VERSION_2
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to