]> Pileus Git - ~andy/gtk/commitdiff
Add shadow-type style property, set shadow-type property of GtkEntry
authorMathias Hasselmann <mathias.hasselmann@gmx.de>
Thu, 8 Mar 2007 02:36:46 +0000 (02:36 +0000)
committerDom Lachowicz <doml@src.gnome.org>
Thu, 8 Mar 2007 02:36:46 +0000 (02:36 +0000)
2007-03-08  Mathias Hasselmann <mathias.hasselmann@gmx.de>

* gtk/gtkcombobox.c: Add shadow-type style property, set shadow-type
property of GtkEntry accordingly, unify size-allocation of toggle
button (#411123, patch from Mathias Hasselmann).
* gtk/gtkentry.c: Add shadow-type property. Query style properties
on style changes only (#411123, patch from Mathias Hasselmann).
* modules/engines/ms-windows/msw_style.c: Drop combo_box_draw_box
hack as GtkComboBox emits drawing requests now (#411123, patch
from Mathias Hasselmann).

svn path=/trunk/; revision=17426

ChangeLog
gtk/gtkcombobox.c
gtk/gtkentry.c
modules/engines/ms-windows/msw_style.c

index 5cee8530b1e306e779b563928a4bcdb913d13c6d..4b672a60880790aa10d9c8d75d9a2c03a6e111d8 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2007-03-08  Mathias Hasselmann <mathias.hasselmann@gmx.de>
+
+       * gtk/gtkcombobox.c: Add shadow-type style property, set shadow-type
+       property of GtkEntry accordingly, unify size-allocation of toggle
+       button (#411123, patch from Mathias Hasselmann).
+       * gtk/gtkentry.c: Add shadow-type property. Query style properties
+       on style changes only (#411123, patch from Mathias Hasselmann).
+       * modules/engines/ms-windows/msw_style.c: Drop combo_box_draw_box
+       hack as GtkComboBox emits drawing requests now (#411123, patch 
+       from Mathias Hasselmann).
+       
 2007-03-08  Mathias Hasselmann <mathias.hasselmann@gmx.de>
 
        * gtk/gtkscrolledindow.c: Improve look of GtkScrolledWindow on Windows
index 08eaea135dc47cf00654418a789a7bd198e262ce..ba0caed88625374f813ee006e679a45e52e8232a 100644 (file)
@@ -79,6 +79,7 @@ struct _GtkComboBoxPrivate
   gint row_column;
 
   gint wrap_width;
+  GtkShadowType shadow_type;
 
   GtkTreeRowReference *active_row;
 
@@ -775,6 +776,21 @@ gtk_combo_box_class_init (GtkComboBoxClass *klass)
                                                             15,
                                                             GTK_PARAM_READABLE));
 
+  /**
+   * GtkComboBox:shadow-type:
+   *
+   * Which kind of shadow to draw around the combo box.
+   *
+   * Since: 2.12
+   */
+  gtk_widget_class_install_style_property (widget_class,
+                                           g_param_spec_enum ("shadow-type",
+                                                              P_("Shadow type"),
+                                                              P_("Which kind of shadow to draw around the combo box"),
+                                                              GTK_TYPE_SHADOW_TYPE,
+                                                              GTK_SHADOW_NONE,
+                                                              GTK_PARAM_READABLE));
+
   g_type_class_add_private (object_class, sizeof (GtkComboBoxPrivate));
 }
 
@@ -1019,6 +1035,10 @@ gtk_combo_box_check_appearance (GtkComboBox *combo_box)
       if (!GTK_IS_MENU (combo_box->priv->popup_widget))
        gtk_combo_box_menu_setup (combo_box, TRUE);
     }
+
+  gtk_widget_style_get (GTK_WIDGET (combo_box),
+                       "shadow-type", &combo_box->priv->shadow_type,
+                       NULL);
 }
 
 static void
