[Libreoffice-commits] core.git: vcl/inc vcl/unx

Caolán McNamara caolanm at redhat.com
Tue Dec 5 15:59:56 UTC 2017


 vcl/inc/unx/gtk/gtkgdi.hxx                |    4 
 vcl/unx/gtk/gtkinst.cxx                   |    2 
 vcl/unx/gtk/gtksalmenu.cxx                |    7 
 vcl/unx/gtk3/gtk3gtkframe.cxx             |   29 
 vcl/unx/gtk3/gtk3salnativewidgets-gtk.cxx | 1739 +++++++++++++++++++++---------
 5 files changed, 1302 insertions(+), 479 deletions(-)

New commits:
commit 8c8fa0783ddfee50e55deae307901a1691b88009
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Tue Dec 5 15:55:20 2017 +0000

    Revert "require at least gtk3 3.20.0 to build and run gtk3 bits"
    
    Linux-deb-x86_64_56-lhm-ubuntu-trusty is at 3.18, not defunct
    Linux-Ubuntu-x86_64_54-TDE
    
    This reverts commit 75e828cad5e652f111278b103b72b9a9a344b689.
    
    Change-Id: I8939e4bb1876186f5ed75b3ad4c2626e37e4c81c

diff --git a/vcl/inc/unx/gtk/gtkgdi.hxx b/vcl/inc/unx/gtk/gtkgdi.hxx
index 386224895471..fc896db7f913 100644
--- a/vcl/inc/unx/gtk/gtkgdi.hxx
+++ b/vcl/inc/unx/gtk/gtkgdi.hxx
@@ -131,7 +131,9 @@ public:
 
     virtual void GetResolution(sal_Int32& rDPIX, sal_Int32& rDPIY) override;
 
-    GtkStyleContext* createStyleContext(GtkControlPart ePart);
+    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;
diff --git a/vcl/unx/gtk/gtkinst.cxx b/vcl/unx/gtk/gtkinst.cxx
index 2aeffb894952..30f0aa51843f 100644
--- a/vcl/unx/gtk/gtkinst.cxx
+++ b/vcl/unx/gtk/gtkinst.cxx
@@ -82,7 +82,7 @@ extern "C"
             XInitThreads();
 
 #if GTK_CHECK_VERSION(3,0,0)
