Index: gtk/gtkpaned.c
===================================================================
--- gtk/gtkpaned.c	(Revision 19546)
+++ gtk/gtkpaned.c	(Arbeitskopie)
@@ -40,6 +40,8 @@ enum {
   PROP_0,
   PROP_POSITION,
   PROP_POSITION_SET,
+  PROP_RATIO,
+  PROP_RATIO_SET,
   PROP_MIN_POSITION,
   PROP_MAX_POSITION
 };
@@ -138,6 +140,8 @@ struct _GtkPanedPrivate
   GtkWidget *saved_focus;
   GtkPaned  *first_paned;
   guint32    grab_time;
+  gdouble    ratio;
+  gboolean   ratio_set;
 };
 
 G_DEFINE_ABSTRACT_TYPE (GtkPaned, gtk_paned, GTK_TYPE_CONTAINER)
@@ -229,7 +233,42 @@ gtk_paned_class_init (GtkPanedClass *cla
 							 P_("TRUE if the Position property should be used"),
 							 FALSE,
 							 GTK_PARAM_READWRITE));
-				   
+
+ /**
+ * GtkPaned:ratio:
+ *
+ * The "ratio" property determines the relative position of the divider
+ * based on the actual size of the widget. Allowed values are percentages
+ * from 0.0 to 1.0.
+ *
+ * Since: 2.14
+ */
+  g_object_class_install_property (object_class,
+				   PROP_RATIO,
+				   g_param_spec_double ("ratio",
+						        P_("Ratio"),
+						        P_("Ratio of panel separator in percent (0.0 to 1.0)"),
+						        0,
+						        1.0,
+						        0,
+						        GTK_PARAM_READWRITE));
+
+ /**
+ * GtkPaned:ratio-set:
+ *
+ * TRUE if the divider position should be computed relative to the allocated
+ * size of the widget, based on the value of "ratio".
+ *
+ * Since: 2.14
+ */
+  g_object_class_install_property (object_class,
+				   PROP_RATIO_SET,
+				   g_param_spec_boolean ("ratio-set",
+						         P_("Ratio Set"),
+						         P_("TRUE if the Ratio property should be used"),
+						         FALSE,
+						         GTK_PARAM_READWRITE));
+
   gtk_widget_class_install_style_property (widget_class,
 					   g_param_spec_int ("handle-size",
 							     P_("Handle Size"),
@@ -551,6 +590,8 @@ gtk_paned_init (GtkPaned *paned)
   paned->in_drag = FALSE;
 
   paned->priv = G_TYPE_INSTANCE_GET_PRIVATE (paned, GTK_TYPE_PANED, GtkPanedPrivate);
+  paned->priv->ratio = 0.0;
+  paned->priv->ratio_set = FALSE;
   paned->last_child1_focus = NULL;
   paned->last_child2_focus = NULL;
   paned->in_recursion = FALSE;
@@ -580,6 +621,13 @@ gtk_paned_set_property (GObject        *
       paned->position_set = g_value_get_boolean (value);
       gtk_widget_queue_resize (GTK_WIDGET (paned));
       break;
+    case PROP_RATIO:
+      gtk_paned_set_ratio (paned, g_value_get_double (value));
+      break;
+    case PROP_RATIO_SET:
+      paned->priv->ratio_set = g_value_get_boolean (value);
+      gtk_widget_queue_resize (GTK_WIDGET (paned));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -602,6 +650,12 @@ gtk_paned_get_property (GObject        *
     case PROP_POSITION_SET:
       g_value_set_boolean (value, paned->position_set);
       break;
+    case PROP_RATIO:
+      g_value_set_double (value, paned->priv->ratio);
+      break;
+    case PROP_RATIO_SET:
+      g_value_set_boolean (value, paned->priv->ratio_set);
+      break;
     case PROP_MIN_POSITION:
       g_value_set_int (value, paned->min_position);
       break;
@@ -978,10 +1032,17 @@ gtk_paned_grab_broken (GtkWidget        
 		       GdkEventGrabBroken *event)
 {
   GtkPaned *paned = GTK_PANED (widget);
+  GObject *object = G_OBJECT (object);
 
   paned->in_drag = FALSE;
   paned->drag_pos = -1;
   paned->position_set = TRUE;
+  paned->priv->ratio_set = FALSE;
+
+  g_object_freeze_notify (object);
+  g_object_notify (object, "position-set");
+  g_object_notify (object, "ratio-set");
+  g_object_thaw_notify (object);
 
   return TRUE;
 }
@@ -989,9 +1050,18 @@ gtk_paned_grab_broken (GtkWidget        
 static void
 stop_drag (GtkPaned *paned)
 {
+  GObject *object = G_OBJECT (object);
+
   paned->in_drag = FALSE;
   paned->drag_pos = -1;
   paned->position_set = TRUE;
+  paned->priv->ratio_set = FALSE;
+
+  g_object_freeze_notify (object);
+  g_object_notify (object, "position-set");
+  g_object_notify (object, "ratio-set");
+  g_object_thaw_notify (object);
+
   gdk_display_pointer_ungrab (gtk_widget_get_display (GTK_WIDGET (paned)),
 			      paned->priv->grab_time);
 }
@@ -1194,6 +1264,31 @@ gtk_paned_get_position (GtkPaned  *paned
   return paned->child1_size;
 }
 
+void
+_gtk_paned_update_divider (GtkPaned *paned)
+{
+  GObject *object;
+
+  object = G_OBJECT (paned);
+
+  g_object_freeze_notify (object);
+  g_object_notify (object, "position");
+  g_object_notify (object, "position-set");
+  g_object_notify (object, "ratio");
+  g_object_notify (object, "ratio-set");
+  g_object_thaw_notify (object);
+
+  gtk_widget_queue_resize (GTK_WIDGET (paned));
+
+#ifdef G_OS_WIN32
+  /* Hacky work-around for bug #144269 */
+  if (paned->child2 != NULL)
+    {
+      gtk_widget_queue_draw (paned->child2);
+    }
+#endif
+}
+
 /**
  * gtk_paned_set_position:
  * @paned: a #GtkPaned widget
@@ -1201,17 +1296,18 @@ gtk_paned_get_position (GtkPaned  *paned
  *            is unset.
  * 
  * Sets the position of the divider between the two panes.
+ *
+ * Note that the position cannot exceed the available space, so if @panel
+ * is too small, the resulting position differs from the value set.
  **/
 void
 gtk_paned_set_position (GtkPaned *paned,
 			gint      position)
 {
   GObject *object;
-  
+
   g_return_if_fail (GTK_IS_PANED (paned));
 
-  object = G_OBJECT (paned);
-  
   if (position >= 0)
     {
       /* We don't clamp here - the assumption is that
@@ -1228,21 +1324,58 @@ gtk_paned_set_position (GtkPaned *paned,
     {
       paned->position_set = FALSE;
     }
+  paned->priv->ratio_set = FALSE;
 
-  g_object_freeze_notify (object);
-  g_object_notify (object, "position");
-  g_object_notify (object, "position-set");
-  g_object_thaw_notify (object);
+  _gtk_paned_update_divider (paned);
+}
 
-  gtk_widget_queue_resize (GTK_WIDGET (paned));
+/**
+ * gtk_paned_get_ratio:
+ * @paned: a #GtkPaned widget
+ *
+ * Obtains the ratio that determines the relative position of the divider
+ * between the two panes.
+ *
+ * Since: 2.14
+ * 
+ * Return value: ratio in percent
+ **/
+gdouble
+gtk_paned_get_ratio (GtkPaned  *paned)
+{
+  g_return_val_if_fail (GTK_IS_PANED (paned), 0.0);
 
-#ifdef G_OS_WIN32
-  /* Hacky work-around for bug #144269 */
-  if (paned->child2 != NULL)
-    {
-      gtk_widget_queue_draw (paned->child2);
-    }
-#endif
+  return paned->priv->ratio;
+}
+
+/**
+ * gtk_paned_set_ratio:
+ * @paned: a #GtkPaned widget
+ * @ratio: relative position of the divider
+ *
+ * Sets the relative position of the divider between the two panes, i.e. the
+ * relative size of the first child. Whenever the size of @paned changes, the
+ * divider is repositioned and the value of "position" is updated accordingly.
+ *
+ * The value should be between 0.0 and 1.0, inclusive.
+ *
+ * Note that any manual adjustment of "position" through code or user
+ * interaction will override the effects of "ratio".
+ *
+ * Since: 2.14
+ **/
+void
+gtk_paned_set_ratio (GtkPaned *paned,
+		     gdouble   ratio)
+{
+  g_return_if_fail (GTK_IS_PANED (paned));
+  g_return_if_fail (ratio >= 0.0 && ratio <= 1.0);
+
+  paned->position_set = FALSE;
+  paned->priv->ratio_set = TRUE;
+  paned->priv->ratio = ratio;
+
+  _gtk_paned_update_divider (paned);
 }
 
 /**
@@ -1293,6 +1426,10 @@ gtk_paned_compute_position (GtkPaned *pa
   
   g_return_if_fail (GTK_IS_PANED (paned));
 
+  if (paned->priv->ratio_set)
+      paned->child1_size = GTK_WIDGET (paned)->allocation.width
+                           * paned->priv->ratio;
+
   old_position = paned->child1_size;
   old_min_position = paned->min_position;
   old_max_position = paned->max_position;
@@ -1304,7 +1441,7 @@ gtk_paned_compute_position (GtkPaned *pa
     paned->max_position = MAX (1, paned->max_position - child2_req);
   paned->max_position = MAX (paned->min_position, paned->max_position);
 
-  if (!paned->position_set)
+  if (!paned->position_set && !paned->priv->ratio_set)
     {
       if (paned->child1_resize && !paned->child2_resize)
 	paned->child1_size = MAX (0, allocation - child2_req);
Index: gtk/gtkpaned.h
===================================================================
--- gtk/gtkpaned.h	(Revision 19546)
+++ gtk/gtkpaned.h	(Arbeitskopie)
@@ -119,6 +119,9 @@ void    gtk_paned_pack2           (GtkPa
 gint    gtk_paned_get_position    (GtkPaned  *paned);
 void    gtk_paned_set_position    (GtkPaned  *paned,
 				   gint       position);
+gdouble gtk_paned_get_ratio	  (GtkPaned  *paned);
+void    gtk_paned_set_ratio	  (GtkPaned  *paned,
+				   gdouble    ratio);
 
 GtkWidget *gtk_paned_get_child1   (GtkPaned  *paned);
 GtkWidget *gtk_paned_get_child2   (GtkPaned  *paned);
Index: ChangeLog
===================================================================
--- ChangeLog	(Revision 19546)
+++ ChangeLog	(Arbeitskopie)
@@ -1,3 +1,24 @@
+2008-02-14  Christian Dywan  <christian@imendio.com>
+
+        Allow the divider of GtkPaned to have a relative position and improve
+        documentation.
+
+ 	* gtk/gtkpaned.h:
+        * gtk/gtkpaned.c:
+        (gtk_paned_set_position): Explicitly document that the position can
+        never exceed available space.
+        (gtk_paned_class_init),
+        (gtk_paned_init),
+        (_gtk_paned_update_divider)
+        (gtk_paned_get_position),
+        (gtk_paned_set_position),
+        (gtk_paned_set_property),
+        (gtk_paned_get_property),
+        (gtk_paned_set_ratio),
+        (gtk_paned_get_ratio),
+        (gtk_paned_compute_position): Introduce the properties "ratio" and
+        "ratio_set" along with accessors to define a relative divider position.
+
 2008-02-12  Federico Mena Quintero  <federico@novell.com>
 
 	Merged from gtk-2-12:
