[Libreoffice-commits] core.git: Branch 'libreoffice-5-2' - vcl/inc vcl/unx

Caolán McNamara caolanm at redhat.com
Thu Nov 24 11:59:38 UTC 2016


 vcl/inc/unx/gtk/gtkgdi.hxx                |   88 +
 vcl/unx/gtk3/gtk3salnativewidgets-gtk.cxx | 1692 ++++++++++++++++++++----------
 2 files changed, 1215 insertions(+), 565 deletions(-)

New commits:
commit 83dc2227f35795aee4e2ccaccbb7d67d4c50ba3f
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Wed Oct 12 21:17:43 2016 +0100

    Resolves: tdf#92776 backport gtk3 >= 3.20 themeing improvements
    
    Related: tdf#92776 set parent style of notebook to toplevel window style
    
    Change-Id: Iec16b2617c82c363a540f967f66c514b5b2b104b
    (cherry picked from commit 570669631359021a8ad420753c87bcf4419d06cd)
    
    Related: tdf#101699 gtk3: get correct combobox and listbox arrows
    
    Change-Id: Ib2322bfda09b05925c74d93a530b9ed9fac73032
    (cherry picked from commit 6e8dbdbe1a9d15d7e7d000e4132fd5df3fecd660)
    
    Related: tdf#101699 gtk3: get correct arrow width
    
    Change-Id: If02c598306ec6f19cf83958c4a176cafa67076dc
    (cherry picked from commit 4cb720836ab03701ce508e302790c115c7808619)
    
    silence warnings
    
    Change-Id: I80abf5092c7d4e7b8cf75e4b79ffdb9a5e0c7580
    (cherry picked from commit 7ae079274d15ab309c9811c0b3966bed727a6afe)
    
    loplugin:nullptr
    
    Change-Id: Id9f702b2772a23c52a9b829093d10c83a5ab3acd
    (cherry picked from commit 1f8f140601bd654f97d0c1e6e05b3bef949ddfaf)
    
    bundle duplicate code together
    
    Change-Id: Id67e5026e21138c0583df8099436da01e4e2dab3
    (cherry picked from commit e3fca8b4a0f5e517f994b35f1d4ff152fb17c3a2)
    
    split these ifdefs into larger blocks
    
    Change-Id: I501d06096aa51066af8806277b7d392e39747494
    (cherry picked from commit d5b8b98393f529d1181b0305313a95ab90ef0bf2)
    
    gtk3: select old/new gtk theme behaviour etc at runtime
    
    Reviewed-on: https://gerrit.libreoffice.org/29969
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>
    (cherry picked from commit 70f7697c4243739c28feaa33b091f6c64a8356cb)
    
    Change-Id: Ie09419049e3d839315f4fc8a937f0dde74688d98
    
    need 3.19.2 or above for these
    
    (cherry picked from commit dd04278bfc3c89336283fcab1222147dcd796a77)
    
    Change-Id: If385b45b12c72a0d7460a9a4c9d0b0e3bfc1195e
    
    use released 3.20.0 instead of 3.19.2
    
    (cherry picked from commit 4fce8bd59eae6d2ed6e5a3f9a3d4898fcd3431a9)
    
    Change-Id: Iac311e0c326cf79a2dbacb889d39ab49ccaa9325
    
    Resolves: tdf#101699 get combobox junction right
    
    gtk3-demo has examples of foreign drawing, follow
    the patterns there to figure out what to do, add
    stuff to gtk3-demo to demo what we need to do if
    any particular case here is lacking
    
    Change-Id: Ia1a22280161c97a3eab2d94fc4744fe971d31727
    (cherry picked from commit e2af8f92a7308bc28c257b7905ec3a8a724554b1)
    
    gtk3: rework theme code to separate old and new theming schemes
    
    Change-Id: I7c1341a920c4607937ffab06c182a0ba0e0b26fd
    (cherry picked from commit ac53789077eef17e2d895826abfe22888716600a)
    
    older gtk3 versions still out there to build against
    
    Change-Id: I64cb12185fc3943a211928e35e756b82942095b0
    (cherry picked from commit a906f24a7830a12c4f1e2f8fa0c3df7961a64d6c)
    
    GTK_STYLE_CLASS_POPUP not defined in older gtks
    
    Change-Id: I6192d13419aab42993e4b6dc011db30a4c3c1787
    (cherry picked from commit 7403c95540ba96a304eaebcb4845e910746133bb)
    
    Resolves: tdf#92776 ensure correct notebook tab font color
    
    despite various theme layout differences
    
    Change-Id: I209258583571b57b2b7869937fa4821855125eac
    (cherry picked from commit 69c9acd4b8dcd7ec8a5c3c380ad5cd8b797661ea)
    
    gtk3: split out gtk->vcl font mapping code
    
    (cherry picked from commit eb935ee8f511265038a949f74958ae716ac0e8ca)
    
    Change-Id: Ic379307ba9e663e0ffc27c945852f6d68197f995
    
    gtk3: use theme tab font
    
    Change-Id: I3ea5a9e65e62133c910945e603bdc1155c9a07c3
    (cherry picked from commit d786606b33cfc146a3a1f3adf814196993d3b310)
    
    gtk3: split tabitem rendering to a standalone thing
    
    Change-Id: I88cd8926b733717c9ea0ecf64a9882eaa777dcfe
    (cherry picked from commit dcfddd3f079a45fc59fe50475020091c6c4694e2)
    
    GTK_STYLE_CLASS_LABEL no defined in all versions
    
    Change-Id: I648067e30d5a2e725111b2bc920367ac2d5e0f80
    (cherry picked from commit 352ddafd05c5de4335746d52c79e8cf9689cba86)
    
    Resolves: tdf#89760 get correct menubar text color for 'close preview'
    
    Change-Id: Ife6f2665eabeefd6125a53318404dbd7b9af42ee
    (cherry picked from commit b5f9fdff49e6955550cffa5318bee9d5c09f3479)
    
    -Werror,-Wimplicit-fallthrough
    
    Change-Id: I13a6a64f118bcfb99f47cd47a0dc638c5c9a5a14
    (cherry picked from commit e64ea98801d20e5024da900a0ac8faaf565f4bf3)
    
    Resolves: tdf#100251 gtk3 toolbar separators are white in Adwaita
    
    Change-Id: Iceeba474535026cd13393432ef9a2e25121c134a
    (cherry picked from commit 3498ed37527b7af795f00dc6a55c11e65a313186)
    
    Resolves: tdf#103320 pressed buttons appear as hover buttons in toolbar
    
    since...
    
    commit 3498ed37527b7af795f00dc6a55c11e65a313186
    Author: Caolán McNamara <caolanm at redhat.com>
    Date:   Tue Oct 18 13:08:47 2016 +0100
    
        Resolves: tdf#100251 gtk3 toolbar separators are white in Adwaita
    
    so remove setting the parent of the toolbar again, colors remain good
    cause we ended up using gtk_render_background+gtk_render_frame for
    the new-style code path anyway
    
    Change-Id: Idd01537acbd92d6b41e0ff7fa2306b8c49f23ad3
    (cherry picked from commit 7f6f5519079e3508ac1302aa5907cfc6098c525e)
    
    Resolves: tdf#92776 tab names unreadable under Ambiance theme 3.20
    
    thanks Benjamin
    
    Reviewed-on: https://gerrit.libreoffice.org/30910
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>
    (cherry picked from commit 567580bddfa7b3d437b072698de77968c6513513)
    
    Change-Id: I7ea0f6c8a8b8b35f864036844f1dc786e1f6bda8
    
    gtk3: spinbuttons under Ambiance don't look beautiful enough
    
    lets draw the frame after the sub-contents are done, and
    use a dedicated entry child
    
    Change-Id: I7db1ac56e5cfb1a46ddd2fb56c5e95deaa83a95d
    (cherry picked from commit 4579c43861635dda15158478404aa90151228e91)
    
    put the render frame at the end of these blocks too
    
    Change-Id: I72270faa4138377ea04467ad0c6f01a3de0156b6
    (cherry picked from commit 7f1af0a1c7401552704eaba2091b078890567cd8)
    Reviewed-on: https://gerrit.libreoffice.org/30936
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Tomaž Vajngerl <quikee at gmail.com>

diff --git a/vcl/inc/unx/gtk/gtkgdi.hxx b/vcl/inc/unx/gtk/gtkgdi.hxx
index 3aac4d1..7e09707 100644
--- a/vcl/inc/unx/gtk/gtkgdi.hxx
+++ b/vcl/inc/unx/gtk/gtkgdi.hxx
@@ -35,6 +35,7 @@
 
 enum class GtkControlPart
 {
+    ToplevelWindow,
     Button,
     LinkButton,
     CheckButton,
@@ -42,36 +43,60 @@ enum class GtkControlPart
     RadioButton,
     RadioButtonRadio,
     Entry,
+    Combobox,
+    ComboboxBox,
+    ComboboxBoxEntry,
+    ComboboxBoxButton,
+    ComboboxBoxButtonBox,
+    ComboboxBoxButtonBoxArrow,
+    Listbox,
+    ListboxBox,
+    ListboxBoxButton,
+    ListboxBoxButtonBox,
+    ListboxBoxButtonBoxArrow,
     SpinButton,
+    SpinButtonEntry,
     SpinButtonUpButton,
     SpinButtonDownButton,
     ScrollbarVertical,
+    ScrollbarVerticalContents,
+    ScrollbarVerticalTrough,
+    ScrollbarVerticalSlider,
+    ScrollbarVerticalButton,
     ScrollbarHorizontal,
-    ScrollbarContents,
-    ScrollbarTrough,
-    ScrollbarSlider,
-    ScrollbarButton,
+    ScrollbarHorizontalContents,
+    ScrollbarHorizontalTrough,
+    ScrollbarHorizontalSlider,
+    ScrollbarHorizontalButton,
     ProgressBar,
     ProgressBarTrough,
     ProgressBarProgress,
+    Notebook,
+    NotebookHeader,
+    NotebookStack,
+    NotebookHeaderTabs,
+    NotebookHeaderTabsTab,
+    NotebookHeaderTabsTabLabel,
+    NotebookHeaderTabsTabActiveLabel,
+    NotebookHeaderTabsTabHoverLabel,
+    FrameBorder,
     MenuBar,
+    MenuBarItem,
+    MenuWindow,
+    Menu,
     MenuItem,
+    MenuItemLabel,
     MenuItemArrow,
-    Menu,
     CheckMenuItem,
     CheckMenuItemCheck,
     RadioMenuItem,
     RadioMenuItemRadio,
     SeparatorMenuItem,
     SeparatorMenuItemSeparator,
-    Notebook,
-    NotebookHeader,
-    NotebookStack,
-    NotebookHeaderTabs,
-    NotebookHeaderTabsTab,
-    FrameBorder,
 };
 
+typedef void (*gtk_widget_path_iter_set_object_nameFunc)(GtkWidgetPath *, guint, const char*);
+
 class GtkSalGraphics : public SvpSalGraphics
 {
     GtkSalFrame *mpFrame;
@@ -99,8 +124,14 @@ public:
     static void signalSettingsNotify( GObject*, GParamSpec *pSpec, gpointer );
 
     virtual void GetResolution(sal_Int32& rDPIX, sal_Int32& rDPIY) override;
+
+    GtkStyleContext* createStyleContext(gtk_widget_path_iter_set_object_nameFunc set_object_name, GtkControlPart ePart);
+    GtkStyleContext* createNewContext(GtkControlPart ePart, gtk_widget_path_iter_set_object_nameFunc set_object_name);
+    GtkStyleContext* createOldContext(GtkControlPart ePart);
+    GtkStyleContext* makeContext(GtkWidgetPath *pPath, GtkStyleContext *pParent);
 private:
     GtkWidget       *mpWindow;
+    static GtkStyleContext *mpWindowStyle;
     static GtkStyleContext *mpButtonStyle;
     static GtkStyleContext *mpLinkButtonStyle;
     static GtkStyleContext *mpEntryStyle;
@@ -119,22 +150,24 @@ private:
     static GtkStyleContext *mpToolButtonStyle;
     static GtkStyleContext *mpToolbarSeperatorStyle;
     static GtkStyleContext *mpCheckButtonStyle;
+    static GtkStyleContext *mpCheckButtonCheckStyle;
     static GtkStyleContext *mpRadioButtonStyle;
-    static GtkStyleContext *mpMenuBarStyle;
-    static GtkStyleContext *mpMenuBarItemStyle;
-    static GtkStyleContext *mpMenuStyle;
+    static GtkStyleContext *mpRadioButtonRadioStyle;
     static GtkStyleContext *mpSpinStyle;
+    static GtkStyleContext *mpSpinEntryStyle;
     static GtkStyleContext *mpSpinUpStyle;
     static GtkStyleContext *mpSpinDownStyle;
-    static GtkStyleContext *mpMenuItemStyle;
-    static GtkStyleContext *mpMenuItemArrowStyle;
-    static GtkStyleContext *mpCheckMenuItemStyle;
-    static GtkStyleContext *mpRadioMenuItemStyle;
-    static GtkStyleContext *mpSeparatorMenuItemStyle;
     static GtkStyleContext *mpComboboxStyle;
+    static GtkStyleContext *mpComboboxBoxStyle;
+    static GtkStyleContext *mpComboboxEntryStyle;
     static GtkStyleContext *mpComboboxButtonStyle;
+    static GtkStyleContext *mpComboboxButtonBoxStyle;
+    static GtkStyleContext *mpComboboxButtonArrowStyle;
     static GtkStyleContext *mpListboxStyle;
+    static GtkStyleContext *mpListboxBoxStyle;
     static GtkStyleContext *mpListboxButtonStyle;
+    static GtkStyleContext *mpListboxButtonBoxStyle;
+    static GtkStyleContext *mpListboxButtonArrowStyle;
     static GtkStyleContext *mpFrameInStyle;
     static GtkStyleContext *mpFrameOutStyle;
     static GtkStyleContext *mpFixedHoriLineStyle;
@@ -149,6 +182,21 @@ private:
     static GtkStyleContext *mpNotebookHeaderTabsStyle;
     static GtkStyleContext *mpNotebookHeaderTabsTabStyle;
     static GtkStyleContext *mpNotebookHeaderTabsTabLabelStyle;
+    static GtkStyleContext *mpNotebookHeaderTabsTabActiveLabelStyle;
+    static GtkStyleContext *mpNotebookHeaderTabsTabHoverLabelStyle;
+    static GtkStyleContext *mpMenuBarStyle;
+    static GtkStyleContext *mpMenuBarItemStyle;
+    static GtkStyleContext *mpMenuWindowStyle;
+    static GtkStyleContext *mpMenuStyle;
+    static GtkStyleContext *mpMenuItemStyle;
+    static GtkStyleContext *mpMenuItemLabelStyle;
+    static GtkStyleContext *mpMenuItemArrowStyle;
+    static GtkStyleContext *mpCheckMenuItemStyle;
+    static GtkStyleContext *mpCheckMenuItemCheckStyle;
+    static GtkStyleContext *mpRadioMenuItemStyle;
+    static GtkStyleContext *mpRadioMenuItemRadioStyle;
+    static GtkStyleContext *mpSeparatorMenuItemStyle;
+    static GtkStyleContext *mpSeparatorMenuItemSeparatorStyle;
 
     static Rectangle NWGetScrollButtonRect( ControlPart nPart, Rectangle aAreaRect );
     static Rectangle NWGetSpinButtonRect( ControlPart nPart, Rectangle aAreaRect);
@@ -166,7 +214,7 @@ private:
                              ControlPart nPart,
                              Rectangle aAreaRect,
                              ControlState nState );