-        if (gtk_minor_version < 20)
+        if (gtk_minor_version < 18)
         {
             g_warning("require a newer gtk than 3.%d for theme expectations", gtk_minor_version);
             return nullptr;
diff --git a/vcl/unx/gtk/gtksalmenu.cxx b/vcl/unx/gtk/gtksalmenu.cxx
index 61be00fe48c3..6f16984ba6d0 100644
--- a/vcl/unx/gtk/gtksalmenu.cxx
+++ b/vcl/unx/gtk/gtksalmenu.cxx
@@ -630,7 +630,12 @@ void GtkSalMenu::ShowCloseButton(bool bShow)
       "min-width: 18px;"
       "min-height: 18px;"
       "}";
-    gtk_css_provider_load_from_data(pProvider, data, -1, nullptr);
+    const gchar olddata[] = "* { "
+      "padding: 0;"
+      "margin-left: 8px;"
+      "margin-right: 8px;"
+      "}";
+    gtk_css_provider_load_from_data(pProvider, gtk_check_version(3, 20, 0) == nullptr ? data : olddata, -1, nullptr);
     gtk_style_context_add_provider(pButtonContext,
                                    GTK_STYLE_PROVIDER(pProvider),
                                    GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
diff --git a/vcl/unx/gtk3/gtk3gtkframe.cxx b/vcl/unx/gtk3/gtk3gtkframe.cxx
index 8ce0586ea835..1f90760f7666 100644
--- a/vcl/unx/gtk3/gtk3gtkframe.cxx
+++ b/vcl/unx/gtk3/gtk3gtkframe.cxx
@@ -2081,15 +2081,36 @@ void GtkSalFrame::grabPointer( bool bGrab, bool bOwnerEvents )
     if (!m_pWindow)
         return;
 
-    GdkSeat* pSeat = gdk_display_get_default_seat(getGdkDisplay());
+#if GTK_CHECK_VERSION(3, 20, 0)
+    if (gtk_check_version(3, 20, 0) == nullptr)
+    {
+        GdkSeat* pSeat = gdk_display_get_default_seat(getGdkDisplay());
+        if (bGrab)
+        {
+            gdk_seat_grab(pSeat, widget_get_window(getMouseEventWidget()), GDK_SEAT_CAPABILITY_ALL_POINTING,
+                          bOwnerEvents, nullptr, nullptr, nullptr, nullptr);
+        }
+        else
+        {
+            gdk_seat_ungrab(pSeat);
+        }
+        return;
+    }
+#endif
+
+    //else older gtk3
+    const int nMask = (GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK);
+
+    GdkDeviceManager* pDeviceManager = gdk_display_get_device_manager(getGdkDisplay());
+    GdkDevice* pPointer = gdk_device_manager_get_client_pointer(pDeviceManager);
     if (bGrab)
     {
-        gdk_seat_grab(pSeat, widget_get_window(getMouseEventWidget()), GDK_SEAT_CAPABILITY_ALL_POINTING,
-                      bOwnerEvents, nullptr, nullptr, nullptr, nullptr);
+        gdk_device_grab(pPointer, widget_get_window(getMouseEventWidget()), GDK_OWNERSHIP_NONE,
+                        bOwnerEvents, (GdkEventMask) nMask, m_pCurrentCursor, gtk_get_current_event_time());
     }
     else
     {
-        gdk_seat_ungrab(pSeat);
+        gdk_device_ungrab(pPointer, gtk_get_current_event_time());
     }
 }
 
diff --git a/vcl/unx/gtk3/gtk3salnativewidgets-gtk.cxx b/vcl/unx/gtk3/gtk3salnativewidgets-gtk.cxx
index 5ae090f37d1d..38b724be27d8 100644
--- a/vcl/unx/gtk3/gtk3salnativewidgets-gtk.cxx
+++ b/vcl/unx/gtk3/gtk3salnativewidgets-gtk.cxx
@@ -259,6 +259,8 @@ tools::Rectangle GtkSalGraphics::NWGetScrollButtonRect( ControlPart nPart, tools
                                  "has-secondary-forward-stepper", &has_forward2,
                                  "has-backward-stepper", &has_backward,
                                  "has-secondary-backward-stepper", &has_backward2, nullptr );
+    gint       buttonWidth;
+    gint       buttonHeight;
 
     gint nFirst = 0;
     gint nSecond = 0;
@@ -268,46 +270,103 @@ tools::Rectangle GtkSalGraphics::NWGetScrollButtonRect( ControlPart nPart, tools
     if ( has_backward )  nFirst  += 1;
     if ( has_backward2 ) nSecond += 1;
 
-    Size aSize;
-    if (nPart == ControlPart::ButtonLeft || nPart == ControlPart::ButtonRight)
+    if (gtk_check_version(3, 20, 0) == nullptr)
     {
-        QuerySize(mpHScrollbarStyle, aSize);
-        QuerySize(mpHScrollbarContentsStyle, aSize);
-        QuerySize(mpHScrollbarButtonStyle, aSize);
+        Size aSize;
+        if (nPart == ControlPart::ButtonLeft || nPart == ControlPart::ButtonRight)
+        {
+            QuerySize(mpHScrollbarStyle, aSize);
+            QuerySize(mpHScrollbarContentsStyle, aSize);
+            QuerySize(mpHScrollbarButtonStyle, aSize);
+        }
+        else
+        {
+            QuerySize(mpVScrollbarStyle, aSize);
+            QuerySize(mpVScrollbarContentsStyle, aSize);
+            QuerySize(mpVScrollbarButtonStyle, aSize);
+        }
+
+        if (nPart == ControlPart::ButtonUp)
+        {
+            aSize.Height() *= nFirst;
+            buttonRect.setX(aAreaRect.Left());
+            buttonRect.setY(aAreaRect.Top());
+        }
+        else if (nPart == ControlPart::ButtonLeft)
+        {
+            aSize.Width() *= nFirst;
+            buttonRect.setX(aAreaRect.Left());
+            buttonRect.setY(aAreaRect.Top());
+        }
+        else if (nPart == ControlPart::ButtonDown)
+        {
+            aSize.Height() *= nSecond;
+            buttonRect.setX(aAreaRect.Left());
+            buttonRect.setY(aAreaRect.Top() + aAreaRect.GetHeight() - aSize.Height());
+        }
+        else if (nPart == ControlPart::ButtonRight)
+        {
+            aSize.Width() *= nSecond;
+            buttonRect.setX(aAreaRect.Left() + aAreaRect.GetWidth() - aSize.Width());
+            buttonRect.setY(aAreaRect.Top());
+        }
+
+        buttonRect.SetSize(aSize);
+
+        return buttonRect;
+    }
+
+    gint slider_width;
+    gint stepper_size;
+    gint stepper_spacing;
+    gint trough_border;
+
+    // Grab some button style attributes
+    gtk_style_context_get_style( pScrollbarStyle,
+                                 "slider-width", &slider_width,
+                                 "stepper-size", &stepper_size,
+                                 "trough-border", &trough_border,
+                                 "stepper-spacing", &stepper_spacing, nullptr );
+
+    if ( ( nPart == ControlPart::ButtonUp ) || ( nPart == ControlPart::ButtonDown ) )
+    {
+        buttonWidth = slider_width + 2 * trough_border;
+        buttonHeight = stepper_size + trough_border + stepper_spacing;
     }
     else
     {
-        QuerySize(mpVScrollbarStyle, aSize);
-        QuerySize(mpVScrollbarContentsStyle, aSize);
-        QuerySize(mpVScrollbarButtonStyle, aSize);
+        buttonWidth = stepper_size + trough_border + stepper_spacing;
+        buttonHeight = slider_width + 2 * trough_border;
     }
 
-    if (nPart == ControlPart::ButtonUp)
+    if ( nPart == ControlPart::ButtonUp )
     {
-        aSize.Height() *= nFirst;
-        buttonRect.setX(aAreaRect.Left());
-        buttonRect.setY(aAreaRect.Top());
+        buttonHeight *= nFirst;
+        buttonHeight -= 1;
+        buttonRect.setX( aAreaRect.Left() );
+        buttonRect.setY( aAreaRect.Top() );
     }
-    else if (nPart == ControlPart::ButtonLeft)
+    else if ( nPart == ControlPart::ButtonLeft )
     {
-        aSize.Width() *= nFirst;
-        buttonRect.setX(aAreaRect.Left());
-        buttonRect.setY(aAreaRect.Top());
+        buttonWidth *= nFirst;
+        buttonWidth -= 1;
+        buttonRect.setX( aAreaRect.Left() );
+        buttonRect.setY( aAreaRect.Top() );
     }
-    else if (nPart == ControlPart::ButtonDown)
+    else if ( nPart == ControlPart::ButtonDown )
     {
-        aSize.Height() *= nSecond;
-        buttonRect.setX(aAreaRect.Left());
-        buttonRect.setY(aAreaRect.Top() + aAreaRect.GetHeight() - aSize.Height());
+        buttonHeight *= nSecond;
+        buttonRect.setX( aAreaRect.Left() );
+        buttonRect.setY( aAreaRect.Top() + aAreaRect.GetHeight() - buttonHeight );
     }
-    else if (nPart == ControlPart::ButtonRight)
+    else if ( nPart == ControlPart::ButtonRight )
     {
-        aSize.Width() *= nSecond;
-        buttonRect.setX(aAreaRect.Left() + aAreaRect.GetWidth() - aSize.Width());
-        buttonRect.setY(aAreaRect.Top());
+        buttonWidth *= nSecond;
+        buttonRect.setX( aAreaRect.Left() + aAreaRect.GetWidth() - buttonWidth );
+        buttonRect.setY( aAreaRect.Top() );
     }
 
-    buttonRect.SetSize(aSize);
+    buttonRect.SetSize( Size( buttonWidth, buttonHeight ) );
 
     return buttonRect;
 }
@@ -379,7 +438,328 @@ void GtkSalGraphics::PaintScrollbar(GtkStyleContext *context,
                                     ControlPart nPart,
                                     const ImplControlValue& rValue )
 {
-    assert(rValue.getType() == ControlType::Scrollbar);
+    if (gtk_check_version(3, 20, 0) == nullptr)
+    {
+        assert(rValue.getType() == ControlType::Scrollbar);
+        const ScrollbarValue& rScrollbarVal = static_cast<const ScrollbarValue&>(rValue);
+        tools::Rectangle        scrollbarRect;
+        GtkStateFlags    stateFlags;
+        GtkOrientation    scrollbarOrientation;
+        tools::Rectangle        thumbRect = rScrollbarVal.maThumbRect;
+        tools::Rectangle        button11BoundRect = rScrollbarVal.maButton1Rect;   // backward
+        tools::Rectangle        button22BoundRect = rScrollbarVal.maButton2Rect;   // forward
+        tools::Rectangle        button12BoundRect = rScrollbarVal.maButton1Rect;   // secondary forward
+        tools::Rectangle        button21BoundRect = rScrollbarVal.maButton2Rect;   // secondary backward
+        gdouble          arrow1Angle;                                        // backward
+        gdouble          arrow2Angle;                                        // forward
+        tools::Rectangle        arrowRect;
+        gint            slider_width = 0;
+        gint            stepper_size = 0;
+
+        // make controlvalue rectangles relative to area
+        thumbRect.Move( -rControlRectangle.Left(), -rControlRectangle.Top() );
+        button11BoundRect.Move( -rControlRectangle.Left(), -rControlRectangle.Top() );
+        button22BoundRect.Move( -rControlRectangle.Left(), -rControlRectangle.Top() );
+        button12BoundRect.Move( -rControlRectangle.Left(), -rControlRectangle.Top() );
+        button21BoundRect.Move( -rControlRectangle.Left(), -rControlRectangle.Top() );
+
+        // Find the overall bounding rect of the control
+        scrollbarRect = rControlRectangle;
+        if (scrollbarRect.GetWidth() <= 0 || scrollbarRect.GetHeight() <= 0)
+            return;
+
+        gint slider_side;
+        Size aSize;
+        if (nPart == ControlPart::DrawBackgroundHorz)
+        {
+            QuerySize(mpHScrollbarStyle, aSize);
+            QuerySize(mpHScrollbarContentsStyle, aSize);
+            QuerySize(mpHScrollbarTroughStyle, aSize);
+            QuerySize(mpHScrollbarSliderStyle, aSize);
+            slider_side = aSize.Height();
+            gtk_style_context_get(mpHScrollbarButtonStyle,
+                                  gtk_style_context_get_state(mpHScrollbarButtonStyle),
+                                  "min-height", &slider_width,
+                                  "min-width", &stepper_size, nullptr);
+        }
+        else
+        {
+            QuerySize(mpVScrollbarStyle, aSize);
+            QuerySize(mpVScrollbarContentsStyle, aSize);
+            QuerySize(mpVScrollbarTroughStyle, aSize);
+            QuerySize(mpVScrollbarSliderStyle, aSize);
+            slider_side = aSize.Width();
+            gtk_style_context_get(mpVScrollbarButtonStyle,
+                                  gtk_style_context_get_state(mpVScrollbarButtonStyle),
+                                  "min-width", &slider_width,
+                                  "min-height", &stepper_size, nullptr);
+        }
+
+        gboolean has_forward;
+        gboolean has_forward2;
+        gboolean has_backward;
+        gboolean has_backward2;
+
+        gtk_style_context_get_style( context,
+                                     "has-forward-stepper", &has_forward,
+                                     "has-secondary-forward-stepper", &has_forward2,
+                                     "has-backward-stepper", &has_backward,
+                                     "has-secondary-backward-stepper", &has_backward2, nullptr );
+
+        if ( nPart == ControlPart::DrawBackgroundHorz )
+        {
+            // Center vertically in the track
+            scrollbarRect.Move( 0, (scrollbarRect.GetHeight() - slider_side) / 2 );
+            scrollbarRect.SetSize( Size( scrollbarRect.GetWidth(), slider_side ) );
+            thumbRect.Move( 0, (scrollbarRect.GetHeight() - slider_side) / 2 );
+            thumbRect.SetSize( Size( thumbRect.GetWidth(), slider_side ) );
+
+            scrollbarOrientation = GTK_ORIENTATION_HORIZONTAL;
+            arrow1Angle = G_PI * 3 / 2;
+            arrow2Angle = G_PI / 2;
+
+            if ( has_backward )
+            {
+                button12BoundRect.Move( stepper_size,
+                                        (scrollbarRect.GetHeight() - slider_width) / 2 );
+            }
+
+            button11BoundRect.Move( 0, (scrollbarRect.GetHeight() - slider_width) / 2 );
+            button11BoundRect.SetSize( Size( stepper_size, slider_width ) );
+            button12BoundRect.SetSize( Size( stepper_size, slider_width ) );
+
+            if ( has_backward2 )
+            {
+                button22BoundRect.Move( stepper_size, (scrollbarRect.GetHeight() - slider_width) / 2 );
+                button21BoundRect.Move( 0, (scrollbarRect.GetHeight() - slider_width) / 2 );
+            }
+            else
+            {
+                button22BoundRect.Move( 0, (scrollbarRect.GetHeight() - slider_width) / 2 );
+            }
+
+            button21BoundRect.SetSize( Size( stepper_size, slider_width ) );
+            button22BoundRect.SetSize( Size( stepper_size, slider_width ) );
+        }
+        else
+        {
+            // Center horizontally in the track
+            scrollbarRect.Move( (scrollbarRect.GetWidth() - slider_side) / 2, 0 );
+            scrollbarRect.SetSize( Size( slider_side, scrollbarRect.GetHeight() ) );
+            thumbRect.Move( (scrollbarRect.GetWidth() - slider_side) / 2, 0 );
+            thumbRect.SetSize( Size( slider_side, thumbRect.GetHeight() ) );
+
+            scrollbarOrientation = GTK_ORIENTATION_VERTICAL;
+            arrow1Angle = 0;
+            arrow2Angle = G_PI;
+
+            if ( has_backward )
+            {
+                button12BoundRect.Move( (scrollbarRect.GetWidth() - slider_width) / 2,
+                                        stepper_size );
+            }
+            button11BoundRect.Move( (scrollbarRect.GetWidth() - slider_width) / 2, 0 );
+            button11BoundRect.SetSize( Size( slider_width, stepper_size ) );
+            button12BoundRect.SetSize( Size( slider_width, stepper_size ) );
+
+            if ( has_backward2 )
+            {
+                button22BoundRect.Move( (scrollbarRect.GetWidth() - slider_width) / 2, stepper_size );
+                button21BoundRect.Move( (scrollbarRect.GetWidth() - slider_width) / 2, 0 );
+            }
+            else
+            {
+                button22BoundRect.Move( (scrollbarRect.GetWidth() - slider_width) / 2, 0 );
+            }
+
+            button21BoundRect.SetSize( Size( slider_width, stepper_size ) );
+            button22BoundRect.SetSize( Size( slider_width, stepper_size ) );
+        }
+
+        bool has_slider = ( thumbRect.GetWidth() > 0 && thumbRect.GetHeight() > 0 );
+
+        // ----------------- CONTENTS
+        GtkStyleContext* pScrollbarContentsStyle = scrollbarOrientation == GTK_ORIENTATION_VERTICAL ?
+                                                  mpVScrollbarContentsStyle : mpHScrollbarContentsStyle;
+
+        gtk_render_background(gtk_widget_get_style_context(gCacheWindow), cr, 0, 0,
+                              scrollbarRect.GetWidth(), scrollbarRect.GetHeight() );
+
+        gtk_render_background(context, cr, 0, 0,
+                              scrollbarRect.GetWidth(), scrollbarRect.GetHeight() );
+        gtk_render_frame(context, cr, 0, 0,
+                         scrollbarRect.GetWidth(), scrollbarRect.GetHeight() );
+
+        gtk_render_background(pScrollbarContentsStyle, cr, 0, 0,
+                              scrollbarRect.GetWidth(), scrollbarRect.GetHeight() );
+        gtk_render_frame(pScrollbarContentsStyle, cr, 0, 0,
+                         scrollbarRect.GetWidth(), scrollbarRect.GetHeight() );
+
+        bool backwardButtonInsensitive =
+            rScrollbarVal.mnCur == rScrollbarVal.mnMin;
+        bool forwardButtonInsensitive = rScrollbarVal.mnMax == 0 ||
+            rScrollbarVal.mnCur + rScrollbarVal.mnVisibleSize >= rScrollbarVal.mnMax;
+
+        // ----------------- BUTTON 1
+        if ( has_backward )
+        {
+            stateFlags = NWConvertVCLStateToGTKState(rScrollbarVal.mnButton1State);
+            if ( backwardButtonInsensitive )
+                stateFlags = GTK_STATE_FLAG_INSENSITIVE;
+
+            GtkStyleContext* pScrollbarButtonStyle = scrollbarOrientation == GTK_ORIENTATION_VERTICAL ?
+                                                     mpVScrollbarButtonStyle : mpHScrollbarButtonStyle;
+
+            gtk_style_context_set_state(pScrollbarButtonStyle, stateFlags);
+
+            gtk_render_background(pScrollbarButtonStyle, cr,
+                                  button11BoundRect.Left(), button11BoundRect.Top(),
+                                  button11BoundRect.GetWidth(), button11BoundRect.GetHeight() );
+            gtk_render_frame(pScrollbarButtonStyle, cr,
+                             button11BoundRect.Left(), button11BoundRect.Top(),
+                             button11BoundRect.GetWidth(), button11BoundRect.GetHeight() );
+
+            // ----------------- ARROW 1
+            NWCalcArrowRect( button11BoundRect, arrowRect );
+            gtk_render_arrow(pScrollbarButtonStyle, cr,
+                             arrow1Angle,
+                             arrowRect.Left(), arrowRect.Top(),
+                             MIN(arrowRect.GetWidth(), arrowRect.GetHeight()) );
+        }
+        if ( has_forward2 )
+        {
+            stateFlags = NWConvertVCLStateToGTKState(rScrollbarVal.mnButton2State);
+            if ( forwardButtonInsensitive )
+                stateFlags = GTK_STATE_FLAG_INSENSITIVE;
+
+            GtkStyleContext* pScrollbarButtonStyle = scrollbarOrientation == GTK_ORIENTATION_VERTICAL ?
+                                                     mpVScrollbarButtonStyle : mpHScrollbarButtonStyle;
+
+            gtk_style_context_set_state(pScrollbarButtonStyle, stateFlags);
+
+            gtk_render_background(pScrollbarButtonStyle, cr,
+                                  button12BoundRect.Left(), button12BoundRect.Top(),
+                                  button12BoundRect.GetWidth(), button12BoundRect.GetHeight() );
+            gtk_render_frame(pScrollbarButtonStyle, cr,
+                             button12BoundRect.Left(), button12BoundRect.Top(),
+                             button12BoundRect.GetWidth(), button12BoundRect.GetHeight() );
+
+            // ----------------- ARROW 1
+            NWCalcArrowRect( button12BoundRect, arrowRect );
+            gtk_render_arrow(pScrollbarButtonStyle, cr,
+                             arrow2Angle,
+                             arrowRect.Left(), arrowRect.Top(),
+                             MIN(arrowRect.GetWidth(), arrowRect.GetHeight()) );
+        }
+        // ----------------- BUTTON 2
+
+        if ( has_forward )
+        {
+            stateFlags = NWConvertVCLStateToGTKState(rScrollbarVal.mnButton2State);
+            if ( forwardButtonInsensitive )
+                stateFlags = GTK_STATE_FLAG_INSENSITIVE;
+
+            GtkStyleContext* pScrollbarButtonStyle = scrollbarOrientation == GTK_ORIENTATION_VERTICAL ?
+                                                     mpVScrollbarButtonStyle : mpHScrollbarButtonStyle;
+
+            gtk_style_context_set_state(pScrollbarButtonStyle, stateFlags);
+
+            gtk_render_background(pScrollbarButtonStyle, cr,
+                           button22BoundRect.Left(), button22BoundRect.Top(),
+                           button22BoundRect.GetWidth(), button22BoundRect.GetHeight() );
+            gtk_render_frame(pScrollbarButtonStyle, cr,
+                           button22BoundRect.Left(), button22BoundRect.Top(),
+                           button22BoundRect.GetWidth(), button22BoundRect.GetHeight() );
+
+            // ----------------- ARROW 2
+            NWCalcArrowRect( button22BoundRect, arrowRect );
+            gtk_render_arrow(pScrollbarButtonStyle, cr,
+                             arrow2Angle,
+                             arrowRect.Left(), arrowRect.Top(),
+                             MIN(arrowRect.GetWidth(), arrowRect.GetHeight()) );
+        }
+
+        if ( has_backward2 )
+        {
+            stateFlags = NWConvertVCLStateToGTKState(rScrollbarVal.mnButton1State);
+            if ( backwardButtonInsensitive )
+                stateFlags = GTK_STATE_FLAG_INSENSITIVE;
+
+            GtkStyleContext* pScrollbarButtonStyle = scrollbarOrientation == GTK_ORIENTATION_VERTICAL ?
+                                                     mpVScrollbarButtonStyle : mpHScrollbarButtonStyle;
+
+            gtk_style_context_set_state(pScrollbarButtonStyle, stateFlags);
+
+            gtk_render_background(pScrollbarButtonStyle, cr,
+                                  button21BoundRect.Left(), button21BoundRect.Top(),
+                                  button21BoundRect.GetWidth(), button21BoundRect.GetHeight() );
+            gtk_render_frame(pScrollbarButtonStyle, cr,
+                             button21BoundRect.Left(), button21BoundRect.Top(),
+                             button21BoundRect.GetWidth(), button21BoundRect.GetHeight() );
+
+            // ----------------- ARROW 2
+            NWCalcArrowRect( button21BoundRect, arrowRect );
+            gtk_render_arrow(pScrollbarButtonStyle, cr,
+                             arrow1Angle,
+                             arrowRect.Left(), arrowRect.Top(),
+                             MIN(arrowRect.GetWidth(), arrowRect.GetHeight()) );
+        }
+
+        // ----------------- TROUGH
+        // trackrect matches that of ScrollBar::ImplCalc
+        tools::Rectangle aTrackRect(Point(0, 0), scrollbarRect.GetSize());
+        if (nPart == ControlPart::DrawBackgroundHorz)
+        {
+            tools::Rectangle aBtn1Rect = NWGetScrollButtonRect(ControlPart::ButtonLeft, aTrackRect);
+            tools::Rectangle aBtn2Rect = NWGetScrollButtonRect(ControlPart::ButtonRight, aTrackRect);
+            aTrackRect.Left() = aBtn1Rect.Right();
+            aTrackRect.Right() = aBtn2Rect.Left();
+        }
+        else
+        {
+            tools::Rectangle aBtn1Rect = NWGetScrollButtonRect(ControlPart::ButtonUp, aTrackRect);
+            tools::Rectangle aBtn2Rect = NWGetScrollButtonRect(ControlPart::ButtonDown, aTrackRect);
+            aTrackRect.Top() = aBtn1Rect.Bottom() + 1;
+            aTrackRect.Bottom() = aBtn2Rect.Top();
+        }
+
+        GtkStyleContext* pScrollbarTroughStyle = scrollbarOrientation == GTK_ORIENTATION_VERTICAL ?
+                                                  mpVScrollbarTroughStyle : mpHScrollbarTroughStyle;
+        gtk_render_background(pScrollbarTroughStyle, cr, aTrackRect.Left(), aTrackRect.Top(),
+                              aTrackRect.GetWidth(), aTrackRect.GetHeight() );
+        gtk_render_frame(pScrollbarTroughStyle, cr, aTrackRect.Left(), aTrackRect.Top(),
+                         aTrackRect.GetWidth(), aTrackRect.GetHeight() );
+
+        // ----------------- THUMB
+        if ( has_slider )
+        {
+            stateFlags = NWConvertVCLStateToGTKState(rScrollbarVal.mnThumbState);
+            if ( rScrollbarVal.mnThumbState & ControlState::PRESSED )
+                stateFlags = (GtkStateFlags) (stateFlags | GTK_STATE_PRELIGHT);
+
+            GtkStyleContext* pScrollbarSliderStyle = scrollbarOrientation == GTK_ORIENTATION_VERTICAL ?
+                                                      mpVScrollbarSliderStyle : mpHScrollbarSliderStyle;
+
+            gtk_style_context_set_state(pScrollbarSliderStyle, stateFlags);
+
+            GtkBorder margin;
+            gtk_style_context_get_margin(pScrollbarSliderStyle, stateFlags, &margin);
+
+            gtk_render_background(pScrollbarSliderStyle, cr,
+                              thumbRect.Left() + margin.left, thumbRect.Top() + margin.top,
+                              thumbRect.GetWidth() - margin.left - margin.right,
+                              thumbRect.GetHeight() - margin.top - margin.bottom);
+
+            gtk_render_frame(pScrollbarSliderStyle, cr,
+                              thumbRect.Left() + margin.left, thumbRect.Top() + margin.top,
+                              thumbRect.GetWidth() - margin.left - margin.right,
+                              thumbRect.GetHeight() - margin.top - margin.bottom);
+        }
+
+        return;
+    }
+
+    OSL_ASSERT( rValue.getType() == ControlType::Scrollbar );
     const ScrollbarValue& rScrollbarVal = static_cast<const ScrollbarValue&>(rValue);
     tools::Rectangle        scrollbarRect;
     GtkStateFlags    stateFlags;
@@ -394,6 +774,7 @@ void GtkSalGraphics::PaintScrollbar(GtkStyleContext *context,
     tools::Rectangle        arrowRect;
     gint            slider_width = 0;
     gint            stepper_size = 0;
+    gint            trough_border = 0;
 
     // make controlvalue rectangles relative to area
     thumbRect.Move( -rControlRectangle.Left(), -rControlRectangle.Top() );
@@ -404,36 +785,17 @@ void GtkSalGraphics::PaintScrollbar(GtkStyleContext *context,
 
     // Find the overall bounding rect of the control
     scrollbarRect = rControlRectangle;
-    if (scrollbarRect.GetWidth() <= 0 || scrollbarRect.GetHeight() <= 0)
-        return;
+    scrollbarRect.SetSize( Size( scrollbarRect.GetWidth() + 1,
+                                 scrollbarRect.GetHeight() + 1 ) );
 
-    gint slider_side;
-    Size aSize;
-    if (nPart == ControlPart::DrawBackgroundHorz)
-    {
-        QuerySize(mpHScrollbarStyle, aSize);
-        QuerySize(mpHScrollbarContentsStyle, aSize);
-        QuerySize(mpHScrollbarTroughStyle, aSize);
-        QuerySize(mpHScrollbarSliderStyle, aSize);
-        slider_side = aSize.Height();
-        gtk_style_context_get(mpHScrollbarButtonStyle,
-                              gtk_style_context_get_state(mpHScrollbarButtonStyle),
-                              "min-height", &slider_width,
-                              "min-width", &stepper_size, nullptr);
-    }
-    else
-    {
-        QuerySize(mpVScrollbarStyle, aSize);
-        QuerySize(mpVScrollbarContentsStyle, aSize);
-        QuerySize(mpVScrollbarTroughStyle, aSize);
-        QuerySize(mpVScrollbarSliderStyle, aSize);
-        slider_side = aSize.Width();
-        gtk_style_context_get(mpVScrollbarButtonStyle,
-                              gtk_style_context_get_state(mpVScrollbarButtonStyle),
-                              "min-width", &slider_width,
-                              "min-height", &stepper_size, nullptr);
-    }
+    if ( (scrollbarRect.GetWidth() <= 1) || (scrollbarRect.GetHeight() <= 1) )
+        return;
 
+    // Grab some button style attributes
+    gtk_style_context_get_style( context,
+                                 "slider_width", &slider_width,
+                                 "stepper_size", &stepper_size,
+                                 "trough_border", &trough_border, nullptr );
     gboolean has_forward;
     gboolean has_forward2;
     gboolean has_backward;
@@ -444,14 +806,13 @@ void GtkSalGraphics::PaintScrollbar(GtkStyleContext *context,
                                  "has-secondary-forward-stepper", &has_forward2,
                                  "has-backward-stepper", &has_backward,
                                  "has-secondary-backward-stepper", &has_backward2, nullptr );
+    gint magic = trough_border ? 1 : 0;
+    gint slider_side = slider_width + (trough_border * 2);
 
     if ( nPart == ControlPart::DrawBackgroundHorz )
     {
-        // Center vertically in the track
         scrollbarRect.Move( 0, (scrollbarRect.GetHeight() - slider_side) / 2 );
         scrollbarRect.SetSize( Size( scrollbarRect.GetWidth(), slider_side ) );
-        thumbRect.Move( 0, (scrollbarRect.GetHeight() - slider_side) / 2 );
-        thumbRect.SetSize( Size( thumbRect.GetWidth(), slider_side ) );
 
         scrollbarOrientation = GTK_ORIENTATION_HORIZONTAL;
         arrow1Angle = G_PI * 3 / 2;
@@ -459,34 +820,39 @@ void GtkSalGraphics::PaintScrollbar(GtkStyleContext *context,
 
         if ( has_backward )
         {
-            button12BoundRect.Move( stepper_size,
+            button12BoundRect.Move( stepper_size - trough_border,
                                     (scrollbarRect.GetHeight() - slider_width) / 2 );
         }
 
-        button11BoundRect.Move( 0, (scrollbarRect.GetHeight() - slider_width) / 2 );
+        button11BoundRect.Move( trough_border, (scrollbarRect.GetHeight() - slider_width) / 2 );
         button11BoundRect.SetSize( Size( stepper_size, slider_width ) );
         button12BoundRect.SetSize( Size( stepper_size, slider_width ) );
 
         if ( has_backward2 )
         {
-            button22BoundRect.Move( stepper_size, (scrollbarRect.GetHeight() - slider_width) / 2 );
-            button21BoundRect.Move( 0, (scrollbarRect.GetHeight() - slider_width) / 2 );
+            button22BoundRect.Move( stepper_size+(trough_border+1)/2, (scrollbarRect.GetHeight() - slider_width) / 2 );
+            button21BoundRect.Move( (trough_border+1)/2, (scrollbarRect.GetHeight() - slider_width) / 2 );
         }
         else
         {
-            button22BoundRect.Move( 0, (scrollbarRect.GetHeight() - slider_width) / 2 );
+            button22BoundRect.Move( (trough_border+1)/2, (scrollbarRect.GetHeight() - slider_width) / 2 );
         }
 
         button21BoundRect.SetSize( Size( stepper_size, slider_width ) );
         button22BoundRect.SetSize( Size( stepper_size, slider_width ) );
+
+        thumbRect.Bottom() = thumbRect.Top() + slider_width - 1;
+        // Make sure the thumb is at least the default width (so we don't get tiny thumbs),
+        // but if the VCL gives us a size smaller than the theme's default thumb size,
+        // honor the VCL size
+        thumbRect.Right() += magic;
+        // Center vertically in the track
+        thumbRect.Move( 0, (scrollbarRect.GetHeight() - slider_width) / 2 );
     }
     else
     {
-        // Center horizontally in the track
         scrollbarRect.Move( (scrollbarRect.GetWidth() - slider_side) / 2, 0 );
         scrollbarRect.SetSize( Size( slider_side, scrollbarRect.GetHeight() ) );
-        thumbRect.Move( (scrollbarRect.GetWidth() - slider_side) / 2, 0 );
-        thumbRect.SetSize( Size( slider_side, thumbRect.GetHeight() ) );
 
         scrollbarOrientation = GTK_ORIENTATION_VERTICAL;
         arrow1Angle = 0;
@@ -495,24 +861,30 @@ void GtkSalGraphics::PaintScrollbar(GtkStyleContext *context,
         if ( has_backward )
         {
             button12BoundRect.Move( (scrollbarRect.GetWidth() - slider_width) / 2,
-                                    stepper_size );
+                                    stepper_size + trough_border );
         }
-        button11BoundRect.Move( (scrollbarRect.GetWidth() - slider_width) / 2, 0 );
+        button11BoundRect.Move( (scrollbarRect.GetWidth() - slider_width) / 2, trough_border );
         button11BoundRect.SetSize( Size( slider_width, stepper_size ) );
         button12BoundRect.SetSize( Size( slider_width, stepper_size ) );
 
         if ( has_backward2 )
         {
-            button22BoundRect.Move( (scrollbarRect.GetWidth() - slider_width) / 2, stepper_size );
-            button21BoundRect.Move( (scrollbarRect.GetWidth() - slider_width) / 2, 0 );
+            button22BoundRect.Move( (scrollbarRect.GetWidth() - slider_width) / 2, stepper_size+(trough_border+1)/2 );
+            button21BoundRect.Move( (scrollbarRect.GetWidth() - slider_width) / 2, (trough_border+1)/2 );
         }
         else
         {
-            button22BoundRect.Move( (scrollbarRect.GetWidth() - slider_width) / 2, 0 );
+            button22BoundRect.Move( (scrollbarRect.GetWidth() - slider_width) / 2, (trough_border+1)/2 );
         }
 
         button21BoundRect.SetSize( Size( slider_width, stepper_size ) );
         button22BoundRect.SetSize( Size( slider_width, stepper_size ) );
+
+        thumbRect.Right() = thumbRect.Left() + slider_width - 1;
+
+        thumbRect.Bottom() += magic;
+        // Center horizontally in the track
+        thumbRect.Move( (scrollbarRect.GetWidth() - slider_width) / 2, 0 );
     }
 
     bool has_slider = ( thumbRect.GetWidth() > 0 && thumbRect.GetHeight() > 0 );
@@ -534,6 +906,40 @@ void GtkSalGraphics::PaintScrollbar(GtkStyleContext *context,
     gtk_render_frame(pScrollbarContentsStyle, cr, 0, 0,
                      scrollbarRect.GetWidth(), scrollbarRect.GetHeight() );
 
+    // ----------------- TROUGH
+    GtkStyleContext* pScrollbarTroughStyle = scrollbarOrientation == GTK_ORIENTATION_VERTICAL ?
+                                              mpVScrollbarTroughStyle : mpHScrollbarTroughStyle;
+    gtk_render_background(pScrollbarTroughStyle, cr, 0, 0,
+                          scrollbarRect.GetWidth(), scrollbarRect.GetHeight() );
+    gtk_render_frame(pScrollbarTroughStyle, cr, 0, 0,
+                     scrollbarRect.GetWidth(), scrollbarRect.GetHeight() );
+
+    // ----------------- THUMB
+    if ( has_slider )
+    {
+        stateFlags = NWConvertVCLStateToGTKState(rScrollbarVal.mnThumbState);
+        if ( rScrollbarVal.mnThumbState & ControlState::PRESSED )
+            stateFlags = (GtkStateFlags) (stateFlags | GTK_STATE_PRELIGHT);
+
+        GtkStyleContext* pScrollbarSliderStyle = scrollbarOrientation == GTK_ORIENTATION_VERTICAL ?
+                                                  mpVScrollbarSliderStyle : mpHScrollbarSliderStyle;
+
+        gtk_style_context_set_state(pScrollbarSliderStyle, stateFlags);
+
+        GtkBorder margin;
+        gtk_style_context_get_margin(pScrollbarSliderStyle, stateFlags, &margin);
+
+        gtk_render_background(pScrollbarSliderStyle, cr,
+                          thumbRect.Left() + margin.left, thumbRect.Top() + margin.top,
+                          thumbRect.GetWidth() - margin.left - margin.right,
+                          thumbRect.GetHeight() - margin.top - margin.bottom);
+
+        gtk_render_frame(pScrollbarSliderStyle, cr,
+                          thumbRect.Left() + margin.left, thumbRect.Top() + margin.top,
+                          thumbRect.GetWidth() - margin.left - margin.right,
+                          thumbRect.GetHeight() - margin.top - margin.bottom);
+    }
+
     bool backwardButtonInsensitive =
         rScrollbarVal.mnCur == rScrollbarVal.mnMin;
     bool forwardButtonInsensitive = rScrollbarVal.mnMax == 0 ||
@@ -591,11 +997,10 @@ void GtkSalGraphics::PaintScrollbar(GtkStyleContext *context,
                          MIN(arrowRect.GetWidth(), arrowRect.GetHeight()) );
     }
     // ----------------- BUTTON 2
-
-    if ( has_forward )
+    if ( has_backward2 )
     {
-        stateFlags = NWConvertVCLStateToGTKState(rScrollbarVal.mnButton2State);
-        if ( forwardButtonInsensitive )
+        stateFlags = NWConvertVCLStateToGTKState(rScrollbarVal.mnButton1State);
+        if ( backwardButtonInsensitive )
             stateFlags = GTK_STATE_FLAG_INSENSITIVE;
 
         GtkStyleContext* pScrollbarButtonStyle = scrollbarOrientation == GTK_ORIENTATION_VERTICAL ?
@@ -604,24 +1009,23 @@ void GtkSalGraphics::PaintScrollbar(GtkStyleContext *context,
         gtk_style_context_set_state(pScrollbarButtonStyle, stateFlags);
 
         gtk_render_background(pScrollbarButtonStyle, cr,
-                       button22BoundRect.Left(), button22BoundRect.Top(),
-                       button22BoundRect.GetWidth(), button22BoundRect.GetHeight() );
+                              button21BoundRect.Left(), button21BoundRect.Top(),
+                              button21BoundRect.GetWidth(), button21BoundRect.GetHeight() );
         gtk_render_frame(pScrollbarButtonStyle, cr,
-                       button22BoundRect.Left(), button22BoundRect.Top(),
-                       button22BoundRect.GetWidth(), button22BoundRect.GetHeight() );
+                         button21BoundRect.Left(), button21BoundRect.Top(),
+                         button21BoundRect.GetWidth(), button21BoundRect.GetHeight() );
 
         // ----------------- ARROW 2
-        NWCalcArrowRect( button22BoundRect, arrowRect );
+        NWCalcArrowRect( button21BoundRect, arrowRect );
         gtk_render_arrow(pScrollbarButtonStyle, cr,
-                         arrow2Angle,
+                         arrow1Angle,
                          arrowRect.Left(), arrowRect.Top(),
                          MIN(arrowRect.GetWidth(), arrowRect.GetHeight()) );
     }
-
-    if ( has_backward2 )
+    if ( has_forward )
     {
-        stateFlags = NWConvertVCLStateToGTKState(rScrollbarVal.mnButton1State);
-        if ( backwardButtonInsensitive )
+        stateFlags = NWConvertVCLStateToGTKState(rScrollbarVal.mnButton2State);
+        if ( forwardButtonInsensitive )
             stateFlags = GTK_STATE_FLAG_INSENSITIVE;
 
         GtkStyleContext* pScrollbarButtonStyle = scrollbarOrientation == GTK_ORIENTATION_VERTICAL ?
@@ -630,70 +1034,19 @@ void GtkSalGraphics::PaintScrollbar(GtkStyleContext *context,
         gtk_style_context_set_state(pScrollbarButtonStyle, stateFlags);
 
         gtk_render_background(pScrollbarButtonStyle, cr,
-                              button21BoundRect.Left(), button21BoundRect.Top(),
-                              button21BoundRect.GetWidth(), button21BoundRect.GetHeight() );
+                       button22BoundRect.Left(), button22BoundRect.Top(),
+                       button22BoundRect.GetWidth(), button22BoundRect.GetHeight() );
         gtk_render_frame(pScrollbarButtonStyle, cr,
-                         button21BoundRect.Left(), button21BoundRect.Top(),
-                         button21BoundRect.GetWidth(), button21BoundRect.GetHeight() );
+                       button22BoundRect.Left(), button22BoundRect.Top(),
+                       button22BoundRect.GetWidth(), button22BoundRect.GetHeight() );
 
         // ----------------- ARROW 2
-        NWCalcArrowRect( button21BoundRect, arrowRect );
+        NWCalcArrowRect( button22BoundRect, arrowRect );
         gtk_render_arrow(pScrollbarButtonStyle, cr,
-                         arrow1Angle,
+                         arrow2Angle,
                          arrowRect.Left(), arrowRect.Top(),
                          MIN(arrowRect.GetWidth(), arrowRect.GetHeight()) );
     }
-
-    // ----------------- TROUGH
-    // trackrect matches that of ScrollBar::ImplCalc
-    tools::Rectangle aTrackRect(Point(0, 0), scrollbarRect.GetSize());
-    if (nPart == ControlPart::DrawBackgroundHorz)
-    {
-        tools::Rectangle aBtn1Rect = NWGetScrollButtonRect(ControlPart::ButtonLeft, aTrackRect);
-        tools::Rectangle aBtn2Rect = NWGetScrollButtonRect(ControlPart::ButtonRight, aTrackRect);
-        aTrackRect.Left() = aBtn1Rect.Right();
-        aTrackRect.Right() = aBtn2Rect.Left();
-    }
-    else
-    {
-        tools::Rectangle aBtn1Rect = NWGetScrollButtonRect(ControlPart::ButtonUp, aTrackRect);
-        tools::Rectangle aBtn2Rect = NWGetScrollButtonRect(ControlPart::ButtonDown, aTrackRect);
-        aTrackRect.Top() = aBtn1Rect.Bottom() + 1;
-        aTrackRect.Bottom() = aBtn2Rect.Top();
-    }
-
-    GtkStyleContext* pScrollbarTroughStyle = scrollbarOrientation == GTK_ORIENTATION_VERTICAL ?
-                                              mpVScrollbarTroughStyle : mpHScrollbarTroughStyle;
-    gtk_render_background(pScrollbarTroughStyle, cr, aTrackRect.Left(), aTrackRect.Top(),
-                          aTrackRect.GetWidth(), aTrackRect.GetHeight() );
-    gtk_render_frame(pScrollbarTroughStyle, cr, aTrackRect.Left(), aTrackRect.Top(),
-                     aTrackRect.GetWidth(), aTrackRect.GetHeight() );
-
-    // ----------------- THUMB
-    if ( has_slider )
-    {
-        stateFlags = NWConvertVCLStateToGTKState(rScrollbarVal.mnThumbState);
-        if ( rScrollbarVal.mnThumbState & ControlState::PRESSED )
-            stateFlags = (GtkStateFlags) (stateFlags | GTK_STATE_PRELIGHT);
-
-        GtkStyleContext* pScrollbarSliderStyle = scrollbarOrientation == GTK_ORIENTATION_VERTICAL ?
-                                                  mpVScrollbarSliderStyle : mpHScrollbarSliderStyle;
-
-        gtk_style_context_set_state(pScrollbarSliderStyle, stateFlags);
-
-        GtkBorder margin;
-        gtk_style_context_get_margin(pScrollbarSliderStyle, stateFlags, &margin);
-
-        gtk_render_background(pScrollbarSliderStyle, cr,
-                          thumbRect.Left() + margin.left, thumbRect.Top() + margin.top,
-                          thumbRect.GetWidth() - margin.left - margin.right,
-                          thumbRect.GetHeight() - margin.top - margin.bottom);
-
-        gtk_render_frame(pScrollbarSliderStyle, cr,
-                          thumbRect.Left() + margin.left, thumbRect.Top() + margin.top,
-                          thumbRect.GetWidth() - margin.left - margin.right,
-                          thumbRect.GetHeight() - margin.top - margin.bottom);
-    }
 }
 
 void GtkSalGraphics::PaintOneSpinButton( GtkStyleContext *context,
@@ -804,9 +1157,12 @@ tools::Rectangle GtkSalGraphics::NWGetComboBoxButtonRect(
     gtk_style_context_get_padding( mpButtonStyle, gtk_style_context_get_state(mpButtonStyle), &padding);
 
     gint nArrowWidth = FALLBACK_ARROW_SIZE;
-    gtk_style_context_get(mpComboboxButtonArrowStyle,
-        gtk_style_context_get_state(mpComboboxButtonArrowStyle),
-        "min-width", &nArrowWidth, nullptr);
+    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 )
@@ -859,18 +1215,20 @@ void GtkSalGraphics::PaintCombobox( GtkStateFlags flags, cairo_t *cr,
         aEditBoxRect.SetPos( Point( areaRect.Left() + buttonRect.GetWidth(), areaRect.Top() ) );
 
     gint arrow_width = FALLBACK_ARROW_SIZE, arrow_height = FALLBACK_ARROW_SIZE;
-
-    if (nType == ControlType::Combobox)
+    if (gtk_check_version(3, 20, 0) == nullptr)
     {
-        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);
+        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));
@@ -923,74 +1281,497 @@ void GtkSalGraphics::PaintCombobox( GtkStateFlags flags, cairo_t *cr,
                              0, 0,
                              areaRect.GetWidth(), areaRect.GetHeight());
         }
-        else
+        else
+        {
+            render_common(mpListboxStyle, cr, aRect, flags);
+            render_common(mpListboxBoxStyle, cr, aRect, flags);
+
+            render_common(mpListboxButtonStyle, cr, aRect, flags);
+
+            gtk_render_arrow(mpListboxButtonArrowStyle, cr,
+                             G_PI,
+                             (arrowRect.Left() - areaRect.Left()), (arrowRect.Top() - areaRect.Top()),
+                             arrowRect.GetWidth() );
+        }
+    }
+}
+
+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)
+{
+    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);
+            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);
+            set_object_name(path, -1, "button");
+            gtk_widget_path_iter_add_class(path, -1, "link");
+            return makeContext(path, nullptr);
+        }
+        case GtkControlPart::CheckButton:
+        {
+            GtkWidgetPath *path = gtk_widget_path_new();
+            gtk_widget_path_append_type(path, GTK_TYPE_CHECK_BUTTON);
+            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);
+            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);
+            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);
+            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_copy(gtk_style_context_get_path(mpWindowStyle));
+            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, mpWindowStyle);
+        }
+        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:
         {
-            render_common(mpListboxStyle, cr, aRect, flags);
-            render_common(mpListboxBoxStyle, cr, aRect, flags);
-
-            render_common(mpListboxButtonStyle, cr, aRect, flags);
-
-            gtk_render_arrow(mpListboxButtonArrowStyle, cr,
-                             G_PI,
-                             (arrowRect.Left() - areaRect.Left()), (arrowRect.Top() - areaRect.Top()),
-                             arrowRect.GetWidth() );
+            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);
         }
     }
