<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[199476] releases/WebKitGTK/webkit-2.12</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/199476">199476</a></dd>
<dt>Author</dt> <dd>carlosgc@webkit.org</dd>
<dt>Date</dt> <dd>2016-04-13 06:40:36 -0700 (Wed, 13 Apr 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Merge <a href="http://trac.webkit.org/projects/webkit/changeset/199292">r199292</a> - [GTK] Rework the theming code for GTK+ 3.20
https://bugs.webkit.org/show_bug.cgi?id=156333

Reviewed by Michael Catanzaro.

.:

Add a manual test to check how themed elements are rendered.

* ManualTests/gtk/theme.html: Added.

Source/WebCore:

During the 3.19 GTK+ release cycle, the GTK+ css system was reworked, making themes and programs rendering
themed widgets, incompatible with the new system. We were trying to fix our rendering every time GTK+ broke
something, but we were just changing whatever it was needed to make our rendering look like current GTK+ with
the default theme Adwaita. This means that our rendering will be broken for other themes or that changes in
Adwaita can break our rendering. This solution was good enough to ensure WebKitGTK+ 2.12 looked good with GTK+
3.20, but it doesn't work in the long term. We need to ensure that our theming code honors the new GTK+ CSS
properties (max-width, min-width, margin, padding, border, ...) in all the cases, not only the cases where
Adwaita uses them like we currently do.
This patch splits all rendering methods to keep the current code for previous GTK+ versions and adds new code
for GTK+ &gt;= 3.20 using the new RenderThemeGadget classes. This makes the code easier to read, since there aren't
ifdef blocks in the functions, and we ensure we don't break previous rendering.

* PlatformGTK.cmake: Add new files to compilation.
* html/shadow/SpinButtonElement.cpp:
(WebCore::SpinButtonElement::defaultEventHandler): Check the button layout used by the theme to decide the
current buttons state.
* platform/gtk/RenderThemeGadget.cpp: Added.
(WebCore::RenderThemeGadget::create):
(WebCore::createStyleContext):
(WebCore::appendElementToPath):
(WebCore::RenderThemeGadget::RenderThemeGadget):
(WebCore::RenderThemeGadget::~RenderThemeGadget):
(WebCore::RenderThemeGadget::marginBox):
(WebCore::RenderThemeGadget::borderBox):
(WebCore::RenderThemeGadget::paddingBox):
(WebCore::RenderThemeGadget::contentsBox):
(WebCore::RenderThemeGadget::color):
(WebCore::RenderThemeGadget::backgroundColor):
(WebCore::RenderThemeGadget::minimumSize):
(WebCore::RenderThemeGadget::preferredSize):
(WebCore::RenderThemeGadget::render):
(WebCore::RenderThemeGadget::renderFocus):
(WebCore::RenderThemeBoxGadget::RenderThemeBoxGadget):
(WebCore::RenderThemeTextFieldGadget::RenderThemeTextFieldGadget):
(WebCore::RenderThemeTextFieldGadget::minimumSize):
(WebCore::RenderThemeToggleGadget::RenderThemeToggleGadget):
(WebCore::RenderThemeToggleGadget::render):
(WebCore::RenderThemeArrowGadget::RenderThemeArrowGadget):
(WebCore::RenderThemeArrowGadget::render):
(WebCore::RenderThemeIconGadget::RenderThemeIconGadget):
(WebCore::RenderThemeIconGadget::gtkIconSizeForPixelSize):
(WebCore::RenderThemeIconGadget::render):
(WebCore::RenderThemeIconGadget::minimumSize):
* platform/gtk/RenderThemeGadget.h: Added.
(WebCore::RenderThemeGadget::context):
* rendering/RenderTheme.h:
(WebCore::RenderTheme::innerSpinButtonLayout): Added this method to allow themes use a different layout for the
buttons.
* rendering/RenderThemeGtk.cpp:
(WebCore::themeChangedCallback): Just moved this code to a common place.
(WebCore::RenderThemeGtk::RenderThemeGtk): Initialize the theme monitor in the constructor.
(WebCore::createStyleContext): Remove the render parts that are specific to GTK+ 3.20.
(WebCore::RenderThemeGtk::adjustRepaintRect): Moved inside a GTK+ &lt; 3.20 ifdef block.
(WebCore::themePartStateFlags): Helper function to get the GtkStateFlags of a theme part for a given RenderObject.
(WebCore::shrinkToMinimumSizeAndCenterRectangle): Move this common code to a helper function.
(WebCore::setToggleSize):
(WebCore::paintToggle):
(WebCore::RenderThemeGtk::paintButton):
(WebCore::RenderThemeGtk::popupInternalPaddingBox):
(WebCore::RenderThemeGtk::paintMenuList):
(WebCore::RenderThemeGtk::adjustTextFieldStyle): For GTK+ 3.20 we need to ensure a minimum size for spin buttons,
so if the text field is for a spin button, we adjust the desired size here.
(WebCore::RenderThemeGtk::paintTextField): In GTK+ 3.20 the CSS gadgets used to render spin buttons are
different, so we check here if this is the entry of a spin button to use the right gadgets.
(WebCore::adjustSearchFieldIconStyle):
(WebCore::RenderThemeGtk::paintTextArea):
(WebCore::RenderThemeGtk::adjustSearchFieldResultsButtonStyle):
(WebCore::RenderThemeGtk::paintSearchFieldResultsButton):
(WebCore::RenderThemeGtk::adjustSearchFieldResultsDecorationPartStyle):
(WebCore::RenderThemeGtk::adjustSearchFieldCancelButtonStyle):
(WebCore::paintSearchFieldIcon):
(WebCore::RenderThemeGtk::paintSearchFieldResultsDecorationPart):
(WebCore::RenderThemeGtk::paintSearchFieldCancelButton):
(WebCore::centerRectVerticallyInParentInputElement): Moved inside a GTK+ &lt; 3.20 ifdef block.
(WebCore::RenderThemeGtk::paintSliderTrack):
(WebCore::RenderThemeGtk::adjustSliderThumbSize):
(WebCore::RenderThemeGtk::paintSliderThumb):
(WebCore::RenderThemeGtk::progressBarRectForBounds): Ensure a minimum size of progress bars in GTK+ 3.20.
(WebCore::RenderThemeGtk::paintProgressBar):
(WebCore::RenderThemeGtk::innerSpinButtonLayout): Use an horizontal layout for spin buttons.
(WebCore::RenderThemeGtk::adjustInnerSpinButtonStyle):
(WebCore::RenderThemeGtk::paintInnerSpinButton):
(WebCore::styleColor):
(WebCore::RenderThemeGtk::paintMediaButton):
* rendering/RenderThemeGtk.h:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#releasesWebKitGTKwebkit212ChangeLog">releases/WebKitGTK/webkit-2.12/ChangeLog</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceWebCoreChangeLog">releases/WebKitGTK/webkit-2.12/Source/WebCore/ChangeLog</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceWebCorePlatformGTKcmake">releases/WebKitGTK/webkit-2.12/Source/WebCore/PlatformGTK.cmake</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceWebCorehtmlshadowSpinButtonElementcpp">releases/WebKitGTK/webkit-2.12/Source/WebCore/html/shadow/SpinButtonElement.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceWebCorerenderingRenderThemeh">releases/WebKitGTK/webkit-2.12/Source/WebCore/rendering/RenderTheme.h</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceWebCorerenderingRenderThemeGtkcpp">releases/WebKitGTK/webkit-2.12/Source/WebCore/rendering/RenderThemeGtk.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceWebCorerenderingRenderThemeGtkh">releases/WebKitGTK/webkit-2.12/Source/WebCore/rendering/RenderThemeGtk.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#releasesWebKitGTKwebkit212ManualTestsgtkthemehtml">releases/WebKitGTK/webkit-2.12/ManualTests/gtk/theme.html</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceWebCoreplatformgtkRenderThemeGadgetcpp">releases/WebKitGTK/webkit-2.12/Source/WebCore/platform/gtk/RenderThemeGadget.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceWebCoreplatformgtkRenderThemeGadgeth">releases/WebKitGTK/webkit-2.12/Source/WebCore/platform/gtk/RenderThemeGadget.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="releasesWebKitGTKwebkit212ChangeLog"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/ChangeLog (199475 => 199476)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/ChangeLog        2016-04-13 13:40:11 UTC (rev 199475)
+++ releases/WebKitGTK/webkit-2.12/ChangeLog        2016-04-13 13:40:36 UTC (rev 199476)
</span><span class="lines">@@ -1,3 +1,14 @@
</span><ins>+2016-04-07  Carlos Garcia Campos  &lt;cgarcia@igalia.com&gt;
+
+        [GTK] Rework the theming code for GTK+ 3.20
+        https://bugs.webkit.org/show_bug.cgi?id=156333
+
+        Reviewed by Michael Catanzaro.
+
+        Add a manual test to check how themed elements are rendered.
+
+        * ManualTests/gtk/theme.html: Added.
+
</ins><span class="cx"> 2016-03-22  Carlos Garcia Campos  &lt;cgarcia@igalia.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed. Update OptionsGTK.cmake and NEWS for 2.12.0 release.
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212ManualTestsgtkthemehtml"></a>
<div class="addfile"><h4>Added: releases/WebKitGTK/webkit-2.12/ManualTests/gtk/theme.html (0 => 199476)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/ManualTests/gtk/theme.html                                (rev 0)
+++ releases/WebKitGTK/webkit-2.12/ManualTests/gtk/theme.html        2016-04-13 13:40:36 UTC (rev 199476)
</span><span class="lines">@@ -0,0 +1,151 @@
</span><ins>+&lt;html&gt;
+
+  &lt;body id=&quot;body&quot;&gt;
+  &lt;h1&gt;GTK+ themed elements&lt;/h1&gt;
+
+  &lt;p&gt;This is a manual tests to check how all elements having a native appearance are rendered by WebKitGTK+.
+    To test different themes, open this test in MiniBrowser (or any other WebKitGTK+ based browser) passing
+    GTK_THEME=theme-name[:variant] environment variable.
+  &lt;/p&gt;
+
+  &lt;p&gt;Text direction: &lt;select onchange=&quot;body = document.getElementById('body'); if (this.selectedIndex == 0) body.style.direction='ltr'; else body.style.direction='rtl';&quot;&gt;
+      &lt;option&gt;Left to right&lt;/option&gt;&lt;option&gt;Right to left&lt;/option&gt;&lt;/select&gt;
+  &lt;/p&gt;
+
+  &lt;h1&gt;Buttons&lt;/h1&gt;
+  &lt;table&gt;
+    &lt;tr&gt;
+      &lt;td&gt;&lt;button type=&quot;button&quot;&gt;Button&lt;/button&gt;&lt;/td&gt;
+      &lt;td&gt;&lt;button type=&quot;button&quot; disabled&gt;Disabled&lt;/button&gt;&lt;/td&gt;
+    &lt;/tr&gt;
+    &lt;tr&gt;
+      &lt;td&gt;&lt;input type=&quot;radio&quot; name=&quot;radio&quot;/&gt;Radio 1&lt;/td&gt;
+      &lt;td&gt;&lt;input type=&quot;radio&quot; name=&quot;radio&quot;/&gt;Radio 2&lt;/td&gt;
+    &lt;/tr&gt;
+    &lt;tr&gt;
+      &lt;td&gt;&lt;input type=&quot;radio&quot; name=&quot;radio-disabled&quot; disabled/&gt;Disabled&lt;/td&gt;
+      &lt;td&gt;&lt;input type=&quot;radio&quot; name=&quot;radio-disabled&quot; disabled checked/&gt;Checked Disabled&lt;/td&gt;
+    &lt;/tr&gt;
+    &lt;tr&gt;
+      &lt;td&gt;&lt;input type=&quot;checkbox&quot; name=&quot;check&quot;/&gt;Check&lt;/td&gt;
+      &lt;td&gt;&lt;input type=&quot;checkbox&quot; name=&quot;check-disabled&quot; checked disabled/&gt;Check Disabled&lt;/td&gt;
+    &lt;/tr&gt;
+  &lt;/table&gt;
+
+  &lt;h1&gt;Combos&lt;/h1&gt;
+  &lt;table&gt;
+    &lt;tr&gt;
+      &lt;td&gt;&lt;select&gt;&lt;option&gt;A&lt;/option&gt;&lt;option selected&gt;B&lt;/option&gt;&lt;option&gt;C&lt;/option&gt;&lt;/td&gt;
+      &lt;td&gt;&lt;select&gt;&lt;option&gt;Combo option 1&lt;/option&gt;&lt;option&gt;Combo option 2&lt;/option&gt;&lt;option&gt;Combo option 3&lt;/option&gt;&lt;/td&gt;
+    &lt;/tr&gt;
+  &lt;/table&gt;
+
+  &lt;h1&gt;Text areas&lt;/h1&gt;
+  &lt;table&gt;
+    &lt;tr&gt;
+      &lt;td&gt;&lt;input value=&quot;Entry&quot;&gt;&lt;/td&gt;
+      &lt;td&gt;&lt;input value=&quot;Disabled&quot; disabled&gt;&lt;/td&gt;
+      &lt;td&gt;&lt;input value=&quot;Read only&quot; readonly&gt;&lt;/td&gt;
+    &lt;/tr&gt;
+    &lt;tr&gt;
+      &lt;td&gt;&lt;input type=&quot;password&quot; value=&quot;Password&quot;&gt;&lt;/td&gt;
+      &lt;td&gt;&lt;input type=&quot;password&quot; value=&quot;Disabled&quot; disabled&gt;&lt;/td&gt;
+      &lt;td&gt;&lt;input type=&quot;password&quot; value=&quot;Read only&quot; readonly&gt;&lt;/td&gt;
+    &lt;/tr&gt;
+    &lt;tr&gt;
+      &lt;td&gt;&lt;textarea rows=&quot;1&quot;&gt;Single row text area&lt;/textarea&gt;&lt;/td&gt;
+      &lt;td&gt;&lt;textarea rows=&quot;1&quot; disabled&gt;Disabled&lt;/textarea&gt;&lt;/td&gt;
+      &lt;td&gt;&lt;textarea rows=&quot;1&quot; readonly&gt;Read only&lt;/textarea&gt;&lt;/td&gt;
+    &lt;/tr&gt;
+    &lt;tr&gt;
+      &lt;td&gt;&lt;textarea rows=&quot;5&quot;&gt;No scrollbars initially&lt;/textarea&gt;&lt;/td&gt;
+      &lt;td&gt;&lt;textarea rows=&quot;5&quot;&gt;With vertical scrollbar
+
+
+
+
+
+
+      &lt;/textarea&gt;&lt;/td&gt;
+      &lt;td&gt;&lt;textarea rows=&quot;5&quot; style='white-space: nowrap'&gt;With horizontal scrollbars..................&lt;/textarea&gt;&lt;/td&gt;
+    &lt;/tr&gt;
+  &lt;/table&gt;
+
+  &lt;h1&gt;Search field&lt;/h1&gt;
+  &lt;table&gt;
+    &lt;tr&gt;
+      &lt;td&gt;&lt;input type=&quot;search&quot; results value=&quot;Small&quot; style=&quot;font-size: 8px;&quot;&gt;&lt;/td&gt;
+      &lt;td&gt;&lt;input type=&quot;search&quot; results value=&quot;Big&quot; style=&quot;font-size: 32px;&quot;&gt;&lt;/td&gt;
+    &lt;/tr&gt;
+  &lt;/table&gt;
+
+  &lt;h1&gt;Spin buttons&lt;/h1&gt;
+  &lt;table&gt;
+    &lt;tr&gt;
+      &lt;td&gt;&lt;input type=&quot;number&quot; value=&quot;Small&quot; style=&quot;font-size: 8px;&quot;&gt;&lt;/td&gt;
+      &lt;td&gt;&lt;input type=&quot;number&quot; value=&quot;Big&quot; style=&quot;font-size: 32px;&quot;&gt;&lt;/td&gt;
+    &lt;/tr&gt;
+  &lt;/table&gt;
+
+  &lt;h1&gt;Option lists&lt;/h1&gt;
+  &lt;table&gt;
+    &lt;tr&gt;
+      &lt;td&gt;
+        &lt;select size=&quot;5&quot;&gt;
+          &lt;option&gt;Option 1&lt;/option&gt;&lt;option&gt;Option 2&lt;/option&gt;&lt;option&gt;Option 3&lt;/option&gt;&lt;option selected&gt;Option 4&lt;/option&gt;&lt;option&gt;Option 5&lt;/option&gt;
+        &lt;/select&gt;
+      &lt;/td&gt;
+      &lt;td&gt;
+        &lt;select size=&quot;3&quot;&gt;
+          &lt;option&gt;Option 1&lt;/option&gt;&lt;option&gt;Option 2&lt;/option&gt;&lt;option&gt;Option 3&lt;/option&gt;&lt;option selected&gt;Option 4&lt;/option&gt;&lt;option&gt;Option 5&lt;/option&gt;
+        &lt;/select&gt;
+      &lt;/td&gt;
+      &lt;td&gt;
+        &lt;select size=&quot;3&quot;&gt;
+          &lt;option disabled&gt;Option 1&lt;/option&gt;&lt;option disabled&gt;Option 2&lt;/option&gt;&lt;option&gt;Option 3&lt;/option&gt;&lt;option selected&gt;Option 4&lt;/option&gt;&lt;option&gt;Option 5&lt;/option&gt;
+        &lt;/select&gt;
+      &lt;/td&gt;
+      &lt;td&gt;
+        &lt;select size=&quot;3&quot; disabled&gt;
+          &lt;option&gt;Option 1&lt;/option&gt;&lt;option&gt;Option 2&lt;/option&gt;&lt;option&gt;Option 3&lt;/option&gt;&lt;option selected&gt;Option 4&lt;/option&gt;&lt;option&gt;Option 5&lt;/option&gt;
+        &lt;/select&gt;
+      &lt;/td&gt;
+    &lt;/tr&gt;
+  &lt;/table&gt;
+
+  &lt;h1&gt;Progress bars&lt;/h1&gt;
+  &lt;table&gt;
+    &lt;tr&gt;
+      &lt;td&gt;&lt;progress value=&quot;50&quot; max=&quot;100&quot;&gt;&lt;/progress&gt;&lt;/td&gt;
+      &lt;td&gt;&lt;progress indeterminate=&quot;true&quot;&gt;&lt;/progress&gt;&lt;/td&gt;
+      &lt;td&gt;&lt;progress value=&quot;50&quot; max=&quot;100&quot; style=&quot;width: 150px; height: 16px;&quot;&gt;&lt;/progress&gt;&lt;/td&gt;
+      &lt;td&gt;&lt;progress indeterminate=&quot;true&quot; style=&quot;width: 150px; height: 16px;&quot;&gt;&lt;/progress&gt;&lt;/td&gt;
+    &lt;/tr&gt;
+  &lt;/table&gt;
+
+  &lt;h1&gt;Range selector&lt;/h1&gt;
+  &lt;table&gt;
+    &lt;tr&gt;
+      &lt;td&gt;&lt;input type=&quot;range&quot; value=&quot;50&quot; max=&quot;100&quot;&gt;&lt;/input&gt;&lt;/td&gt;
+      &lt;td&gt;&lt;input type=&quot;range&quot; value=&quot;50&quot; max=&quot;100&quot; style=&quot;-webkit-appearance: slider-vertical&quot;&gt;&lt;/input&gt;&lt;/td&gt;
+      &lt;td&gt;&lt;input type=&quot;range&quot; value=&quot;50&quot; max=&quot;100&quot; disabled&gt;&lt;/input&gt;&lt;/td&gt;
+      &lt;td&gt;&lt;input type=&quot;range&quot; value=&quot;50&quot; max=&quot;100&quot; style=&quot;-webkit-appearance: slider-vertical&quot; disabled&gt;&lt;/input&gt;&lt;/td&gt;
+    &lt;/tr&gt;
+  &lt;/table&gt;
+
+  &lt;h1&gt;Iframe scrollbars&lt;/h1&gt;
+  &lt;iframe width=&quot;200&quot; height=&quot;100&quot; scrolling=&quot;yes&quot; src=&quot;data:text/html,
+      &lt;html&gt;
+        &lt;body&gt;
+          Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
+          Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure
+          dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
+          proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
+        &lt;/body&gt;
+      &lt;/html&gt;&quot;&gt;
+  &lt;/iframe&gt;
+
+  &lt;h1&gt;Media controls&lt;/h1&gt;
+  &lt;video controls&gt;&lt;/video&gt;
+  &lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/WebCore/ChangeLog (199475 => 199476)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/WebCore/ChangeLog        2016-04-13 13:40:11 UTC (rev 199475)
+++ releases/WebKitGTK/webkit-2.12/Source/WebCore/ChangeLog        2016-04-13 13:40:36 UTC (rev 199476)
</span><span class="lines">@@ -1,3 +1,96 @@
</span><ins>+2016-04-07  Carlos Garcia Campos  &lt;cgarcia@igalia.com&gt;
+
+        [GTK] Rework the theming code for GTK+ 3.20
+        https://bugs.webkit.org/show_bug.cgi?id=156333
+
+        Reviewed by Michael Catanzaro.
+
+        During the 3.19 GTK+ release cycle, the GTK+ css system was reworked, making themes and programs rendering
+        themed widgets, incompatible with the new system. We were trying to fix our rendering every time GTK+ broke
+        something, but we were just changing whatever it was needed to make our rendering look like current GTK+ with
+        the default theme Adwaita. This means that our rendering will be broken for other themes or that changes in
+        Adwaita can break our rendering. This solution was good enough to ensure WebKitGTK+ 2.12 looked good with GTK+
+        3.20, but it doesn't work in the long term. We need to ensure that our theming code honors the new GTK+ CSS
+        properties (max-width, min-width, margin, padding, border, ...) in all the cases, not only the cases where
+        Adwaita uses them like we currently do.
+        This patch splits all rendering methods to keep the current code for previous GTK+ versions and adds new code
+        for GTK+ &gt;= 3.20 using the new RenderThemeGadget classes. This makes the code easier to read, since there aren't
+        ifdef blocks in the functions, and we ensure we don't break previous rendering.
+
+        * PlatformGTK.cmake: Add new files to compilation.
+        * html/shadow/SpinButtonElement.cpp:
+        (WebCore::SpinButtonElement::defaultEventHandler): Check the button layout used by the theme to decide the
+        current buttons state.
+        * platform/gtk/RenderThemeGadget.cpp: Added.
+        (WebCore::RenderThemeGadget::create):
+        (WebCore::createStyleContext):
+        (WebCore::appendElementToPath):
+        (WebCore::RenderThemeGadget::RenderThemeGadget):
+        (WebCore::RenderThemeGadget::~RenderThemeGadget):
+        (WebCore::RenderThemeGadget::marginBox):
+        (WebCore::RenderThemeGadget::borderBox):
+        (WebCore::RenderThemeGadget::paddingBox):
+        (WebCore::RenderThemeGadget::contentsBox):
+        (WebCore::RenderThemeGadget::color):
+        (WebCore::RenderThemeGadget::backgroundColor):
+        (WebCore::RenderThemeGadget::minimumSize):
+        (WebCore::RenderThemeGadget::preferredSize):
+        (WebCore::RenderThemeGadget::render):
+        (WebCore::RenderThemeGadget::renderFocus):
+        (WebCore::RenderThemeBoxGadget::RenderThemeBoxGadget):
+        (WebCore::RenderThemeTextFieldGadget::RenderThemeTextFieldGadget):
+        (WebCore::RenderThemeTextFieldGadget::minimumSize):
+        (WebCore::RenderThemeToggleGadget::RenderThemeToggleGadget):
+        (WebCore::RenderThemeToggleGadget::render):
+        (WebCore::RenderThemeArrowGadget::RenderThemeArrowGadget):
+        (WebCore::RenderThemeArrowGadget::render):
+        (WebCore::RenderThemeIconGadget::RenderThemeIconGadget):
+        (WebCore::RenderThemeIconGadget::gtkIconSizeForPixelSize):
+        (WebCore::RenderThemeIconGadget::render):
+        (WebCore::RenderThemeIconGadget::minimumSize):
+        * platform/gtk/RenderThemeGadget.h: Added.
+        (WebCore::RenderThemeGadget::context):
+        * rendering/RenderTheme.h:
+        (WebCore::RenderTheme::innerSpinButtonLayout): Added this method to allow themes use a different layout for the
+        buttons.
+        * rendering/RenderThemeGtk.cpp:
+        (WebCore::themeChangedCallback): Just moved this code to a common place.
+        (WebCore::RenderThemeGtk::RenderThemeGtk): Initialize the theme monitor in the constructor.
+        (WebCore::createStyleContext): Remove the render parts that are specific to GTK+ 3.20.
+        (WebCore::RenderThemeGtk::adjustRepaintRect): Moved inside a GTK+ &lt; 3.20 ifdef block.
+        (WebCore::themePartStateFlags): Helper function to get the GtkStateFlags of a theme part for a given RenderObject.
+        (WebCore::shrinkToMinimumSizeAndCenterRectangle): Move this common code to a helper function.
+        (WebCore::setToggleSize):
+        (WebCore::paintToggle):
+        (WebCore::RenderThemeGtk::paintButton):
+        (WebCore::RenderThemeGtk::popupInternalPaddingBox):
+        (WebCore::RenderThemeGtk::paintMenuList):
+        (WebCore::RenderThemeGtk::adjustTextFieldStyle): For GTK+ 3.20 we need to ensure a minimum size for spin buttons,
+        so if the text field is for a spin button, we adjust the desired size here.
+        (WebCore::RenderThemeGtk::paintTextField): In GTK+ 3.20 the CSS gadgets used to render spin buttons are
+        different, so we check here if this is the entry of a spin button to use the right gadgets.
+        (WebCore::adjustSearchFieldIconStyle):
+        (WebCore::RenderThemeGtk::paintTextArea):
+        (WebCore::RenderThemeGtk::adjustSearchFieldResultsButtonStyle):
+        (WebCore::RenderThemeGtk::paintSearchFieldResultsButton):
+        (WebCore::RenderThemeGtk::adjustSearchFieldResultsDecorationPartStyle):
+        (WebCore::RenderThemeGtk::adjustSearchFieldCancelButtonStyle):
+        (WebCore::paintSearchFieldIcon):
+        (WebCore::RenderThemeGtk::paintSearchFieldResultsDecorationPart):
+        (WebCore::RenderThemeGtk::paintSearchFieldCancelButton):
+        (WebCore::centerRectVerticallyInParentInputElement): Moved inside a GTK+ &lt; 3.20 ifdef block.
+        (WebCore::RenderThemeGtk::paintSliderTrack):
+        (WebCore::RenderThemeGtk::adjustSliderThumbSize):
+        (WebCore::RenderThemeGtk::paintSliderThumb):
+        (WebCore::RenderThemeGtk::progressBarRectForBounds): Ensure a minimum size of progress bars in GTK+ 3.20.
+        (WebCore::RenderThemeGtk::paintProgressBar):
+        (WebCore::RenderThemeGtk::innerSpinButtonLayout): Use an horizontal layout for spin buttons.
+        (WebCore::RenderThemeGtk::adjustInnerSpinButtonStyle):
+        (WebCore::RenderThemeGtk::paintInnerSpinButton):
+        (WebCore::styleColor):
+        (WebCore::RenderThemeGtk::paintMediaButton):
+        * rendering/RenderThemeGtk.h:
+
</ins><span class="cx"> 2016-04-03  Carlos Garcia Campos  &lt;cgarcia@igalia.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Replace all RenderTheme::popupInternalPadding methods with a single one returning a LengthBox
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceWebCorePlatformGTKcmake"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/WebCore/PlatformGTK.cmake (199475 => 199476)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/WebCore/PlatformGTK.cmake        2016-04-13 13:40:11 UTC (rev 199475)
+++ releases/WebKitGTK/webkit-2.12/Source/WebCore/PlatformGTK.cmake        2016-04-13 13:40:36 UTC (rev 199476)
</span><span class="lines">@@ -216,6 +216,7 @@
</span><span class="cx">     platform/gtk/PlatformMouseEventGtk.cpp
</span><span class="cx">     platform/gtk/PlatformScreenGtk.cpp
</span><span class="cx">     platform/gtk/PlatformWheelEventGtk.cpp
</span><ins>+    platform/gtk/RenderThemeGadget.cpp
</ins><span class="cx">     platform/gtk/ScrollbarThemeGtk.cpp
</span><span class="cx">     platform/gtk/SoundGtk.cpp
</span><span class="cx">     platform/gtk/WidgetGtk.cpp
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceWebCorehtmlshadowSpinButtonElementcpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/WebCore/html/shadow/SpinButtonElement.cpp (199475 => 199476)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/WebCore/html/shadow/SpinButtonElement.cpp        2016-04-13 13:40:11 UTC (rev 199475)
+++ releases/WebKitGTK/webkit-2.12/Source/WebCore/html/shadow/SpinButtonElement.cpp        2016-04-13 13:40:36 UTC (rev 199476)
</span><span class="lines">@@ -35,6 +35,7 @@
</span><span class="cx"> #include &quot;MouseEvent.h&quot;
</span><span class="cx"> #include &quot;Page.h&quot;
</span><span class="cx"> #include &quot;RenderBox.h&quot;
</span><ins>+#include &quot;RenderTheme.h&quot;
</ins><span class="cx"> #include &quot;ScrollbarTheme.h&quot;
</span><span class="cx"> #include &quot;WheelEvent.h&quot;
</span><span class="cx"> #include &lt;wtf/Ref.h&gt;
</span><span class="lines">@@ -122,7 +123,17 @@
</span><span class="cx">                 }
</span><span class="cx">             }
</span><span class="cx">             UpDownState oldUpDownState = m_upDownState;
</span><del>-            m_upDownState = local.y() &lt; box-&gt;height() / 2 ? Up : Down;
</del><ins>+            switch (renderer()-&gt;theme().innerSpinButtonLayout(*renderer())) {
+            case RenderTheme::InnerSpinButtonLayout::Vertical:
+                m_upDownState = local.y() &lt; box-&gt;height() / 2 ? Up : Down;
+                break;
+            case RenderTheme::InnerSpinButtonLayout::HorizontalUpLeft:
+                m_upDownState = local.x() &lt; box-&gt;width() / 2 ? Up : Down;
+                break;
+            case RenderTheme::InnerSpinButtonLayout::HorizontalUpRight:
+                m_upDownState = local.x() &gt; box-&gt;width() / 2 ? Up : Down;
+                break;
+            }
</ins><span class="cx">             if (m_upDownState != oldUpDownState)
</span><span class="cx">                 renderer()-&gt;repaint();
</span><span class="cx">         } else {
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceWebCoreplatformgtkRenderThemeGadgetcpp"></a>
<div class="addfile"><h4>Added: releases/WebKitGTK/webkit-2.12/Source/WebCore/platform/gtk/RenderThemeGadget.cpp (0 => 199476)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/WebCore/platform/gtk/RenderThemeGadget.cpp                                (rev 0)
+++ releases/WebKitGTK/webkit-2.12/Source/WebCore/platform/gtk/RenderThemeGadget.cpp        2016-04-13 13:40:36 UTC (rev 199476)
</span><span class="lines">@@ -0,0 +1,327 @@
</span><ins>+/*
+ * Copyright (C) 2016 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include &quot;config.h&quot;
+#include &quot;RenderThemeGadget.h&quot;
+
+#if GTK_CHECK_VERSION(3, 20, 0)
+
+#include &quot;FloatRect.h&quot;
+#include &quot;GRefPtrGtk.h&quot;
+
+namespace WebCore {
+
+std::unique_ptr&lt;RenderThemeGadget&gt; RenderThemeGadget::create(const RenderThemeGadget::Info&amp; info, RenderThemeGadget* parent, const Vector&lt;RenderThemeGadget::Info&gt; siblings, unsigned position)
+{
+    switch (info.type) {
+    case RenderThemeGadget::Type::Generic:
+        return std::make_unique&lt;RenderThemeGadget&gt;(info, parent, siblings, position);
+    case RenderThemeGadget::Type::TextField:
+        return std::make_unique&lt;RenderThemeTextFieldGadget&gt;(info, parent, siblings, position);
+    case RenderThemeGadget::Type::Radio:
+    case RenderThemeGadget::Type::Check:
+        return std::make_unique&lt;RenderThemeToggleGadget&gt;(info, parent, siblings, position);
+    case RenderThemeGadget::Type::Arrow:
+        return std::make_unique&lt;RenderThemeArrowGadget&gt;(info, parent, siblings, position);
+    case RenderThemeGadget::Type::Icon:
+        return std::make_unique&lt;RenderThemeIconGadget&gt;(info, parent, siblings, position);
+    }
+
+    ASSERT_NOT_REACHED();
+    return nullptr;
+}
+
+static GRefPtr&lt;GtkStyleContext&gt; createStyleContext(GtkWidgetPath* path, GtkStyleContext* parent)
+{
+    GRefPtr&lt;GtkStyleContext&gt; context = adoptGRef(gtk_style_context_new());
+    gtk_style_context_set_path(context.get(), path);
+    gtk_style_context_set_parent(context.get(), parent);
+    // Unfortunately, we have to explicitly set the state again here for it to take effect.
+    gtk_style_context_set_state(context.get(), gtk_widget_path_iter_get_state(path, -1));
+    return context;
+}
+
+static void appendElementToPath(GtkWidgetPath* path, const RenderThemeGadget::Info&amp; info)
+{
+    gtk_widget_path_append_type(path, G_TYPE_NONE);
+    gtk_widget_path_iter_set_object_name(path, -1, info.name);
+    for (const auto* className : info.classList)
+        gtk_widget_path_iter_add_class(path, -1, className);
+    gtk_widget_path_iter_set_state(path, -1, static_cast&lt;GtkStateFlags&gt;(gtk_widget_path_iter_get_state(path, -1) | info.state));
+}
+
+RenderThemeGadget::RenderThemeGadget(const RenderThemeGadget::Info&amp; info, RenderThemeGadget* parent, const Vector&lt;RenderThemeGadget::Info&gt; siblings, unsigned position)
+{
+    GRefPtr&lt;GtkWidgetPath&gt; path = parent ? adoptGRef(gtk_widget_path_copy(gtk_style_context_get_path(parent-&gt;context()))) : adoptGRef(gtk_widget_path_new());
+    if (!siblings.isEmpty()) {
+        GRefPtr&lt;GtkWidgetPath&gt; siblingsPath = adoptGRef(gtk_widget_path_new());
+        for (const auto&amp; siblingInfo : siblings)
+            appendElementToPath(siblingsPath.get(), siblingInfo);
+        gtk_widget_path_append_with_siblings(path.get(), siblingsPath.get(), position);
+    } else
+        appendElementToPath(path.get(), info);
+    m_context = createStyleContext(path.get(), parent ? parent-&gt;context() : nullptr);
+}
+
+RenderThemeGadget::~RenderThemeGadget()
+{
+}
+
+GtkBorder RenderThemeGadget::marginBox() const
+{
+    GtkBorder returnValue;
+    gtk_style_context_get_margin(m_context.get(), gtk_style_context_get_state(m_context.get()), &amp;returnValue);
+    return returnValue;
+}
+
+GtkBorder RenderThemeGadget::borderBox() const
+{
+    GtkBorder returnValue;
+    gtk_style_context_get_border(m_context.get(), gtk_style_context_get_state(m_context.get()), &amp;returnValue);
+    return returnValue;
+}
+
+GtkBorder RenderThemeGadget::paddingBox() const
+{
+    GtkBorder returnValue;
+    gtk_style_context_get_padding(m_context.get(), gtk_style_context_get_state(m_context.get()), &amp;returnValue);
+    return returnValue;
+}
+
+GtkBorder RenderThemeGadget::contentsBox() const
+{
+    auto margin = marginBox();
+    auto border = borderBox();
+    auto padding = paddingBox();
+    padding.left += margin.left + border.left;
+    padding.right += margin.right + border.right;
+    padding.top += margin.top + border.top;
+    padding.bottom += margin.bottom + border.bottom;
+    return padding;
+}
+
+Color RenderThemeGadget::color() const
+{
+    GdkRGBA returnValue;
+    gtk_style_context_get_color(m_context.get(), gtk_style_context_get_state(m_context.get()), &amp;returnValue);
+    return returnValue;
+}
+
+Color RenderThemeGadget::backgroundColor() const
+{
+    GdkRGBA returnValue;
+    gtk_style_context_get_background_color(m_context.get(), gtk_style_context_get_state(m_context.get()), &amp;returnValue);
+    return returnValue;
+}
+
+IntSize RenderThemeGadget::minimumSize() const
+{
+    int width, height;
+    gtk_style_context_get(m_context.get(), gtk_style_context_get_state(m_context.get()), &quot;min-width&quot;, &amp;width, &quot;min-height&quot;, &amp;height, nullptr);
+    return IntSize(width, height);
+}
+
+IntSize RenderThemeGadget::preferredSize() const
+{
+    auto margin = marginBox();
+    auto border = borderBox();
+    auto padding = paddingBox();
+    auto minSize = minimumSize();
+    minSize.expand(margin.left + margin.right + border.left + border.right + padding.left + padding.right,
+        margin.top + margin.bottom + border.top + border.bottom + padding.top + padding.bottom);
+    return minSize;
+}
+
+bool RenderThemeGadget::render(cairo_t* cr, const FloatRect&amp; paintRect, FloatRect* contentsRect)
+{
+    FloatRect rect = paintRect;
+
+    auto margin = marginBox();
+    rect.move(margin.left, margin.top);
+    rect.contract(margin.left + margin.right, margin.top + margin.bottom);
+
+    auto minSize = minimumSize();
+    rect.setWidth(std::max&lt;float&gt;(rect.width(), minSize.width()));
+    rect.setHeight(std::max&lt;float&gt;(rect.height(), minSize.height()));
+
+    gtk_render_background(m_context.get(), cr, rect.x(), rect.y(), rect.width(), rect.height());
+    gtk_render_frame(m_context.get(), cr, rect.x(), rect.y(), rect.width(), rect.height());
+
+    if (contentsRect) {
+        auto border = borderBox();
+        auto padding = paddingBox();
+        *contentsRect = rect;
+        contentsRect-&gt;move(border.left + padding.left, border.top + padding.top);
+        contentsRect-&gt;contract(border.left + border.right + padding.left + padding.right, border.top + border.bottom + padding.top + padding.bottom);
+    }
+
+    return true;
+}
+
+void RenderThemeGadget::renderFocus(cairo_t* cr, const FloatRect&amp; focusRect)
+{
+    FloatRect rect = focusRect;
+    auto margin = marginBox();
+    rect.move(margin.left, margin.top);
+    rect.contract(margin.left + margin.right, margin.top + margin.bottom);
+    gtk_render_focus(m_context.get(), cr, rect.x(), rect.y(), rect.width(), rect.height());
+}
+
+RenderThemeBoxGadget::RenderThemeBoxGadget(const RenderThemeGadget::Info&amp; info, const Vector&lt;RenderThemeGadget::Info&gt; children, RenderThemeGadget* parent)
+    : RenderThemeGadget(info, parent, Vector&lt;RenderThemeGadget::Info&gt;(), 0)
+{
+    m_children.reserveCapacity(children.size());
+    unsigned index = 0;
+    for (const auto&amp; childInfo : children)
+        m_children.uncheckedAppend(RenderThemeGadget::create(childInfo, this, children, index++));
+}
+
+IntSize RenderThemeBoxGadget::preferredSize() const
+{
+    IntSize minSize = RenderThemeGadget::preferredSize();
+    for (const auto&amp; child : m_children)
+        minSize += child-&gt;preferredSize();
+    return minSize;
+}
+
+RenderThemeTextFieldGadget::RenderThemeTextFieldGadget(const RenderThemeGadget::Info&amp; info, RenderThemeGadget* parent, const Vector&lt;RenderThemeGadget::Info&gt; siblings, unsigned position)
+    : RenderThemeGadget(info, parent, siblings, position)
+{
+}
+
+IntSize RenderThemeTextFieldGadget::minimumSize() const
+{
+    // We allow text fields smaller than the min size set on themes.
+    return IntSize();
+}
+
+RenderThemeToggleGadget::RenderThemeToggleGadget(const RenderThemeGadget::Info&amp; info, RenderThemeGadget* parent, const Vector&lt;RenderThemeGadget::Info&gt; siblings, unsigned position)
+    : RenderThemeGadget(info, parent, siblings, position)
+    , m_type(info.type)
+{
+    ASSERT(m_type == RenderThemeGadget::Type::Radio || m_type == RenderThemeGadget::Type::Check);
+}
+
+bool RenderThemeToggleGadget::render(cairo_t* cr, const FloatRect&amp; paintRect, FloatRect*)
+{
+    FloatRect contentsRect;
+    RenderThemeGadget::render(cr, paintRect, &amp;contentsRect);
+    if (m_type == RenderThemeGadget::Type::Radio)
+        gtk_render_option(m_context.get(), cr, contentsRect.x(), contentsRect.y(), contentsRect.width(), contentsRect.height());
+    else
+        gtk_render_check(m_context.get(), cr, contentsRect.x(), contentsRect.y(), contentsRect.width(), contentsRect.height());
+    return true;
+}
+
+RenderThemeArrowGadget::RenderThemeArrowGadget(const RenderThemeGadget::Info&amp; info, RenderThemeGadget* parent, const Vector&lt;RenderThemeGadget::Info&gt; siblings, unsigned position)
+    : RenderThemeGadget(info, parent, siblings, position)
+{
+}
+
+bool RenderThemeArrowGadget::render(cairo_t* cr, const FloatRect&amp; paintRect, FloatRect*)
+{
+    FloatRect contentsRect;
+    RenderThemeGadget::render(cr, paintRect, &amp;contentsRect);
+    IntSize minSize = minimumSize();
+    int arrowSize = std::min(minSize.width(), minSize.height());
+    FloatPoint arrowPosition(contentsRect.x(), contentsRect.y() + (contentsRect.height() - arrowSize) / 2);
+    if (gtk_style_context_get_state(m_context.get()) &amp; GTK_STATE_FLAG_DIR_LTR)
+        arrowPosition.move(contentsRect.width() - arrowSize, 0);
+    gtk_render_arrow(m_context.get(), cr, G_PI / 2, arrowPosition.x(), arrowPosition.y(), arrowSize);
+    return true;
+}
+
+RenderThemeIconGadget::RenderThemeIconGadget(const RenderThemeGadget::Info&amp; info, RenderThemeGadget* parent, const Vector&lt;RenderThemeGadget::Info&gt; siblings, unsigned position)
+    : RenderThemeGadget(info, parent, siblings, position)
+{
+}
+
+GtkIconSize RenderThemeIconGadget::gtkIconSizeForPixelSize(unsigned pixelSize) const
+{
+    if (pixelSize &lt; IconSizeGtk::SmallToolbar)
+        return GTK_ICON_SIZE_MENU;
+    if (pixelSize &gt;= IconSizeGtk::SmallToolbar &amp;&amp; pixelSize &lt; IconSizeGtk::Button)
+        return GTK_ICON_SIZE_SMALL_TOOLBAR;
+    if (pixelSize &gt;= IconSizeGtk::Button &amp;&amp; pixelSize &lt; IconSizeGtk::LargeToolbar)
+        return GTK_ICON_SIZE_BUTTON;
+    if (pixelSize &gt;= IconSizeGtk::LargeToolbar &amp;&amp; pixelSize &lt; IconSizeGtk::DragAndDrop)
+        return GTK_ICON_SIZE_LARGE_TOOLBAR;
+    if (pixelSize &gt;= IconSizeGtk::DragAndDrop &amp;&amp; pixelSize &lt; IconSizeGtk::Dialog)
+        return GTK_ICON_SIZE_DND;
+
+    return GTK_ICON_SIZE_DIALOG;
+}
+
+bool RenderThemeIconGadget::render(cairo_t* cr, const FloatRect&amp; paintRect, FloatRect*)
+{
+    ASSERT(!m_iconName.isNull());
+    GRefPtr&lt;GIcon&gt; icon = adoptGRef(g_themed_icon_new(m_iconName.data()));
+    unsigned lookupFlags = GTK_ICON_LOOKUP_USE_BUILTIN | GTK_ICON_LOOKUP_FORCE_SIZE | GTK_ICON_LOOKUP_FORCE_SVG;
+    GtkTextDirection direction = gtk_style_context_get_direction(m_context.get());
+    if (direction &amp; GTK_TEXT_DIR_LTR)
+        lookupFlags |= GTK_ICON_LOOKUP_DIR_LTR;
+    else if (direction &amp; GTK_TEXT_DIR_RTL)
+        lookupFlags |= GTK_ICON_LOOKUP_DIR_RTL;
+    int iconWidth, iconHeight;
+    if (!gtk_icon_size_lookup(gtkIconSizeForPixelSize(m_iconSize), &amp;iconWidth, &amp;iconHeight))
+        iconWidth = iconHeight = m_iconSize;
+    GRefPtr&lt;GtkIconInfo&gt; iconInfo = adoptGRef(gtk_icon_theme_lookup_by_gicon(gtk_icon_theme_get_default(), icon.get(),
+        std::min(iconWidth, iconHeight), static_cast&lt;GtkIconLookupFlags&gt;(lookupFlags)));
+    if (!iconInfo)
+        return false;
+
+    GRefPtr&lt;GdkPixbuf&gt; iconPixbuf = adoptGRef(gtk_icon_info_load_symbolic_for_context(iconInfo.get(), m_context.get(), nullptr, nullptr));
+    if (!iconPixbuf)
+        return false;
+
+    FloatSize pixbufSize(gdk_pixbuf_get_width(iconPixbuf.get()), gdk_pixbuf_get_height(iconPixbuf.get()));
+    FloatRect contentsRect;
+    RenderThemeGadget::render(cr, paintRect, &amp;contentsRect);
+    if (pixbufSize.width() &gt; contentsRect.width() || pixbufSize.height() &gt; contentsRect.height()) {
+        iconWidth = iconHeight = std::min(contentsRect.width(), contentsRect.height());
+        pixbufSize = FloatSize(iconWidth, iconHeight);
+        iconPixbuf = adoptGRef(gdk_pixbuf_scale_simple(iconPixbuf.get(), pixbufSize.width(), pixbufSize.height(), GDK_INTERP_BILINEAR));
+    }
+
+    gtk_render_icon(m_context.get(), cr, iconPixbuf.get(), contentsRect.x() + (contentsRect.width() - pixbufSize.width()) / 2,
+        contentsRect.y() + (contentsRect.height() - pixbufSize.height()) / 2);
+    return true;
+}
+
+IntSize RenderThemeIconGadget::minimumSize() const
+{
+    if (m_iconSize &lt; IconSizeGtk::Menu)
+        return IntSize(m_iconSize, m_iconSize);
+
+    int iconWidth, iconHeight;
+    if (gtk_icon_size_lookup(gtkIconSizeForPixelSize(m_iconSize), &amp;iconWidth, &amp;iconHeight))
+        return IntSize(iconWidth, iconHeight);
+
+    return IntSize(m_iconSize, m_iconSize);
+}
+
+} // namespace WebCore
+
+#endif // GTK_CHECK_VERSION(3, 20, 0)
</ins></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceWebCoreplatformgtkRenderThemeGadgeth"></a>
<div class="addfile"><h4>Added: releases/WebKitGTK/webkit-2.12/Source/WebCore/platform/gtk/RenderThemeGadget.h (0 => 199476)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/WebCore/platform/gtk/RenderThemeGadget.h                                (rev 0)
+++ releases/WebKitGTK/webkit-2.12/Source/WebCore/platform/gtk/RenderThemeGadget.h        2016-04-13 13:40:36 UTC (rev 199476)
</span><span class="lines">@@ -0,0 +1,149 @@
</span><ins>+/*
+ * Copyright (C) 2016 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include &lt;gtk/gtk.h&gt;
+
+#if GTK_CHECK_VERSION(3, 20, 0)
+
+#include &quot;Color.h&quot;
+#include &quot;IntSize.h&quot;
+#include &lt;wtf/Vector.h&gt;
+#include &lt;wtf/glib/GRefPtr.h&gt;
+#include &lt;wtf/text/CString.h&gt;
+
+namespace WebCore {
+class FloatRect;
+
+class RenderThemeGadget {
+    WTF_MAKE_FAST_ALLOCATED;
+    WTF_MAKE_NONCOPYABLE(RenderThemeGadget);
+public:
+    enum class Type {
+        Generic,
+        TextField,
+        Check,
+        Radio,
+        Arrow,
+        Icon
+    };
+
+    struct Info {
+        Type type;
+        const char* name;
+        GtkStateFlags state;
+        Vector&lt;const char*&gt; classList;
+    };
+
+    static std::unique_ptr&lt;RenderThemeGadget&gt; create(const Info&amp;, RenderThemeGadget* parent = nullptr, const Vector&lt;RenderThemeGadget::Info&gt; siblings = Vector&lt;RenderThemeGadget::Info&gt;(), unsigned position = 0);
+    RenderThemeGadget(const Info&amp;, RenderThemeGadget* parent, const Vector&lt;RenderThemeGadget::Info&gt; siblings, unsigned position);
+    virtual ~RenderThemeGadget();
+
+    virtual IntSize preferredSize() const;
+    virtual bool render(cairo_t*, const FloatRect&amp;, FloatRect* = nullptr);
+    virtual IntSize minimumSize() const;
+
+    void renderFocus(cairo_t*, const FloatRect&amp;);
+
+    GtkBorder contentsBox() const;
+    Color color() const;
+    Color backgroundColor() const;
+
+protected:
+    GtkStyleContext* context() const { return m_context.get(); }
+    GtkBorder marginBox() const;
+    GtkBorder borderBox() const;
+    GtkBorder paddingBox() const;
+
+    GRefPtr&lt;GtkStyleContext&gt; m_context;
+};
+
+class RenderThemeBoxGadget final : public RenderThemeGadget {
+public:
+    RenderThemeBoxGadget(const RenderThemeGadget::Info&amp;, const Vector&lt;RenderThemeGadget::Info&gt; children, RenderThemeGadget* parent = nullptr);
+
+    IntSize preferredSize() const override;
+
+    RenderThemeGadget* child(unsigned index) const { return m_children[index].get(); }
+
+private:
+    Vector&lt;std::unique_ptr&lt;RenderThemeGadget&gt;&gt; m_children;
+};
+
+class RenderThemeTextFieldGadget final : public RenderThemeGadget {
+public:
+    RenderThemeTextFieldGadget(const Info&amp;, RenderThemeGadget* parent, const Vector&lt;RenderThemeGadget::Info&gt; siblings, unsigned position);
+
+    IntSize minimumSize() const override;
+};
+
+class RenderThemeToggleGadget final : public RenderThemeGadget {
+public:
+    RenderThemeToggleGadget(const Info&amp;, RenderThemeGadget* parent, const Vector&lt;RenderThemeGadget::Info&gt; siblings, unsigned position);
+
+    bool render(cairo_t*, const FloatRect&amp;, FloatRect* = nullptr) override;
+
+private:
+    RenderThemeGadget::Type m_type;
+};
+
+class RenderThemeArrowGadget final : public RenderThemeGadget {
+public:
+    RenderThemeArrowGadget(const Info&amp;, RenderThemeGadget* parent, const Vector&lt;RenderThemeGadget::Info&gt; siblings, unsigned position);
+
+    bool render(cairo_t*, const FloatRect&amp;, FloatRect* = nullptr) override;
+};
+
+class RenderThemeIconGadget final : public RenderThemeGadget {
+public:
+    RenderThemeIconGadget(const Info&amp;, RenderThemeGadget* parent, const Vector&lt;RenderThemeGadget::Info&gt; siblings, unsigned position);
+
+    bool render(cairo_t*, const FloatRect&amp;, FloatRect* = nullptr) override;
+    IntSize minimumSize() const override;
+
+    void setIconName(const char* iconName) { m_iconName = iconName; }
+    void setIconSize(unsigned iconSize) { m_iconSize = iconSize; }
+
+    // Defined in GTK+ (gtk/gtkiconfactory.c).
+    enum IconSizeGtk {
+        Menu = 16,
+        SmallToolbar = 18,
+        Button = 20,
+        LargeToolbar = 24,
+        DragAndDrop = 32,
+        Dialog = 48
+    };
+
+private:
+    GtkIconSize gtkIconSizeForPixelSize(unsigned) const;
+
+    CString m_iconName;
+    unsigned m_iconSize { 0 };
+};
+
+} // namespace WebCore
+
+#endif // GTK_CHECK_VERSION(3, 20, 0)
</ins></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceWebCorerenderingRenderThemeh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/WebCore/rendering/RenderTheme.h (199475 => 199476)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/WebCore/rendering/RenderTheme.h        2016-04-13 13:40:11 UTC (rev 199475)
+++ releases/WebKitGTK/webkit-2.12/Source/WebCore/rendering/RenderTheme.h        2016-04-13 13:40:36 UTC (rev 199476)
</span><span class="lines">@@ -253,6 +253,9 @@
</span><span class="cx">     virtual int attachmentBaseline(const RenderAttachment&amp;) const { return -1; }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+    enum class InnerSpinButtonLayout { Vertical, HorizontalUpLeft, HorizontalUpRight };
+    virtual InnerSpinButtonLayout innerSpinButtonLayout(const RenderObject&amp;) const { return InnerSpinButtonLayout::Vertical; }
+
</ins><span class="cx"> protected:
</span><span class="cx">     virtual FontCascadeDescription&amp; cachedSystemFontDescription(CSSValueID systemFontID) const;
</span><span class="cx">     virtual void updateCachedSystemFontDescription(CSSValueID systemFontID, FontCascadeDescription&amp;) const = 0;
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceWebCorerenderingRenderThemeGtkcpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/WebCore/rendering/RenderThemeGtk.cpp (199475 => 199476)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/WebCore/rendering/RenderThemeGtk.cpp        2016-04-13 13:40:11 UTC (rev 199475)
+++ releases/WebKitGTK/webkit-2.12/Source/WebCore/rendering/RenderThemeGtk.cpp        2016-04-13 13:40:36 UTC (rev 199476)
</span><span class="lines">@@ -46,6 +46,7 @@
</span><span class="cx"> #include &quot;RenderBox.h&quot;
</span><span class="cx"> #include &quot;RenderObject.h&quot;
</span><span class="cx"> #include &quot;RenderProgress.h&quot;
</span><ins>+#include &quot;RenderThemeGadget.h&quot;
</ins><span class="cx"> #include &quot;ScrollbarThemeGtk.h&quot;
</span><span class="cx"> #include &quot;StringTruncator.h&quot;
</span><span class="cx"> #include &quot;TimeRanges.h&quot;
</span><span class="lines">@@ -133,11 +134,22 @@
</span><span class="cx"> 
</span><span class="cx"> #ifndef GTK_API_VERSION_2
</span><span class="cx"> 
</span><del>-// This is the default value defined by GTK+, where it was defined as MIN_ARROW_SIZE in gtkarrow.c.
-static const int minArrowSize = 15;
-// This is the default value defined by GTK+, where it was defined as MIN_ARROW_WIDTH in gtkspinbutton.c.
-static const int minSpinButtonArrowSize = 6;
</del><ins>+static void themeChangedCallback()
+{
+    Page::updateStyleForAllPagesAfterGlobalChangeInEnvironment();
+}
</ins><span class="cx"> 
</span><ins>+RenderThemeGtk::RenderThemeGtk()
+{
+    static bool themeMonitorInitialized = false;
+    if (!themeMonitorInitialized) {
+        GtkSettings* settings = gtk_settings_get_default();
+        g_signal_connect(settings, &quot;notify::gtk-theme-name&quot;, G_CALLBACK(themeChangedCallback), nullptr);
+        g_signal_connect(settings, &quot;notify::gtk-color-scheme&quot;, G_CALLBACK(themeChangedCallback), nullptr);
+        themeMonitorInitialized = true;
+    }
+}
+
</ins><span class="cx"> enum RenderThemePart {
</span><span class="cx">     Entry,
</span><span class="cx">     EntrySelection,
</span><span class="lines">@@ -145,17 +157,13 @@
</span><span class="cx">     EntryIconRight,
</span><span class="cx">     Button,
</span><span class="cx">     CheckButton,
</span><del>-    CheckButtonCheck,
</del><span class="cx">     RadioButton,
</span><del>-    RadioButtonRadio,
</del><span class="cx">     ComboBox,
</span><span class="cx">     ComboBoxButton,
</span><span class="cx">     ComboBoxArrow,
</span><span class="cx">     Scale,
</span><del>-    ScaleContents,
</del><span class="cx">     ScaleTrough,
</span><span class="cx">     ScaleSlider,
</span><del>-    ScaleHighlight,
</del><span class="cx">     ProgressBar,
</span><span class="cx">     ProgressBarTrough,
</span><span class="cx">     ProgressBarProgress,
</span><span class="lines">@@ -168,220 +176,102 @@
</span><span class="cx"> #endif
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-static void gtkStyleChangedCallback(GObject*, GParamSpec*)
-{
-    Page::updateStyleForAllPagesAfterGlobalChangeInEnvironment();
-}
</del><ins>+#if !GTK_CHECK_VERSION(3, 20, 0)
+// This is the default value defined by GTK+, where it was defined as MIN_ARROW_SIZE in gtkarrow.c.
+static const int minArrowSize = 15;
+// This is the default value defined by GTK+, where it was defined as MIN_ARROW_WIDTH in gtkspinbutton.c.
+static const int minSpinButtonArrowSize = 6;
</ins><span class="cx"> 
</span><span class="cx"> static GRefPtr&lt;GtkStyleContext&gt; createStyleContext(RenderThemePart themePart, GtkStyleContext* parent = nullptr)
</span><span class="cx"> {
</span><del>-    static bool initialized = false;
-    if (!initialized) {
-        GtkSettings* settings = gtk_settings_get_default();
-        g_signal_connect(settings, &quot;notify::gtk-theme-name&quot;, G_CALLBACK(gtkStyleChangedCallback), nullptr);
-        g_signal_connect(settings, &quot;notify::gtk-color-scheme&quot;, G_CALLBACK(gtkStyleChangedCallback), nullptr);
-        initialized = true;
-    }
-
</del><span class="cx">     GRefPtr&lt;GtkWidgetPath&gt; path = adoptGRef(parent ? gtk_widget_path_copy(gtk_style_context_get_path(parent)) : gtk_widget_path_new());
</span><span class="cx"> 
</span><span class="cx">     switch (themePart) {
</span><span class="cx">     case Entry:
</span><span class="cx">         gtk_widget_path_append_type(path.get(), GTK_TYPE_ENTRY);
</span><del>-#if GTK_CHECK_VERSION(3, 19, 2)
-        gtk_widget_path_iter_set_object_name(path.get(), -1, &quot;entry&quot;);
-#else
</del><span class="cx">         gtk_widget_path_iter_add_class(path.get(), -1, GTK_STYLE_CLASS_ENTRY);
</span><del>-#endif
</del><span class="cx">         break;
</span><del>-    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, &quot;selection&quot;);
-#else
-        gtk_widget_path_iter_add_class(path.get(), -1, GTK_STYLE_CLASS_ENTRY);
-#endif
-        break;
</del><span class="cx">     case EntryIconLeft:
</span><span class="cx">     case EntryIconRight:
</span><span class="cx">         gtk_widget_path_append_type(path.get(), GTK_TYPE_ENTRY);
</span><del>-#if GTK_CHECK_VERSION(3, 19, 2)
-        gtk_widget_path_iter_set_object_name(path.get(), -1, &quot;image&quot;);
-        gtk_widget_path_iter_add_class(path.get(), -1, themePart == EntryIconLeft ? &quot;left&quot; : &quot;right&quot;);
-#endif
</del><span class="cx">         break;
</span><span class="cx">     case Button:
</span><span class="cx">         gtk_widget_path_append_type(path.get(), GTK_TYPE_BUTTON);
</span><del>-#if GTK_CHECK_VERSION(3, 19, 2)
-        gtk_widget_path_iter_set_object_name(path.get(), -1, &quot;button&quot;);
-#else
</del><span class="cx">         gtk_widget_path_iter_add_class(path.get(), -1, GTK_STYLE_CLASS_BUTTON);
</span><del>-#endif
</del><span class="cx">         gtk_widget_path_iter_add_class(path.get(), -1, &quot;text-button&quot;);
</span><span class="cx">         break;
</span><span class="cx">     case CheckButton:
</span><span class="cx">         gtk_widget_path_append_type(path.get(), GTK_TYPE_CHECK_BUTTON);
</span><del>-#if GTK_CHECK_VERSION(3, 19, 2)
-        gtk_widget_path_iter_set_object_name(path.get(), -1, &quot;checkbutton&quot;);
-#else
</del><span class="cx">         gtk_widget_path_iter_add_class(path.get(), -1, GTK_STYLE_CLASS_CHECK);
</span><del>-#endif
</del><span class="cx">         break;
</span><del>-    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, &quot;check&quot;);
-#else
-        gtk_widget_path_iter_add_class(path.get(), -1, GTK_STYLE_CLASS_CHECK);
-#endif
-        break;
</del><span class="cx">     case RadioButton:
</span><span class="cx">         gtk_widget_path_append_type(path.get(), GTK_TYPE_RADIO_BUTTON);
</span><del>-#if GTK_CHECK_VERSION(3, 19, 2)
-        gtk_widget_path_iter_set_object_name(path.get(), -1, &quot;radiobutton&quot;);
-#else
</del><span class="cx">         gtk_widget_path_iter_add_class(path.get(), -1, GTK_STYLE_CLASS_RADIO);
</span><del>-#endif
</del><span class="cx">         break;
</span><del>-    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, &quot;radio&quot;);
-#else
-        gtk_widget_path_iter_add_class(path.get(), -1, GTK_STYLE_CLASS_RADIO);
-#endif
-        break;
</del><span class="cx">     case ComboBox:
</span><span class="cx">         gtk_widget_path_append_type(path.get(), GTK_TYPE_COMBO_BOX);
</span><del>-#if GTK_CHECK_VERSION(3, 19, 2)
-        gtk_widget_path_iter_set_object_name(path.get(), -1, &quot;combobox&quot;);
-#endif
</del><span class="cx">         break;
</span><span class="cx">     case ComboBoxButton:
</span><span class="cx">         gtk_widget_path_append_type(path.get(), GTK_TYPE_BUTTON);
</span><del>-#if GTK_CHECK_VERSION(3, 19, 2)
-        gtk_widget_path_iter_set_object_name(path.get(), -1, &quot;button&quot;);
-#else
</del><span class="cx">         gtk_widget_path_iter_add_class(path.get(), -1, GTK_STYLE_CLASS_BUTTON);
</span><del>-#endif
</del><span class="cx">         gtk_widget_path_iter_add_class(path.get(), -1, &quot;text-button&quot;);
</span><span class="cx">         gtk_widget_path_iter_add_class(path.get(), -1, &quot;combo&quot;);
</span><span class="cx">         break;
</span><span class="cx">     case ComboBoxArrow:
</span><span class="cx">         gtk_widget_path_append_type(path.get(), GTK_TYPE_ARROW);
</span><del>-#if GTK_CHECK_VERSION(3, 19, 2)
-        gtk_widget_path_iter_set_object_name(path.get(), -1, &quot;arrow&quot;);
-#else
</del><span class="cx">         gtk_widget_path_iter_add_class(path.get(), -1, &quot;arrow&quot;);
</span><del>-#endif
</del><span class="cx">         break;
</span><span class="cx">     case Scale:
</span><span class="cx">         gtk_widget_path_append_type(path.get(), GTK_TYPE_SCALE);
</span><del>-#if GTK_CHECK_VERSION(3, 19, 2)
-        gtk_widget_path_iter_set_object_name(path.get(), -1, &quot;scale&quot;);
-#else
</del><span class="cx">         gtk_widget_path_iter_add_class(path.get(), -1, GTK_STYLE_CLASS_SCALE);
</span><del>-#endif
</del><span class="cx">         break;
</span><del>-    case ScaleContents:
-#if GTK_CHECK_VERSION(3, 19, 11)
-        gtk_widget_path_append_type(path.get(), GTK_TYPE_SCALE);
-        gtk_widget_path_iter_set_object_name(path.get(), -1, &quot;contents&quot;);
-        gtk_widget_path_iter_add_class(path.get(), -1, GTK_STYLE_CLASS_SCALE);
-#else
-        ASSERT_NOT_REACHED();
-#endif
-        break;
</del><span class="cx">     case ScaleTrough:
</span><span class="cx">         gtk_widget_path_append_type(path.get(), GTK_TYPE_SCALE);
</span><del>-#if GTK_CHECK_VERSION(3, 19, 2)
-        gtk_widget_path_iter_set_object_name(path.get(), -1, &quot;trough&quot;);
-#else
</del><span class="cx">         gtk_widget_path_iter_add_class(path.get(), -1, GTK_STYLE_CLASS_SCALE);
</span><span class="cx">         gtk_widget_path_iter_add_class(path.get(), -1, GTK_STYLE_CLASS_TROUGH);
</span><del>-#endif
</del><span class="cx">         break;
</span><span class="cx">     case ScaleSlider:
</span><span class="cx">         gtk_widget_path_append_type(path.get(), GTK_TYPE_SCALE);
</span><del>-#if GTK_CHECK_VERSION(3, 19, 2)
-        gtk_widget_path_iter_set_object_name(path.get(), -1, &quot;slider&quot;);
-#else
</del><span class="cx">         gtk_widget_path_iter_add_class(path.get(), -1, GTK_STYLE_CLASS_SCALE);
</span><span class="cx">         gtk_widget_path_iter_add_class(path.get(), -1, GTK_STYLE_CLASS_SLIDER);
</span><del>-#endif
</del><span class="cx">         break;
</span><del>-    case ScaleHighlight:
-#if GTK_CHECK_VERSION(3, 19, 11)
-        gtk_widget_path_append_type(path.get(), GTK_TYPE_SCALE);
-        gtk_widget_path_iter_set_object_name(path.get(), -1, &quot;highlight&quot;);
-        gtk_widget_path_iter_add_class(path.get(), -1, GTK_STYLE_CLASS_SCALE);
-#else
-        ASSERT_NOT_REACHED();
-#endif
-        break;
</del><span class="cx">     case ProgressBar:
</span><span class="cx">         gtk_widget_path_append_type(path.get(), GTK_TYPE_PROGRESS_BAR);
</span><del>-#if GTK_CHECK_VERSION(3, 19, 2)
-        gtk_widget_path_iter_set_object_name(path.get(), -1, &quot;progressbar&quot;);
-#else
</del><span class="cx">         gtk_widget_path_iter_add_class(path.get(), -1, GTK_STYLE_CLASS_PROGRESSBAR);
</span><del>-#endif
</del><span class="cx">         gtk_widget_path_iter_add_class(path.get(), -1, GTK_STYLE_CLASS_HORIZONTAL);
</span><span class="cx">         break;
</span><span class="cx">     case ProgressBarTrough:
</span><span class="cx">         gtk_widget_path_append_type(path.get(), GTK_TYPE_PROGRESS_BAR);
</span><del>-#if GTK_CHECK_VERSION(3, 19, 2)
-        gtk_widget_path_iter_set_object_name(path.get(), -1, &quot;trough&quot;);
-#else
-        gtk_widget_path_iter_add_class(path.get(), -1, GTK_STYLE_CLASS_PROGRESSBAR);
</del><span class="cx">         gtk_widget_path_iter_add_class(path.get(), -1, GTK_STYLE_CLASS_TROUGH);
</span><del>-#endif
</del><span class="cx">         break;
</span><span class="cx">     case ProgressBarProgress:
</span><span class="cx">         gtk_widget_path_append_type(path.get(), GTK_TYPE_PROGRESS_BAR);
</span><del>-#if GTK_CHECK_VERSION(3, 19, 2)
-        gtk_widget_path_iter_set_object_name(path.get(), -1, &quot;progress&quot;);
-#else
</del><span class="cx">         gtk_widget_path_iter_add_class(path.get(), -1, GTK_STYLE_CLASS_PROGRESSBAR);
</span><del>-#endif
</del><span class="cx">         break;
</span><span class="cx">     case ListBox:
</span><span class="cx">         gtk_widget_path_append_type(path.get(), GTK_TYPE_TREE_VIEW);
</span><del>-#if GTK_CHECK_VERSION(3, 19, 2)
-        gtk_widget_path_iter_set_object_name(path.get(), -1, &quot;treeview&quot;);
-#endif
</del><span class="cx">         gtk_widget_path_iter_add_class(path.get(), -1, GTK_STYLE_CLASS_VIEW);
</span><span class="cx">         break;
</span><span class="cx">     case SpinButton:
</span><span class="cx">         gtk_widget_path_append_type(path.get(), GTK_TYPE_SPIN_BUTTON);
</span><del>-#if GTK_CHECK_VERSION(3, 19, 2)
-        gtk_widget_path_iter_set_object_name(path.get(), -1, &quot;spinbutton&quot;);
-#else
</del><span class="cx">         gtk_widget_path_iter_add_class(path.get(), -1, GTK_STYLE_CLASS_SPINBUTTON);
</span><del>-#endif
</del><span class="cx">         gtk_widget_path_iter_add_class(path.get(), -1, GTK_STYLE_CLASS_HORIZONTAL);
</span><span class="cx">         break;
</span><span class="cx">     case SpinButtonUpButton:
</span><span class="cx">     case SpinButtonDownButton:
</span><span class="cx">         gtk_widget_path_append_type(path.get(), GTK_TYPE_SPIN_BUTTON);
</span><del>-#if GTK_CHECK_VERSION(3, 19, 2)
-        gtk_widget_path_iter_set_object_name(path.get(), -1, &quot;button&quot;);
-        gtk_widget_path_iter_add_class(path.get(), -1, themePart == SpinButtonUpButton ? &quot;up&quot; : &quot;down&quot;);
-#else
</del><span class="cx">         gtk_widget_path_iter_add_class(path.get(), -1, GTK_STYLE_CLASS_SPINBUTTON);
</span><span class="cx">         gtk_widget_path_iter_add_class(path.get(), -1, GTK_STYLE_CLASS_BUTTON);
</span><del>-#endif
</del><span class="cx">         break;
</span><span class="cx"> #if ENABLE(VIDEO)
</span><span class="cx">     case MediaButton:
</span><span class="cx">         gtk_widget_path_append_type(path.get(), GTK_TYPE_IMAGE);
</span><del>-#if GTK_CHECK_VERSION(3, 19, 2)
-        gtk_widget_path_iter_set_object_name(path.get(), -1, &quot;image&quot;);
-#else
</del><span class="cx">         gtk_widget_path_iter_add_class(path.get(), -1, GTK_STYLE_CLASS_IMAGE);
</span><del>-#endif
</del><span class="cx">         break;
</span><span class="cx"> #endif // ENABLE(VIDEO)
</span><ins>+    default:
+        ASSERT_NOT_REACHED();
+        break;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     GRefPtr&lt;GtkStyleContext&gt; context = adoptGRef(gtk_style_context_new());
</span><span class="lines">@@ -409,6 +299,7 @@
</span><span class="cx"> 
</span><span class="cx">     return adoptGRef(gtk_icon_info_load_symbolic_for_context(iconInfo.get(), context, nullptr, nullptr));
</span><span class="cx"> }
</span><ins>+#endif // !GTK_CHECK_VERSION(3, 20, 0)
</ins><span class="cx"> 
</span><span class="cx"> static bool nodeHasPseudo(Node* node, const char* pseudo)
</span><span class="cx"> {
</span><span class="lines">@@ -471,6 +362,71 @@
</span><span class="cx">     return RenderTheme::baselinePosition(box);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#if GTK_CHECK_VERSION(3, 20, 0)
+void RenderThemeGtk::adjustRepaintRect(const RenderObject&amp;, FloatRect&amp;)
+{
+}
+static GtkStateFlags themePartStateFlags(const RenderThemeGtk&amp; theme, RenderThemePart themePart, const RenderObject&amp; renderObject)
+{
+    unsigned stateFlags = 0;
+    switch (renderObject.style().direction()) {
+    case RTL:
+        stateFlags |= GTK_STATE_FLAG_DIR_RTL;
+        break;
+    case LTR:
+        stateFlags |= GTK_STATE_FLAG_DIR_LTR;
+        break;
+    }
+
+    if (!theme.isEnabled(renderObject) || (themePart == Entry &amp;&amp; theme.isReadOnlyControl(renderObject)))
+        stateFlags |= GTK_STATE_FLAG_INSENSITIVE;
+    else {
+        if (theme.isHovered(renderObject))
+            stateFlags |= GTK_STATE_FLAG_PRELIGHT;
+        if (theme.isFocused(renderObject))
+            stateFlags |= GTK_STATE_FLAG_FOCUSED;
+    }
+
+    switch (themePart) {
+    case CheckButton:
+    case RadioButton:
+        if (theme.isChecked(renderObject))
+            stateFlags |= GTK_STATE_FLAG_CHECKED;
+        if (theme.isIndeterminate(renderObject))
+            stateFlags |= GTK_STATE_FLAG_INCONSISTENT;
+        if (theme.isPressed(renderObject))
+            stateFlags |= GTK_STATE_FLAG_SELECTED;
+        break;
+    case Button:
+    case ComboBoxButton:
+    case ScaleSlider:
+    case EntryIconLeft:
+    case EntryIconRight:
+#if ENABLE(VIDEO)
+    case MediaButton:
+#endif
+        if (theme.isPressed(renderObject))
+            stateFlags |= GTK_STATE_FLAG_ACTIVE;
+        break;
+    case SpinButtonUpButton:
+        if (theme.isPressed(renderObject) &amp;&amp; theme.isSpinUpButtonPartPressed(renderObject))
+            stateFlags |= GTK_STATE_FLAG_ACTIVE;
+        if (theme.isHovered(renderObject) &amp;&amp; !theme.isSpinUpButtonPartHovered(renderObject))
+            stateFlags &amp;= ~GTK_STATE_FLAG_PRELIGHT;
+        break;
+    case SpinButtonDownButton:
+        if (theme.isPressed(renderObject) &amp;&amp; !theme.isSpinUpButtonPartPressed(renderObject))
+            stateFlags |= GTK_STATE_FLAG_ACTIVE;
+        if (theme.isHovered(renderObject) &amp;&amp; theme.isSpinUpButtonPartHovered(renderObject))
+            stateFlags &amp;= ~GTK_STATE_FLAG_PRELIGHT;
+        break;
+    default:
+        break;
+    }
+
+    return static_cast&lt;GtkStateFlags&gt;(stateFlags);
+}
+#else
</ins><span class="cx"> static GtkTextDirection gtkTextDirection(TextDirection direction)
</span><span class="cx"> {
</span><span class="cx">     switch (direction) {
</span><span class="lines">@@ -545,6 +501,7 @@
</span><span class="cx">     }
</span><span class="cx">     adjustRectForFocus(context.get(), rect);
</span><span class="cx"> }
</span><ins>+#endif // GTK_CHECK_VERSION(3, 20, 0)
</ins><span class="cx"> 
</span><span class="cx"> void RenderThemeGtk::adjustButtonStyle(StyleResolver&amp;, RenderStyle&amp; style, Element*) const
</span><span class="cx"> {
</span><span class="lines">@@ -553,39 +510,111 @@
</span><span class="cx">         style.setLineHeight(RenderStyle::initialLineHeight());
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static void shrinkToMinimumSizeAndCenterRectangle(FloatRect&amp; rect, const IntSize&amp; minSize)
+{
+    if (rect.width() &gt; minSize.width()) {
+        rect.inflateX(-(rect.width() - minSize.width()) / 2);
+        rect.setWidth(minSize.width()); // In case rect.width() was equal to minSize.width() + 1.
+    }
+
+    if (rect.height() &gt; minSize.height()) {
+        rect.inflateY(-(rect.height() - minSize.height()) / 2);
+        rect.setHeight(minSize.height()); // In case rect.height() was equal to minSize.height() + 1.
+    }
+}
+
+#if GTK_CHECK_VERSION(3, 20, 0)
</ins><span class="cx"> static void setToggleSize(RenderThemePart themePart, RenderStyle&amp; style)
</span><span class="cx"> {
</span><ins>+    ASSERT(themePart == CheckButton || themePart == RadioButton);
+
</ins><span class="cx">     // The width and height are both specified, so we shouldn't change them.
</span><span class="cx">     if (!style.width().isIntrinsicOrAuto() &amp;&amp; !style.height().isAuto())
</span><span class="cx">         return;
</span><span class="cx"> 
</span><ins>+    RenderThemeGadget::Info info = {
+        .type = RenderThemeGadget::Type::Generic,
+        .name = themePart == CheckButton ? &quot;checkbutton&quot; : &quot;radiobutton&quot;,
+        .state = GTK_STATE_FLAG_NORMAL,
+        .classList = { }
+    };
+    auto parentGadget = RenderThemeGadget::create(info);
+    if (themePart == CheckButton) {
+        info.type = RenderThemeGadget::Type::Check;
+        info.name = &quot;check&quot;;
+    } else {
+        info.type = RenderThemeGadget::Type::Radio;
+        info.name = &quot;radio&quot;;
+    }
+    auto gadget = RenderThemeToggleGadget::create(info);
+    IntSize preferredSize = parentGadget-&gt;preferredSize();
+    preferredSize = preferredSize.expandedTo(gadget-&gt;preferredSize());
+
+    if (style.width().isIntrinsicOrAuto())
+        style.setWidth(Length(preferredSize.width(), Fixed));
+
+    if (style.height().isAuto())
+        style.setHeight(Length(preferredSize.height(), Fixed));
+}
+
+static void paintToggle(const RenderThemeGtk* theme, RenderThemePart themePart, const RenderObject&amp; renderObject, const PaintInfo&amp; paintInfo, const IntRect&amp; fullRect)
+{
+    ASSERT(themePart == CheckButton || themePart == RadioButton);
+
+    RenderThemeGadget::Info parentInfo = {
+        .type = RenderThemeGadget::Type::Generic,
+        .name = themePart == CheckButton ? &quot;checkbutton&quot; : &quot;radiobutton&quot;,
+        .state = themePartStateFlags(*theme, themePart, renderObject),
+        .classList = { &quot;text-button&quot; }
+    };
+    auto parentGadget = RenderThemeGadget::create(parentInfo);
+    RenderThemeGadget::Info info;
+    info.state = parentInfo.state;
+    if (themePart == CheckButton) {
+        info.type = RenderThemeGadget::Type::Check;
+        info.name = &quot;check&quot;;
+    } else {
+        info.type = RenderThemeGadget::Type::Radio;
+        info.name = &quot;radio&quot;;
+    }
+    auto gadget = RenderThemeGadget::create(info, parentGadget.get());
+
+    FloatRect rect = fullRect;
+    // Some themes do not render large toggle buttons properly, so we simply
+    // shrink the rectangle back down to the default size and then center it
+    // in the full toggle button region. The reason for not simply forcing toggle
+    // buttons to be a smaller size is that we don't want to break site layouts.
+    IntSize preferredSize = parentGadget-&gt;preferredSize();
+    preferredSize = preferredSize.expandedTo(gadget-&gt;preferredSize());
+    shrinkToMinimumSizeAndCenterRectangle(rect, preferredSize);
+    parentGadget-&gt;render(paintInfo.context().platformContext()-&gt;cr(), rect);
+    gadget-&gt;render(paintInfo.context().platformContext()-&gt;cr(), rect);
+
+    if (theme-&gt;isFocused(renderObject))
+        parentGadget-&gt;renderFocus(paintInfo.context().platformContext()-&gt;cr(), rect);
+}
+#else
+static void setToggleSize(RenderThemePart themePart, RenderStyle&amp; style)
+{
+    // The width and height are both specified, so we shouldn't change them.
+    if (!style.width().isIntrinsicOrAuto() &amp;&amp; !style.height().isAuto())
+        return;
+
</ins><span class="cx">     GRefPtr&lt;GtkStyleContext&gt; context = createStyleContext(themePart);
</span><span class="cx">     // Other ports hard-code this to 13. GTK+ users tend to demand the native look.
</span><span class="cx">     gint indicatorSize;
</span><span class="cx">     gtk_style_context_get_style(context.get(), &quot;indicator-size&quot;, &amp;indicatorSize, nullptr);
</span><del>-    IntSize minSize(indicatorSize, indicatorSize);
</del><span class="cx"> 
</span><del>-#if GTK_CHECK_VERSION(3, 19, 7)
-    GRefPtr&lt;GtkStyleContext&gt; childContext = createStyleContext(themePart == CheckButton ? CheckButtonCheck : RadioButtonRadio, context.get());
-    gint minWidth, minHeight;
-    gtk_style_context_get(childContext.get(), gtk_style_context_get_state(childContext.get()), &quot;min-width&quot;, &amp;minWidth, &quot;min-height&quot;, &amp;minHeight, nullptr);
-    if (minWidth)
-        minSize.setWidth(minWidth);
-    if (minHeight)
-        minSize.setHeight(minHeight);
-#endif
-
</del><span class="cx">     if (style.width().isIntrinsicOrAuto())
</span><del>-        style.setWidth(Length(minSize.width(), Fixed));
</del><ins>+        style.setWidth(Length(indicatorSize, Fixed));
</ins><span class="cx"> 
</span><span class="cx">     if (style.height().isAuto())
</span><del>-        style.setHeight(Length(minSize.height(), Fixed));
</del><ins>+        style.setHeight(Length(indicatorSize, Fixed));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static void paintToggle(const RenderThemeGtk* theme, RenderThemePart themePart, const RenderObject&amp; renderObject, const PaintInfo&amp; paintInfo, const IntRect&amp; fullRect)
</span><span class="cx"> {
</span><del>-    GRefPtr&lt;GtkStyleContext&gt; parentContext = createStyleContext(themePart);
-    GRefPtr&lt;GtkStyleContext&gt; context = createStyleContext(themePart == CheckButton ? CheckButtonCheck : RadioButtonRadio, parentContext.get());
</del><ins>+    GRefPtr&lt;GtkStyleContext&gt; context = createStyleContext(themePart);
</ins><span class="cx">     gtk_style_context_set_direction(context.get(), static_cast&lt;GtkTextDirection&gt;(gtkTextDirection(renderObject.style().direction())));
</span><span class="cx"> 
</span><span class="cx">     unsigned flags = 0;
</span><span class="lines">@@ -609,30 +638,12 @@
</span><span class="cx">     // shrink the rectangle back down to the default size and then center it
</span><span class="cx">     // in the full toggle button region. The reason for not simply forcing toggle
</span><span class="cx">     // buttons to be a smaller size is that we don't want to break site layouts.
</span><ins>+    FloatRect rect(fullRect);
</ins><span class="cx">     gint indicatorSize;
</span><span class="cx">     gtk_style_context_get_style(context.get(), &quot;indicator-size&quot;, &amp;indicatorSize, nullptr);
</span><span class="cx">     IntSize minSize(indicatorSize, indicatorSize);
</span><ins>+    shrinkToMinimumSizeAndCenterRectangle(rect, minSize);
</ins><span class="cx"> 
</span><del>-#if GTK_CHECK_VERSION(3, 19, 7)
-    gint minWidth, minHeight;
-    gtk_style_context_get(context.get(), gtk_style_context_get_state(context.get()), &quot;min-width&quot;, &amp;minWidth, &quot;min-height&quot;, &amp;minHeight, nullptr);
-    if (minWidth)
-        minSize.setWidth(minWidth);
-    if (minHeight)
-        minSize.setHeight(minHeight);
-#endif
-
-    IntRect rect(fullRect);
-    if (rect.width() &gt; minSize.width()) {
-        rect.inflateX(-(rect.width() - minSize.width()) / 2);
-        rect.setWidth(minSize.width()); // In case rect.width() was equal to minSize.width() + 1.
-    }
-
-    if (rect.height() &gt; minSize.height()) {
-        rect.inflateY(-(rect.height() - minSize.height()) / 2);
-        rect.setHeight(minSize.height()); // In case rect.height() was equal to minSize.height() + 1.
-    }
-
</del><span class="cx">     gtk_render_background(context.get(), paintInfo.context().platformContext()-&gt;cr(), rect.x(), rect.y(), rect.width(), rect.height());
</span><span class="cx">     gtk_render_frame(context.get(), paintInfo.context().platformContext()-&gt;cr(), rect.x(), rect.y(), rect.width(), rect.height());
</span><span class="cx"> 
</span><span class="lines">@@ -650,6 +661,7 @@
</span><span class="cx">             indicatorRect.width(), indicatorRect.height());
</span><span class="cx">     }
</span><span class="cx"> }
</span><ins>+#endif // GTK_CHECK_VERSION(3, 20, 0)
</ins><span class="cx"> 
</span><span class="cx"> void RenderThemeGtk::setCheckboxSize(RenderStyle&amp; style) const
</span><span class="cx"> {
</span><span class="lines">@@ -673,6 +685,19 @@
</span><span class="cx">     return false;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#if GTK_CHECK_VERSION(3, 20, 0)
+bool RenderThemeGtk::paintButton(const RenderObject&amp; renderObject, const PaintInfo&amp; paintInfo, const IntRect&amp; rect)
+{
+    RenderThemeGadget::Info info = { RenderThemeGadget::Type::Generic, &quot;button&quot;, themePartStateFlags(*this, Button, renderObject), { &quot;text-button&quot; } };
+    if (isDefault(renderObject))
+        info.classList.append(&quot;default&quot;);
+    auto gadget = RenderThemeGadget::create(info);
+    gadget-&gt;render(paintInfo.context().platformContext()-&gt;cr(), rect);
+    if (isFocused(renderObject))
+        gadget-&gt;renderFocus(paintInfo.context().platformContext()-&gt;cr(), rect);
+    return false;
+}
+#else
</ins><span class="cx"> static void renderButton(RenderTheme* theme, GtkStyleContext* context, const RenderObject&amp; renderObject, const PaintInfo&amp; paintInfo, const IntRect&amp; rect)
</span><span class="cx"> {
</span><span class="cx">     IntRect buttonRect(rect);
</span><span class="lines">@@ -746,6 +771,7 @@
</span><span class="cx">     renderButton(this, context.get(), renderObject, paintInfo, rect);
</span><span class="cx">     return false;
</span><span class="cx"> }
</span><ins>+#endif // GTK_CHECK_VERSION(3, 20, 0)
</ins><span class="cx"> 
</span><span class="cx"> void RenderThemeGtk::adjustMenuListStyle(StyleResolver&amp;, RenderStyle&amp; style, Element*) const
</span><span class="cx"> {
</span><span class="lines">@@ -761,9 +787,86 @@
</span><span class="cx">     adjustMenuListStyle(styleResolver, style, e);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#if GTK_CHECK_VERSION(3, 20, 0)
+/*
+ * GtkComboBox gadgets tree
+ *
+ * combobox
+ * ├── box.linked
+ * │   ╰── button.combo
+ * │       ╰── box
+ * │           ├── cellview
+ * │           ╰── arrow
+ * ╰── window.popup
+ */
</ins><span class="cx"> LengthBox RenderThemeGtk::popupInternalPaddingBox(const RenderStyle&amp; style) const
</span><span class="cx"> {
</span><span class="cx">     if (style.appearance() == NoControlPart)
</span><ins>+        return LengthBox(0);
+
+    RenderThemeGadget::Info info = { RenderThemeGadget::Type::Generic, &quot;combobox&quot;, GTK_STATE_FLAG_NORMAL, { } };
+    auto comboGadget = RenderThemeGadget::create(info);
+    Vector&lt;RenderThemeGadget::Info&gt; children = {
+        { RenderThemeGadget::Type::Generic, &quot;button&quot;, GTK_STATE_FLAG_NORMAL, { &quot;combo&quot; } }
+    };
+    info.name = &quot;box&quot;;
+    info.classList = { &quot;horizontal&quot;, &quot;linked&quot; };
+    auto boxGadget = std::make_unique&lt;RenderThemeBoxGadget&gt;(info, children, comboGadget.get());
+    RenderThemeGadget* buttonGadget = boxGadget-&gt;child(0);
+    info.classList.removeLast();
+    auto buttonBoxGadget = RenderThemeGadget::create(info, buttonGadget);
+    info.name = &quot;arrow&quot;;
+    info.classList = { };
+    auto arrowGadget = RenderThemeGadget::create(info, buttonBoxGadget.get());
+    GtkBorder comboContentsBox = comboGadget-&gt;contentsBox();
+    GtkBorder boxContentsBox = boxGadget-&gt;contentsBox();
+    GtkBorder buttonContentsBox = buttonGadget-&gt;contentsBox();
+    GtkBorder buttonBoxContentsBox = buttonBoxGadget-&gt;contentsBox();
+    GtkBorder padding;
+    padding.left = comboContentsBox.left + boxContentsBox.left + buttonContentsBox.left + buttonBoxContentsBox.left;
+    padding.right = comboContentsBox.right + boxContentsBox.right + buttonContentsBox.right + buttonBoxContentsBox.right;
+    padding.top = comboContentsBox.top + boxContentsBox.top + buttonContentsBox.top + buttonBoxContentsBox.top;
+    padding.bottom = comboContentsBox.bottom + boxContentsBox.bottom + buttonContentsBox.bottom + buttonBoxContentsBox.bottom;
+
+    auto arrowSize = arrowGadget-&gt;preferredSize();
+    return LengthBox(padding.top, padding.right + (style.direction() == LTR ? arrowSize.width() : 0),
+        padding.bottom, padding.left + (style.direction() == RTL ? arrowSize.width() : 0));
+}
+
+bool RenderThemeGtk::paintMenuList(const RenderObject&amp; renderObject, const PaintInfo&amp; paintInfo, const FloatRect&amp; rect)
+{
+    RenderThemeGadget::Info info = { RenderThemeGadget::Type::Generic, &quot;combobox&quot;, themePartStateFlags(*this, ComboBoxButton, renderObject), { } };
+    auto comboGadget = RenderThemeGadget::create(info);
+    Vector&lt;RenderThemeGadget::Info&gt; children = {
+        { RenderThemeGadget::Type::Generic, &quot;button&quot;, info.state, { &quot;combo&quot; } }
+    };
+    info.name = &quot;box&quot;;
+    info.classList = { &quot;horizontal&quot;, &quot;linked&quot; };
+    auto boxGadget = std::make_unique&lt;RenderThemeBoxGadget&gt;(info, children, comboGadget.get());
+    RenderThemeGadget* buttonGadget = boxGadget-&gt;child(0);
+    info.classList.removeLast();
+    auto buttonBoxGadget = RenderThemeGadget::create(info, buttonGadget);
+    info.type = RenderThemeGadget::Type::Arrow;
+    info.name = &quot;arrow&quot;;
+    info.classList = { };
+    auto arrowGadget = RenderThemeGadget::create(info, buttonBoxGadget.get());
+
+    cairo_t* cr = paintInfo.context().platformContext()-&gt;cr();
+    comboGadget-&gt;render(cr, rect);
+    boxGadget-&gt;render(cr, rect);
+    FloatRect contentsRect;
+    buttonGadget-&gt;render(cr, rect, &amp;contentsRect);
+    buttonBoxGadget-&gt;render(cr, contentsRect);
+    arrowGadget-&gt;render(cr, contentsRect);
+    if (isFocused(renderObject))
+        buttonGadget-&gt;renderFocus(cr, rect);
+
+    return false;
+}
+#else
+LengthBox RenderThemeGtk::popupInternalPaddingBox(const RenderStyle&amp; style) const
+{
+    if (style.appearance() == NoControlPart)
</ins><span class="cx">         return { 0, 0, 0, 0 };
</span><span class="cx"> 
</span><span class="cx">     GRefPtr&lt;GtkStyleContext&gt; parentContext = createStyleContext(ComboBox);
</span><span class="lines">@@ -831,13 +934,8 @@
</span><span class="cx">     GRefPtr&lt;GtkStyleContext&gt; arrowStyleContext = createStyleContext(ComboBoxArrow, buttonStyleContext.get());
</span><span class="cx">     gtk_style_context_set_direction(arrowStyleContext.get(), direction);
</span><span class="cx"> 
</span><del>-#if GTK_CHECK_VERSION(3, 19, 2)
-    // arrow-scaling style property is now deprecated and ignored.
-    gfloat arrowScaling = 1.;
-#else
</del><span class="cx">     gfloat arrowScaling;
</span><span class="cx">     gtk_style_context_get_style(parentStyleContext.get(), &quot;arrow-scaling&quot;, &amp;arrowScaling, nullptr);
</span><del>-#endif
</del><span class="cx"> 
</span><span class="cx">     IntSize arrowSize(minArrowSize, innerRect.height());
</span><span class="cx">     FloatPoint arrowPosition(innerRect.location());
</span><span class="lines">@@ -854,14 +952,67 @@
</span><span class="cx"> 
</span><span class="cx">     return false;
</span><span class="cx"> }
</span><ins>+#endif // GTK_CHECK_VERSION(3, 20, 0)
</ins><span class="cx"> 
</span><span class="cx"> bool RenderThemeGtk::paintMenuListButtonDecorations(const RenderBox&amp; object, const PaintInfo&amp; info, const FloatRect&amp; rect)
</span><span class="cx"> {
</span><span class="cx">     return paintMenuList(object, info, rect);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#if GTK_CHECK_VERSION(3, 20, 0)
+void RenderThemeGtk::adjustTextFieldStyle(StyleResolver&amp;, RenderStyle&amp; style, Element* element) const
+{
+    if (!is&lt;HTMLInputElement&gt;(element) || !shouldHaveSpinButton(downcast&lt;HTMLInputElement&gt;(*element)))
+        return;
+
+    // Spinbuttons need a minimum height to be rendered correctly.
+    RenderThemeGadget::Info info = { RenderThemeGadget::Type::Generic, &quot;spinbutton&quot;, GTK_STATE_FLAG_NORMAL, { &quot;horizontal&quot; } };
+    auto spinbuttonGadget = RenderThemeGadget::create(info);
+    info.type = RenderThemeGadget::Type::TextField;
+    info.name = &quot;entry&quot;;
+    info.classList.clear();
+    auto entryGadget = RenderThemeGadget::create(info, spinbuttonGadget.get());
+    info.type = RenderThemeGadget::Type::Icon;
+    info.name = &quot;button&quot;;
+    info.classList.append(&quot;up&quot;);
+    auto buttonUpGadget = RenderThemeGadget::create(info, spinbuttonGadget.get());
+    static_cast&lt;RenderThemeIconGadget*&gt;(buttonUpGadget.get())-&gt;setIconSize(RenderThemeIconGadget::IconSizeGtk::Menu);
+    info.classList[0] = &quot;down&quot;;
+    auto buttonDownGadget = RenderThemeGadget::create(info, spinbuttonGadget.get());
+    static_cast&lt;RenderThemeIconGadget*&gt;(buttonDownGadget.get())-&gt;setIconSize(RenderThemeIconGadget::IconSizeGtk::Menu);
+    IntSize preferredSize = spinbuttonGadget-&gt;preferredSize();
+    preferredSize = preferredSize.expandedTo(entryGadget-&gt;preferredSize());
+    IntSize upPreferredSize = preferredSize.expandedTo(buttonUpGadget-&gt;preferredSize());
+    IntSize downPreferredSize = preferredSize.expandedTo(buttonDownGadget-&gt;preferredSize());
+    int height = std::max(upPreferredSize.height(), downPreferredSize.height());
+    style.setMinHeight(Length(height, Fixed));
+}
+
</ins><span class="cx"> bool RenderThemeGtk::paintTextField(const RenderObject&amp; renderObject, const PaintInfo&amp; paintInfo, const FloatRect&amp; rect)
</span><span class="cx"> {
</span><ins>+    RenderThemeGadget::Info info = { RenderThemeGadget::Type::TextField, &quot;entry&quot;, themePartStateFlags(*this, Entry, renderObject), { } };
+    std::unique_ptr&lt;RenderThemeGadget&gt; parentGadget;
+    if (is&lt;HTMLInputElement&gt;(renderObject.node()) &amp;&amp; shouldHaveSpinButton(downcast&lt;HTMLInputElement&gt;(*renderObject.node()))) {
+        info.name = &quot;spinbutton&quot;;
+        info.classList.append(&quot;horizontal&quot;);
+        parentGadget = RenderThemeTextFieldGadget::create(info);
+        info.name = &quot;entry&quot;;
+        info.classList.clear();
+    }
+
+    auto entryGadget = RenderThemeTextFieldGadget::create(info, parentGadget.get());
+    if (parentGadget)
+        parentGadget-&gt;render(paintInfo.context().platformContext()-&gt;cr(), rect);
+    entryGadget-&gt;render(paintInfo.context().platformContext()-&gt;cr(), rect);
+    return false;
+}
+#else
+void RenderThemeGtk::adjustTextFieldStyle(StyleResolver&amp;, RenderStyle&amp;, Element*) const
+{
+}
+
+bool RenderThemeGtk::paintTextField(const RenderObject&amp; renderObject, const PaintInfo&amp; paintInfo, const FloatRect&amp; rect)
+{
</ins><span class="cx">     GRefPtr&lt;GtkStyleContext&gt; context = createStyleContext(Entry);
</span><span class="cx">     gtk_style_context_set_direction(context.get(), static_cast&lt;GtkTextDirection&gt;(gtkTextDirection(renderObject.style().direction())));
</span><span class="cx"> 
</span><span class="lines">@@ -888,12 +1039,34 @@
</span><span class="cx"> 
</span><span class="cx">     return false;
</span><span class="cx"> }
</span><ins>+#endif
</ins><span class="cx"> 
</span><del>-bool RenderThemeGtk::paintTextArea(const RenderObject&amp; o, const PaintInfo&amp; i, const FloatRect&amp; r)
</del><ins>+#if GTK_CHECK_VERSION(3, 20, 0)
+static void adjustSearchFieldIconStyle(RenderThemePart themePart, RenderStyle&amp; style)
</ins><span class="cx"> {
</span><del>-    return paintTextField(o, i, r);
</del><ins>+    ASSERT(themePart == EntryIconLeft || themePart == EntryIconRight);
+    RenderThemeGadget::Info info = { RenderThemeGadget::Type::TextField, &quot;entry&quot;, GTK_STATE_FLAG_NORMAL, { } };
+    auto parentGadget = RenderThemeGadget::create(info);
+    info.type = RenderThemeGadget::Type::Icon;
+    info.name = &quot;image&quot;;
+    if (themePart == EntryIconLeft)
+        info.classList.append(&quot;left&quot;);
+    else
+        info.classList.append(&quot;right&quot;);
+    auto gadget = RenderThemeIconGadget::create(info, parentGadget.get());
+
+    // Get the icon size based on the font size.
+    static_cast&lt;RenderThemeIconGadget*&gt;(gadget.get())-&gt;setIconSize(style.fontSize());
+    IntSize preferredSize = gadget-&gt;preferredSize();
+    GtkBorder contentsBox = parentGadget-&gt;contentsBox();
+    if (themePart == EntryIconLeft)
+        preferredSize.expand(contentsBox.left, contentsBox.top + contentsBox.bottom);
+    else
+        preferredSize.expand(contentsBox.right, contentsBox.top + contentsBox.bottom);
+    style.setWidth(Length(preferredSize.width(), Fixed));
+    style.setHeight(Length(preferredSize.height(), Fixed));
</ins><span class="cx"> }
</span><del>-
</del><ins>+#else
</ins><span class="cx"> // Defined in GTK+ (gtk/gtkiconfactory.c)
</span><span class="cx"> static const gint gtkIconSizeMenu = 16;
</span><span class="cx"> static const gint gtkIconSizeSmallToolbar = 18;
</span><span class="lines">@@ -918,16 +1091,6 @@
</span><span class="cx">     return GTK_ICON_SIZE_DIALOG;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void RenderThemeGtk::adjustSearchFieldResultsButtonStyle(StyleResolver&amp; styleResolver, RenderStyle&amp; style, Element* e) const
-{
-    adjustSearchFieldCancelButtonStyle(styleResolver, style, e);
-}
-
-bool RenderThemeGtk::paintSearchFieldResultsButton(const RenderBox&amp; o, const PaintInfo&amp; i, const IntRect&amp; rect)
-{
-    return paintSearchFieldResultsDecorationPart(o, i, rect);
-}
-
</del><span class="cx"> static void adjustSearchFieldIconStyle(RenderThemePart themePart, RenderStyle&amp; style)
</span><span class="cx"> {
</span><span class="cx">     style.resetBorder();
</span><span class="lines">@@ -951,35 +1114,72 @@
</span><span class="cx">     style.setWidth(Length(width + (padding.left + padding.right), Fixed));
</span><span class="cx">     style.setHeight(Length(height + (padding.top + padding.bottom), Fixed));
</span><span class="cx"> }
</span><ins>+#endif
</ins><span class="cx"> 
</span><ins>+bool RenderThemeGtk::paintTextArea(const RenderObject&amp; o, const PaintInfo&amp; i, const FloatRect&amp; r)
+{
+    return paintTextField(o, i, r);
+}
+
+void RenderThemeGtk::adjustSearchFieldResultsButtonStyle(StyleResolver&amp; styleResolver, RenderStyle&amp; style, Element* e) const
+{
+    adjustSearchFieldCancelButtonStyle(styleResolver, style, e);
+}
+
+bool RenderThemeGtk::paintSearchFieldResultsButton(const RenderBox&amp; o, const PaintInfo&amp; i, const IntRect&amp; rect)
+{
+    return paintSearchFieldResultsDecorationPart(o, i, rect);
+}
+
</ins><span class="cx"> void RenderThemeGtk::adjustSearchFieldResultsDecorationPartStyle(StyleResolver&amp;, RenderStyle&amp; style, Element*) const
</span><span class="cx"> {
</span><span class="cx">     adjustSearchFieldIconStyle(EntryIconLeft, style);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static IntRect centerRectVerticallyInParentInputElement(const RenderObject&amp; renderObject, const IntRect&amp; rect)
</del><ins>+void RenderThemeGtk::adjustSearchFieldCancelButtonStyle(StyleResolver&amp;, RenderStyle&amp; style, Element*) const
</ins><span class="cx"> {
</span><del>-    if (!renderObject.node())
-        return IntRect();
</del><ins>+    adjustSearchFieldIconStyle(EntryIconRight, style);
+}
</ins><span class="cx"> 
</span><del>-    // Get the renderer of &lt;input&gt; element.
-    Node* input = renderObject.node()-&gt;shadowHost();
-    if (!input)
-        input = renderObject.node();
-    if (!is&lt;RenderBox&gt;(*input-&gt;renderer()))
-        return IntRect();
</del><ins>+#if GTK_CHECK_VERSION(3, 20, 0)
+static bool paintSearchFieldIcon(RenderThemeGtk* theme, RenderThemePart themePart, const RenderBox&amp; renderObject, const PaintInfo&amp; paintInfo, const IntRect&amp; rect)
+{
+    ASSERT(themePart == EntryIconLeft || themePart == EntryIconRight);
+    RenderThemeGadget::Info info = { RenderThemeGadget::Type::TextField, &quot;entry&quot;, themePartStateFlags(*theme, Entry, renderObject), { } };
+    auto parentGadget = RenderThemeGadget::create(info);
+    info.type = RenderThemeGadget::Type::Icon;
+    info.state = themePartStateFlags(*theme, themePart, renderObject);
+    info.name = &quot;image&quot;;
+    if (themePart == EntryIconLeft)
+        info.classList.append(&quot;left&quot;);
+    else
+        info.classList.append(&quot;right&quot;);
+    auto gadget = RenderThemeGadget::create(info, parentGadget.get());
+    auto* gadgetIcon = static_cast&lt;RenderThemeIconGadget*&gt;(gadget.get());
+    gadgetIcon-&gt;setIconSize(renderObject.style().fontSize());
+    if (themePart == EntryIconLeft)
+        gadgetIcon-&gt;setIconName(&quot;edit-find-symbolic&quot;);
+    else
+        gadgetIcon-&gt;setIconName(&quot;edit-clear-symbolic&quot;);
+    GtkBorder contentsBox = parentGadget-&gt;contentsBox();
+    IntRect iconRect = rect;
+    if (themePart == EntryIconLeft) {
+        iconRect.move(contentsBox.left, contentsBox.top);
+        iconRect.contract(contentsBox.left, contentsBox.top + contentsBox.bottom);
+    } else
+        iconRect.contract(contentsBox.right, contentsBox.top + contentsBox.bottom);
+    return !gadget-&gt;render(paintInfo.context().platformContext()-&gt;cr(), iconRect);
+}
+bool RenderThemeGtk::paintSearchFieldResultsDecorationPart(const RenderBox&amp; renderObject, const PaintInfo&amp; paintInfo, const IntRect&amp; rect)
+{
+    return paintSearchFieldIcon(this, EntryIconLeft, renderObject, paintInfo, rect);
+}
</ins><span class="cx"> 
</span><del>-    // 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 = downcast&lt;RenderBox&gt;(*input-&gt;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;
</del><ins>+bool RenderThemeGtk::paintSearchFieldCancelButton(const RenderBox&amp; renderObject, const PaintInfo&amp; paintInfo, const IntRect&amp; rect)
+{
+    return paintSearchFieldIcon(this, EntryIconRight, renderObject, paintInfo, rect);
</ins><span class="cx"> }
</span><del>-
</del><ins>+#else
</ins><span class="cx"> static bool paintIcon(GtkStyleContext* context, GraphicsContext&amp; graphicsContext, const IntRect&amp; rect, const char* iconName)
</span><span class="cx"> {
</span><span class="cx">     GRefPtr&lt;GdkPixbuf&gt; icon = loadThemedIcon(context, iconName, getIconSizeForPixelSize(rect.height()));
</span><span class="lines">@@ -1002,6 +1202,29 @@
</span><span class="cx">     return paintIcon(context.get(), graphicsContext, rect, iconName);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static IntRect centerRectVerticallyInParentInputElement(const RenderObject&amp; renderObject, const IntRect&amp; rect)
+{
+    if (!renderObject.node())
+        return IntRect();
+
+    // Get the renderer of &lt;input&gt; element.
+    Node* input = renderObject.node()-&gt;shadowHost();
+    if (!input)
+        input = renderObject.node();
+    if (!is&lt;RenderBox&gt;(*input-&gt;renderer()))
+        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 = downcast&lt;RenderBox&gt;(*input-&gt;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;
+}
+
</ins><span class="cx"> bool RenderThemeGtk::paintSearchFieldResultsDecorationPart(const RenderBox&amp; renderObject, const PaintInfo&amp; paintInfo, const IntRect&amp; rect)
</span><span class="cx"> {
</span><span class="cx">     IntRect iconRect = centerRectVerticallyInParentInputElement(renderObject, rect);
</span><span class="lines">@@ -1012,11 +1235,6 @@
</span><span class="cx">         gtkIconStateFlags(this, renderObject));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void RenderThemeGtk::adjustSearchFieldCancelButtonStyle(StyleResolver&amp;, RenderStyle&amp; style, Element*) const
-{
-    adjustSearchFieldIconStyle(EntryIconRight, style);
-}
-
</del><span class="cx"> bool RenderThemeGtk::paintSearchFieldCancelButton(const RenderBox&amp; renderObject, const PaintInfo&amp; paintInfo, const IntRect&amp; rect)
</span><span class="cx"> {
</span><span class="cx">     IntRect iconRect = centerRectVerticallyInParentInputElement(renderObject, rect);
</span><span class="lines">@@ -1026,6 +1244,7 @@
</span><span class="cx">     return !paintEntryIcon(EntryIconRight, &quot;edit-clear-symbolic&quot;, paintInfo.context(), iconRect, gtkTextDirection(renderObject.style().direction()),
</span><span class="cx">         gtkIconStateFlags(this, renderObject));
</span><span class="cx"> }
</span><ins>+#endif // GTK_CHECK_VERSION(3, 20, 0)
</ins><span class="cx"> 
</span><span class="cx"> void RenderThemeGtk::adjustSearchFieldStyle(StyleResolver&amp;, RenderStyle&amp; style, Element*) const
</span><span class="cx"> {
</span><span class="lines">@@ -1055,19 +1274,167 @@
</span><span class="cx">     style.setBoxShadow(nullptr);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#if GTK_CHECK_VERSION(3, 20, 0)
+/*
+ * GtkScale
+ *
+ * scale
+ * ╰── contents
+ *     ╰── trough
+ *         ├── slider
+ *         ╰── [highlight]
+ */
</ins><span class="cx"> bool RenderThemeGtk::paintSliderTrack(const RenderObject&amp; renderObject, const PaintInfo&amp; paintInfo, const IntRect&amp; rect)
</span><span class="cx"> {
</span><span class="cx">     ControlPart part = renderObject.style().appearance();
</span><span class="cx">     ASSERT(part == SliderHorizontalPart || part == SliderVerticalPart);
</span><span class="cx"> 
</span><ins>+    RenderThemeGadget::Info info = { RenderThemeGadget::Type::Generic, &quot;scale&quot;, themePartStateFlags(*this, Scale, renderObject), { } };
+    if (part == SliderHorizontalPart)
+        info.classList.append(&quot;horizontal&quot;);
+    else
+        info.classList.append(&quot;vertical&quot;);
+    auto scaleGadget = RenderThemeGadget::create(info);
+    info.name = &quot;contents&quot;;
+    info.classList.clear();
+    auto contentsGadget = RenderThemeGadget::create(info, scaleGadget.get());
+    info.name = &quot;trough&quot;;
+    auto troughGadget = RenderThemeGadget::create(info, contentsGadget.get());
+    info.name = &quot;slider&quot;;
+    auto sliderGadget = RenderThemeGadget::create(info, troughGadget.get());
+    info.name = &quot;highlight&quot;;
+    auto highlightGadget = RenderThemeGadget::create(info, troughGadget.get());
+
+    // The given rectangle is not calculated based on the scale size, but all the margins and paddings are based on it.
+    IntSize preferredSize = scaleGadget-&gt;preferredSize();
+    preferredSize = preferredSize.expandedTo(contentsGadget-&gt;preferredSize());
+    preferredSize = preferredSize.expandedTo(troughGadget-&gt;preferredSize());
+    FloatRect trackRect = rect;
+    if (part == SliderHorizontalPart) {
+        trackRect.move(0, rect.height() / 2 - (preferredSize.height() / 2));
+        trackRect.setHeight(preferredSize.height());
+    } else {
+        trackRect.move(rect.width() / 2 - (preferredSize.width() / 2), 0);
+        trackRect.setWidth(preferredSize.width());
+    }
+
+    FloatRect contentsRect;
+    scaleGadget-&gt;render(paintInfo.context().platformContext()-&gt;cr(), trackRect, &amp;contentsRect);
+    contentsGadget-&gt;render(paintInfo.context().platformContext()-&gt;cr(), contentsRect, &amp;contentsRect);
+    // Scale trough defines its size querying slider and highlight.
+    if (part == SliderHorizontalPart)
+        contentsRect.setHeight(troughGadget-&gt;preferredSize().height() + std::max(sliderGadget-&gt;preferredSize().height(), highlightGadget-&gt;preferredSize().height()));
+    else
+        contentsRect.setWidth(troughGadget-&gt;preferredSize().width() + std::max(sliderGadget-&gt;preferredSize().width(), highlightGadget-&gt;preferredSize().width()));
+    FloatRect troughRect = contentsRect;
+    troughGadget-&gt;render(paintInfo.context().platformContext()-&gt;cr(), troughRect, &amp;contentsRect);
+    if (isFocused(renderObject))
+        troughGadget-&gt;renderFocus(paintInfo.context().platformContext()-&gt;cr(), troughRect);
+
+    LayoutPoint thumbLocation;
+    if (is&lt;HTMLInputElement&gt;(renderObject.node())) {
+        auto&amp; input = downcast&lt;HTMLInputElement&gt;(*renderObject.node());
+        if (auto* element = input.sliderThumbElement())
+            thumbLocation = element-&gt;renderBox()-&gt;location();
+    }
+
+    if (part == SliderHorizontalPart) {
+        if (renderObject.style().direction() == RTL) {
+            contentsRect.move(thumbLocation.x(), 0);
+            contentsRect.setWidth(contentsRect.width() - thumbLocation.x());
+        } else
+            contentsRect.setWidth(thumbLocation.x());
+    } else
+        contentsRect.setHeight(thumbLocation.y());
+    highlightGadget-&gt;render(paintInfo.context().platformContext()-&gt;cr(), contentsRect);
+
+    return false;
+}
+
+void RenderThemeGtk::adjustSliderThumbSize(RenderStyle&amp; style, Element*) const
+{
+    ControlPart part = style.appearance();
+    if (part != SliderThumbHorizontalPart &amp;&amp; part != SliderThumbVerticalPart)
+        return;
+
+    RenderThemeGadget::Info info = { RenderThemeGadget::Type::Generic, &quot;scale&quot;, GTK_STATE_FLAG_NORMAL, { } };
+    if (part == SliderHorizontalPart)
+        info.classList.append(&quot;horizontal&quot;);
+    else
+        info.classList.append(&quot;vertical&quot;);
+    auto scaleGadget = RenderThemeGadget::create(info);
+    info.name = &quot;contents&quot;;
+    info.classList.clear();
+    auto contentsGadget = RenderThemeGadget::create(info, scaleGadget.get());
+    info.name = &quot;trough&quot;;
+    auto troughGadget = RenderThemeGadget::create(info, contentsGadget.get());
+    info.name = &quot;slider&quot;;
+    auto sliderGadget = RenderThemeGadget::create(info, troughGadget.get());
+    info.name = &quot;highlight&quot;;
+    auto highlightGadget = RenderThemeGadget::create(info, troughGadget.get());
+
+    IntSize preferredSize = scaleGadget-&gt;preferredSize();
+    preferredSize = preferredSize.expandedTo(contentsGadget-&gt;preferredSize());
+    preferredSize = preferredSize.expandedTo(troughGadget-&gt;preferredSize());
+    preferredSize = preferredSize.expandedTo(sliderGadget-&gt;preferredSize());
+    if (part == SliderThumbHorizontalPart) {
+        style.setWidth(Length(preferredSize.width(), Fixed));
+        style.setHeight(Length(preferredSize.height(), Fixed));
+        return;
+    }
+    ASSERT(part == SliderThumbVerticalPart);
+    style.setWidth(Length(preferredSize.height(), Fixed));
+    style.setHeight(Length(preferredSize.width(), Fixed));
+}
+
+bool RenderThemeGtk::paintSliderThumb(const RenderObject&amp; renderObject, const PaintInfo&amp; paintInfo, const IntRect&amp; rect)
+{
+    ControlPart part = renderObject.style().appearance();
+    ASSERT(part == SliderThumbHorizontalPart || part == SliderThumbVerticalPart);
+
+    RenderThemeGadget::Info info = { RenderThemeGadget::Type::Generic, &quot;scale&quot;, themePartStateFlags(*this, Scale, renderObject), { } };
+    if (part == SliderHorizontalPart)
+        info.classList.append(&quot;horizontal&quot;);
+    else
+        info.classList.append(&quot;vertical&quot;);
+    auto scaleGadget = RenderThemeGadget::create(info);
+    info.name = &quot;contents&quot;;
+    info.classList.clear();
+    auto contentsGadget = RenderThemeGadget::create(info, scaleGadget.get());
+    info.name = &quot;trough&quot;;
+    auto troughGadget = RenderThemeGadget::create(info, contentsGadget.get());
+    info.name = &quot;slider&quot;;
+    info.state = themePartStateFlags(*this, ScaleSlider, renderObject);
+    auto sliderGadget = RenderThemeGadget::create(info, troughGadget.get());
+    info.name = &quot;highlight&quot;;
+    auto highlightGadget = RenderThemeGadget::create(info, troughGadget.get());
+
+    GtkBorder scaleContentsBox = scaleGadget-&gt;contentsBox();
+    GtkBorder contentsContentsBox = contentsGadget-&gt;contentsBox();
+    GtkBorder troughContentsBox = troughGadget-&gt;contentsBox();
+    GtkBorder padding;
+    padding.left = scaleContentsBox.left + contentsContentsBox.left + troughContentsBox.left;
+    padding.right = scaleContentsBox.right + contentsContentsBox.right + troughContentsBox.right;
+    padding.top = scaleContentsBox.top + contentsContentsBox.top + troughContentsBox.top;
+    padding.bottom = scaleContentsBox.bottom + contentsContentsBox.bottom + troughContentsBox.bottom;
+
+    // Scale trough defines its size querying slider and highlight.
+    int troughHeight = troughGadget-&gt;preferredSize().height() + std::max(sliderGadget-&gt;preferredSize().height(), highlightGadget-&gt;preferredSize().height());
+    IntRect sliderRect(rect.location(), IntSize(troughHeight, troughHeight));
+    sliderRect.move(padding.left, padding.top);
+    sliderRect.contract(padding.left + padding.right, padding.top + padding.bottom);
+    sliderGadget-&gt;render(paintInfo.context().platformContext()-&gt;cr(), sliderRect);
+    return false;
+}
+#else
+bool RenderThemeGtk::paintSliderTrack(const RenderObject&amp; renderObject, const PaintInfo&amp; paintInfo, const IntRect&amp; rect)
+{
+    ControlPart part = renderObject.style().appearance();
+    ASSERT(part == SliderHorizontalPart || part == SliderVerticalPart);
+
</ins><span class="cx">     GRefPtr&lt;GtkStyleContext&gt; parentContext = createStyleContext(Scale);
</span><span class="cx">     gtk_style_context_add_class(parentContext.get(), part == SliderHorizontalPart ? GTK_STYLE_CLASS_HORIZONTAL : GTK_STYLE_CLASS_VERTICAL);
</span><del>-#if GTK_CHECK_VERSION(3, 19, 11)
-    GRefPtr&lt;GtkStyleContext&gt; contentsContext = createStyleContext(ScaleContents, parentContext.get());
-    GRefPtr&lt;GtkStyleContext&gt; context = createStyleContext(ScaleTrough, contentsContext.get());
-#else
</del><span class="cx">     GRefPtr&lt;GtkStyleContext&gt; context = createStyleContext(ScaleTrough, parentContext.get());
</span><del>-#endif
</del><span class="cx">     gtk_style_context_set_direction(context.get(), gtkTextDirection(renderObject.style().direction()));
</span><span class="cx"> 
</span><span class="cx">     if (!isEnabled(renderObject))
</span><span class="lines">@@ -1091,25 +1458,6 @@
</span><span class="cx">     gtk_render_background(context.get(), paintInfo.context().platformContext()-&gt;cr(), sliderRect.x(), sliderRect.y(), sliderRect.width(), sliderRect.height());
</span><span class="cx">     gtk_render_frame(context.get(), paintInfo.context().platformContext()-&gt;cr(), sliderRect.x(), sliderRect.y(), sliderRect.width(), sliderRect.height());
</span><span class="cx"> 
</span><del>-#if GTK_CHECK_VERSION(3, 19, 11)
-    GRefPtr&lt;GtkStyleContext&gt; highlightContext = createStyleContext(ScaleHighlight, context.get());
-    LayoutPoint thumbLocation;
-    if (is&lt;HTMLInputElement&gt;(renderObject.node())) {
-        auto&amp; input = downcast&lt;HTMLInputElement&gt;(*renderObject.node());
-        if (auto* element = input.sliderThumbElement())
-            thumbLocation = element-&gt;renderBox()-&gt;location();
-    }
-
-    IntRect highlightRect = sliderRect;
-    if (part == SliderHorizontalPart)
-        highlightRect.setWidth(thumbLocation.x());
-    else
-        highlightRect.setHeight(thumbLocation.y());
-
-    gtk_render_background(highlightContext.get(), paintInfo.context().platformContext()-&gt;cr(), highlightRect.x(), highlightRect.y(), highlightRect.width(), highlightRect.height());
-    gtk_render_frame(highlightContext.get(), paintInfo.context().platformContext()-&gt;cr(), highlightRect.x(), highlightRect.y(), highlightRect.width(), highlightRect.height());
-#endif
-
</del><span class="cx">     if (isFocused(renderObject)) {
</span><span class="cx">         gint focusWidth, focusPad;
</span><span class="cx">         gtk_style_context_get_style(context.get(), &quot;focus-line-width&quot;, &amp;focusWidth, &quot;focus-padding&quot;, &amp;focusPad, nullptr);
</span><span class="lines">@@ -1121,6 +1469,26 @@
</span><span class="cx">     return false;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void RenderThemeGtk::adjustSliderThumbSize(RenderStyle&amp; style, Element*) const
+{
+    ControlPart part = style.appearance();
+    if (part != SliderThumbHorizontalPart &amp;&amp; part != SliderThumbVerticalPart)
+        return;
+
+    GRefPtr&lt;GtkStyleContext&gt; context = createStyleContext(Scale);
+    gint sliderWidth, sliderLength;
+    gtk_style_context_get_style(context.get(), &quot;slider-width&quot;, &amp;sliderWidth, &quot;slider-length&quot;, &amp;sliderLength, nullptr);
+
+    if (part == SliderThumbHorizontalPart) {
+        style.setWidth(Length(sliderLength, Fixed));
+        style.setHeight(Length(sliderWidth, Fixed));
+        return;
+    }
+    ASSERT(part == SliderThumbVerticalPart);
+    style.setWidth(Length(sliderWidth, Fixed));
+    style.setHeight(Length(sliderLength, Fixed));
+}
+
</ins><span class="cx"> bool RenderThemeGtk::paintSliderThumb(const RenderObject&amp; renderObject, const PaintInfo&amp; paintInfo, const IntRect&amp; rect)
</span><span class="cx"> {
</span><span class="cx">     ControlPart part = renderObject.style().appearance();
</span><span class="lines">@@ -1129,12 +1497,7 @@
</span><span class="cx">     // FIXME: The entire slider is too wide, stretching the thumb into an oval rather than a circle.
</span><span class="cx">     GRefPtr&lt;GtkStyleContext&gt; parentContext = createStyleContext(Scale);
</span><span class="cx">     gtk_style_context_add_class(parentContext.get(), part == SliderThumbHorizontalPart ? GTK_STYLE_CLASS_HORIZONTAL : GTK_STYLE_CLASS_VERTICAL);
</span><del>-#if GTK_CHECK_VERSION(3, 19, 11)
-    GRefPtr&lt;GtkStyleContext&gt; contentsContext = createStyleContext(ScaleContents, parentContext.get());
-    GRefPtr&lt;GtkStyleContext&gt; troughContext = createStyleContext(ScaleTrough, contentsContext.get());
-#else
</del><span class="cx">     GRefPtr&lt;GtkStyleContext&gt; troughContext = createStyleContext(ScaleTrough, parentContext.get());
</span><del>-#endif
</del><span class="cx">     GRefPtr&lt;GtkStyleContext&gt; context = createStyleContext(ScaleSlider, troughContext.get());
</span><span class="cx">     gtk_style_context_set_direction(context.get(), gtkTextDirection(renderObject.style().direction()));
</span><span class="cx"> 
</span><span class="lines">@@ -1152,35 +1515,60 @@
</span><span class="cx"> 
</span><span class="cx">     return false;
</span><span class="cx"> }
</span><ins>+#endif
</ins><span class="cx"> 
</span><del>-void RenderThemeGtk::adjustSliderThumbSize(RenderStyle&amp; style, Element*) const
</del><ins>+#if GTK_CHECK_VERSION(3, 20, 0)
+IntRect RenderThemeGtk::progressBarRectForBounds(const RenderObject&amp; renderObject, const IntRect&amp; bounds) const
</ins><span class="cx"> {
</span><del>-    ControlPart part = style.appearance();
-    if (part != SliderThumbHorizontalPart &amp;&amp; part != SliderThumbVerticalPart)
-        return;
</del><ins>+    RenderThemeGadget::Info info = { RenderThemeGadget::Type::Generic, &quot;progressbar&quot;, GTK_STATE_FLAG_NORMAL, { &quot;horizontal&quot; } };
+    auto progressBarGadget = RenderThemeGadget::create(info);
+    info.name = &quot;trough&quot;;
+    info.classList.clear();
+    auto troughGadget = RenderThemeGadget::create(info, progressBarGadget.get());
+    info.name = &quot;progress&quot;;
+    if (renderObject.style().direction() == RTL)
+        info.classList.append(&quot;right&quot;);
+    else
+        info.classList.append(&quot;left&quot;);
+    const auto&amp; renderProgress = downcast&lt;RenderProgress&gt;(renderObject);
+    if (renderProgress.isDeterminate())
+        info.classList.append(&quot;pulse&quot;);
+    auto progressGadget = RenderThemeGadget::create(info, troughGadget.get());
+    IntSize preferredSize = progressBarGadget-&gt;preferredSize();
+    preferredSize = preferredSize.expandedTo(troughGadget-&gt;preferredSize());
+    preferredSize = preferredSize.expandedTo(progressGadget-&gt;preferredSize());
+    return IntRect(bounds.x(), bounds.y(), bounds.width(), preferredSize.height());
+}
</ins><span class="cx"> 
</span><del>-    GRefPtr&lt;GtkStyleContext&gt; context = createStyleContext(Scale);
-    gint sliderWidth, sliderLength;
-#if GTK_CHECK_VERSION(3, 19, 11)
-    GRefPtr&lt;GtkStyleContext&gt; contentsContext = createStyleContext(ScaleContents, context.get());
-    GRefPtr&lt;GtkStyleContext&gt; troughContext = createStyleContext(ScaleTrough, contentsContext.get());
-    GRefPtr&lt;GtkStyleContext&gt; sliderContext = createStyleContext(ScaleSlider, troughContext.get());
-    gtk_style_context_get(sliderContext.get(), gtk_style_context_get_state(sliderContext.get()), &quot;min-width&quot;, &amp;sliderWidth, &quot;min-height&quot;, &amp;sliderLength, nullptr);
-    GtkBorder border;
-    gtk_style_context_get_border(sliderContext.get(), gtk_style_context_get_state(sliderContext.get()), &amp;border);
-    sliderWidth += border.left + border.right;
-    sliderLength += border.top + border.bottom;
</del><ins>+bool RenderThemeGtk::paintProgressBar(const RenderObject&amp; renderObject, const PaintInfo&amp; paintInfo, const IntRect&amp; rect)
+{
+    if (!renderObject.isProgress())
+        return true;
+
+    RenderThemeGadget::Info info = { RenderThemeGadget::Type::Generic, &quot;progressbar&quot;, GTK_STATE_FLAG_NORMAL, { &quot;horizontal&quot; } };
+    auto progressBarGadget = RenderThemeGadget::create(info);
+    info.name = &quot;trough&quot;;
+    info.classList.clear();
+    auto troughGadget = RenderThemeGadget::create(info, progressBarGadget.get());
+    info.name = &quot;progress&quot;;
+    if (renderObject.style().direction() == RTL)
+        info.classList.append(&quot;right&quot;);
+    else
+        info.classList.append(&quot;left&quot;);
+    const auto&amp; renderProgress = downcast&lt;RenderProgress&gt;(renderObject);
+    if (renderProgress.isDeterminate())
+        info.classList.append(&quot;pulse&quot;);
+    auto progressGadget = RenderThemeGadget::create(info, troughGadget.get());
+
+    progressBarGadget-&gt;render(paintInfo.context().platformContext()-&gt;cr(), rect);
+    troughGadget-&gt;render(paintInfo.context().platformContext()-&gt;cr(), rect);
+    progressGadget-&gt;render(paintInfo.context().platformContext()-&gt;cr(), calculateProgressRect(renderObject, rect));
+    return false;
+}
</ins><span class="cx"> #else
</span><del>-    gtk_style_context_get_style(context.get(), &quot;slider-width&quot;, &amp;sliderWidth, &quot;slider-length&quot;, &amp;sliderLength, nullptr);
-#endif
-    if (part == SliderThumbHorizontalPart) {
-        style.setWidth(Length(sliderLength, Fixed));
-        style.setHeight(Length(sliderWidth, Fixed));
-        return;
-    }
-    ASSERT(part == SliderThumbVerticalPart);
-    style.setWidth(Length(sliderWidth, Fixed));
-    style.setHeight(Length(sliderLength, Fixed));
</del><ins>+IntRect RenderThemeGtk::progressBarRectForBounds(const RenderObject&amp;, const IntRect&amp; bounds) const
+{
+    return bounds;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool RenderThemeGtk::paintProgressBar(const RenderObject&amp; renderObject, const PaintInfo&amp; paintInfo, const IntRect&amp; rect)
</span><span class="lines">@@ -1217,7 +1605,79 @@
</span><span class="cx"> 
</span><span class="cx">     return false;
</span><span class="cx"> }
</span><ins>+#endif // GTK_CHECK_VERSION(3, 20, 0)
</ins><span class="cx"> 
</span><ins>+#if GTK_CHECK_VERSION(3, 20, 0)
+RenderTheme::InnerSpinButtonLayout RenderThemeGtk::innerSpinButtonLayout(const RenderObject&amp; renderObject) const
+{
+    return renderObject.style().direction() == RTL ? InnerSpinButtonLayout::HorizontalUpLeft : InnerSpinButtonLayout::HorizontalUpRight;
+}
+
+void RenderThemeGtk::adjustInnerSpinButtonStyle(StyleResolver&amp;, RenderStyle&amp; style, Element*) const
+{
+    RenderThemeGadget::Info info = { RenderThemeGadget::Type::Generic, &quot;spinbutton&quot;, GTK_STATE_FLAG_NORMAL, { &quot;horizontal&quot; } };
+    auto spinbuttonGadget = RenderThemeGadget::create(info);
+    info.type = RenderThemeGadget::Type::TextField;
+    info.name = &quot;entry&quot;;
+    info.classList.clear();
+    auto entryGadget = RenderThemeGadget::create(info, spinbuttonGadget.get());
+    info.type = RenderThemeGadget::Type::Icon;
+    info.name = &quot;button&quot;;
+    info.classList.append(&quot;up&quot;);
+    auto buttonUpGadget = RenderThemeGadget::create(info, spinbuttonGadget.get());
+    static_cast&lt;RenderThemeIconGadget*&gt;(buttonUpGadget.get())-&gt;setIconSize(RenderThemeIconGadget::IconSizeGtk::Menu);
+    info.classList[0] = &quot;down&quot;;
+    auto buttonDownGadget = RenderThemeGadget::create(info, spinbuttonGadget.get());
+    static_cast&lt;RenderThemeIconGadget*&gt;(buttonDownGadget.get())-&gt;setIconSize(RenderThemeIconGadget::IconSizeGtk::Menu);
+    IntSize upPreferredSize = buttonUpGadget-&gt;preferredSize();
+    IntSize downPreferredSize = buttonDownGadget-&gt;preferredSize();
+    int buttonSize = std::max(std::max(upPreferredSize.width(), downPreferredSize.width()), std::max(upPreferredSize.height(), downPreferredSize.height()));
+    style.setWidth(Length(buttonSize * 2, Fixed));
+    style.setHeight(Length(buttonSize, Fixed));
+}
+
+bool RenderThemeGtk::paintInnerSpinButton(const RenderObject&amp; renderObject, const PaintInfo&amp; paintInfo, const IntRect&amp; rect)
+{
+    RenderThemeGadget::Info info = { RenderThemeGadget::Type::Generic, &quot;spinbutton&quot;, themePartStateFlags(*this, SpinButton, renderObject), { } };
+    auto spinbuttonGadget = RenderThemeGadget::create(info);
+    info.type = RenderThemeGadget::Type::TextField;
+    info.name = &quot;entry&quot;;
+    info.classList.clear();
+    auto entryGadget = RenderThemeGadget::create(info, spinbuttonGadget.get());
+    info.type = RenderThemeGadget::Type::Icon;
+    info.name = &quot;button&quot;;
+    info.classList.append(&quot;up&quot;);
+    info.state = themePartStateFlags(*this, SpinButtonUpButton, renderObject);
+    auto buttonUpGadget = RenderThemeGadget::create(info, spinbuttonGadget.get());
+    auto* gadgetIcon = static_cast&lt;RenderThemeIconGadget*&gt;(buttonUpGadget.get());
+    gadgetIcon-&gt;setIconSize(RenderThemeIconGadget::IconSizeGtk::Menu);
+    gadgetIcon-&gt;setIconName(&quot;list-add-symbolic&quot;);
+    info.classList[0] = &quot;down&quot;;
+    info.state = themePartStateFlags(*this, SpinButtonDownButton, renderObject);
+    auto buttonDownGadget = RenderThemeGadget::create(info, spinbuttonGadget.get());
+    gadgetIcon = static_cast&lt;RenderThemeIconGadget*&gt;(buttonDownGadget.get());
+    gadgetIcon-&gt;setIconSize(RenderThemeIconGadget::IconSizeGtk::Menu);
+    gadgetIcon-&gt;setIconName(&quot;list-remove-symbolic&quot;);
+
+    IntRect iconRect = rect;
+    iconRect.setWidth(iconRect.width() / 2);
+    if (renderObject.style().direction() == RTL)
+        buttonUpGadget-&gt;render(paintInfo.context().platformContext()-&gt;cr(), iconRect);
+    else
+        buttonDownGadget-&gt;render(paintInfo.context().platformContext()-&gt;cr(), iconRect);
+    iconRect.move(iconRect.width(), 0);
+    if (renderObject.style().direction() == RTL)
+        buttonDownGadget-&gt;render(paintInfo.context().platformContext()-&gt;cr(), iconRect);
+    else
+        buttonUpGadget-&gt;render(paintInfo.context().platformContext()-&gt;cr(), iconRect);
+
+    return false;
+}
+#else
+RenderTheme::InnerSpinButtonLayout RenderThemeGtk::innerSpinButtonLayout(const RenderObject&amp;) const
+{
+    return InnerSpinButtonLayout::Vertical;
+}
</ins><span class="cx"> static gint spinButtonArrowSize(GtkStyleContext* context)
</span><span class="cx"> {
</span><span class="cx">     PangoFontDescription* fontDescription;
</span><span class="lines">@@ -1320,6 +1780,7 @@
</span><span class="cx"> 
</span><span class="cx">     return false;
</span><span class="cx"> }
</span><ins>+#endif // GTK_CHECK_VERSION(3, 20, 0)
</ins><span class="cx"> 
</span><span class="cx"> double RenderThemeGtk::caretBlinkInterval() const
</span><span class="cx"> {
</span><span class="lines">@@ -1338,16 +1799,44 @@
</span><span class="cx"> 
</span><span class="cx"> enum StyleColorType { StyleColorBackground, StyleColorForeground };
</span><span class="cx"> 
</span><ins>+#if GTK_CHECK_VERSION(3, 20, 0)
</ins><span class="cx"> static Color styleColor(RenderThemePart themePart, GtkStateFlags state, StyleColorType colorType)
</span><span class="cx"> {
</span><del>-    GRefPtr&lt;GtkStyleContext&gt; parentContext;
</del><ins>+    RenderThemeGadget::Info info = { RenderThemeGadget::Type::Generic, nullptr, state, { } };
+    std::unique_ptr&lt;RenderThemeGadget&gt; parentGadget;
</ins><span class="cx">     RenderThemePart part = themePart;
</span><span class="cx">     if (themePart == Entry &amp;&amp; (state &amp; GTK_STATE_FLAG_SELECTED)) {
</span><del>-        parentContext = createStyleContext(Entry);
</del><ins>+        info.name = &quot;entry&quot;;
+        parentGadget = RenderThemeGadget::create(info);
</ins><span class="cx">         part = EntrySelection;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    GRefPtr&lt;GtkStyleContext&gt; context = createStyleContext(part, parentContext.get());
</del><ins>+    switch (part) {
+    case Entry:
+        info.name = &quot;entry&quot;;
+        break;
+    case EntrySelection:
+        info.name = &quot;selection&quot;;
+        break;
+    case ListBox:
+        info.name = &quot;treeview&quot;;
+        info.classList.append(&quot;view&quot;);
+        break;
+    case Button:
+        info.name = &quot;button&quot;;
+        break;
+    default:
+        ASSERT_NOT_REACHED();
+        info.name = &quot;entry&quot;;
+    }
+
+    auto gadget = RenderThemeGadget::create(info, parentGadget.get());
+    return colorType == StyleColorBackground ? gadget-&gt;backgroundColor() : gadget-&gt;color();
+}
+#else
+static Color styleColor(RenderThemePart themePart, GtkStateFlags state, StyleColorType colorType)
+{
+    GRefPtr&lt;GtkStyleContext&gt; context = createStyleContext(themePart);
</ins><span class="cx">     gtk_style_context_set_state(context.get(), state);
</span><span class="cx"> 
</span><span class="cx">     GdkRGBA gdkRGBAColor;
</span><span class="lines">@@ -1357,6 +1846,7 @@
</span><span class="cx">         gtk_style_context_get_color(context.get(), state, &amp;gdkRGBAColor);
</span><span class="cx">     return gdkRGBAColor;
</span><span class="cx"> }
</span><ins>+#endif // GTK_CHECK_VERSION(3, 20, 0)
</ins><span class="cx"> 
</span><span class="cx"> Color RenderThemeGtk::platformActiveSelectionBackgroundColor() const
</span><span class="cx"> {
</span><span class="lines">@@ -1428,8 +1918,19 @@
</span><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+#if GTK_CHECK_VERSION(3, 20, 0)
</ins><span class="cx"> bool RenderThemeGtk::paintMediaButton(const RenderObject&amp; renderObject, GraphicsContext&amp; graphicsContext, const IntRect&amp; rect, const char* iconName)
</span><span class="cx"> {
</span><ins>+    RenderThemeGadget::Info info = { RenderThemeGadget::Type::Icon, &quot;image&quot;, themePartStateFlags(*this, MediaButton, renderObject), { } };
+    auto gadget = RenderThemeGadget::create(info);
+    auto* gadgetIcon = static_cast&lt;RenderThemeIconGadget*&gt;(gadget.get());
+    gadgetIcon-&gt;setIconSize(RenderThemeIconGadget::IconSizeGtk::Menu);
+    gadgetIcon-&gt;setIconName(iconName);
+    return !gadget-&gt;render(graphicsContext.platformContext()-&gt;cr(), rect);
+}
+#else
+bool RenderThemeGtk::paintMediaButton(const RenderObject&amp; renderObject, GraphicsContext&amp; graphicsContext, const IntRect&amp; rect, const char* iconName)
+{
</ins><span class="cx">     GRefPtr&lt;GtkStyleContext&gt; context = createStyleContext(MediaButton);
</span><span class="cx">     gtk_style_context_set_direction(context.get(), gtkTextDirection(renderObject.style().direction()));
</span><span class="cx">     gtk_style_context_set_state(context.get(), gtkIconStateFlags(this, renderObject));
</span><span class="lines">@@ -1437,6 +1938,7 @@
</span><span class="cx">     IntRect iconRect(rect.x() + (rect.width() - mediaIconSize) / 2, rect.y() + (rect.height() - mediaIconSize) / 2, mediaIconSize, mediaIconSize);
</span><span class="cx">     return !paintIcon(context.get(), graphicsContext, iconRect, iconName);
</span><span class="cx"> }
</span><ins>+#endif // GTK_CHECK_VERSION(3, 20, 0)
</ins><span class="cx"> 
</span><span class="cx"> bool RenderThemeGtk::hasOwnDisabledStateHandlingFor(ControlPart part) const
</span><span class="cx"> {
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceWebCorerenderingRenderThemeGtkh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/WebCore/rendering/RenderThemeGtk.h (199475 => 199476)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/WebCore/rendering/RenderThemeGtk.h        2016-04-13 13:40:11 UTC (rev 199475)
+++ releases/WebKitGTK/webkit-2.12/Source/WebCore/rendering/RenderThemeGtk.h        2016-04-13 13:40:36 UTC (rev 199476)
</span><span class="lines">@@ -105,6 +105,7 @@
</span><span class="cx">     virtual bool shouldHaveCapsLockIndicator(HTMLInputElement&amp;) const override;
</span><span class="cx"> 
</span><span class="cx"> private:
</span><ins>+    RenderThemeGtk();
</ins><span class="cx">     virtual ~RenderThemeGtk();
</span><span class="cx"> 
</span><span class="cx">     virtual bool paintCheckbox(const RenderObject&amp;, const PaintInfo&amp;, const IntRect&amp;) override;
</span><span class="lines">@@ -116,8 +117,9 @@
</span><span class="cx">     virtual void adjustButtonStyle(StyleResolver&amp;, RenderStyle&amp;, Element*) const override;
</span><span class="cx">     virtual bool paintButton(const RenderObject&amp;, const PaintInfo&amp;, const IntRect&amp;) override;
</span><span class="cx"> 
</span><del>-    virtual bool paintTextField(const RenderObject&amp;, const PaintInfo&amp;, const FloatRect&amp;) override;
-    virtual bool paintTextArea(const RenderObject&amp;, const PaintInfo&amp;, const FloatRect&amp;) override;
</del><ins>+    void adjustTextFieldStyle(StyleResolver&amp;, RenderStyle&amp;, Element*) const override;
+    bool paintTextField(const RenderObject&amp;, const PaintInfo&amp;, const FloatRect&amp;) override;
+    bool paintTextArea(const RenderObject&amp;, const PaintInfo&amp;, const FloatRect&amp;) override;
</ins><span class="cx"> 
</span><span class="cx">     LengthBox popupInternalPaddingBox(const RenderStyle&amp;) const override;
</span><span class="cx"> 
</span><span class="lines">@@ -167,13 +169,15 @@
</span><span class="cx"> #endif
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-    virtual double animationRepeatIntervalForProgressBar(RenderProgress&amp;) const override;
-    virtual double animationDurationForProgressBar(RenderProgress&amp;) const override;
-    virtual void adjustProgressBarStyle(StyleResolver&amp;, RenderStyle&amp;, Element*) const override;
-    virtual bool paintProgressBar(const RenderObject&amp;, const PaintInfo&amp;, const IntRect&amp;) override;
</del><ins>+    double animationRepeatIntervalForProgressBar(RenderProgress&amp;) const override;
+    double animationDurationForProgressBar(RenderProgress&amp;) const override;
+    void adjustProgressBarStyle(StyleResolver&amp;, RenderStyle&amp;, Element*) const override;
+    IntRect progressBarRectForBounds(const RenderObject&amp;, const IntRect&amp;) const override;
+    bool paintProgressBar(const RenderObject&amp;, const PaintInfo&amp;, const IntRect&amp;) override;
</ins><span class="cx"> 
</span><del>-    virtual void adjustInnerSpinButtonStyle(StyleResolver&amp;, RenderStyle&amp;, Element*) const override;
-    virtual bool paintInnerSpinButton(const RenderObject&amp;, const PaintInfo&amp;, const IntRect&amp;) override;
</del><ins>+    InnerSpinButtonLayout innerSpinButtonLayout(const RenderObject&amp;) const override;
+    void adjustInnerSpinButtonStyle(StyleResolver&amp;, RenderStyle&amp;, Element*) const override;
+    bool paintInnerSpinButton(const RenderObject&amp;, const PaintInfo&amp;, const IntRect&amp;) override;
</ins><span class="cx"> 
</span><span class="cx">     virtual String fileListNameForWidth(const FileList*, const FontCascade&amp;, int width, bool multipleFilesAllowed) const override;
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>