@@ -1032,6 +1052,11 @@ gtk_combo_box_style_set (GtkWidget *widget,
   if (combo_box->priv->tree_view && combo_box->priv->cell_view)
     gtk_cell_view_set_background_color (GTK_CELL_VIEW (combo_box->priv->cell_view), 
                                        &widget->style->base[GTK_WIDGET_STATE (widget)]);
+
+  if (GTK_IS_ENTRY (GTK_BIN (combo_box)->child))
+    g_object_set (GTK_BIN (combo_box)->child, "shadow-type",
+                  GTK_SHADOW_NONE == combo_box->priv->shadow_type ?
+                  GTK_SHADOW_IN : GTK_SHADOW_NONE, NULL);
 }
 
 static void
@@ -1344,6 +1369,9 @@ gtk_combo_box_menu_position_below (GtkMenu  *menu,
        sy += child->allocation.y;
       }
 
+   if (GTK_SHADOW_NONE != combo_box->priv->shadow_type)
+     sx -= GTK_WIDGET (combo_box)->style->xthickness;
+
    gtk_widget_size_request (GTK_WIDGET (menu), &req);
 
    if (gtk_widget_get_direction (GTK_WIDGET (combo_box)) == GTK_TEXT_DIR_LTR)
@@ -2026,13 +2054,36 @@ gtk_combo_box_size_request (GtkWidget      *widget,
       requisition->height = MAX (requisition->height, button_req.height);
       requisition->width += button_req.width;
     }
+
+  if (GTK_SHADOW_NONE != combo_box->priv->shadow_type)
+    {
+      requisition->height += 2 * widget->style->ythickness;
+      requisition->width += 2 * widget->style->xthickness;
+    }
 }
 