-}
-
-static void appendComboEntry(GtkWidgetPath* pSiblingsPath)
-{
-    gtk_widget_path_append_type(pSiblingsPath, GTK_TYPE_ENTRY);
-    gtk_widget_path_iter_set_object_name(pSiblingsPath, -1, "entry");
-    gtk_widget_path_iter_add_class(pSiblingsPath, -1, "combo");
-}
-
-static void appendComboButton(GtkWidgetPath* pSiblingsPath)
-{
-    gtk_widget_path_append_type(pSiblingsPath, GTK_TYPE_BUTTON);
-    gtk_widget_path_iter_set_object_name(pSiblingsPath, -1, "button");
-    gtk_widget_path_iter_add_class(pSiblingsPath, -1, "combo");
-}
-
-static GtkWidgetPath* buildLTRComboSiblingsPath()
-{
-    GtkWidgetPath* pSiblingsPath = gtk_widget_path_new();
-
-    appendComboEntry(pSiblingsPath);
-    appendComboButton(pSiblingsPath);
-
-    return pSiblingsPath;
-}
-
-static GtkWidgetPath* buildRTLComboSiblingsPath()
-{
-    GtkWidgetPath* pSiblingsPath = gtk_widget_path_new();
 
-    appendComboButton(pSiblingsPath);
-    appendComboEntry(pSiblingsPath);
-
-    return pSiblingsPath;
+    return nullptr;
 }
 