-           void PaintSpinButton(GtkStyleContext *context,
+           void PaintSpinButton(GtkStateFlags flags,
                          cairo_t *cr,
                          const Rectangle& rControlRectangle,
                          ControlType nType,
diff --git a/vcl/unx/gtk3/gtk3salnativewidgets-gtk.cxx b/vcl/unx/gtk3/gtk3salnativewidgets-gtk.cxx
index 52c3246..d1f24dd 100644
--- a/vcl/unx/gtk3/gtk3salnativewidgets-gtk.cxx
+++ b/vcl/unx/gtk3/gtk3salnativewidgets-gtk.cxx
@@ -21,6 +21,7 @@
 
 #include <boost/optional.hpp>
 
+GtkStyleContext* GtkSalGraphics::mpWindowStyle = nullptr;
 GtkStyleContext* GtkSalGraphics::mpButtonStyle = nullptr;
 GtkStyleContext* GtkSalGraphics::mpLinkButtonStyle = nullptr;
 GtkStyleContext* GtkSalGraphics::mpEntryStyle = nullptr;
@@ -39,22 +40,24 @@ GtkStyleContext* GtkSalGraphics::mpToolbarStyle = nullptr;
 GtkStyleContext* GtkSalGraphics::mpToolButtonStyle = nullptr;
 GtkStyleContext* GtkSalGraphics::mpToolbarSeperatorStyle = nullptr;
 GtkStyleContext* GtkSalGraphics::mpCheckButtonStyle = nullptr;
+GtkStyleContext* GtkSalGraphics::mpCheckButtonCheckStyle = nullptr;
 GtkStyleContext* GtkSalGraphics::mpRadioButtonStyle = nullptr;
-GtkStyleContext* GtkSalGraphics::mpMenuBarStyle = nullptr;
-GtkStyleContext* GtkSalGraphics::mpMenuBarItemStyle = nullptr;
-GtkStyleContext* GtkSalGraphics::mpMenuStyle = nullptr;
-GtkStyleContext* GtkSalGraphics::mpMenuItemStyle = nullptr;
-GtkStyleContext* GtkSalGraphics::mpMenuItemArrowStyle = nullptr;
-GtkStyleContext* GtkSalGraphics::mpCheckMenuItemStyle = nullptr;
-GtkStyleContext* GtkSalGraphics::mpRadioMenuItemStyle = nullptr;
-GtkStyleContext* GtkSalGraphics::mpSeparatorMenuItemStyle = nullptr;
+GtkStyleContext* GtkSalGraphics::mpRadioButtonRadioStyle = nullptr;
 GtkStyleContext* GtkSalGraphics::mpSpinStyle = nullptr;
+GtkStyleContext* GtkSalGraphics::mpSpinEntryStyle = nullptr;
 GtkStyleContext* GtkSalGraphics::mpSpinUpStyle = nullptr;
 GtkStyleContext* GtkSalGraphics::mpSpinDownStyle = nullptr;
 GtkStyleContext* GtkSalGraphics::mpComboboxStyle = nullptr;
+GtkStyleContext* GtkSalGraphics::mpComboboxBoxStyle = nullptr;
+GtkStyleContext* GtkSalGraphics::mpComboboxEntryStyle = nullptr;
 GtkStyleContext* GtkSalGraphics::mpComboboxButtonStyle = nullptr;
+GtkStyleContext* GtkSalGraphics::mpComboboxButtonBoxStyle = nullptr;
+GtkStyleContext* GtkSalGraphics::mpComboboxButtonArrowStyle = nullptr;
 GtkStyleContext* GtkSalGraphics::mpListboxStyle = nullptr;
+GtkStyleContext* GtkSalGraphics::mpListboxBoxStyle = nullptr;
 GtkStyleContext* GtkSalGraphics::mpListboxButtonStyle = nullptr;
+GtkStyleContext* GtkSalGraphics::mpListboxButtonBoxStyle= nullptr;
+GtkStyleContext* GtkSalGraphics::mpListboxButtonArrowStyle = nullptr;
 GtkStyleContext* GtkSalGraphics::mpFrameInStyle = nullptr;
 GtkStyleContext* GtkSalGraphics::mpFrameOutStyle = nullptr;
 GtkStyleContext* GtkSalGraphics::mpFixedHoriLineStyle = nullptr;
@@ -68,6 +71,22 @@ GtkStyleContext* GtkSalGraphics::mpNotebookStackStyle = nullptr;
 GtkStyleContext* GtkSalGraphics::mpNotebookHeaderStyle = nullptr;
 GtkStyleContext* GtkSalGraphics::mpNotebookHeaderTabsStyle = nullptr;
 GtkStyleContext* GtkSalGraphics::mpNotebookHeaderTabsTabStyle = nullptr;
+GtkStyleContext* GtkSalGraphics::mpNotebookHeaderTabsTabLabelStyle = nullptr;
+GtkStyleContext* GtkSalGraphics::mpNotebookHeaderTabsTabActiveLabelStyle = nullptr;
+GtkStyleContext* GtkSalGraphics::mpNotebookHeaderTabsTabHoverLabelStyle = nullptr;
+GtkStyleContext* GtkSalGraphics::mpMenuBarStyle = nullptr;
+GtkStyleContext* GtkSalGraphics::mpMenuBarItemStyle = nullptr;
+GtkStyleContext* GtkSalGraphics::mpMenuWindowStyle = nullptr;
+GtkStyleContext* GtkSalGraphics::mpMenuStyle = nullptr;
+GtkStyleContext* GtkSalGraphics::mpMenuItemStyle = nullptr;
+GtkStyleContext* GtkSalGraphics::mpMenuItemArrowStyle = nullptr;
+GtkStyleContext* GtkSalGraphics::mpMenuItemLabelStyle = nullptr;
+GtkStyleContext* GtkSalGraphics::mpCheckMenuItemStyle = nullptr;
+GtkStyleContext* GtkSalGraphics::mpCheckMenuItemCheckStyle = nullptr;
+GtkStyleContext* GtkSalGraphics::mpRadioMenuItemStyle = nullptr;
+GtkStyleContext* GtkSalGraphics::mpRadioMenuItemRadioStyle = nullptr;
+GtkStyleContext* GtkSalGraphics::mpSeparatorMenuItemStyle = nullptr;
+GtkStyleContext* GtkSalGraphics::mpSeparatorMenuItemSeparatorStyle = nullptr;
 
 bool GtkSalGraphics::style_loaded = false;
 /************************************************************************
@@ -125,6 +144,7 @@ enum class RenderType {
     Expander,
     Icon,
     Progress,
+    TabItem,
     Focus
 };
 
@@ -290,6 +310,56 @@ static GtkWidget* gMenuItemMenuBarWidget;
 static GtkWidget* gCheckMenuItemWidget;
 static GtkWidget* gTreeViewWidget;
 
+namespace
+{
+    void parent_styles_context_set_state(GtkStyleContext* context, GtkStateFlags flags)
+    {
+        while ((context = gtk_style_context_get_parent(context)))
+        {
+            gtk_style_context_set_state(context, flags);
+        }
+    }
+
+    void style_context_set_state(GtkStyleContext* context, GtkStateFlags flags)
+    {
+        gtk_style_context_set_state(context, flags);
+        parent_styles_context_set_state(context, flags);
+    }
+
+    Rectangle render_common(GtkStyleContext *pContext, cairo_t *cr, const Rectangle &rIn, GtkStateFlags flags)
+    {
+        if (!pContext)
+            return rIn;
+
+        gtk_style_context_set_state(pContext, flags);
+
+        Rectangle aRect(rIn);
+        GtkBorder margin;
+        gtk_style_context_get_margin(pContext, gtk_style_context_get_state(pContext), &margin);
+
+        aRect.Left() += margin.left;
+        aRect.Top() += margin.top;
+        aRect.Right() -= margin.right;
+        aRect.Bottom() -= margin.bottom;
+
+        gtk_render_background(pContext, cr, aRect.Left(), aRect.Top(),
+                                            aRect.GetWidth(), aRect.GetHeight());
+        gtk_render_frame(pContext, cr, aRect.Left(), aRect.Top(),
+                                       aRect.GetWidth(), aRect.GetHeight());
+
+        GtkBorder border, padding;
+        gtk_style_context_get_border(pContext, gtk_style_context_get_state(pContext), &border);
+        gtk_style_context_get_padding(pContext, gtk_style_context_get_state(pContext), &padding);
+
+        aRect.Left() += border.left + padding.left;
+        aRect.Top() += border.top + padding.top;
+        aRect.Right() -= border.right + padding.right;
+        aRect.Bottom() -= border.bottom + padding.bottom;
+
+        return aRect;
+    }
+}
+
 void GtkSalGraphics::PaintScrollbar(GtkStyleContext *context,
                                     cairo_t *cr,
                                     const Rectangle& rControlRectangle,
@@ -613,9 +683,6 @@ void GtkSalGraphics::PaintOneSpinButton( GtkStyleContext *context,
     gtk_render_background(context, cr,
                           buttonRect.Left(), buttonRect.Top(),
                           buttonRect.GetWidth(), buttonRect.GetHeight() );
-    gtk_render_frame(context, cr,
-                     buttonRect.Left(), buttonRect.Top(),
-                     buttonRect.GetWidth(), buttonRect.GetHeight() );
 
     gint iconWidth = (buttonRect.GetWidth() - padding.left - padding.right - border.left - border.right);
     gint iconHeight = (buttonRect.GetHeight() - padding.top - padding.bottom - border.top - border.bottom);
@@ -638,9 +705,13 @@ void GtkSalGraphics::PaintOneSpinButton( GtkStyleContext *context,
 
     gtk_render_icon(context, cr, pixbuf, arrowRect.Left(), arrowRect.Top());
     g_object_unref(pixbuf);
+
+    gtk_render_frame(context, cr,
+                     buttonRect.Left(), buttonRect.Top(),
+                     buttonRect.GetWidth(), buttonRect.GetHeight() );
 }
 
-void GtkSalGraphics::PaintSpinButton(GtkStyleContext *context,
+void GtkSalGraphics::PaintSpinButton(GtkStateFlags flags,
                                      cairo_t *cr,
                                      const Rectangle& rControlRectangle,
                                      ControlType nType,
@@ -664,21 +735,28 @@ void GtkSalGraphics::PaintSpinButton(GtkStyleContext *context,
 
     if (nPart == ControlPart::Entire)
     {
-        gtk_render_background(context, cr,
+        gtk_style_context_set_state(mpSpinStyle, flags);
+
+        gtk_render_background(mpSpinStyle, cr,
                               0, 0,
                               rControlRectangle.GetWidth(), rControlRectangle.GetHeight() );
-        gtk_render_frame(context, cr,
-                         0, 0,
-                         rControlRectangle.GetWidth(), rControlRectangle.GetHeight() );
     }
 
     cairo_translate(cr, -rControlRectangle.Left(), -rControlRectangle.Top());
     PaintOneSpinButton(mpSpinUpStyle, cr, nType, upBtnPart, rControlRectangle, upBtnState );
     PaintOneSpinButton(mpSpinDownStyle, cr, nType, downBtnPart, rControlRectangle, downBtnState );
     cairo_translate(cr, rControlRectangle.Left(), rControlRectangle.Top());
+
+    if (nPart == ControlPart::Entire)
+    {
+        gtk_render_frame(mpSpinStyle, cr,
+                         0, 0,
+                         rControlRectangle.GetWidth(), rControlRectangle.GetHeight() );
+    }
 }
 
-#define ARROW_SIZE 11 * 0.85
+#define FALLBACK_ARROW_SIZE 11 * 0.85
+
 Rectangle GtkSalGraphics::NWGetComboBoxButtonRect( ControlType nType,
                                                    ControlPart nPart,
                                                    Rectangle aAreaRect )
@@ -690,7 +768,14 @@ Rectangle GtkSalGraphics::NWGetComboBoxButtonRect( ControlType nType,
     GtkBorder padding;
     gtk_style_context_get_padding( mpButtonStyle, gtk_style_context_get_state(mpButtonStyle), &padding);
 
-    gint nArrowWidth = ARROW_SIZE;
+    gint nArrowWidth = FALLBACK_ARROW_SIZE;
+    if (gtk_check_version(3, 20, 0) == nullptr)
+    {
+        gtk_style_context_get(mpComboboxButtonArrowStyle,
+            gtk_style_context_get_state(mpComboboxButtonArrowStyle),
+            "min-width", &nArrowWidth, nullptr);
+    }
+
     gint nButtonWidth = nArrowWidth + padding.left + padding.right;
     if( nPart == ControlPart::ButtonDown )
     {
@@ -736,66 +821,69 @@ void GtkSalGraphics::PaintCombobox( GtkStateFlags flags, cairo_t *cr,
     areaRect = rControlRectangle;
 
     buttonRect = NWGetComboBoxButtonRect( nType, ControlPart::ButtonDown, areaRect );
-    if( nPart == ControlPart::ButtonDown )
-        buttonRect.Left() += 1;
 
     Rectangle        aEditBoxRect( areaRect );
     aEditBoxRect.SetSize( Size( areaRect.GetWidth() - buttonRect.GetWidth(), aEditBoxRect.GetHeight() ) );
     if (AllSettings::GetLayoutRTL())
         aEditBoxRect.SetPos( Point( areaRect.Left() + buttonRect.GetWidth(), areaRect.Top() ) );
 
-    arrowRect.SetSize( Size( (gint)(ARROW_SIZE),
-                             (gint)(ARROW_SIZE) ) );
+    gint arrow_width = FALLBACK_ARROW_SIZE, arrow_height = FALLBACK_ARROW_SIZE;
+    if (gtk_check_version(3, 20, 0) == nullptr)
+    {
+        if (nType == ControlType::Combobox)
+        {
+            gtk_style_context_get(mpComboboxButtonArrowStyle,
+                gtk_style_context_get_state(mpComboboxButtonArrowStyle),
+                "min-width", &arrow_width, "min-height", &arrow_height, nullptr);
+        }
+        else if (nType == ControlType::Listbox)
+        {
+            gtk_style_context_get(mpListboxButtonArrowStyle,
+                gtk_style_context_get_state(mpListboxButtonArrowStyle),
+                "min-width", &arrow_width, "min-height", &arrow_height, nullptr);
+        }
+    }
+
+    arrowRect.SetSize(Size(arrow_width, arrow_height));
     arrowRect.SetPos( Point( buttonRect.Left() + (gint)((buttonRect.GetWidth() - arrowRect.GetWidth()) / 2),
                              buttonRect.Top() + (gint)((buttonRect.GetHeight() - arrowRect.GetHeight()) / 2) ) );
 
 
-    if ( nType == ControlType::Combobox )
-    {
-        gtk_style_context_save(mpComboboxButtonStyle);
-        gtk_style_context_set_state(mpComboboxButtonStyle, flags);
+    Rectangle aRect(Point(0, 0), Size(areaRect.GetWidth(), areaRect.GetHeight()));
 
+    if (nType == ControlType::Combobox)
+    {
         if( nPart == ControlPart::Entire )
         {
-            GtkJunctionSides eJuncSides = gtk_style_context_get_junction_sides(mpEntryStyle);
-            gtk_style_context_set_state(mpEntryStyle, flags);
+            render_common(mpComboboxStyle, cr, aRect, flags);
+            render_common(mpComboboxBoxStyle, cr, aRect, flags);
+            Rectangle aEntryRect(Point(aEditBoxRect.Left() - areaRect.Left(),
+                                 aEditBoxRect.Top() - areaRect.Top()),
+                                 Size(aEditBoxRect.GetWidth(), aEditBoxRect.GetHeight()));
+
+            GtkJunctionSides eJuncSides = gtk_style_context_get_junction_sides(mpComboboxEntryStyle);
             if (AllSettings::GetLayoutRTL())
-                gtk_style_context_set_junction_sides(mpEntryStyle, GTK_JUNCTION_LEFT);
+                gtk_style_context_set_junction_sides(mpComboboxEntryStyle, GTK_JUNCTION_LEFT);
             else
-                gtk_style_context_set_junction_sides(mpEntryStyle, GTK_JUNCTION_RIGHT);
+                gtk_style_context_set_junction_sides(mpComboboxEntryStyle, GTK_JUNCTION_RIGHT);
+            render_common(mpComboboxEntryStyle, cr, aEntryRect, flags);
+            gtk_style_context_set_junction_sides(mpComboboxEntryStyle, eJuncSides);
+        }
 
-            gtk_render_background(mpComboboxStyle, cr,
-                                  0, 0,
-                                  areaRect.GetWidth(), areaRect.GetHeight());
-            gtk_render_frame(mpComboboxStyle, cr,
-                             0, 0,
-                             areaRect.GetWidth(), areaRect.GetHeight());
-            gtk_render_background(mpEntryStyle, cr,
-                                  (aEditBoxRect.Left() - areaRect.Left()),
-                                  (aEditBoxRect.Top() - areaRect.Top()),
-                                  aEditBoxRect.GetWidth(), aEditBoxRect.GetHeight() );
-            gtk_render_frame(mpEntryStyle, cr,
-                             (aEditBoxRect.Left() - areaRect.Left()),
-                             (aEditBoxRect.Top() - areaRect.Top()),
-                             aEditBoxRect.GetWidth(), aEditBoxRect.GetHeight() );
-            gtk_style_context_set_junction_sides(mpEntryStyle, eJuncSides);
-        }
-
-        gtk_render_background(mpComboboxButtonStyle, cr,
-                              (buttonRect.Left() - areaRect.Left()),
-                              (buttonRect.Top() - areaRect.Top()),
-                              buttonRect.GetWidth(), buttonRect.GetHeight() );
-        gtk_render_frame(mpComboboxButtonStyle, cr,
-                         (buttonRect.Left() - areaRect.Left()),
-                         (buttonRect.Top() - areaRect.Top()),
-                         buttonRect.GetWidth(), buttonRect.GetHeight() );
-
-        gtk_render_arrow(mpComboboxStyle, cr,
+        Rectangle aButtonRect(Point(buttonRect.Left() - areaRect.Left(), buttonRect.Top() - areaRect.Top()),
+                              Size(buttonRect.GetWidth(), buttonRect.GetHeight()));
+        GtkJunctionSides eJuncSides = gtk_style_context_get_junction_sides(mpComboboxButtonStyle);
+        if (AllSettings::GetLayoutRTL())
+            gtk_style_context_set_junction_sides(mpComboboxButtonStyle, GTK_JUNCTION_RIGHT);
+        else
+            gtk_style_context_set_junction_sides(mpComboboxButtonStyle, GTK_JUNCTION_LEFT);
+        render_common(mpComboboxButtonStyle, cr, aButtonRect, flags);
+        gtk_style_context_set_junction_sides(mpComboboxButtonStyle, eJuncSides);
+
+        gtk_render_arrow(mpComboboxButtonArrowStyle, cr,
                          G_PI,
                          (arrowRect.Left() - areaRect.Left()), (arrowRect.Top() - areaRect.Top()),
                          arrowRect.GetWidth() );
-
-        gtk_style_context_restore(mpComboboxButtonStyle);
     }
     else if (nType == ControlType::Listbox)
     {
@@ -808,347 +896,855 @@ void GtkSalGraphics::PaintCombobox( GtkStateFlags flags, cairo_t *cr,
         }
         else
         {
-            gtk_style_context_save(mpListboxButtonStyle);
-            gtk_style_context_set_state(mpListboxButtonStyle, flags);
-
-            gtk_render_background(mpListboxStyle, cr,
-                                  0, 0,
-                                  areaRect.GetWidth(), areaRect.GetHeight());
-            gtk_render_frame(mpListboxStyle, cr,
-                             0, 0,
-                             areaRect.GetWidth(), areaRect.GetHeight());
+            render_common(mpListboxStyle, cr, aRect, flags);
+            render_common(mpListboxBoxStyle, cr, aRect, flags);
 
-            gtk_render_background(mpListboxButtonStyle, cr,
-                                  0, 0,
-                                  areaRect.GetWidth(), areaRect.GetHeight());
-            gtk_render_frame(mpListboxButtonStyle, cr,
-                             0, 0,
-                             areaRect.GetWidth(), areaRect.GetHeight());
+            render_common(mpListboxButtonStyle, cr, aRect, flags);
 
-            gtk_render_arrow(mpListboxStyle, cr,
+            gtk_render_arrow(mpListboxButtonArrowStyle, cr,
                              G_PI,
                              (arrowRect.Left() - areaRect.Left()), (arrowRect.Top() - areaRect.Top()),
                              arrowRect.GetWidth() );
-
-            gtk_style_context_restore(mpListboxButtonStyle);
         }
     }
 }
 
-static GtkStyleContext* createStyleContext(GtkControlPart ePart, GtkStyleContext* parent = nullptr)
+static void appendComboEntry(GtkWidgetPath* pSiblingsPath, gtk_widget_path_iter_set_object_nameFunc set_object_name)
+{
+    gtk_widget_path_append_type(pSiblingsPath, GTK_TYPE_ENTRY);
+    set_object_name(pSiblingsPath, -1, "entry");
+    gtk_widget_path_iter_add_class(pSiblingsPath, -1, "combo");
+}
+
+static void appendComboButton(GtkWidgetPath* pSiblingsPath, gtk_widget_path_iter_set_object_nameFunc set_object_name)
+{
+    gtk_widget_path_append_type(pSiblingsPath, GTK_TYPE_BUTTON);
+    set_object_name(pSiblingsPath, -1, "button");
+    gtk_widget_path_iter_add_class(pSiblingsPath, -1, "combo");
+}
+
+static GtkWidgetPath* buildLTRComboSiblingsPath(gtk_widget_path_iter_set_object_nameFunc set_object_name)
+{
+    GtkWidgetPath* pSiblingsPath = gtk_widget_path_new();
+
+    appendComboEntry(pSiblingsPath, set_object_name);
+    appendComboButton(pSiblingsPath, set_object_name);
+
+    return pSiblingsPath;
+}
+
+static GtkWidgetPath* buildRTLComboSiblingsPath(gtk_widget_path_iter_set_object_nameFunc set_object_name)
+{
+    GtkWidgetPath* pSiblingsPath = gtk_widget_path_new();
+
+    appendComboButton(pSiblingsPath, set_object_name);
+    appendComboEntry(pSiblingsPath, set_object_name);
+
+    return pSiblingsPath;
+}
+
+GtkStyleContext* GtkSalGraphics::makeContext(GtkWidgetPath *pPath, GtkStyleContext *pParent)
+{
+    GtkStyleContext* context = gtk_style_context_new();
+    gtk_style_context_set_screen(context, gtk_window_get_screen(GTK_WINDOW(mpWindow)));
+    gtk_style_context_set_path(context, pPath);
+    gtk_style_context_set_parent(context, pParent);
+    gtk_widget_path_unref(pPath);
+    return context;
+}
+
+GtkStyleContext* GtkSalGraphics::createNewContext(GtkControlPart ePart, gtk_widget_path_iter_set_object_nameFunc set_object_name)
 {
-    GtkWidgetPath *path = parent ? gtk_widget_path_copy(gtk_style_context_get_path(parent)) : gtk_widget_path_new();
     switch (ePart)
     {
+        case GtkControlPart::ToplevelWindow:
+        {
+            GtkWidgetPath *path = gtk_widget_path_new();
+            gtk_widget_path_append_type(path, G_TYPE_NONE);
+            set_object_name(path, -1, "window");
+            gtk_widget_path_iter_add_class(path, -1, "background");
+            return makeContext(path, nullptr);
+        }
         case GtkControlPart::Button:
+        {
+            GtkWidgetPath *path = gtk_widget_path_new();
             gtk_widget_path_append_type(path, GTK_TYPE_BUTTON);
-#if GTK_CHECK_VERSION(3, 19, 2)
-            gtk_widget_path_iter_set_object_name(path, -1, "button");
-#else
-            gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_BUTTON);
-#endif
-            break;
+            set_object_name(path, -1, "button");
+            return makeContext(path, nullptr);
+        }
         case GtkControlPart::LinkButton:
+        {
+            GtkWidgetPath *path = gtk_widget_path_new();
             gtk_widget_path_append_type(path, GTK_TYPE_BUTTON);
-#if GTK_CHECK_VERSION(3, 19, 2)
-            gtk_widget_path_iter_set_object_name(path, -1, "button");
-#else
-            gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_BUTTON);
-#endif
+            set_object_name(path, -1, "button");
             gtk_widget_path_iter_add_class(path, -1, "link");
-            break;
+            return makeContext(path, nullptr);
+        }
         case GtkControlPart::CheckButton:
+        {
+            GtkWidgetPath *path = gtk_widget_path_new();
             gtk_widget_path_append_type(path, GTK_TYPE_CHECK_BUTTON);
-#if GTK_CHECK_VERSION(3, 19, 2)
-            gtk_widget_path_iter_set_object_name(path, -1, "checkbutton");
-#else
-            gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_CHECK);
-#endif
-            break;
+            set_object_name(path, -1, "checkbutton");
+            return makeContext(path, nullptr);
+        }
         case GtkControlPart::CheckButtonCheck:
+        {
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpCheckButtonStyle));
             gtk_widget_path_append_type(path, GTK_TYPE_CHECK_BUTTON);
-#if GTK_CHECK_VERSION(3, 19, 2)
-            gtk_widget_path_iter_set_object_name(path, -1, "check");
-#else
-            gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_CHECK);
-#endif
-            break;
+            set_object_name(path, -1, "check");
+            return makeContext(path, mpCheckButtonStyle);
+        }
         case GtkControlPart::RadioButton:
+        {
+            GtkWidgetPath *path = gtk_widget_path_new();
             gtk_widget_path_append_type(path, GTK_TYPE_RADIO_BUTTON);
-#if GTK_CHECK_VERSION(3, 19, 2)
-            gtk_widget_path_iter_set_object_name(path, -1, "radiobutton");
-#else
-            gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_RADIO);
-#endif
-            break;
+            set_object_name(path, -1, "radiobutton");
+            return makeContext(path, nullptr);
+        }
         case GtkControlPart::RadioButtonRadio:
+        {
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpRadioButtonStyle));
             gtk_widget_path_append_type(path, GTK_TYPE_RADIO_BUTTON);
-#if GTK_CHECK_VERSION(3, 19, 2)
-            gtk_widget_path_iter_set_object_name(path, -1, "radio");
-#else
-            gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_RADIO);
+            set_object_name(path, -1, "radio");
+            return makeContext(path, mpRadioButtonStyle);
+        }
+        case GtkControlPart::ComboboxBoxButtonBoxArrow:
+        {
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpComboboxButtonBoxStyle));
+            gtk_widget_path_append_type(path, GTK_TYPE_RADIO_BUTTON);
+            gtk_widget_path_append_type(path, GTK_TYPE_BUTTON);
+            set_object_name(path, -1, "arrow");
+            return makeContext(path, mpComboboxButtonBoxStyle);
+        }
+        case GtkControlPart::ListboxBoxButtonBoxArrow:
+        {
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpListboxButtonBoxStyle));
+            gtk_widget_path_append_type(path, GTK_TYPE_RADIO_BUTTON);
+            gtk_widget_path_append_type(path, GTK_TYPE_BUTTON);
+            set_object_name(path, -1, "arrow");
+            return makeContext(path, mpListboxButtonBoxStyle);
+        }
+        case GtkControlPart::Entry:
+        {
+            GtkWidgetPath *path = gtk_widget_path_new();
+            gtk_widget_path_append_type(path, GTK_TYPE_ENTRY);
+            set_object_name(path, -1, "entry");
+            return makeContext(path, nullptr);
+        }
+        case GtkControlPart::Combobox:
+        case GtkControlPart::Listbox:
+        {
+            GtkWidgetPath *path = gtk_widget_path_new();
+            gtk_widget_path_append_type(path, G_TYPE_NONE);
+            set_object_name(path, -1, "combobox");
+            return makeContext(path, nullptr);
+        }
+        case GtkControlPart::ComboboxBox:
+        {
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpComboboxStyle));
+            gtk_widget_path_append_type(path, G_TYPE_NONE);
+            set_object_name(path, -1, "box");
+            gtk_widget_path_iter_add_class(path, -1, "horizontal");
+            gtk_widget_path_iter_add_class(path, -1, "linked");
+            return makeContext(path, mpComboboxStyle);
+        }
+        case GtkControlPart::ListboxBox:
+        {
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpListboxStyle));
+            gtk_widget_path_append_type(path, G_TYPE_NONE);
+            set_object_name(path, -1, "box");
+            gtk_widget_path_iter_add_class(path, -1, "horizontal");
+            gtk_widget_path_iter_add_class(path, -1, "linked");
+            return makeContext(path, mpListboxStyle);
+        }
+        case GtkControlPart::ComboboxBoxEntry:
+        {
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpComboboxBoxStyle));
+            GtkWidgetPath* pSiblingsPath;
+            if (AllSettings::GetLayoutRTL())
+            {
+                pSiblingsPath = buildRTLComboSiblingsPath(set_object_name);
+                gtk_widget_path_append_with_siblings(path, pSiblingsPath, 1);
+            }
+            else
+            {
+                pSiblingsPath = buildLTRComboSiblingsPath(set_object_name);
+                gtk_widget_path_append_with_siblings(path, pSiblingsPath, 0);
+            }
+            gtk_widget_path_unref(pSiblingsPath);
+            return makeContext(path, mpComboboxBoxStyle);
+        }
+        case GtkControlPart::ComboboxBoxButton:
+        {
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpComboboxBoxStyle));
+            GtkWidgetPath* pSiblingsPath;
+            if (AllSettings::GetLayoutRTL())
+            {
+                pSiblingsPath = buildRTLComboSiblingsPath(set_object_name);
+                gtk_widget_path_append_with_siblings(path, pSiblingsPath, 0);
+            }
+            else
+            {
+                pSiblingsPath = buildLTRComboSiblingsPath(set_object_name);
+                gtk_widget_path_append_with_siblings(path, pSiblingsPath, 1);
+            }
+            gtk_widget_path_unref(pSiblingsPath);
+            return makeContext(path, mpComboboxBoxStyle);
+        }
+        case GtkControlPart::ListboxBoxButton:
+        {
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpListboxBoxStyle));
+            GtkWidgetPath* pSiblingsPath = gtk_widget_path_new();
+
+            gtk_widget_path_append_type(pSiblingsPath, GTK_TYPE_BUTTON);
+            set_object_name(pSiblingsPath, -1, "button");
+            gtk_widget_path_iter_add_class(pSiblingsPath, -1, "combo");
+
+            gtk_widget_path_append_with_siblings(path, pSiblingsPath, 0);
+            gtk_widget_path_unref(pSiblingsPath);
+            return makeContext(path, mpListboxBoxStyle);
+        }
+        case GtkControlPart::ComboboxBoxButtonBox:
+        {
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpComboboxButtonStyle));
+            gtk_widget_path_append_type(path, G_TYPE_NONE);
+            set_object_name(path, -1, "box");
+            gtk_widget_path_iter_add_class(path, -1, "horizontal");
+            return makeContext(path, mpComboboxButtonStyle);
+        }
+        case GtkControlPart::ListboxBoxButtonBox:
+        {
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpListboxButtonStyle));
+            gtk_widget_path_append_type(path, G_TYPE_NONE);
+            set_object_name(path, -1, "box");
+            gtk_widget_path_iter_add_class(path, -1, "horizontal");
+            return makeContext(path, mpListboxButtonStyle);
+        }
+        case GtkControlPart::SpinButton:
+        {
+            GtkWidgetPath *path = gtk_widget_path_new();
+            gtk_widget_path_append_type(path, GTK_TYPE_SPIN_BUTTON);
+            set_object_name(path, -1, "spinbutton");
+            gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_HORIZONTAL);
+            return makeContext(path, nullptr);
+        }
+        case GtkControlPart::SpinButtonEntry:
+        {
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpSpinStyle));
+            gtk_widget_path_append_type(path, G_TYPE_NONE);
+            set_object_name(path, -1, "entry");
+            return makeContext(path, mpSpinStyle);
+        }
+        case GtkControlPart::SpinButtonUpButton:
+        case GtkControlPart::SpinButtonDownButton:
+        {
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpSpinStyle));
+            gtk_widget_path_append_type(path, GTK_TYPE_SPIN_BUTTON);
+            set_object_name(path, -1, "button");
+            gtk_widget_path_iter_add_class(path, -1, ePart == GtkControlPart::SpinButtonUpButton ? "up" : "down");
+            return makeContext(path, mpSpinStyle);
+        }
+        case GtkControlPart::ScrollbarVertical:
+        case GtkControlPart::ScrollbarHorizontal:
+        {
+            GtkWidgetPath *path = gtk_widget_path_new();
+            gtk_widget_path_append_type(path, GTK_TYPE_SCROLLBAR);
+            set_object_name(path, -1, "scrollbar");
+            gtk_widget_path_iter_add_class(path, -1, ePart == GtkControlPart::ScrollbarVertical ? "vertical" : "horizontal");
+            return makeContext(path, nullptr);
+        }
+        case GtkControlPart::ScrollbarVerticalContents:
+        case GtkControlPart::ScrollbarHorizontalContents:
+        {
+            GtkStyleContext *pParent =
+                (ePart == GtkControlPart::ScrollbarVerticalContents) ? mpVScrollbarStyle : mpHScrollbarStyle;
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(pParent));
+            gtk_widget_path_append_type(path, GTK_TYPE_SCROLLBAR);
+            set_object_name(path, -1, "contents");
+            return makeContext(path, pParent);
+        }
+        case GtkControlPart::ScrollbarVerticalTrough:
+        case GtkControlPart::ScrollbarHorizontalTrough:
+        {
+            GtkStyleContext *pParent =
+                (ePart == GtkControlPart::ScrollbarVerticalTrough) ? mpVScrollbarContentsStyle : mpHScrollbarContentsStyle;
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(pParent));
+            gtk_widget_path_append_type(path, GTK_TYPE_SCROLLBAR);
+            set_object_name(path, -1, "trough");
+            return makeContext(path, pParent);
+        }
+        case GtkControlPart::ScrollbarVerticalSlider:
+        case GtkControlPart::ScrollbarHorizontalSlider:
+        {
+            GtkStyleContext *pParent =
+                (ePart == GtkControlPart::ScrollbarVerticalSlider) ? mpVScrollbarTroughStyle : mpHScrollbarTroughStyle;
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(pParent));
+            gtk_widget_path_append_type(path, GTK_TYPE_SCROLLBAR);
+            set_object_name(path, -1, "slider");
+            return makeContext(path, pParent);
+        }
+        case GtkControlPart::ScrollbarVerticalButton:
+        case GtkControlPart::ScrollbarHorizontalButton:
+        {
+            GtkStyleContext *pParent =
+                (ePart == GtkControlPart::ScrollbarVerticalButton) ? mpVScrollbarStyle : mpHScrollbarStyle;
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(pParent));
+            gtk_widget_path_append_type(path, GTK_TYPE_SCROLLBAR);
+            set_object_name(path, -1, "button");
+            return makeContext(path, pParent);
+        }
+        case GtkControlPart::ProgressBar:
+        {
+            GtkWidgetPath *path = gtk_widget_path_new();
+            gtk_widget_path_append_type(path, GTK_TYPE_PROGRESS_BAR);
+            set_object_name(path, -1, "progressbar");
+            gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_HORIZONTAL);
+            return makeContext(path, nullptr);
+        }
+        case GtkControlPart::ProgressBarTrough:
+        {
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpProgressBarStyle));
+            gtk_widget_path_append_type(path, GTK_TYPE_PROGRESS_BAR);
+            set_object_name(path, -1, "trough");
+            return makeContext(path, mpProgressBarStyle);
+        }
+        case GtkControlPart::ProgressBarProgress:
+        {
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpProgressBarTroughStyle));
+            gtk_widget_path_append_type(path, GTK_TYPE_PROGRESS_BAR);
+            set_object_name(path, -1, "progress");
+            return makeContext(path, mpProgressBarTroughStyle);
+        }
+        case GtkControlPart::Notebook:
+        {
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpWindowStyle));
+            gtk_widget_path_append_type(path, GTK_TYPE_NOTEBOOK);
+            set_object_name(path, -1, "notebook");
+            return makeContext(path, mpWindowStyle);
+        }
+        case GtkControlPart::NotebookStack:
+        {
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpNotebookStyle));
+            gtk_widget_path_append_type(path, GTK_TYPE_NOTEBOOK);
+            set_object_name(path, -1, "stack");
+            return makeContext(path, mpNotebookStyle);
+        }
+        case GtkControlPart::NotebookHeader:
+        {
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpNotebookStyle));
+            gtk_widget_path_append_type(path, GTK_TYPE_NOTEBOOK);
+            set_object_name(path, -1, "header");
+            gtk_widget_path_iter_add_class(path, -1, "frame");
+            gtk_widget_path_iter_add_class(path, -1, "top");
+            return makeContext(path, mpNotebookStyle);
+        }
+        case GtkControlPart::NotebookHeaderTabs:
+        {
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpNotebookHeaderStyle));
+            gtk_widget_path_append_type(path, GTK_TYPE_NOTEBOOK);
+            set_object_name(path, -1, "tabs");
+            gtk_widget_path_iter_add_class(path, -1, "top");
+            return makeContext(path, mpNotebookHeaderStyle);
+        }
+        case GtkControlPart::NotebookHeaderTabsTab:
+        {
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpNotebookHeaderTabsStyle));
+            gtk_widget_path_append_type(path, GTK_TYPE_NOTEBOOK);
+            set_object_name(path, -1, "tab");
+            gtk_widget_path_iter_add_class(path, -1, "top");
+            return makeContext(path, mpNotebookHeaderTabsStyle);
+        }
+        case GtkControlPart::NotebookHeaderTabsTabLabel:
+        {
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpNotebookHeaderTabsTabStyle));
+            gtk_widget_path_append_type(path, G_TYPE_NONE);
+            set_object_name(path, -1, "label");
+            return makeContext(path, mpNotebookHeaderTabsTabStyle);
+        }
+        case GtkControlPart::NotebookHeaderTabsTabActiveLabel:
+        case GtkControlPart::NotebookHeaderTabsTabHoverLabel:
+            return mpNotebookHeaderTabsTabLabelStyle;
+        case GtkControlPart::FrameBorder:
+        {
+            GtkWidgetPath *path = gtk_widget_path_new();
+            gtk_widget_path_append_type(path, GTK_TYPE_FRAME);
+            set_object_name(path, -1, "frame");
+            gtk_widget_path_iter_add_class(path, -1, "frame");
+            return makeContext(path, nullptr);
+        }
+        case GtkControlPart::MenuBar:
+        {
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpWindowStyle));
+            gtk_widget_path_append_type(path, GTK_TYPE_MENU_BAR);
+            set_object_name(path, -1, "menubar");
+            return makeContext(path, mpWindowStyle);
+        }
+        case GtkControlPart::MenuBarItem:
+        {
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpMenuBarStyle));
+            gtk_widget_path_append_type(path, GTK_TYPE_MENU_ITEM);
+            set_object_name(path, -1, "menuitem");
+            return makeContext(path, mpMenuBarStyle);
+        }
+        case GtkControlPart::MenuWindow:
+        {
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpMenuBarItemStyle));
+            gtk_widget_path_append_type(path, G_TYPE_NONE);
+            set_object_name(path, -1, "window");
+            gtk_widget_path_iter_add_class(path, -1, "background");
+            gtk_widget_path_iter_add_class(path, -1, "popup");
+            return makeContext(path, mpMenuBarItemStyle);
+        }
+        case GtkControlPart::Menu:
+        {
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpMenuWindowStyle));
+            gtk_widget_path_append_type(path, GTK_TYPE_MENU);
+            set_object_name(path, -1, "menu");
+            return makeContext(path, mpMenuWindowStyle);
+        }
+        case GtkControlPart::MenuItem:
+        {
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpMenuStyle));
+            gtk_widget_path_append_type(path, GTK_TYPE_MENU_ITEM);
+            set_object_name(path, -1, "menuitem");
+            return makeContext(path, mpMenuStyle);
+        }
+        case GtkControlPart::MenuItemLabel:
+        {
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpMenuItemStyle));
+            gtk_widget_path_append_type(path, G_TYPE_NONE);
+            set_object_name(path, -1, "label");
+            return makeContext(path, mpMenuItemStyle);
+        }
+        case GtkControlPart::MenuItemArrow:
+        {
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpMenuItemStyle));
+            gtk_widget_path_append_type(path, GTK_TYPE_MENU_ITEM);
+            set_object_name(path, -1, "arrow");
+            return makeContext(path, mpMenuItemStyle);
+        }
+        case GtkControlPart::CheckMenuItem:
+        {
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpMenuStyle));
+            gtk_widget_path_append_type(path, GTK_TYPE_CHECK_MENU_ITEM);
+            set_object_name(path, -1, "menuitem");
+            return makeContext(path, mpMenuStyle);
+        }
+        case GtkControlPart::CheckMenuItemCheck:
+        {
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpCheckMenuItemStyle));
+            gtk_widget_path_append_type(path, GTK_TYPE_CHECK_MENU_ITEM);
+            set_object_name(path, -1, "check");
+            return makeContext(path, mpCheckMenuItemStyle);
+        }
+        case GtkControlPart::RadioMenuItem:
+        {
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpMenuStyle));
+            gtk_widget_path_append_type(path, GTK_TYPE_RADIO_MENU_ITEM);
+            set_object_name(path, -1, "menuitem");
+            return makeContext(path, mpMenuStyle);
+        }
+        case GtkControlPart::RadioMenuItemRadio:
+        {
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpRadioMenuItemStyle));
+            gtk_widget_path_append_type(path, GTK_TYPE_RADIO_MENU_ITEM);
+            set_object_name(path, -1, "radio");
+            return makeContext(path, mpRadioMenuItemStyle);
+        }
+        case GtkControlPart::SeparatorMenuItem:
+        {
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpMenuStyle));
+            gtk_widget_path_append_type(path, GTK_TYPE_SEPARATOR_MENU_ITEM);
+            set_object_name(path, -1, "menuitem");
+            return makeContext(path, mpMenuStyle);
+        }
+        case GtkControlPart::SeparatorMenuItemSeparator:
+        {
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpSeparatorMenuItemStyle));
+            gtk_widget_path_append_type(path, GTK_TYPE_SEPARATOR_MENU_ITEM);
+            set_object_name(path, -1, "separator");
+            return makeContext(path, mpSeparatorMenuItemStyle);
+        }
+    }
+
+    return nullptr;
+}
+
+#ifndef GTK_STYLE_CLASS_POPUP
+#define GTK_STYLE_CLASS_POPUP "popup"
 #endif
-        break;
-    case GtkControlPart::Entry:
+#ifndef GTK_STYLE_CLASS_LABEL
+#define GTK_STYLE_CLASS_LABEL "label"
+#endif
+
+GtkStyleContext* GtkSalGraphics::createOldContext(GtkControlPart ePart)
+{
+    switch (ePart)
+    {
+        case GtkControlPart::ToplevelWindow:
+        {
+            GtkWidgetPath *path = gtk_widget_path_new();
+            gtk_widget_path_append_type(path, GTK_TYPE_WINDOW);
+            gtk_widget_path_iter_add_class(path, -1, "background");
+            return makeContext(path, nullptr);
+        }
+        case GtkControlPart::Button:
+        {
+            GtkWidgetPath *path = gtk_widget_path_new();
+            gtk_widget_path_append_type(path, GTK_TYPE_BUTTON);
+            gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_BUTTON);
+            gtk_widget_path_iter_add_class(path, -1, "button");
+            gtk_widget_path_iter_add_class(path, -1, "text-button");
+            return makeContext(path, nullptr);
+        }
+        case GtkControlPart::LinkButton:
+        {
+            GtkWidgetPath *path = gtk_widget_path_new();
+            gtk_widget_path_append_type(path, GTK_TYPE_LINK_BUTTON);
+            gtk_widget_path_iter_add_class(path, -1, "text-button");
+            return makeContext(path, nullptr);
+        }
+        case GtkControlPart::CheckButton:
+        {
+            GtkWidgetPath *path = gtk_widget_path_new();
+            gtk_widget_path_append_type(path, GTK_TYPE_CHECK_BUTTON);
+            gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_CHECK);
+            gtk_widget_path_iter_add_class(path, -1, "text-button");
+            return makeContext(path, nullptr);
+        }
+        case GtkControlPart::CheckButtonCheck:
+            return mpCheckButtonStyle;
+        case GtkControlPart::RadioButton:
+        {
+            GtkWidgetPath *path = gtk_widget_path_new();
+            gtk_widget_path_append_type(path, GTK_TYPE_RADIO_BUTTON);
+            gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_RADIO);
+            gtk_widget_path_iter_add_class(path, -1, "text-button");
+            return makeContext(path, nullptr);
+        }
+        case GtkControlPart::RadioButtonRadio:
+            return mpRadioButtonStyle;
+        case GtkControlPart::ComboboxBoxButtonBoxArrow:
+        case GtkControlPart::ListboxBoxButtonBoxArrow:
+        {
+            return (ePart == GtkControlPart::ComboboxBoxButtonBoxArrow)
+                ? mpComboboxButtonStyle : mpListboxButtonStyle;
+        }
+        case GtkControlPart::Entry:
+        case GtkControlPart::ComboboxBoxEntry:
+        case GtkControlPart::SpinButtonEntry:
+        {
+            GtkWidgetPath *path = gtk_widget_path_new();
             gtk_widget_path_append_type(path, GTK_TYPE_ENTRY);
-#if GTK_CHECK_VERSION(3, 19, 2)
-            gtk_widget_path_iter_set_object_name(path, -1, "entry");
-#else
             gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_ENTRY);
-#endif
-            break;
+            return makeContext(path, nullptr);
+        }
+        case GtkControlPart::Combobox:
+        {
+            GtkWidgetPath *path = gtk_widget_path_new();
+            gtk_widget_path_append_type(path, GTK_TYPE_COMBO_BOX_TEXT);
+            return makeContext(path, nullptr);
+        }
+        case GtkControlPart::Listbox:
+        {
+            GtkWidgetPath *path = gtk_widget_path_new();
+            gtk_widget_path_append_type(path, GTK_TYPE_COMBO_BOX);
+            return makeContext(path, nullptr);
+        }
+        case GtkControlPart::ComboboxBoxButton:
+        case GtkControlPart::ListboxBoxButton:
+        {
+            GtkStyleContext *pParent =
+                (ePart == GtkControlPart::ComboboxBoxButton ) ? mpComboboxStyle : mpListboxStyle;
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(pParent));
+            gtk_widget_path_append_type(path, GTK_TYPE_TOGGLE_BUTTON);
+            gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_BUTTON);
+            gtk_widget_path_iter_add_class(path, -1, "the-button-in-the-combobox");
+            return makeContext(path, pParent);
+        }
         case GtkControlPart::SpinButton:
+        {
+            GtkWidgetPath *path = gtk_widget_path_new();
             gtk_widget_path_append_type(path, GTK_TYPE_SPIN_BUTTON);
-#if GTK_CHECK_VERSION(3, 19, 2)
-            gtk_widget_path_iter_set_object_name(path, -1, "spinbutton");
-#else
-            gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_SPINBUTTON);
-#endif
+            gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_ENTRY);
             gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_HORIZONTAL);
-            break;
+            gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_SPINBUTTON);
+            return makeContext(path, nullptr);
+        }
         case GtkControlPart::SpinButtonUpButton:
         case GtkControlPart::SpinButtonDownButton:
+        {
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpSpinStyle));
             gtk_widget_path_append_type(path, GTK_TYPE_SPIN_BUTTON);
-#if GTK_CHECK_VERSION(3, 19, 2)
-            gtk_widget_path_iter_set_object_name(path, -1, "button");
-            gtk_widget_path_iter_add_class(path, -1, ePart == GtkControlPart::SpinButtonUpButton ? "up" : "down");
-#else
             gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_SPINBUTTON);
             gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_BUTTON);
-#endif
-            break;
+            return makeContext(path, mpSpinStyle);
+        }
         case GtkControlPart::ScrollbarVertical:
         case GtkControlPart::ScrollbarHorizontal:
+        {
+            GtkWidgetPath *path = gtk_widget_path_new();
             gtk_widget_path_append_type(path, GTK_TYPE_SCROLLBAR);
-#if GTK_CHECK_VERSION(3, 19, 2)
-            gtk_widget_path_iter_set_object_name(path, -1, "scrollbar");
-#else
             gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_SCROLLBAR);
-#endif
             gtk_widget_path_iter_add_class(path, -1, ePart == GtkControlPart::ScrollbarVertical ? "vertical" : "horizontal");
-            break;
-        case GtkControlPart::ScrollbarContents:
+            return makeContext(path, nullptr);
+        }
+        case GtkControlPart::ScrollbarVerticalContents:
+        case GtkControlPart::ScrollbarHorizontalContents:
+        {
+            GtkStyleContext *pParent =
+                (ePart == GtkControlPart::ScrollbarVerticalContents) ? mpVScrollbarStyle : mpHScrollbarStyle;
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(pParent));
             gtk_widget_path_append_type(path, GTK_TYPE_SCROLLBAR);
-#if GTK_CHECK_VERSION(3, 19, 2)
-            gtk_widget_path_iter_set_object_name(path, -1, "contents");
-#else
             gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_SCROLLBAR);
             gtk_widget_path_iter_add_class(path, -1, "contents");
-#endif
-            break;
-        case GtkControlPart::ScrollbarTrough:
+            return makeContext(path, pParent);
+        }
+        case GtkControlPart::ScrollbarHorizontalTrough:
+        case GtkControlPart::ScrollbarVerticalTrough:
+        {
+            GtkStyleContext *pParent =
+                (ePart == GtkControlPart::ScrollbarVerticalTrough) ? mpVScrollbarContentsStyle : mpHScrollbarContentsStyle;
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(pParent));
             gtk_widget_path_append_type(path, GTK_TYPE_SCROLLBAR);
-#if GTK_CHECK_VERSION(3, 19, 2)
-            gtk_widget_path_iter_set_object_name(path, -1, "trough");
-#else
             gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_SCROLLBAR);
             gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_TROUGH);
-#endif
-            break;
-        case GtkControlPart::ScrollbarSlider:
+            return makeContext(path, pParent);
+        }
+        case GtkControlPart::ScrollbarHorizontalSlider:
+        case GtkControlPart::ScrollbarVerticalSlider:
+        {
+            GtkStyleContext *pParent =
+                (ePart == GtkControlPart::ScrollbarVerticalSlider) ? mpVScrollbarContentsStyle : mpHScrollbarContentsStyle;
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(pParent));
             gtk_widget_path_append_type(path, GTK_TYPE_SCROLLBAR);
-#if GTK_CHECK_VERSION(3, 19, 2)
-            gtk_widget_path_iter_set_object_name(path, -1, "slider");
-#else
             gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_SCROLLBAR);
             gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_SLIDER);
-#endif
-            break;
-        case GtkControlPart::ScrollbarButton:
+            return makeContext(path, pParent);
+        }
+        case GtkControlPart::ScrollbarHorizontalButton:
+        case GtkControlPart::ScrollbarVerticalButton:
+        {
+            GtkStyleContext *pParent =
+                (ePart == GtkControlPart::ScrollbarVerticalButton) ? mpVScrollbarStyle : mpHScrollbarStyle;
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(pParent));
             gtk_widget_path_append_type(path, GTK_TYPE_SCROLLBAR);
-#if GTK_CHECK_VERSION(3, 19, 2)
-            gtk_widget_path_iter_set_object_name(path, -1, "button");
-#else
             gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_SCROLLBAR);
             gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_BUTTON);
-#endif
-            break;
+            return makeContext(path, pParent);
+        }
         case GtkControlPart::ProgressBar:
+        {
+            GtkWidgetPath *path = gtk_widget_path_new();
             gtk_widget_path_append_type(path, GTK_TYPE_PROGRESS_BAR);
-#if GTK_CHECK_VERSION(3, 19, 2)
-            gtk_widget_path_iter_set_object_name(path, -1, "progressbar");
-#else
             gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_PROGRESSBAR);
-#endif
             gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_HORIZONTAL);
-            break;
+            return makeContext(path, nullptr);
+        }
         case GtkControlPart::ProgressBarTrough:
+        {
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpProgressBarStyle));
             gtk_widget_path_append_type(path, GTK_TYPE_PROGRESS_BAR);
-#if GTK_CHECK_VERSION(3, 19, 2)
-            gtk_widget_path_iter_set_object_name(path, -1, "trough");
-#else
             gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_PROGRESSBAR);
             gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_TROUGH);
-#endif
-            break;
+            return makeContext(path, mpProgressBarStyle);
+        }
         case GtkControlPart::ProgressBarProgress:
+        {
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpProgressBarTroughStyle));
             gtk_widget_path_append_type(path, GTK_TYPE_PROGRESS_BAR);
-#if GTK_CHECK_VERSION(3, 19, 2)
-            gtk_widget_path_iter_set_object_name(path, -1, "progress");
-#else
             gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_PROGRESSBAR);
-#endif
-            break;
+            return makeContext(path, mpProgressBarTroughStyle);
+        }
+        case GtkControlPart::Notebook:
+        {
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpWindowStyle));
+            gtk_widget_path_append_type(path, GTK_TYPE_NOTEBOOK);
+            gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_NOTEBOOK);
+            gtk_widget_path_iter_add_class(path, -1, "frame");
+            return makeContext(path, mpWindowStyle);
+        }
+        case GtkControlPart::NotebookStack:
+            return mpNotebookStyle;
+        case GtkControlPart::NotebookHeader:
+        {
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpNotebookStyle));
+            gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_HEADER);
+            gtk_widget_path_iter_add_class(path, -1, "top");
+            return makeContext(path, gtk_style_context_get_parent(mpNotebookStyle));
+        }
+        case GtkControlPart::NotebookHeaderTabs:
+            return mpNotebookHeaderStyle;
+        case GtkControlPart::NotebookHeaderTabsTab:
+        {
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpNotebookHeaderTabsStyle));
+            gtk_widget_path_append_type(path, GTK_TYPE_NOTEBOOK);
+            gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_HEADER);
+            gtk_widget_path_iter_add_class(path, -1, "top");
+            gtk_widget_path_iter_add_region(path, -1, GTK_STYLE_REGION_TAB, static_cast<GtkRegionFlags>(GTK_REGION_EVEN | GTK_REGION_FIRST));
+            return makeContext(path, mpNotebookHeaderTabsStyle);
+        }
+        case GtkControlPart::NotebookHeaderTabsTabLabel:
+        {
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpNotebookHeaderTabsTabStyle));
+            gtk_widget_path_append_type(path, GTK_TYPE_LABEL);
+            gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_LABEL);
+            return makeContext(path, mpNotebookHeaderTabsTabStyle);
+        }
+        case GtkControlPart::NotebookHeaderTabsTabActiveLabel:
+        {
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpNotebookHeaderTabsTabStyle));
+            gtk_widget_path_append_type(path, GTK_TYPE_LABEL);
+            gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_LABEL);
+            gtk_widget_path_iter_add_class(path, -1, "active-page");
+            return makeContext(path, mpNotebookHeaderTabsTabStyle);
+        }
+        case GtkControlPart::NotebookHeaderTabsTabHoverLabel:
+        {
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpNotebookHeaderTabsTabStyle));
+            gtk_widget_path_append_type(path, GTK_TYPE_LABEL);
+            gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_LABEL);
+            gtk_widget_path_iter_add_class(path, -1, "prelight-page");
+            return makeContext(path, mpNotebookHeaderTabsTabStyle);
+        }
+        case GtkControlPart::FrameBorder:
+        {
+            GtkWidgetPath *path = gtk_widget_path_new();
+            gtk_widget_path_append_type(path, GTK_TYPE_FRAME);
+            gtk_widget_path_iter_add_class(path, -1, "frame");
+            return makeContext(path, nullptr);
+        }
         case GtkControlPart::MenuBar:
+        {
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpWindowStyle));
             gtk_widget_path_append_type(path, GTK_TYPE_MENU_BAR);
-#if GTK_CHECK_VERSION(3, 19, 2)
-            gtk_widget_path_iter_set_object_name(path, -1, "menubar");
-#else
             gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_MENUBAR);
-#endif
-            break;
+            return makeContext(path, mpWindowStyle);
+        }
+        case GtkControlPart::MenuBarItem:
+        {
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpMenuBarStyle));
+            gtk_widget_path_append_type(path, GTK_TYPE_MENU_ITEM);
+            gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_MENUITEM);
+            return makeContext(path, mpMenuBarStyle);
+        }
+        case GtkControlPart::MenuWindow:
+        {
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpMenuBarItemStyle));
+            gtk_widget_path_append_type(path, GTK_TYPE_WINDOW);
+            gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_POPUP);
+            gtk_widget_path_iter_add_class(path, -1, "background");
+            return makeContext(path, mpMenuBarItemStyle);
+        }
+        case GtkControlPart::Menu:
+        {
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpMenuWindowStyle));
+            gtk_widget_path_append_type(path, GTK_TYPE_MENU);
+            gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_MENU);
+            return makeContext(path, mpMenuWindowStyle);
+        }
         case GtkControlPart::MenuItem:
+        {
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpMenuStyle));
             gtk_widget_path_append_type(path, GTK_TYPE_MENU_ITEM);
-#if GTK_CHECK_VERSION(3, 19, 2)
-            gtk_widget_path_iter_set_object_name(path, -1, "menuitem");
-#else
             gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_MENUITEM);
-#endif
-            break;
+            return makeContext(path, mpMenuStyle);
+        }
+        case GtkControlPart::MenuItemLabel:
+        {
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpMenuItemStyle));
+            gtk_widget_path_append_type(path, GTK_TYPE_LABEL);
+            return makeContext(path, mpMenuItemStyle);
+        }
         case GtkControlPart::MenuItemArrow:
+        {
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpMenuItemStyle));
             gtk_widget_path_append_type(path, GTK_TYPE_MENU_ITEM);
-#if GTK_CHECK_VERSION(3, 19, 2)
-            gtk_widget_path_iter_set_object_name(path, -1, "arrow");
-#else
             gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_ARROW);
-#endif
-            break;
-        case GtkControlPart::Menu:
-            gtk_widget_path_append_type(path, GTK_TYPE_MENU);
-#if GTK_CHECK_VERSION(3, 19, 2)
-            gtk_widget_path_iter_set_object_name(path, -1, "menu");
-#else
-            gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_MENU);
-#endif
-            break;
+            return makeContext(path, mpMenuItemStyle);
+        }
         case GtkControlPart::CheckMenuItem:
+        {
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpMenuStyle));
             gtk_widget_path_append_type(path, GTK_TYPE_CHECK_MENU_ITEM);
-#if GTK_CHECK_VERSION(3, 19, 2)
-            gtk_widget_path_iter_set_object_name(path, -1, "menuitem");
-#else
-            gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_MENUITEM);
-#endif
-            break;
+            gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_CHECK);
+            return makeContext(path, mpMenuStyle);
+        }
         case GtkControlPart::CheckMenuItemCheck:
+        {
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpCheckMenuItemStyle));
             gtk_widget_path_append_type(path, GTK_TYPE_CHECK_MENU_ITEM);
-#if GTK_CHECK_VERSION(3, 19, 2)
-            gtk_widget_path_iter_set_object_name(path, -1, "check");
-#else
             gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_CHECK);
-#endif
-            break;
+            return makeContext(path, mpCheckMenuItemStyle);
+        }
         case GtkControlPart::RadioMenuItem:
+        {
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpMenuStyle));
             gtk_widget_path_append_type(path, GTK_TYPE_RADIO_MENU_ITEM);
-#if GTK_CHECK_VERSION(3, 19, 2)
-            gtk_widget_path_iter_set_object_name(path, -1, "menuitem");
-#else
             gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_MENUITEM);
-#endif
-            break;
+            return makeContext(path, mpMenuStyle);
+        }
         case GtkControlPart::RadioMenuItemRadio:
+        {
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpRadioMenuItemStyle));
             gtk_widget_path_append_type(path, GTK_TYPE_RADIO_MENU_ITEM);
-#if GTK_CHECK_VERSION(3, 19, 2)
-            gtk_widget_path_iter_set_object_name(path, -1, "radio");
-#else
             gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_RADIO);
-#endif
-            break;
+            return makeContext(path, mpRadioMenuItemStyle);
+        }
         case GtkControlPart::SeparatorMenuItem:
+        {
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpMenuStyle));
             gtk_widget_path_append_type(path, GTK_TYPE_SEPARATOR_MENU_ITEM);
-#if GTK_CHECK_VERSION(3, 19, 2)
-            gtk_widget_path_iter_set_object_name(path, -1, "menuitem");
-#else
             gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_MENUITEM);
-#endif
-            break;
+            return makeContext(path, mpMenuStyle);
+        }
         case GtkControlPart::SeparatorMenuItemSeparator:
+        {
+            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpSeparatorMenuItemStyle));
             gtk_widget_path_append_type(path, GTK_TYPE_SEPARATOR_MENU_ITEM);
-#if GTK_CHECK_VERSION(3, 19, 2)
-            gtk_widget_path_iter_set_object_name(path, -1, "separator");
-#else
             gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_SEPARATOR);
-#endif
-            break;
-        case GtkControlPart::Notebook:
-            gtk_widget_path_append_type(path, GTK_TYPE_NOTEBOOK);
-#if GTK_CHECK_VERSION(3, 19, 2)
-            gtk_widget_path_iter_set_object_name(path, -1, "notebook");
-#else
-            gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_NOTEBOOK);
-#endif
-            gtk_widget_path_iter_add_class(path, -1, "frame");
-            break;
-        case GtkControlPart::NotebookStack:
-            gtk_widget_path_append_type(path, GTK_TYPE_NOTEBOOK);
-#if GTK_CHECK_VERSION(3, 19, 2)
-            gtk_widget_path_iter_set_object_name(path, -1, "stack");
-#else
-            gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_NOTEBOOK);
-#endif
-            break;
-        case GtkControlPart::NotebookHeader:
-            gtk_widget_path_append_type(path, GTK_TYPE_NOTEBOOK);
-#if GTK_CHECK_VERSION(3, 19, 2)
-            gtk_widget_path_iter_set_object_name(path, -1, "header");
-#else
-            gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_HEADER);
-#endif
-            gtk_widget_path_iter_add_class(path, -1, "frame");
-            gtk_widget_path_iter_add_class(path, -1, "top");
-            break;
-        case GtkControlPart::NotebookHeaderTabs:
-            gtk_widget_path_append_type(path, GTK_TYPE_NOTEBOOK);
-#if GTK_CHECK_VERSION(3, 19, 2)
-            gtk_widget_path_iter_set_object_name(path, -1, "tabs");
-#else
-            gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_HEADER);
-#endif
-            gtk_widget_path_iter_add_class(path, -1, "top");
-            break;
-        case GtkControlPart::NotebookHeaderTabsTab:
-            gtk_widget_path_append_type(path, GTK_TYPE_NOTEBOOK);
-#if GTK_CHECK_VERSION(3, 19, 2)
-            gtk_widget_path_iter_set_object_name(path, -1, "tab");
-#else
-            gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_HEADER);
-#endif
-            gtk_widget_path_iter_add_class(path, -1, "top");
-            break;
-        case GtkControlPart::FrameBorder:
-            gtk_widget_path_append_type(path, GTK_TYPE_FRAME);
-#if GTK_CHECK_VERSION(3, 19, 2)
-            gtk_widget_path_iter_set_object_name(path, -1, "frame");
-#endif
-            gtk_widget_path_iter_add_class(path, -1, "frame");
+            return makeContext(path, mpSeparatorMenuItemStyle);
+        }
+        case GtkControlPart::ComboboxBox:
+        case GtkControlPart::ListboxBox:
+        case GtkControlPart::ComboboxBoxButtonBox:
+        case GtkControlPart::ListboxBoxButtonBox:
+            return nullptr;
+        default:
             break;
     }
 
-    GtkStyleContext* context = gtk_style_context_new();
-    gtk_style_context_set_path(context, path);
-    gtk_style_context_set_parent(context, parent);
-    gtk_widget_path_unref (path);
-
-#if !GTK_CHECK_VERSION(3, 19, 2)
-    if (ePart == GtkControlPart::NotebookHeaderTabsTab)
-    {
-        gtk_style_context_add_region(context, GTK_STYLE_REGION_TAB, GTK_REGION_ONLY);
-    }
-#endif
+    return mpButtonStyle;
+}
 
-    return context;
+GtkStyleContext* GtkSalGraphics::createStyleContext(gtk_widget_path_iter_set_object_nameFunc set_object_name,
+                                                    GtkControlPart ePart)
+{
+    if (set_object_name)
+        return createNewContext(ePart, set_object_name);
+    return createOldContext(ePart);
 }
 
-#if GTK_CHECK_VERSION(3,13,7)
-#   define CHECKED GTK_STATE_FLAG_CHECKED
-#else
-#   define CHECKED GTK_STATE_FLAG_ACTIVE
+namespace
+{
+    GtkStateFlags CHECKED()
+    {
+#if GTK_CHECK_VERSION(3,14,0)
+        if (gtk_check_version(3, 14, 0) == nullptr)
+            return GTK_STATE_FLAG_CHECKED;
 #endif
+        return GTK_STATE_FLAG_ACTIVE;
+    }
 
-#if GTK_CHECK_VERSION(3,19,11)
-#   define ACTIVE_TAB GTK_STATE_FLAG_CHECKED
-#else
-#   define ACTIVE_TAB GTK_STATE_FLAG_ACTIVE
+    GtkStateFlags ACTIVE_TAB()
+    {
+#if GTK_CHECK_VERSION(3,20,0)
+        if (gtk_check_version(3, 20, 0) == nullptr)
+            return GTK_STATE_FLAG_CHECKED;
 #endif
+        return GTK_STATE_FLAG_ACTIVE;
+    }
+}
 
 void GtkSalGraphics::PaintCheckOrRadio(cairo_t *cr, GtkStyleContext *context,
                                        const Rectangle& rControlRectangle, bool bIsCheck, bool bInMenu)
@@ -1161,12 +1757,13 @@ void GtkSalGraphics::PaintCheckOrRadio(cairo_t *cr, GtkStyleContext *context,
 
     if (!bInMenu)
         gtk_render_background(context, cr, x, y, indicator_size, indicator_size);
-    gtk_render_frame(context, cr, x, y, indicator_size, indicator_size);
 
     if (bIsCheck)
         gtk_render_check(context, cr, x, y, indicator_size, indicator_size);
     else
         gtk_render_option(context, cr, x, y, indicator_size, indicator_size);
+
+    gtk_render_frame(context, cr, x, y, indicator_size, indicator_size);
 }
 
 void GtkSalGraphics::PaintCheck(cairo_t *cr, GtkStyleContext *context,
@@ -1181,14 +1778,6 @@ void GtkSalGraphics::PaintRadio(cairo_t *cr, GtkStyleContext *context,
     PaintCheckOrRadio(cr, context, rControlRectangle, false, bInMenu);
 }
 
-void parent_styles_context_set_state(GtkStyleContext* context, GtkStateFlags flags)
-{
-    while ((context = gtk_style_context_get_parent(context)))
-    {
-        gtk_style_context_set_state(context, flags);
-    }
-}
-
 static gfloat getArrowSize(GtkStyleContext* context)
 {
     gfloat arrow_scaling = 1.0;
@@ -1203,9 +1792,7 @@ bool GtkSalGraphics::drawNativeControl( ControlType nType, ControlPart nPart, co
 {
     RenderType renderType = nPart == ControlPart::Focus ? RenderType::Focus : RenderType::BackgroundAndFrame;
     GtkStyleContext *context = nullptr;
-#if !GTK_CHECK_VERSION(3,19,2)
     const gchar *styleClass = nullptr;
-#endif
     GdkPixbuf *pixbuf = nullptr;
     bool bInMenu = false;
 
@@ -1215,7 +1802,7 @@ bool GtkSalGraphics::drawNativeControl( ControlType nType, ControlPart nPart, co
     {
     case ControlType::Spinbox:
     case ControlType::SpinButtons:
-        context = mpEntryStyle;
+        context = mpSpinStyle;
         renderType = RenderType::Spinbutton;
         break;
     case ControlType::Editbox:
@@ -1229,8 +1816,16 @@ bool GtkSalGraphics::drawNativeControl( ControlType nType, ControlPart nPart, co
         renderType = RenderType::Combobox;
         break;
     case ControlType::Listbox:
-        context = mpListboxStyle;
-        renderType = nPart == ControlPart::Focus ? RenderType::Focus : RenderType::Combobox;
+        if (nPart == ControlPart::Focus)
+        {
+            renderType = RenderType::Focus;
+            context = mpListboxButtonStyle;
+        }
+        else
+        {
+            renderType = RenderType::Combobox;
+            context = mpListboxStyle;
+        }
         break;
     case ControlType::MenuPopup:
         bInMenu = true;
@@ -1246,45 +1841,48 @@ bool GtkSalGraphics::drawNativeControl( ControlType nType, ControlPart nPart, co
             renderType = RenderType::BackgroundAndFrame;
             break;
         case ControlPart::MenuItemCheckMark:
-#if GTK_CHECK_VERSION(3,19,2)
-            context = mpCheckMenuItemStyle;
-#else
-            context = gtk_widget_get_style_context(gCheckMenuItemWidget);
-            styleClass = GTK_STYLE_CLASS_CHECK;
-#endif
+            if (gtk_check_version(3, 20, 0) == nullptr)
+                context = mpCheckMenuItemCheckStyle;
+            else
+            {
+                context = gtk_widget_get_style_context(gCheckMenuItemWidget);
+                styleClass = GTK_STYLE_CLASS_CHECK;
+            }
             renderType = RenderType::Check;
             nType = ControlType::Checkbox;
             if (nState & ControlState::PRESSED)
             {
-                flags = (GtkStateFlags)(flags | CHECKED);
+                flags = (GtkStateFlags)(flags | CHECKED());
             }
             break;
         case ControlPart::MenuItemRadioMark:
-#if GTK_CHECK_VERSION(3,19,2)
-            context = mpRadioMenuItemStyle;
-#else
-            context = gtk_widget_get_style_context(gCheckMenuItemWidget);
-            styleClass = GTK_STYLE_CLASS_RADIO;
-#endif
+            if (gtk_check_version(3, 20, 0) == nullptr)
+                context = mpRadioMenuItemRadioStyle;
+            else
+            {
+                context = gtk_widget_get_style_context(gCheckMenuItemWidget);
+                styleClass = GTK_STYLE_CLASS_RADIO;
+            }
             renderType = RenderType::Radio;
             nType = ControlType::Radiobutton;
             if (nState & ControlState::PRESSED)
             {
-                flags = (GtkStateFlags)(flags | CHECKED);
+                flags = (GtkStateFlags)(flags | CHECKED());
             }
             break;
         case ControlPart::Separator:
-            context = mpSeparatorMenuItemStyle;
+            context = mpSeparatorMenuItemSeparatorStyle;
             flags = (GtkStateFlags)(GTK_STATE_FLAG_BACKDROP | GTK_STATE_FLAG_INSENSITIVE); //GTK_STATE_FLAG_BACKDROP hack ?
             renderType = RenderType::MenuSeparator;
             break;
         case ControlPart::SubmenuArrow:
-#if GTK_CHECK_VERSION(3,19,2)
-            context = mpMenuItemArrowStyle;
-#else
-            context = gtk_widget_get_style_context(gCheckMenuItemWidget);
-            styleClass = GTK_STYLE_CLASS_ARROW;
-#endif
+            if (gtk_check_version(3, 20, 0) == nullptr)
+                context = mpMenuItemArrowStyle;
+            else
+            {
+                context = gtk_widget_get_style_context(gCheckMenuItemWidget);
+                styleClass = GTK_STYLE_CLASS_ARROW;
+            }
             renderType = RenderType::Arrow;
             break;
         case ControlPart::Entire:
@@ -1317,16 +1915,16 @@ bool GtkSalGraphics::drawNativeControl( ControlType nType, ControlPart nPart, co
         break;
     case ControlType::Radiobutton:
         flags = (GtkStateFlags)(flags |
-                ( (rValue.getTristateVal() == ButtonValue::On) ? CHECKED : GTK_STATE_FLAG_NORMAL));
-        context = mpRadioButtonStyle;
+                ( (rValue.getTristateVal() == ButtonValue::On) ? CHECKED() : GTK_STATE_FLAG_NORMAL));
+        context = mpRadioButtonRadioStyle;
         renderType = nPart == ControlPart::Focus ? RenderType::Focus : RenderType::Radio;
         break;
     case ControlType::Checkbox:
         flags = (GtkStateFlags)(flags |
-                ( (rValue.getTristateVal() == ButtonValue::On) ? CHECKED :
+                ( (rValue.getTristateVal() == ButtonValue::On) ? CHECKED() :
                   (rValue.getTristateVal() == ButtonValue::Mixed) ? GTK_STATE_FLAG_INCONSISTENT :
                   GTK_STATE_FLAG_NORMAL));
-        context = mpCheckButtonStyle;
+        context = mpCheckButtonCheckStyle;
         renderType = nPart == ControlPart::Focus ? RenderType::Focus : RenderType::Check;
         break;
     case ControlType::Pushbutton:
@@ -1359,7 +1957,8 @@ bool GtkSalGraphics::drawNativeControl( ControlType nType, ControlPart nPart, co
     case ControlType::TabItem:
         context = mpNotebookHeaderTabsTabStyle;
         if (nState & ControlState::SELECTED)
-            flags = (GtkStateFlags) (flags | ACTIVE_TAB);
+            flags = (GtkStateFlags) (flags | ACTIVE_TAB());
+        renderType = RenderType::TabItem;
         break;
     case ControlType::WindowBackground:
         context = gtk_widget_get_style_context(mpWindow);
@@ -1397,7 +1996,7 @@ bool GtkSalGraphics::drawNativeControl( ControlType nType, ControlPart nPart, co
         context = mpTreeHeaderButtonStyle;
         ButtonValue aButtonValue = rValue.getTristateVal();
         if (aButtonValue == ButtonValue::On)
-            flags = (GtkStateFlags) (flags | CHECKED);
+            flags = (GtkStateFlags) (flags | CHECKED());
         renderType = RenderType::Expander;
         break;
     }
@@ -1431,31 +2030,12 @@ bool GtkSalGraphics::drawNativeControl( ControlType nType, ControlPart nPart, co
     long nWidth = rControlRegion.GetWidth();
     long nHeight = rControlRegion.GetHeight();
 
-    gtk_style_context_set_state(context, flags);
-    parent_styles_context_set_state(context, flags);
-    if (nType == ControlType::TabItem)
-    {
-        GtkBorder margin;
-#if GTK_CHECK_VERSION(3,19,2)
-        gtk_style_context_get_margin(mpNotebookHeaderTabsTabStyle, gtk_style_context_get_state(mpNotebookHeaderTabsTabStyle), &margin);
-#else
-        gint initial_gap(0);
-        gtk_style_context_get_style(mpNotebookStyle,
-                                "initial-gap", &initial_gap,
-                                nullptr);
-
-        margin.left = margin.right = initial_gap/2;
-#endif
-        nX += margin.left;
-        nWidth -= (margin.left + margin.right);
-    }
+    style_context_set_state(context, flags);
 
-#if !GTK_CHECK_VERSION(3,19,2)
     if (styleClass)
     {
         gtk_style_context_add_class(context, styleClass);
     }
-#endif
 
     switch(renderType)
     {
@@ -1483,10 +2063,37 @@ bool GtkSalGraphics::drawNativeControl( ControlType nType, ControlPart nPart, co
                         rControlRegion.GetWidth() - 1, rControlRegion.GetHeight() / 2);
         break;
     case RenderType::ToolbarSeparator:
-        gtk_render_line(context, cr,
-                        rControlRegion.GetWidth() / 2, rControlRegion.GetHeight() * 0.2,
-                        rControlRegion.GetWidth() / 2, rControlRegion.GetHeight() * 0.8 );
+    {
+        const bool bNewStyle = gtk_check_version(3, 20, 0) == nullptr;
+
+        gint nSeparatorWidth = 1;
+
+        if (bNewStyle)
+        {
+            gtk_style_context_get(context,
+                gtk_style_context_get_state(context),
+                "min-width", &nSeparatorWidth, nullptr);
+        }
+
+        gint nHalfSeparatorWidth = nSeparatorWidth / 2;
+        gint nHalfRegionWidth = rControlRegion.GetWidth() / 2;
+
+        nX = nX + nHalfRegionWidth - nHalfSeparatorWidth;
+        nWidth = nSeparatorWidth;
+        nY = rControlRegion.GetHeight() * 0.1;
+        nHeight = rControlRegion.GetHeight() - (2 * nY);
+
+        if (bNewStyle)
+        {
+            gtk_render_background(context, cr, nX, nY, nSeparatorWidth, nHeight);
+            gtk_render_frame(context, cr, nX, nY, nSeparatorWidth, nHeight);
+        }
+        else
+        {
+            gtk_render_line(context, cr, nX, nY, nX, nY + nHeight);
+        }
         break;
+    }
     case RenderType::Separator:
         if (nPart == ControlPart::SeparatorHorz)
             gtk_render_line(context, cr, 0, nHeight / 2, nWidth - 1, nHeight / 2);
@@ -1505,7 +2112,7 @@ bool GtkSalGraphics::drawNativeControl( ControlType nType, ControlPart nPart, co
         PaintScrollbar(context, cr, rControlRegion, nType, nPart, rValue);
         break;
     case RenderType::Spinbutton:
-        PaintSpinButton(context, cr, rControlRegion, nType, nPart, rValue);
+        PaintSpinButton(flags, cr, rControlRegion, nType, nPart, rValue);
         break;
     case RenderType::Combobox:
         PaintCombobox(flags, cr, rControlRegion, nType, nPart, rValue);
@@ -1535,7 +2142,7 @@ bool GtkSalGraphics::drawNativeControl( ControlType nType, ControlPart nPart, co
     case RenderType::Progress:
     {
         gtk_render_background(mpProgressBarTroughStyle, cr, nX, nY, nWidth, nHeight);
-        gtk_render_frame(mpProgressBarTroughStyle, cr, nX, nY, nWidth, nHeight);
+
         long nProgressWidth = rValue.getNumericVal();
         if (nProgressWidth)
         {
@@ -1550,18 +2157,34 @@ bool GtkSalGraphics::drawNativeControl( ControlType nType, ControlPart nPart, co
             gtk_render_frame(context, cr, nX, nY, nProgressWidth, nHeight);
         }
 
+        gtk_render_frame(mpProgressBarTroughStyle, cr, nX, nY, nWidth, nHeight);
+
+        break;
+    }
+    case RenderType::TabItem:
+    {
+        if (gtk_check_version(3, 20, 0) != nullptr)
+        {
+            gint initial_gap(0);
+            gtk_style_context_get_style(mpNotebookStyle,
+                                    "initial-gap", &initial_gap,
+                                    nullptr);
+
+            nX += initial_gap/2;
+            nWidth -= initial_gap;
+        }
+        Rectangle aRect(Point(nX, nY), Size(nWidth, nHeight));
+        render_common(mpNotebookHeaderTabsTabStyle, cr, aRect, flags);
         break;
     }
     default:
         break;
     }
 
-#if !GTK_CHECK_VERSION(3,19,2)
     if (styleClass)
     {
         gtk_style_context_remove_class(context, styleClass);
     }
-#endif
 
     cairo_destroy(cr); // unref
 
@@ -1611,7 +2234,7 @@ bool GtkSalGraphics::getNativeControlRegion( ControlType nType, ControlPart nPar
     {
         rNativeBoundingRegion = rControlRegion;
 
-        GtkStyleContext *pButtonStyle = (nType == ControlType::Checkbox) ? mpCheckButtonStyle : mpRadioButtonStyle;
+        GtkStyleContext *pButtonStyle = (nType == ControlType::Checkbox) ? mpCheckButtonCheckStyle : mpRadioButtonRadioStyle;
 
 
         gtk_style_context_get_style( pButtonStyle,
@@ -1641,7 +2264,8 @@ bool GtkSalGraphics::getNativeControlRegion( ControlType nType, ControlPart nPar
         {
             indicator_size = 0;
 
-            GtkStyleContext *pMenuItemStyle = (nPart == ControlPart::MenuItemCheckMark ) ? mpCheckMenuItemStyle : mpRadioMenuItemStyle;
+            GtkStyleContext *pMenuItemStyle = (nPart == ControlPart::MenuItemCheckMark ) ? mpCheckMenuItemCheckStyle
+                                                                                         : mpRadioMenuItemRadioStyle;
 
             gtk_style_context_get_style( pMenuItemStyle,
                                          "indicator-size", &indicator_size,
@@ -1655,7 +2279,7 @@ bool GtkSalGraphics::getNativeControlRegion( ControlType nType, ControlPart nPar
         {
             gint separator_height, separator_width, wide_separators;
 
-            gtk_style_context_get_style (mpSeparatorMenuItemStyle,
+            gtk_style_context_get_style (mpSeparatorMenuItemSeparatorStyle,
                                          "wide-separators",  &wide_separators,
                                          "separator-width",  &separator_width,
                                          "separator-height", &separator_height,
@@ -1685,10 +2309,6 @@ bool GtkSalGraphics::getNativeControlRegion( ControlType nType, ControlPart nPar
 
         return true;
     }
-    if( (nType == ControlType::Menubar) && (nPart == ControlPart::Entire) )
-    {
-        aEditRect = GetWidgetSize(rControlRegion, gMenuBarWidget);
-    }
     else if ( (nType==ControlType::Spinbox) &&
               ((nPart==ControlPart::ButtonUp) || (nPart==ControlPart::ButtonDown) ||
                (nPart==ControlPart::SubEdit)) )
@@ -1776,39 +2396,8 @@ static inline ::Color getColor( const GdkRGBA& rCol )
     return ::Color( (int)(rCol.red * 0xFFFF) >> 8, (int)(rCol.green * 0xFFFF) >> 8, (int)(rCol.blue * 0xFFFF) >> 8 );
 }
 
-void GtkSalGraphics::updateSettings( AllSettings& rSettings )
+static vcl::Font getFont(GtkStyleContext* pStyle, const css::lang::Locale& rLocale)
 {
-    GtkStyleContext* pStyle = gtk_widget_get_style_context( mpWindow );
-    GtkSettings* pSettings = gtk_widget_get_settings( mpWindow );
-    StyleSettings aStyleSet = rSettings.GetStyleSettings();
-    GdkRGBA color;
-
-    // text colors
-    GdkRGBA text_color;
-    gtk_style_context_set_state(pStyle, GTK_STATE_FLAG_NORMAL);
-    gtk_style_context_get_color(pStyle, gtk_style_context_get_state(pStyle), &text_color);
-    ::Color aTextColor = getColor( text_color );
-    aStyleSet.SetDialogTextColor( aTextColor );
-    aStyleSet.SetButtonTextColor( aTextColor );
-    aStyleSet.SetRadioCheckTextColor( aTextColor );
-    aStyleSet.SetGroupTextColor( aTextColor );
-    aStyleSet.SetLabelTextColor( aTextColor );
-    aStyleSet.SetInfoTextColor( aTextColor );
-    aStyleSet.SetWindowTextColor( aTextColor );
-    aStyleSet.SetFieldTextColor( aTextColor );
-
-    // background colors
-    GdkRGBA background_color;
-    gtk_style_context_get_background_color(pStyle, gtk_style_context_get_state(pStyle), &background_color);
-
-    ::Color aBackColor = getColor( background_color );
-    aStyleSet.Set3DColors( aBackColor );
-    aStyleSet.SetFaceColor( aBackColor );
-    aStyleSet.SetDialogColor( aBackColor );
-    aStyleSet.SetWorkspaceColor( aBackColor );
-    aStyleSet.SetCheckedColorSpecialCase( );
-
-    // UI font
     const PangoFontDescription* font = gtk_style_context_get_font(pStyle, gtk_style_context_get_state(pStyle));
     OString    aFamily        = pango_font_description_get_family( font );
     int nPangoHeight    = pango_font_description_get_size( font );
@@ -1856,7 +2445,7 @@ void GtkSalGraphics::updateSettings( AllSettings& rSettings )
 #endif
 
     // match font to e.g. resolve "Sans"
-    psp::PrintFontManager::get().matchFont( aInfo, rSettings.GetUILanguageTag().getLocale() );
+    psp::PrintFontManager::get().matchFont(aInfo, rLocale);
 
 #if OSL_DEBUG_LEVEL > 1
     fprintf( stderr, "font match %s, name AFTER: \"%s\"\n",
@@ -1865,13 +2454,6 @@ void GtkSalGraphics::updateSettings( AllSettings& rSettings )
 #endif
 
     int nPointHeight = 0;
-    /*sal_Int32 nDispDPIY = GetDisplay()->GetResolution().B();
-    static gboolean(*pAbso)(const PangoFontDescription*) =
-        (gboolean(*)(const PangoFontDescription*))osl_getAsciiFunctionSymbol( GetSalData()->m_pPlugin, "pango_font_description_get_size_is_absolute" );
-
-    if( pAbso && pAbso( font ) )
-        nPointHeight = (nPangoHeight * 72 + nDispDPIY*PANGO_SCALE/2) / (nDispDPIY * PANGO_SCALE);
-    else*/
         nPointHeight = nPangoHeight/PANGO_SCALE;
 
     vcl::Font aFont( aInfo.m_aFamilyName, Size( 0, nPointHeight ) );
@@ -1883,6 +2465,43 @@ void GtkSalGraphics::updateSettings( AllSettings& rSettings )
         aFont.SetItalic( aInfo.m_eItalic );
     if( aInfo.m_ePitch != PITCH_DONTKNOW )
         aFont.SetPitch( aInfo.m_ePitch );
+    return aFont;
+}
+
+void GtkSalGraphics::updateSettings( AllSettings& rSettings )
+{
+    GtkStyleContext* pStyle = gtk_widget_get_style_context( mpWindow );
+    GtkSettings* pSettings = gtk_widget_get_settings( mpWindow );
+    StyleSettings aStyleSet = rSettings.GetStyleSettings();
+    GdkRGBA color;
+
+    // text colors
+    GdkRGBA text_color;
+    style_context_set_state(pStyle, GTK_STATE_FLAG_NORMAL);
+    gtk_style_context_get_color(pStyle, gtk_style_context_get_state(pStyle), &text_color);
+    ::Color aTextColor = getColor( text_color );
+    aStyleSet.SetDialogTextColor( aTextColor );
+    aStyleSet.SetButtonTextColor( aTextColor );
+    aStyleSet.SetRadioCheckTextColor( aTextColor );
+    aStyleSet.SetGroupTextColor( aTextColor );
+    aStyleSet.SetLabelTextColor( aTextColor );
+    aStyleSet.SetInfoTextColor( aTextColor );
+    aStyleSet.SetWindowTextColor( aTextColor );
+    aStyleSet.SetFieldTextColor( aTextColor );
+
+    // background colors
+    GdkRGBA background_color;
+    gtk_style_context_get_background_color(pStyle, gtk_style_context_get_state(pStyle), &background_color);
+
+    ::Color aBackColor = getColor( background_color );
+    aStyleSet.Set3DColors( aBackColor );
+    aStyleSet.SetFaceColor( aBackColor );
+    aStyleSet.SetDialogColor( aBackColor );
+    aStyleSet.SetWorkspaceColor( aBackColor );
+    aStyleSet.SetCheckedColorSpecialCase( );
+
+    // UI font
+    vcl::Font aFont(getFont(pStyle, rSettings.GetUILanguageTag().getLocale()));
 
     aStyleSet.SetAppFont( aFont );
     aStyleSet.SetHelpFont( aFont );
@@ -1897,12 +2516,11 @@ void GtkSalGraphics::updateSettings( AllSettings& rSettings )
     aStyleSet.SetGroupFont( aFont );
 
     aFont.SetWeight( WEIGHT_BOLD );
-    aStyleSet.SetTabFont( aFont );  //pull from notebook style + GTK_STYLE_REGION_TAB ?
     aStyleSet.SetTitleFont( aFont );
     aStyleSet.SetFloatTitleFont( aFont );
 
     // mouse over text colors
-    gtk_style_context_set_state(pStyle, GTK_STATE_FLAG_PRELIGHT);
+    style_context_set_state(pStyle, GTK_STATE_FLAG_PRELIGHT);
     gtk_style_context_get_color(pStyle, gtk_style_context_get_state(pStyle), &text_color);
     aTextColor = getColor( text_color );
     aStyleSet.SetButtonRolloverTextColor( aTextColor );
@@ -1916,15 +2534,13 @@ void GtkSalGraphics::updateSettings( AllSettings& rSettings )
         guint pos = gtk_widget_path_append_type(pCPath, GTK_TYPE_WINDOW);
         gtk_widget_path_iter_add_class(pCPath, pos, GTK_STYLE_CLASS_TOOLTIP);
         pos = gtk_widget_path_append_type (pCPath, GTK_TYPE_LABEL);
-#if GTK_CHECK_VERSION(3,16,0)
         gtk_widget_path_iter_add_class(pCPath, pos, GTK_STYLE_CLASS_LABEL);
-#endif
         pCStyle = gtk_style_context_new();
         gtk_style_context_set_path(pCStyle, pCPath);
         gtk_widget_path_free(pCPath);
 
         GdkRGBA tooltip_bg_color, tooltip_fg_color;
-        gtk_style_context_set_state(pCStyle, GTK_STATE_FLAG_NORMAL);
+        style_context_set_state(pCStyle, GTK_STATE_FLAG_NORMAL);
         gtk_style_context_get_color(pCStyle, gtk_style_context_get_state(pCStyle), &tooltip_fg_color);
         gtk_style_context_get_background_color(pCStyle, gtk_style_context_get_state(pCStyle), &tooltip_bg_color);
         g_object_unref( pCStyle );
@@ -1944,7 +2560,7 @@ void GtkSalGraphics::updateSettings( AllSettings& rSettings )
         gtk_widget_path_free( pCPath );
 

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list