diff --git a/ChangeLog b/ChangeLog
index 4a4172c..7896db8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2008-04-28  Sven Herzberg  <sven@imendio.com>
+
+	Fixes: #516108: Allow themes to define a minimum size and aspect
+	ratio for arrows.
+	Patch based on work by Christian Dywan <christian@imendio.com>
+
+	* gtk/gtkarrow.c:
+	(gtk_arrow_class_init),
+	(gtk_arrow_init),
+	(gtk_arrow_set_property),
+	(gtk_arrow_get_property),
+	(gtk_arrow_expose): Introduce the style properties "min-size" and
+	"aspect-ratio" and adjust the drawing code accordingly.
+
 2008-04-25  Björn Lindqvist  <bjourne@gmail.com>
 
 	* gtk/gtkentry.c: (gtk_entry_expose) Use existing window size when
diff --git a/gtk/gtkarrow.c b/gtk/gtkarrow.c
index 670bed9..8dd9446 100644
--- a/gtk/gtkarrow.c
+++ b/gtk/gtkarrow.c
@@ -31,14 +31,12 @@
 #include "gtkintl.h"
 #include "gtkalias.h"
 
-#define MIN_ARROW_SIZE  15
-
 enum {
   PROP_0,
 
   PROP_ARROW_TYPE,
   PROP_SHADOW_TYPE,
-  
+
   PROP_LAST
 };
 
@@ -53,6 +51,8 @@ static void gtk_arrow_get_property (GObject         *object,
 				    guint            prop_id,
 				    GValue          *value,
 				    GParamSpec      *pspec);
+static void gtk_arrow_size_request (GtkWidget *widget,
+                                    GtkRequisition *requisition);
 
 
 G_DEFINE_TYPE (GtkArrow, gtk_arrow, GTK_TYPE_MISC)
@@ -70,6 +70,8 @@ gtk_arrow_class_init (GtkArrowClass *class)
   gobject_class->set_property = gtk_arrow_set_property;
   gobject_class->get_property = gtk_arrow_get_property;
 
+  widget_class->size_request = gtk_arrow_size_request;
+
   g_object_class_install_property (gobject_class,
                                    PROP_ARROW_TYPE,
                                    g_param_spec_enum ("arrow-type",
@@ -92,6 +94,37 @@ gtk_arrow_class_init (GtkArrowClass *class)
                                                                P_("Amount of space used up by arrow"),
                                                                0.0, 1.0, 0.7,
                                                                GTK_PARAM_READABLE));
+  /**
+   * GtkArrow::min-size:
+   *
+   * Specifies the minimum width and height for the arrow.
+   *
+   * Since: 2.14
+   */
+  gtk_widget_class_install_style_property (widget_class,
+                                           g_param_spec_int ("min-size",
+                                                             P_("Arrow Minimum Size"),
+                                                             P_("Minimum size of the arrow widget"),
+                                                             0,
+                                                             G_MAXINT,
+                                                             15,
+                                                             GTK_PARAM_READABLE));
+  /**
+   * GtkArrow::aspect-ratio:
+   *
+   * Sets the height of the arrow as height = aspect-ratio * width.
+   * The default is 1.0, a square arrow.
+   *
+   * Since: 2.14
+   */
+  gtk_widget_class_install_style_property (widget_class,
+                                           g_param_spec_float ("aspect-ratio",
+                                                               P_("Aspect Ratio"),
+                                                               P_("Aspect ratio of the arrow widget"),
+                                                               -G_MAXFLOAT,
+                                                               G_MAXFLOAT,
+                                                               1.0,
+                                                               GTK_PARAM_READABLE));
 
   widget_class->expose_event = gtk_arrow_expose;
 }
@@ -149,13 +182,25 @@ gtk_arrow_get_property (GObject         *object,
 }
 
 static void
+gtk_arrow_size_request (GtkWidget *widget, GtkRequisition *requisition)
+{
+  gint arrow_min_size;
+  gfloat aspect_ratio;
+
+  gtk_widget_style_get (widget,
+                        "min-size", &arrow_min_size,
+                        "aspect-ratio", &aspect_ratio,
+                        NULL);
+
+  requisition->width = arrow_min_size + GTK_MISC (widget)->xpad * 2;
+  requisition->height = (arrow_min_size *aspect_ratio) + GTK_MISC (widget)->ypad * 2;
+}
+
+static void
 gtk_arrow_init (GtkArrow *arrow)
 {
   GTK_WIDGET_SET_FLAGS (arrow, GTK_NO_WINDOW);
 
-  GTK_WIDGET (arrow)->requisition.width = MIN_ARROW_SIZE + GTK_MISC (arrow)->xpad * 2;
-  GTK_WIDGET (arrow)->requisition.height = MIN_ARROW_SIZE + GTK_MISC (arrow)->ypad * 2;
-
   arrow->arrow_type = GTK_ARROW_RIGHT;
   arrow->shadow_type = GTK_SHADOW_OUT;
 }
@@ -213,7 +258,6 @@ gtk_arrow_expose (GtkWidget      *widget,
   GtkShadowType shadow_type;
   gint width, height;
   gint x, y;
-  gint extent;
   gfloat xalign;
   GtkArrowType effective_arrow_type;
 
@@ -226,7 +270,8 @@ gtk_arrow_expose (GtkWidget      *widget,
 
       width = widget->allocation.width - misc->xpad * 2;
       height = widget->allocation.height - misc->ypad * 2;
-      extent = MIN (width, height) * arrow_scaling;
+      width *= arrow_scaling;
+      height *= arrow_scaling;
       effective_arrow_type = arrow->arrow_type;
 
       if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
@@ -241,10 +286,10 @@ gtk_arrow_expose (GtkWidget      *widget,
 	}
 
       x = floor (widget->allocation.x + misc->xpad
-		 + ((widget->allocation.width - extent) * xalign));
+                 + ((widget->allocation.width - width) * xalign));
       y = floor (widget->allocation.y + misc->ypad 
-		 + ((widget->allocation.height - extent) * misc->yalign));
-      
+		 + ((widget->allocation.height - height) * misc->yalign));
+
       shadow_type = arrow->shadow_type;
 
       if (widget->state == GTK_STATE_ACTIVE)
@@ -263,7 +308,7 @@ gtk_arrow_expose (GtkWidget      *widget,
 		       widget->state, shadow_type,
 		       &event->area, widget, "arrow",
 		       effective_arrow_type, TRUE,
-		       x, y, extent, extent);
+		       x, y, width, height);
     }
 
   return FALSE;