-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;
-}
+#ifndef GTK_STYLE_CLASS_POPUP
+#define GTK_STYLE_CLASS_POPUP "popup"
+#endif
+#ifndef GTK_STYLE_CLASS_LABEL
+#define GTK_STYLE_CLASS_LABEL "label"
+#endif
 
-GtkStyleContext* GtkSalGraphics::createStyleContext(GtkControlPart ePart)
+GtkStyleContext* GtkSalGraphics::createOldContext(GtkControlPart ePart)
 {
     switch (ePart)
     {
         case GtkControlPart::ToplevelWindow:
         {
             GtkWidgetPath *path = gtk_widget_path_new();
-            gtk_widget_path_append_type(path, G_TYPE_NONE);
-            gtk_widget_path_iter_set_object_name(path, -1, "window");
+            gtk_widget_path_append_type(path, GTK_TYPE_WINDOW);
             gtk_widget_path_iter_add_class(path, -1, "background");
             return makeContext(path, nullptr);
         }
@@ -998,179 +1779,92 @@ GtkStyleContext* GtkSalGraphics::createStyleContext(GtkControlPart ePart)
         {
             GtkWidgetPath *path = gtk_widget_path_new();
             gtk_widget_path_append_type(path, GTK_TYPE_BUTTON);
-            gtk_widget_path_iter_set_object_name(path, -1, "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_BUTTON);
-            gtk_widget_path_iter_set_object_name(path, -1, "button");
-            gtk_widget_path_iter_add_class(path, -1, "link");
+            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_set_object_name(path, -1, "checkbutton");
+            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:
-        {
-            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpCheckButtonStyle));
-            gtk_widget_path_append_type(path, GTK_TYPE_CHECK_BUTTON);
-            gtk_widget_path_iter_set_object_name(path, -1, "check");
-            return makeContext(path, mpCheckButtonStyle);
-        }
+            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_set_object_name(path, -1, "radiobutton");
+            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:
-        {
-            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpRadioButtonStyle));
-            gtk_widget_path_append_type(path, GTK_TYPE_RADIO_BUTTON);
-            gtk_widget_path_iter_set_object_name(path, -1, "radio");
-            return makeContext(path, mpRadioButtonStyle);
-        }
+            return 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);
-            gtk_widget_path_iter_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);
-            gtk_widget_path_iter_set_object_name(path, -1, "arrow");
-            return makeContext(path, mpListboxButtonBoxStyle);
+            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);
-            gtk_widget_path_iter_set_object_name(path, -1, "entry");
+            gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_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);
-            gtk_widget_path_iter_set_object_name(path, -1, "combobox");
+            gtk_widget_path_append_type(path, GTK_TYPE_COMBO_BOX_TEXT);
             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);