+#define GTK_COMBO_BOX_SIZE_ALLOCATE_BUTTON                                     \
+  gtk_widget_size_request (combo_box->priv->button, &req);                     \
+                                                                               \
+  if (is_rtl)                                                                  \
+    child.x = allocation->x + shadow_width;                                    \
+  else                                                                         \
+    child.x = allocation->x + allocation->width - req.width - shadow_width;    \
+                                                                               \
+  child.y = allocation->y + shadow_height;                                     \
+  child.width = req.width;                                                     \
+  child.height = allocation->height - 2 * shadow_height;                       \
+  child.width = MAX (1, child.width);                                          \
+  child.height = MAX (1, child.height);                                                \
+                                                                               \
+  gtk_widget_size_allocate (combo_box->priv->button, &child);
+
 static void
 gtk_combo_box_size_allocate (GtkWidget     *widget,
                              GtkAllocation *allocation)
 {
   GtkComboBox *combo_box = GTK_COMBO_BOX (widget);
+  gint shadow_width, shadow_height;
   gint focus_width, focus_pad;
   GtkAllocation child;
   GtkRequisition req;
@@ -2045,6 +2096,17 @@ gtk_combo_box_size_allocate (GtkWidget     *widget,
                        "focus-padding", &focus_pad,
                        NULL);
 
+  if (GTK_SHADOW_NONE != combo_box->priv->shadow_type)
+    {
+      shadow_width = widget->style->xthickness;
+      shadow_height = widget->style->ythickness;
+    }
+  else
+    {
+      shadow_width = 0;
+      shadow_height = 0;
+    }
+
   if (!combo_box->priv->tree_view)
     {
       if (combo_box->priv->cell_view)
@@ -2053,6 +2115,11 @@ gtk_combo_box_size_allocate (GtkWidget     *widget,
           gint width;
 
           /* menu mode */
+          allocation->x += shadow_width;
+          allocation->y += shadow_height;
+          allocation->width -= 2 * shadow_width;
+          allocation->height -= 2 * shadow_height;
+
           gtk_widget_size_allocate (combo_box->priv->button, allocation);
 
           /* set some things ready */
@@ -2113,24 +2180,14 @@ gtk_combo_box_size_allocate (GtkWidget     *widget,
         }
       else
         {
-          gtk_widget_size_request (combo_box->priv->button, &req);
-          if (is_rtl)
-            child.x = allocation->x;
-          else
-            child.x = allocation->x + allocation->width - req.width;
-          child.y = allocation->y;
-          child.width = req.width;
-          child.height = allocation->height;
-         child.width = MAX (1, child.width);
-         child.height = MAX (1, child.height);
-          gtk_widget_size_allocate (combo_box->priv->button, &child);
+          GTK_COMBO_BOX_SIZE_ALLOCATE_BUTTON
 
           if (is_rtl)
-            child.x = allocation->x + req.width;
+            child.x = allocation->x + req.width + shadow_width;
           else
-            child.x = allocation->x;
-          child.y = allocation->y;
-          child.width = allocation->width - req.width;
+            child.x = allocation->x + shadow_width;
+          child.y = allocation->y + shadow_height;
+          child.width = allocation->width - req.width - 2 * shadow_width;
          child.width = MAX (1, child.width);
          child.height = MAX (1, child.height);
           gtk_widget_size_allocate (GTK_BIN (widget)->child, &child);
@@ -2141,17 +2198,7 @@ gtk_combo_box_size_allocate (GtkWidget     *widget,
       /* list mode */
 
       /* button */
-      gtk_widget_size_request (combo_box->priv->button, &req);
-      if (is_rtl)
-        child.x = allocation->x;
-      else
-        child.x = allocation->x + allocation->width - req.width;
-      child.y = allocation->y;
-      child.width = req.width;
-      child.height = allocation->height;
-      child.width = MAX (1, child.width);
-      child.height = MAX (1, child.height);
-      gtk_widget_size_allocate (combo_box->priv->button, &child);
+      GTK_COMBO_BOX_SIZE_ALLOCATE_BUTTON
 
       /* frame */
       if (is_rtl)
@@ -2192,6 +2239,8 @@ gtk_combo_box_size_allocate (GtkWidget     *widget,
     }
 }
 
+#undef GTK_COMBO_BOX_ALLOCATE_BUTTON
+
 static void
 gtk_combo_box_unset_model (GtkComboBox *combo_box)
 {
@@ -2277,6 +2326,16 @@ gtk_combo_box_expose_event (GtkWidget      *widget,
 {
   GtkComboBox *combo_box = GTK_COMBO_BOX (widget);
 
+  if (GTK_WIDGET_DRAWABLE (widget) &&
+      GTK_SHADOW_NONE != combo_box->priv->shadow_type)
+    {
+      gtk_paint_shadow (widget->style, widget->window,
+                        GTK_STATE_NORMAL, combo_box->priv->shadow_type,
+                        NULL, widget, "combobox",
+                        widget->allocation.x, widget->allocation.y,
+                        widget->allocation.width, widget->allocation.height);
+    }
+
   gtk_container_propagate_expose (GTK_CONTAINER (widget),
                                  combo_box->priv->button, event);
 
index 2cf8f8df92cb5f599e4b1272f1507a599dde136b..6f7b1caf18e28c2e1c1e127d41998eba01b9fe2c 100644 (file)
@@ -85,6 +85,10 @@ struct _GtkEntryPrivate
   guint blink_time;  /* time in msec the cursor has blinked since last user event */
   guint real_changed : 1;
   guint change_count : 8;
+
+  gint focus_width;
+  gboolean interior_focus;
+  GtkShadowType shadow_type;
 };
 
 typedef struct _GtkEntryPasswordHint GtkEntryPasswordHint;
@@ -126,7 +130,8 @@ enum {
   PROP_SCROLL_OFFSET,
   PROP_TEXT,
   PROP_XALIGN,
-  PROP_TRUNCATE_MULTILINE
+  PROP_TRUNCATE_MULTILINE,
+  PROP_SHADOW_TYPE
 };
 
 static guint signals[LAST_SIGNAL] = { 0 };
@@ -600,6 +605,22 @@ gtk_entry_class_init (GtkEntryClass *class)
                                                          FALSE,
                                                          GTK_PARAM_READWRITE));
 
+  /**
+   * GtkEntry:shadow-type:
+   *
+   * Which kind of shadow to draw around the entry when has-frame is set.
+   *
+   * Since: 2.12
+   */
+  g_object_class_install_property (gobject_class,
+                                   PROP_SHADOW_TYPE,
+                                   g_param_spec_enum ("shadow-type",
+                                                      P_("Shadow type"),
+                                                      P_("Which kind of shadow to draw around the entry when has-frame is set"),
+                                                      GTK_TYPE_SHADOW_TYPE,
+                                                      GTK_SHADOW_IN,
+                                                      GTK_PARAM_READWRITE));
+
   signals[POPULATE_POPUP] =
     g_signal_new (I_("populate_popup"),
                  G_OBJECT_CLASS_TYPE (gobject_class),
@@ -917,6 +938,7 @@ gtk_entry_set_property (GObject         *object,
                         const GValue    *value,
                         GParamSpec      *pspec)
 {
+  GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (object);
   GtkEntry *entry = GTK_ENTRY (object);
 
   switch (prop_id)
@@ -987,6 +1009,10 @@ gtk_entry_set_property (GObject         *object,
       entry->truncate_multiline = g_value_get_boolean (value);
       break;
 
+    case PROP_SHADOW_TYPE:
+      priv->shadow_type = g_value_get_enum (value);
+      break;
+
     case PROP_SCROLL_OFFSET:
     case PROP_CURSOR_POSITION:
     default:
@@ -1001,6 +1027,7 @@ gtk_entry_get_property (GObject         *object,
                         GValue          *value,
                         GParamSpec      *pspec)
 {
+  GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (object);
   GtkEntry *entry = GTK_ENTRY (object);
 
   switch (prop_id)
@@ -1047,6 +1074,9 @@ gtk_entry_get_property (GObject         *object,
     case PROP_TRUNCATE_MULTILINE:
       g_value_set_boolean (value, entry->truncate_multiline);
       break;
+    case PROP_SHADOW_TYPE:
+      g_value_set_enum (value, priv->shadow_type);
+      break;
 
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -1074,6 +1104,7 @@ gtk_entry_init (GtkEntry *entry)
   entry->editing_canceled = FALSE;
   entry->has_frame = TRUE;
   entry->truncate_multiline = FALSE;
+  priv->shadow_type = GTK_SHADOW_IN;
   priv->xalign = 0.0;
 
   gtk_drag_dest_set (GTK_WIDGET (entry),
@@ -1307,13 +1338,7 @@ _gtk_entry_get_borders (GtkEntry *entry,
                        gint     *yborder)
 {
   GtkWidget *widget = GTK_WIDGET (entry);
-  gint focus_width;
-  gboolean interior_focus;
-
-  gtk_widget_style_get (widget,
-                       "interior-focus", &interior_focus,
-                       "focus-line-width", &focus_width,
-                       NULL);
+  GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (widget);
 
   if (entry->has_frame)
     {
@@ -1326,10 +1351,10 @@ _gtk_entry_get_borders (GtkEntry *entry,
       *yborder = 0;
     }
 
-  if (!interior_focus)
+  if (!priv->interior_focus)
     {
-      *xborder += focus_width;
-      *yborder += focus_width;
+      *xborder += priv->focus_width;
+      *yborder += priv->focus_width;
     }
 }
 
@@ -1382,13 +1407,7 @@ get_text_area_size (GtkEntry *entry,
   gint xborder, yborder;
   GtkRequisition requisition;
   GtkWidget *widget = GTK_WIDGET (entry);
-  gboolean interior_focus;
-  gint focus_width;
-
-  gtk_widget_style_get (widget,
-                        "interior-focus", &interior_focus,
-                        "focus-line-width", &focus_width,
-                        NULL);
+  GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (widget);
 
   gtk_widget_get_child_requisition (widget, &requisition);
   _gtk_entry_get_borders (entry, &xborder, &yborder);
@@ -1398,8 +1417,8 @@ get_text_area_size (GtkEntry *entry,
   else
     frame_height = requisition.height;
 
-  if (GTK_WIDGET_HAS_FOCUS (widget) && !interior_focus)
-      frame_height -= 2 * focus_width;
+  if (GTK_WIDGET_HAS_FOCUS (widget) && !priv->interior_focus)
+      frame_height -= 2 * priv->focus_width;
 
   if (x)
     *x = xborder;
@@ -1509,37 +1528,29 @@ static void
 gtk_entry_draw_frame (GtkWidget    *widget,
                       GdkRectangle *area)
 {
-  gint x = 0, y = 0;
-  gint width, height;
-  gboolean interior_focus;
-  gint focus_width;
-  
-  gtk_widget_style_get (widget,
-                       "interior-focus", &interior_focus,
-                       "focus-line-width", &focus_width,
-                       NULL);
+  GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (widget);
+  gint x = 0, y = 0, width, height;
   
   gdk_drawable_get_size (widget->window, &width, &height);
   
-  if (GTK_WIDGET_HAS_FOCUS (widget) && !interior_focus)
+  if (GTK_WIDGET_HAS_FOCUS (widget) && !priv->interior_focus)
     {
-      x += focus_width;
-      y += focus_width;
-      width -= 2 * focus_width;
-      height -= 2 * focus_width;
+      x += priv->focus_width;
+      y += priv->focus_width;
+      width -= 2 * priv->focus_width;
+      height -= 2 * priv->focus_width;
     }
 
   gtk_paint_shadow (widget->style, widget->window,
-                   GTK_STATE_NORMAL, GTK_SHADOW_IN,
-                   area, widget, "entry",
-                   x, y, width, height);
+                   GTK_STATE_NORMAL, priv->shadow_type,
+                   area, widget, "entry", x, y, width, height);
 
-  if (GTK_WIDGET_HAS_FOCUS (widget) && !interior_focus)
+  if (GTK_WIDGET_HAS_FOCUS (widget) && !priv->interior_focus)
     {
-      x -= focus_width;
-      y -= focus_width;
-      width += 2 * focus_width;
-      height += 2 * focus_width;
+      x -= priv->focus_width;
+      y -= priv->focus_width;
+      width += 2 * priv->focus_width;
+      height += 2 * priv->focus_width;
       
       gtk_paint_focus (widget->style, widget->window, GTK_WIDGET_STATE (widget), 
                       area, widget, "entry",
@@ -2335,7 +2346,13 @@ gtk_entry_style_set      (GtkWidget      *widget,
                         GtkStyle       *previous_style)
 {
   GtkEntry *entry = GTK_ENTRY (widget);
+  GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry);
 
+  gtk_widget_style_get (widget,
+                       "focus-line-width", &priv->focus_width,
+                       "interior-focus", &priv->interior_focus,
+                       NULL);
+  
   gtk_entry_recompute (entry);
 
   if (previous_style && GTK_WIDGET_REALIZED (widget))
index 73504beeb2f1930276a812a68a78c65dca8e6859..07a53ce89d6965a4b0d0bace5baffd2f84da9e28 100755 (executable)
@@ -844,20 +844,32 @@ setup_msw_rc_style (void)
     gtk_rc_parse_string (buf);
 
     /* size of combo box toggle button */
-               g_snprintf (buf, sizeof(buf),
-           "style \"msw-combo-button\" = \"msw-default\"\n"
+    g_snprintf (buf, sizeof(buf),
+               "style \"msw-combobox-button\" = \"msw-default\"\n"
                "{\n"
-               "xthickness = 0\n"
-               "ythickness = 0\n"
-               "GtkButton::default-border = { 0, 0, 0, 0 }\n"
-               "GtkButton::default-outside-border = { 0, 0, 0, 0 }\n"
-               "GtkButton::child-displacement-x = 0\n"
-               "GtkButton::child-displacement-y = 0\n"
-               "GtkWidget::focus-padding = 0\n"
-               "GtkWidget::focus-line-width = 0\n"
+               "xthickness = 0\n"
+               "ythickness = 0\n"
+               "GtkButton::default-border = { 0, 0, 0, 0 }\n"
+               "GtkButton::default-outside-border = { 0, 0, 0, 0 }\n"
+               "GtkButton::child-displacement-x = 0\n"
+               "GtkButton::child-displacement-y = 0\n"
+               "GtkWidget::focus-padding = 0\n"
+               "GtkWidget::focus-line-width = 0\n"
                "}\n"
-           "widget_class \"*ComboBox*ToggleButton*\" style \"msw-combo-button\"\n");
-       gtk_rc_parse_string (buf);
+               "widget_class \"*ComboBox*ToggleButton*\" style \"msw-combobox-button\"\n");
+    gtk_rc_parse_string (buf);
+
+    g_snprintf (buf, sizeof(buf),
+               "style \"msw-combobox\" = \"msw-default\"\n"
+               "{\n"
+               "GtkComboBox::shadow-type = in\n"
+               "xthickness = %d\n"
+               "ythickness = %d\n"
+               "}\n"
+               "class \"GtkComboBox\" style \"msw-combobox\"\n",
+               GetSystemMetrics (SM_CXEDGE),
+               GetSystemMetrics (SM_CYEDGE));
+    gtk_rc_parse_string (buf);
 
     /* size of tree view header */
     g_snprintf (buf, sizeof(buf),
@@ -1036,111 +1048,22 @@ combo_box_draw_arrow (GtkStyle * style,
            GdkRectangle * area,
            GtkWidget * widget)
 {
-    HDC dc;
-    RECT rect;
-
-    if (xp_theme_draw (window, XP_THEME_ELEMENT_COMBOBUTTON,
-                      style, widget->allocation.x, widget->allocation.y,
-                      widget->allocation.width, widget->allocation.height,
-                      state, area))
-       {
-           return TRUE;
-       }
-    else if ( !xp_theme_is_active () && widget && GTK_IS_TOGGLE_BUTTON(widget->parent) )
-    {
-        dc = get_window_dc( style, window, state, area->x, area->y, area->width, area->height, &rect );
-        InflateRect( &rect, 1, 1 );
-        DrawFrameControl( dc, &rect, DFC_SCROLL, DFCS_SCROLLDOWN | 
-            (GTK_TOGGLE_BUTTON(widget->parent)->active ? DFCS_PUSHED|DFCS_FLAT : 0) );
-        release_window_dc( style, window, state );
+    if (xp_theme_is_active ())
         return TRUE;
-    }
-    return FALSE;
-}
 
-/* This is ugly because no box drawing function is invoked for the combo
-   box as a whole, so we draw part of the entire box in every subwidget.
-   We do this by finding the allocation of the combo box in the given
-   window's coordinates and drawing.  The xp drawing routines take care
-   of the clipping. */
-static gboolean
-combo_box_draw_box (GtkStyle * style,
-         GdkWindow * window,
-         GtkStateType state_type,
-         GtkShadowType shadow_type,
-         GdkRectangle * area,
-         GtkWidget * widget,
-         const gchar * detail, gint x, gint y, gint width, gint height)
-{
-    GtkWidget* combo_box;
-    GdkRectangle combo_alloc;
-    HDC dc;
-    RECT rect;
-
-    if (!widget)
-       return FALSE;
-    for (combo_box = widget->parent; combo_box; combo_box = combo_box->parent)
-       {
-           if (GTK_IS_COMBO_BOX(combo_box))
-               break;
-       }
-    if (!combo_box)
-       return FALSE;
+    if (widget && GTK_IS_TOGGLE_BUTTON(widget->parent) )
+    {
+       DWORD border;
+        RECT rect;
+        HDC dc;
 
-    combo_alloc = combo_box->allocation;
-    if (window != combo_box->window)
-       {
-           GtkWidget* tmp;
-           for (tmp = widget; tmp && tmp != combo_box; tmp = widget->parent)
-               {
-                   if (tmp->parent && tmp->window != tmp->parent->window)
-                       {
-                           combo_alloc.x -= tmp->allocation.x;
-                           combo_alloc.y -= tmp->allocation.y;
-                       }
-               }
-       }
+        dc = get_window_dc( style, window, state, area->x, area->y, area->width, area->height, &rect );
+       border = (GTK_TOGGLE_BUTTON(widget->parent)->active ? DFCS_PUSHED|DFCS_FLAT : 0);
 
-    if (xp_theme_draw (window, XP_THEME_ELEMENT_EDIT_TEXT,
-                      style, combo_alloc.x, combo_alloc.y,
-                       combo_alloc.width, combo_alloc.height,
-                      state_type, area))
-       return TRUE;
-    else
-    {
-        UINT edges = 0;
-        gboolean rtl = (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL);
-
-        if( !strcmp(detail, "button") )
-            edges = BF_BOTTOM|BF_TOP|(rtl ? BF_LEFT : BF_RIGHT);
-        else if( !strcmp( detail, "frame") || !strcmp( detail, "entry" ) )
-            edges = BF_BOTTOM|BF_TOP|(rtl ? BF_RIGHT : BF_LEFT);
-        else
-            return TRUE;
-        dc = get_window_dc( style, window, state_type, x, y, width, height, &rect );
-        DrawEdge( dc, &rect, EDGE_SUNKEN, edges );
+        InflateRect( &rect, 1, 1 );
+        DrawFrameControl (dc, &rect, DFC_SCROLL, DFCS_SCROLLDOWN | border);
 
-        /* Fill blank area between frame/entry and button */
-        if( !strcmp(detail, "button") ) {  /* button */
-            if( rtl ) {
-                rect.left = rect.right;
-                rect.right += 2;
-            }
-            else
-                rect.right = rect.left + 2;
-        }
-        else{ /* frame or entry */
-            if( rtl ) {
-                rect.right = rect.left;
-                rect.left -= 2;
-            }
-            else
-                rect.left = rect.right - 2;
-        }
-        rect.top += 2;
-        rect.bottom -= 2;
-        FillRect( dc, &rect, GetSysColorBrush(COLOR_WINDOW) );
-        release_window_dc( style, window, state_type );
+        release_window_dc( style, window, state );
         return TRUE;
     }
 
@@ -1587,6 +1510,8 @@ draw_arrow (GtkStyle * style,
                 case GTK_ARROW_RIGHT:
                     btn_type = DFCS_SCROLLRIGHT;
                     break;
+                case GTK_ARROW_NONE:
+                                       break;
                 }
                 if( state == GTK_STATE_INSENSITIVE )
                     btn_type |= DFCS_INACTIVE;
@@ -1926,13 +1851,26 @@ draw_box (GtkStyle * style,
          GtkWidget * widget,
          const gchar * detail, gint x, gint y, gint width, gint height)
 {
-    if (is_combo_box_child (widget)
-       && combo_box_draw_box (style, window, state_type, shadow_type,
-                              area, widget, detail, x, y, width, height))
-       {
+    if (is_combo_box_child (widget) && detail && !strcmp (detail, "button")) {
+        RECT rect;
+        HDC dc;
+        int cx;
+           
+        dc = get_window_dc (style, window, state_type, x, y, width - cx, height, &rect);
+        FillRect (dc, &rect, GetSysColorBrush(COLOR_WINDOW));
+        release_window_dc (style, window, state_type);
+
+       cx = 2 * GetSystemMetrics (SM_CXEDGE) + 16; /* TODO evaluate arrow width */
+        x += width - cx;
+        width = cx;
+
+       if (xp_theme_is_active () && xp_theme_draw (
+           window, XP_THEME_ELEMENT_COMBOBUTTON, style,
+           x, y, width, height, state_type, area))
            return;
-       }
-    else if (detail &&
+    }
+
+    if (detail &&
        (!strcmp (detail, "button") || !strcmp (detail, "buttondefault")))
        {
            if (GTK_IS_TREE_VIEW (widget->parent)
@@ -2370,6 +2308,8 @@ static void DrawTab(HDC hdc, const RECT R, gint32 aPosition, gboolean aSelected,
        SetRect(&lightRect, R.left, R.bottom-3, R.left+2, R.bottom-1);
        SetRect(&shadeRect, R.right-2, R.bottom-3, R.right, R.bottom-1);
        break;
+     default:
+       g_return_if_reached();
    }
 
    /* Background */
@@ -2699,12 +2639,6 @@ draw_shadow (GtkStyle * style,
     gboolean is_handlebox;
     gboolean is_toolbar;
 
-    if (is_combo_box_child (widget)
-       && combo_box_draw_box (style, window, state_type, shadow_type,
-                              area, widget, detail, x, y, width, height))
-        {
-           return;
-       }
     if( detail && !strcmp( detail, "frame") )
        {
         HDC dc;
@@ -2731,27 +2665,31 @@ draw_shadow (GtkStyle * style,
                 InflateRect( &rect, -1, -1 );
                 draw_3d_border(dc, &rect, TRUE);
                 break;
+            case GTK_SHADOW_NONE:
+                break;
             }
         }
         release_window_dc( style, window, state_type );
         return;
     }
-    if (detail && !strcmp (detail, "entry") )
+    if (detail && (!strcmp (detail, "entry") || !strcmp (detail, "combobox")) )
        {
-           if ( xp_theme_draw (window, XP_THEME_ELEMENT_EDIT_TEXT, style,
-                              x, y, width, height, state_type, area))
-               {
-                   return;
-               }
-            if( shadow_type == GTK_SHADOW_IN ) {
-                HDC dc;
-                RECT rect;
-                dc = get_window_dc( style, window, state_type, 
-                                    x, y, width, height, &rect );
-                DrawEdge( dc, &rect, EDGE_SUNKEN, BF_RECT );
-                release_window_dc( style, window, state_type );
-               return;
-            }
+            if( shadow_type != GTK_SHADOW_IN )
+               return;
+
+           if ( !xp_theme_draw (window, XP_THEME_ELEMENT_EDIT_TEXT, style,
+                                x, y, width, height, state_type, area))
+           {
+               HDC dc;
+               RECT rect;
+
+               dc = get_window_dc (style, window, state_type, 
+                                   x, y, width, height, &rect);
+               DrawEdge (dc, &rect, EDGE_SUNKEN, BF_RECT);
+               release_window_dc (style, window, state_type);
+           }
+
+           return;
        }
 
     if( detail && !strcmp( detail, "spinbutton" ) )
@@ -2777,7 +2715,7 @@ draw_shadow (GtkStyle * style,
         if( widget ) {
             HDC dc;
             RECT rect;
-            HGDIOBJ old_pen;
+            HGDIOBJ old_pen = NULL;
             GtkPositionType pos;
 
             sanitize_size (window, &width, &height);
@@ -2837,7 +2775,8 @@ draw_shadow (GtkStyle * style,
                 MoveToEx( dc, rect.left, rect.bottom-1, NULL );
                 LineTo( dc, rect.right, rect.bottom-1 );
                }
-            SelectObject( dc, old_pen );
+            if (old_pen)
+                SelectObject( dc, old_pen );
             release_window_dc( style, window, state_type );
                        }
         return;