[PATCH 2/2] Fix some visual glitch with GTK+

Lucas Baudin xapantu at gmail.com
Sun May 22 02:04:58 PDT 2011


- Fix separators, they weren't properly aligned, and they didn't use
  gtk_paint_box when needed some gtk themes/engine draw lines with box ^^
  (for 3d appearance for instance)
- Fix pressed toolbar buttons state: it wasn't drawn correctly
- Fix toolbar buttons background: window background was paint, but the
  background was the toolbar, so, now, the background of the toolbar is paint
- Use gtk_paint_box instead of gtk_paint_flat_box for buttondefault, it wasn't
  correct and caused some weird things in the corners
- Code cleanup: remove a function call which set the widgets flags, it is
  useless (and could cause some segfaults) since we must specify widget state
  and shadow in gtk_paint_(flat_)box).
- Code cleanup: remove duplicated code, toolbar button are now drawn using the
  same function as normal buttons
---
 vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx |  228 +++++++++++++++++-------------
 vcl/unx/inc/plugins/gtk/gtkgdi.hxx       |    5 +
 2 files changed, 135 insertions(+), 98 deletions(-)

diff --git a/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx b/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx
index 127c5f0..d4d7702 100644
--- a/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx
+++ b/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx
@@ -1125,11 +1125,12 @@ sal_Bool GtkSalGraphics::getNativeControlRegion(  ControlType nType,
     return( returnVal );
 }
 
-
 /************************************************************************
  * Individual control drawing functions
  ************************************************************************/