-            gtk_widget_path_iter_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);
-            gtk_widget_path_iter_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:
+        case GtkControlPart::Listbox:
         {
-            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpComboboxBoxStyle));
-            GtkWidgetPath* pSiblingsPath;
-            if (AllSettings::GetLayoutRTL())
-            {
-                pSiblingsPath = buildRTLComboSiblingsPath();
-                gtk_widget_path_append_with_siblings(path, pSiblingsPath, 1);
-            }
-            else
-            {
-                pSiblingsPath = buildLTRComboSiblingsPath();
-                gtk_widget_path_append_with_siblings(path, pSiblingsPath, 0);
-            }
-            gtk_widget_path_unref(pSiblingsPath);
-            return makeContext(path, mpComboboxBoxStyle);
+            GtkWidgetPath *path = gtk_widget_path_new();
+            gtk_widget_path_append_type(path, GTK_TYPE_COMBO_BOX);
+            return makeContext(path, nullptr);
         }
         case GtkControlPart::ComboboxBoxButton:
-        {
-            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpComboboxBoxStyle));
-            GtkWidgetPath* pSiblingsPath;
-            if (AllSettings::GetLayoutRTL())
-            {
-                pSiblingsPath = buildRTLComboSiblingsPath();
-                gtk_widget_path_append_with_siblings(path, pSiblingsPath, 0);
-            }
-            else
-            {
-                pSiblingsPath = buildLTRComboSiblingsPath();
-                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);
-            gtk_widget_path_iter_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);
-            gtk_widget_path_iter_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);
-            gtk_widget_path_iter_set_object_name(path, -1, "box");
-            gtk_widget_path_iter_add_class(path, -1, "horizontal");
-            return makeContext(path, mpListboxButtonStyle);
+            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_copy(gtk_style_context_get_path(mpWindowStyle));
+            GtkWidgetPath *path = gtk_widget_path_new();
             gtk_widget_path_append_type(path, GTK_TYPE_SPIN_BUTTON);
-            gtk_widget_path_iter_set_object_name(path, -1, "spinbutton");
+            gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_ENTRY);
             gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_HORIZONTAL);
-            return makeContext(path, mpWindowStyle);
-        }
-        case GtkControlPart::SpinButtonEntry:
-        {
-            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpSpinStyle));
-            gtk_widget_path_append_type(path, G_TYPE_NONE);
-            gtk_widget_path_iter_set_object_name(path, -1, "entry");
-            return makeContext(path, mpSpinStyle);
+            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);
-            gtk_widget_path_iter_set_object_name(path, -1, "button");
-            gtk_widget_path_iter_add_class(path, -1, ePart == GtkControlPart::SpinButtonUpButton ? "up" : "down");
+            gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_SPINBUTTON);
+            gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_BUTTON);
             return makeContext(path, mpSpinStyle);
         }
         case GtkControlPart::ScrollbarVertical:
@@ -1178,7 +1872,7 @@ GtkStyleContext* GtkSalGraphics::createStyleContext(GtkControlPart ePart)
         {
             GtkWidgetPath *path = gtk_widget_path_new();
             gtk_widget_path_append_type(path, GTK_TYPE_SCROLLBAR);
-            gtk_widget_path_iter_set_object_name(path, -1, "scrollbar");
+            gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_SCROLLBAR);
             gtk_widget_path_iter_add_class(path, -1, ePart == GtkControlPart::ScrollbarVertical ? "vertical" : "horizontal");
             return makeContext(path, nullptr);
         }