-sal_Bool GtkSalGraphics::NWPaintGTKButton(
+
+sal_Bool GtkSalGraphics::NWPaintGTKButtonReal(
+            GtkWidget* button,
             GdkDrawable* gdkDrawable,
             ControlType, ControlPart,
             const Rectangle& rControlRectangle,
@@ -1149,17 +1150,32 @@ sal_Bool GtkSalGraphics::NWPaintGTKButton(
     GdkRectangle    clipRect;
 
     NWEnsureGTKButton( m_nScreen );
+    NWEnsureGTKToolbar( m_nScreen );
     NWConvertVCLStateToGTKState( nState, &stateType, &shadowType );
+    NWSetWidgetState( gWidgetData[m_nScreen].gBtnWidget, nState, stateType );
 
     x = rControlRectangle.Left();
     y = rControlRectangle.Top();
     w = rControlRectangle.GetWidth();
     h = rControlRectangle.GetHeight();
 
+    gint internal_padding;
+    if(GTK_IS_TOOL_ITEM(button))
+    {
+        gtk_widget_style_get (GTK_WIDGET (gWidgetData[m_nScreen].gToolbarWidget),
+                "internal-padding", &internal_padding,
+                NULL);
+        x += internal_padding/2;
+        w -= internal_padding;
+        stateType = GTK_STATE_PRELIGHT;
+    }
+
     // Grab some button style attributes
-    gtk_widget_style_get( gWidgetData[m_nScreen].gBtnWidget,    "focus-line-width",    &focusWidth,
+    gtk_widget_style_get( button,    "focus-line-width",    &focusWidth,
                                 "focus-padding",     &focusPad,
                                  "interior_focus",    &interiorFocus,
+                                (char *)NULL );
+    gtk_widget_style_get( gWidgetData[m_nScreen].gBtnWidget,
                                 "default_border",    &pBorder,
                                 (char *)NULL );
 
@@ -1175,8 +1191,6 @@ sal_Bool GtkSalGraphics::NWPaintGTKButton(
     if ( (w < 16) || (h < 16) )
         bDrawFocus = sal_False;
 
-    NWSetWidgetState( gWidgetData[m_nScreen].gBtnWidget, nState, stateType );
-
     gint xi = x, yi = y, wi = w, hi = h;
     if ( (nState & CTRL_STATE_DEFAULT) && bDrawFocus )
     {
@@ -1193,7 +1207,6 @@ sal_Bool GtkSalGraphics::NWPaintGTKButton(
         wi -= 2 * (focusWidth + focusPad);
         hi -= 2 * (focusWidth + focusPad);
     }
-
     for( clipList::const_iterator it = rClipList.begin(); it != rClipList.end(); ++it)
     {
         clipRect.x = it->Left();
@@ -1202,27 +1215,50 @@ sal_Bool GtkSalGraphics::NWPaintGTKButton(
         clipRect.height = it->GetHeight();
 
         // Buttons must paint opaque since some themes have alpha-channel enabled buttons
-        gtk_paint_flat_box( m_pWindow->style, gdkDrawable, GTK_STATE_NORMAL, GTK_SHADOW_NONE,
-                            &clipRect, m_pWindow, "base", x, y, w, h );
-
-        if ( (nState & CTRL_STATE_DEFAULT) && (GTK_BUTTON(gWidgetData[m_nScreen].gBtnWidget)->relief == GTK_RELIEF_NORMAL) )
+        if(button == gWidgetData[m_nScreen].gToolbarButtonWidget)
         {
-            gtk_paint_box( gWidgetData[m_nScreen].gBtnWidget->style, gdkDrawable, GTK_STATE_NORMAL, GTK_SHADOW_IN,
-                           &clipRect, gWidgetData[m_nScreen].gBtnWidget, "buttondefault", x, y, w, h );
+            gtk_paint_box( gWidgetData[m_nScreen].gToolbarWidget->style, gdkDrawable, GTK_STATE_NORMAL, GTK_SHADOW_NONE,
+                                &clipRect, gWidgetData[m_nScreen].gToolbarWidget, "toolbar", x, y, w, h );
+        }
+        else
+        {
+            gtk_paint_box( m_pWindow->style, gdkDrawable, GTK_STATE_NORMAL, GTK_SHADOW_NONE,
+                                &clipRect, m_pWindow, "base", x, y, w, h );
         }
 
-        if ( (GTK_BUTTON(gWidgetData[m_nScreen].gBtnWidget)->relief != GTK_RELIEF_NONE)
-            || (nState & CTRL_STATE_PRESSED)
-            || (nState & CTRL_STATE_ROLLOVER) )
+        if ( (nState & CTRL_STATE_DEFAULT) && GTK_IS_BUTTON(button) )
         {
-            gtk_paint_box( gWidgetData[m_nScreen].gBtnWidget->style, gdkDrawable, stateType, shadowType,
-                           &clipRect, gWidgetData[m_nScreen].gBtnWidget, "button", xi, yi, wi, hi );
+            gtk_paint_box( button->style, gdkDrawable, GTK_STATE_NORMAL, GTK_SHADOW_IN,
+                           &clipRect, button, "buttondefault", x, y, w, h );
         }
+        /* don't draw "button", because it can be a tool_button, and
+         * it causes some weird things, so, the default button is
+         * just fine */
+        gtk_paint_box( gWidgetData[m_nScreen].gBtnWidget->style, gdkDrawable, stateType, shadowType,
+                       &clipRect, gWidgetData[m_nScreen].gBtnWidget, "button", xi, yi, wi, hi );
     }
 
     return( sal_True );
 }
 
+sal_Bool GtkSalGraphics::NWPaintGTKButton(
+            GdkDrawable* gdkDrawable,
+            ControlType type, ControlPart part,
+            const Rectangle& rControlRectangle,
+            const clipList& rClipList,
+            ControlState nState, const ImplControlValue& value,
+            const OUString& string)
+{
+        return NWPaintGTKButtonReal(
+            gWidgetData[m_nScreen].gBtnWidget,
+            gdkDrawable,
+            type, part,
+            rControlRectangle,
+            rClipList,
+            nState, value,
+            string );
+}
+
 static Rectangle NWGetButtonArea( int nScreen,
                                   ControlType, ControlPart, Rectangle aAreaRect, ControlState nState,
                                   const ImplControlValue&, const OUString& )
@@ -1907,7 +1943,10 @@ static void NWPaintOneEditBox(    int nScreen,
     }
     NWSetWidgetState( widget, nState, stateType );
 
-    gtk_paint_box( pBGWidget->style, gdkDrawable, stateType, GTK_SHADOW_NONE,
+    /* This doesn't seem to be necessary, and it causes some weird glitch in
+     * murrine (with the elementary theme for instance) but it fixes some issue
+     * with Orta, so... */
+    gtk_paint_flat_box( pBGWidget->style, gdkDrawable, stateType, GTK_SHADOW_NONE,
                         gdkRect, pBGWidget, "entry_bg",
                         aEditBoxRect.Left(), aEditBoxRect.Top(),
                         aEditBoxRect.GetWidth(), aEditBoxRect.GetHeight() );
@@ -2475,7 +2514,7 @@ sal_Bool GtkSalGraphics::NWPaintGTKToolbar(
             const Rectangle& rControlRectangle,
             const clipList& rClipList,
             ControlState nState, const ImplControlValue& aValue,
-            const OUString& )
+            const OUString& string)
 {
     GtkStateType    stateType;
     GtkShadowType    shadowType;
@@ -2533,22 +2572,12 @@ sal_Bool GtkSalGraphics::NWPaintGTKToolbar(
     // handle button
     else if( nPart == PART_BUTTON )
     {
-        bPaintButton =
-            (GTK_BUTTON(pButtonWidget)->relief != GTK_RELIEF_NONE)
-            || (nState & CTRL_STATE_PRESSED)
+        bPaintButton = (nState & CTRL_STATE_PRESSED)
             || (nState & CTRL_STATE_ROLLOVER);
         if( aValue.getTristateVal() == BUTTONVALUE_ON )
         {
-            pButtonWidget = gWidgetData[m_nScreen].gToolbarToggleWidget;
-            shadowType = GTK_SHADOW_IN;
-            stateType = GTK_STATE_ACTIVE;
-            // special case stateType value for depressed toggle buttons
-            // cf. gtk+/gtk/gtktogglebutton.c (gtk_toggle_button_update_state)
-            if( (nState & (CTRL_STATE_ROLLOVER|CTRL_STATE_PRESSED)) )
-            {
-                stateType = GTK_STATE_PRELIGHT;
-                shadowType = GTK_SHADOW_OUT;
-            }
+                if(!(nState & CTRL_STATE_ROLLOVER))
+            nState |= CTRL_STATE_PRESSED;
             bPaintButton = true;
         }
         else
@@ -2556,77 +2585,80 @@ sal_Bool GtkSalGraphics::NWPaintGTKToolbar(
 
         NWSetWidgetState( pButtonWidget, nState, stateType );
         gtk_widget_ensure_style( pButtonWidget );
+        if(bPaintButton)
+            NWPaintGTKButtonReal(pButtonWidget, gdkDrawable, 0, 0, rControlRectangle, rClipList, nState, aValue, string);
     }
 
-    for( clipList::const_iterator it = rClipList.begin(); it != rClipList.end(); ++it )
+    if( nPart != PART_BUTTON )
     {
-        clipRect.x = it->Left();
-        clipRect.y = it->Top();
-        clipRect.width = it->GetWidth();
-        clipRect.height = it->GetHeight();
-
-        // draw toolbar
-        if( nPart == PART_DRAW_BACKGROUND_HORZ || nPart == PART_DRAW_BACKGROUND_VERT )
+        for( clipList::const_iterator it = rClipList.begin(); it != rClipList.end(); ++it )
         {
-            gtk_paint_flat_box( gWidgetData[m_nScreen].gToolbarWidget->style,
-                                gdkDrawable,
-                                (GtkStateType)GTK_STATE_NORMAL,
-                                GTK_SHADOW_NONE,
-                                &clipRect,
-                                gWidgetData[m_nScreen].gToolbarWidget,
-                                "base",
-                                x, y, w, h );
-            gtk_paint_box( gWidgetData[m_nScreen].gToolbarWidget->style,
-                           gdkDrawable,
-                           stateType,
-                           shadowType,
-                           &clipRect,
-                           gWidgetData[m_nScreen].gToolbarWidget,
-                           "toolbar",
-                           x, y, w, h );
-        }
-        // draw grip
-        else if( nPart == PART_THUMB_HORZ || nPart == PART_THUMB_VERT )
-        {
-            gtk_paint_handle( gWidgetData[m_nScreen].gHandleBoxWidget->style,
-                              gdkDrawable,
-                              GTK_STATE_NORMAL,
-                              GTK_SHADOW_OUT,
-                              &clipRect,
-                              gWidgetData[m_nScreen].gHandleBoxWidget,
-                              "handlebox",
-                              g_x, g_y, g_w, g_h,
-                              nPart == PART_THUMB_HORZ ?
-                              GTK_ORIENTATION_HORIZONTAL :
-                              GTK_ORIENTATION_VERTICAL
-                              );
-        }
-        // draw button
-        else if( nPart == PART_BUTTON )
-        {
-            if( bPaintButton )
+            clipRect.x = it->Left();
+            clipRect.y = it->Top();
+            clipRect.width = it->GetWidth();
+            clipRect.height = it->GetHeight();
+
+            // draw toolbar
+            if( nPart == PART_DRAW_BACKGROUND_HORZ || nPart == PART_DRAW_BACKGROUND_VERT )
             {
-                gtk_paint_box( pButtonWidget->style, gdkDrawable,
+                gtk_paint_flat_box( gWidgetData[m_nScreen].gToolbarWidget->style,
+                                    gdkDrawable,
+                                    (GtkStateType)GTK_STATE_NORMAL,
+                                    GTK_SHADOW_NONE,
+                                    &clipRect,
+                                    gWidgetData[m_nScreen].gToolbarWidget,
+                                    "base",
+                                    x, y, w, h );
+                gtk_paint_box( gWidgetData[m_nScreen].gToolbarWidget->style,
+                               gdkDrawable,
                                stateType,
                                shadowType,
                                &clipRect,
-                               pButtonWidget, "button", x, y, w, h );
+                               gWidgetData[m_nScreen].gToolbarWidget,
+                               "toolbar",
+                               x, y, w, h );
+            }
+            // draw grip
+            else if( nPart == PART_THUMB_HORZ || nPart == PART_THUMB_VERT )
+            {
+                gtk_paint_handle( gWidgetData[m_nScreen].gHandleBoxWidget->style,
+                                  gdkDrawable,
+                                  GTK_STATE_NORMAL,
+                                  GTK_SHADOW_OUT,
+                                  &clipRect,
+                                  gWidgetData[m_nScreen].gHandleBoxWidget,
+                                  "handlebox",
+                                  g_x, g_y, g_w, g_h,
+                                  nPart == PART_THUMB_HORZ ?
+                                  GTK_ORIENTATION_HORIZONTAL :
+                                  GTK_ORIENTATION_VERTICAL
+                                  );
+            }
+            else if(nPart == PART_SEPARATOR )
+            {
+                gint separator_height, separator_width, wide_separators;
+
+                gtk_widget_style_get (gWidgetData[m_nScreen].gVSeparator,
+                                      "wide-separators",  &wide_separators,
+                                      "separator-width",  &separator_width,
+                                      "separator-height", &separator_height,
+                                      NULL);
+                if (wide_separators)
+                    gtk_paint_box (gWidgetData[m_nScreen].gVSeparator->style, gdkDrawable,
+                               GTK_STATE_NORMAL, GTK_SHADOW_ETCHED_OUT,
+                               &clipRect, gWidgetData[m_nScreen].gVSeparator, "vseparator",
+                               x + (w - separator_width) / 2,
+                               y + 7,
+                               separator_width,
+                               h - 14);
+                else
+                    gtk_paint_vline (gWidgetData[m_nScreen].gVSeparator->style, gdkDrawable,
+                                 GTK_STATE_NORMAL,
+                                 &clipRect, gWidgetData[m_nScreen].gVSeparator, "vseparator",
+                                 y + 7,
+                                 y + h - 7,
+                                 x + w/2 - 1);
             }
-        }
-        else if(nPart == PART_SEPARATOR )
-        {
-            gtk_paint_vline( gWidgetData[m_nScreen].gVSeparator->style,
-                              gdkDrawable,
-                              GTK_STATE_NORMAL,
-                              &clipRect,
-                              gWidgetData[m_nScreen].gVSeparator,
-                              "vseparator",
-                              y + 4, y + h - 8 /* -2 and -4 is a dirty
-                                                * hack, to fit most gtk
-                                                * style, but it must be
-                                                * fixed, FIXME */,
-                              x
-                              );
         }
     }
 
@@ -3657,7 +3689,7 @@ GdkPixmap* GtkSalGraphics::NWGetPixmapFromScreen( Rectangle srcRect )
 {
     // Create a new pixmap to hold the composite of the window background and the control
     GdkPixmap * pPixmap        = gdk_pixmap_new( GDK_DRAWABLE(GetGdkWindow()), srcRect.GetWidth(), srcRect.GetHeight(), -1 );
-    GdkGC *     pPixmapGC    = gdk_gc_new( pPixmap );
+    GdkGC *     pPixmapGC      = gdk_gc_new( pPixmap );
 
     if( !pPixmap || !pPixmapGC )
     {
@@ -3956,9 +3988,9 @@ static void NWEnsureGTKToolbar( int nScreen )
     {
         gWidgetData[nScreen].gToolbarWidget = gtk_toolbar_new();
         NWAddWidgetToCacheWindow( gWidgetData[nScreen].gToolbarWidget, nScreen );
-        gWidgetData[nScreen].gToolbarButtonWidget = gtk_button_new();
-        gWidgetData[nScreen].gToolbarToggleWidget = gtk_toggle_button_new();
-        gWidgetData[nScreen].gVSeparator = gtk_vseparator_new();
+        gWidgetData[nScreen].gToolbarButtonWidget = GTK_WIDGET(gtk_button_new());
+        gWidgetData[nScreen].gToolbarToggleWidget = GTK_WIDGET(gtk_toggle_tool_button_new());
+        gWidgetData[nScreen].gVSeparator = GTK_WIDGET(gtk_separator_tool_item_new());
         NWAddWidgetToCacheWindow( gWidgetData[nScreen].gVSeparator, nScreen );
 
         GtkReliefStyle aRelief = GTK_RELIEF_NORMAL;
diff --git a/vcl/unx/inc/plugins/gtk/gtkgdi.hxx b/vcl/unx/inc/plugins/gtk/gtkgdi.hxx
index 2aaafc5..4e4091c 100644
--- a/vcl/unx/inc/plugins/gtk/gtkgdi.hxx
+++ b/vcl/unx/inc/plugins/gtk/gtkgdi.hxx
@@ -95,6 +95,11 @@ protected:
     GdkPixmap* NWGetPixmapFromScreen( Rectangle srcRect );
     sal_Bool NWRenderPixmapToScreen( GdkPixmap*	pPixmap, Rectangle dstRect );
 
+    sal_Bool NWPaintGTKButtonReal( GtkWidget* button, GdkDrawable* gdkDrawable, ControlType nType, ControlPart nPart,
+                           const Rectangle& rControlRectangle,
+                           const clipList& rClipList,
+                           ControlState nState, const ImplControlValue& aValue,
+                           const OUString& rCaption );
     sal_Bool NWPaintGTKButton( GdkDrawable* gdkDrawable, ControlType nType, ControlPart nPart,
                            const Rectangle& rControlRectangle,
                            const clipList& rClipList,
-- 
1.7.4.1


--=-z0CAXJ6Y5pV2PskaCpDJ--



More information about the LibreOffice mailing list