@@ -1189,44 +1883,48 @@ GtkStyleContext* GtkSalGraphics::createStyleContext(GtkControlPart ePart)
                 (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);
-            gtk_widget_path_iter_set_object_name(path, -1, "contents");
+            gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_SCROLLBAR);
+            gtk_widget_path_iter_add_class(path, -1, "contents");
             return makeContext(path, pParent);
         }
-        case GtkControlPart::ScrollbarVerticalTrough:
         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);
-            gtk_widget_path_iter_set_object_name(path, -1, "trough");
+            gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_SCROLLBAR);
+            gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_TROUGH);
             return makeContext(path, pParent);
         }
-        case GtkControlPart::ScrollbarVerticalSlider:
         case GtkControlPart::ScrollbarHorizontalSlider:
+        case GtkControlPart::ScrollbarVerticalSlider:
         {
             GtkStyleContext *pParent =
-                (ePart == GtkControlPart::ScrollbarVerticalSlider) ? mpVScrollbarTroughStyle : mpHScrollbarTroughStyle;
+                (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);
-            gtk_widget_path_iter_set_object_name(path, -1, "slider");
+            gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_SCROLLBAR);
+            gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_SLIDER);
             return makeContext(path, pParent);
         }
-        case GtkControlPart::ScrollbarVerticalButton:
         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);
-            gtk_widget_path_iter_set_object_name(path, -1, "button");
+            gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_SCROLLBAR);
+            gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_BUTTON);
             return makeContext(path, pParent);
         }
         case GtkControlPart::ProgressBar:
         {
             GtkWidgetPath *path = gtk_widget_path_new();
             gtk_widget_path_append_type(path, GTK_TYPE_PROGRESS_BAR);
-            gtk_widget_path_iter_set_object_name(path, -1, "progressbar");
+            gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_PROGRESSBAR);
             gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_HORIZONTAL);
             return makeContext(path, nullptr);
         }
@@ -1234,70 +1932,71 @@ GtkStyleContext* GtkSalGraphics::createStyleContext(GtkControlPart ePart)
         {
             GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpProgressBarStyle));
             gtk_widget_path_append_type(path, GTK_TYPE_PROGRESS_BAR);
-            gtk_widget_path_iter_set_object_name(path, -1, "trough");
+            gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_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);
-            gtk_widget_path_iter_set_object_name(path, -1, "progress");
+            gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_PROGRESSBAR);
             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_set_object_name(path, -1, "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:
-        {
-            GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpNotebookStyle));
-            gtk_widget_path_append_type(path, GTK_TYPE_NOTEBOOK);
-            gtk_widget_path_iter_set_object_name(path, -1, "stack");
-            return makeContext(path, mpNotebookStyle);
-        }
+            return 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);
-            gtk_widget_path_iter_set_object_name(path, -1, "header");
-            gtk_widget_path_iter_add_class(path, -1, "frame");
+            gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_HEADER);
             gtk_widget_path_iter_add_class(path, -1, "top");
-            return makeContext(path, mpNotebookStyle);
+            return makeContext(path, gtk_style_context_get_parent(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);
-            gtk_widget_path_iter_set_object_name(path, -1, "tabs");
-            gtk_widget_path_iter_add_class(path, -1, "top");
-            return makeContext(path, mpNotebookHeaderStyle);
-        }
+            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_set_object_name(path, -1, "tab");
+            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, G_TYPE_NONE);
-            gtk_widget_path_iter_set_object_name(path, -1, "label");
+            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:
-            return mpNotebookHeaderTabsTabLabelStyle;
+        {
+            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_set_object_name(path, -1, "frame");
             gtk_widget_path_iter_add_class(path, -1, "frame");
             return makeContext(path, nullptr);
         }
@@ -1305,98 +2004,123 @@ GtkStyleContext* GtkSalGraphics::createStyleContext(GtkControlPart ePart)
         {
             GtkWidgetPath *path = gtk_widget_path_copy(gtk_style_context_get_path(mpWindowStyle));
             gtk_widget_path_append_type(path, GTK_TYPE_MENU_BAR);
-            gtk_widget_path_iter_set_object_name(path, -1, "menubar");
+            gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_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);
-            gtk_widget_path_iter_set_object_name(path, -1, "menuitem");
+            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, G_TYPE_NONE);
-            gtk_widget_path_iter_set_object_name(path, -1, "window");
+            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");
-            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);
-            gtk_widget_path_iter_set_object_name(path, -1, "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);
-            gtk_widget_path_iter_set_object_name(path, -1, "menuitem");
+            gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_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);
-            gtk_widget_path_iter_set_object_name(path, -1, "label");
+            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);
-            gtk_widget_path_iter_set_object_name(path, -1, "arrow");
+            gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_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);
-            gtk_widget_path_iter_set_object_name(path, -1, "menuitem");
+            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);
-            gtk_widget_path_iter_set_object_name(path, -1, "check");
+            gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_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);
-            gtk_widget_path_iter_set_object_name(path, -1, "menuitem");
+            gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_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);
-            gtk_widget_path_iter_set_object_name(path, -1, "radio");
+            gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_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);
-            gtk_widget_path_iter_set_object_name(path, -1, "menuitem");
+            gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_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);
-            gtk_widget_path_iter_set_object_name(path, -1, "separator");
+            gtk_widget_path_iter_add_class(path, -1, GTK_STYLE_CLASS_SEPARATOR);
             return makeContext(path, mpSeparatorMenuItemStyle);
         }
+        case GtkControlPart::ComboboxBox:
+        case GtkControlPart::ListboxBox:
+        case GtkControlPart::ComboboxBoxButtonBox:
+        case GtkControlPart::ListboxBoxButtonBox:
+            return nullptr;
+        default:
+            break;
     }
 
-    return nullptr;
+    return mpButtonStyle;
+}
+
+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);
+}
+
+namespace
+{
+    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,
@@ -1445,6 +2169,7 @@ bool GtkSalGraphics::drawNativeControl( ControlType nType, ControlPart nPart, co
 {
     RenderType renderType = nPart == ControlPart::Focus ? RenderType::Focus : RenderType::BackgroundAndFrame;
     GtkStyleContext *context = nullptr;
+    const gchar *styleClass = nullptr;
     GdkPixbuf *pixbuf = nullptr;
     bool bInMenu = false;
 
@@ -1493,7 +2218,13 @@ bool GtkSalGraphics::drawNativeControl( ControlType nType, ControlPart nPart, co
             renderType = RenderType::BackgroundAndFrame;
             break;
         case ControlPart::MenuItemCheckMark:
-            context = mpCheckMenuItemCheckStyle;
+            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)

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list