Index: app/tools/gimpcroptool.c
===================================================================
--- app/tools/gimpcroptool.c	(revision 22904)
+++ app/tools/gimpcroptool.c	(arbetskopia)
@@ -78,6 +78,9 @@ static gboolean   gimp_crop_tool_execute
 static void   gimp_crop_tool_notify_layer_only   (GimpCropOptions       *options,
                                                   GParamSpec            *pspec,
                                                   GimpTool              *tool);
+static void   gimp_crop_tool_notify_keep_aspect  (GimpCropOptions       *options,
+                                                  GParamSpec            *pspec,
+                                                  GimpTool              *tool);
 
 
 G_DEFINE_TYPE_WITH_CODE (GimpCropTool, gimp_crop_tool, GIMP_TYPE_DRAW_TOOL,
@@ -164,6 +167,10 @@ gimp_crop_tool_constructor (GType       
                            G_CALLBACK (gimp_crop_tool_notify_layer_only),
                            object, 0);
 
+  g_signal_connect_object (options, "notify::keep-aspect",
+                           G_CALLBACK (gimp_crop_tool_notify_keep_aspect),
+                           object, 0);
+
   gimp_rectangle_tool_set_constraint (GIMP_RECTANGLE_TOOL (object),
                                       options->layer_only ?
                                       GIMP_RECTANGLE_CONSTRAIN_DRAWABLE :
@@ -189,6 +196,14 @@ gimp_crop_tool_button_press (GimpTool   
                              GdkModifierType  state,
                              GimpDisplay     *display)
 {
+  GimpCropOptions *options = GIMP_CROP_TOOL_GET_OPTIONS (tool);
+
+  /* It makes no sense to create a new rectangle with keep-aspect on. */
+  if (tool->display == NULL)
+    g_object_set (options,
+                  "keep-aspect", FALSE,
+                  NULL);
+
   if (tool->display && display != tool->display)
     gimp_rectangle_tool_cancel (GIMP_RECTANGLE_TOOL (tool));
 
@@ -216,8 +231,24 @@ gimp_crop_tool_active_modifier_key (Gimp
                                     GdkModifierType  state,
                                     GimpDisplay     *display)
 {
+  GimpDrawTool    *draw_tool = GIMP_DRAW_TOOL (tool);
+  GimpCropOptions *options   = GIMP_CROP_TOOL_GET_OPTIONS (tool);
+
   GIMP_TOOL_CLASS (parent_class)->active_modifier_key (tool, key, press, state,
                                                        display);
+  gimp_draw_tool_pause (draw_tool);
+
+  if (key == GDK_MOD1_MASK)
+    {
+      g_object_set (options,
+                    "keep-aspect", !options->keep_aspect,
+                    NULL);
+
+      gimp_rectangle_tool_set_keep_aspect (GIMP_RECTANGLE_TOOL (tool),
+                                           options->keep_aspect);
+    }
+
+  gimp_draw_tool_resume (draw_tool);
 
   gimp_rectangle_tool_active_modifier_key (tool, key, press, state, display);
 }
@@ -291,6 +322,7 @@ gimp_crop_tool_execute (GimpRectangleToo
   return TRUE;
 }
 
+
 static void
 gimp_crop_tool_notify_layer_only (GimpCropOptions *options,
                                   GParamSpec      *pspec,
@@ -301,3 +333,12 @@ gimp_crop_tool_notify_layer_only (GimpCr
                                       GIMP_RECTANGLE_CONSTRAIN_DRAWABLE :
                                       GIMP_RECTANGLE_CONSTRAIN_IMAGE);
 }
+
+static void
+gimp_crop_tool_notify_keep_aspect (GimpCropOptions *options,
+                                   GParamSpec      *pspec,
+                                   GimpTool        *tool)
+{
+  gimp_rectangle_tool_set_keep_aspect (GIMP_RECTANGLE_TOOL (tool),
+                                       options->keep_aspect);
+}
Index: app/tools/gimpcropoptions.c
===================================================================
--- app/tools/gimpcropoptions.c	(revision 22904)
+++ app/tools/gimpcropoptions.c	(arbetskopia)
@@ -37,7 +37,8 @@
 
 enum
 {
-  PROP_LAYER_ONLY = GIMP_RECTANGLE_OPTIONS_PROP_LAST + 1
+  PROP_LAYER_ONLY = GIMP_RECTANGLE_OPTIONS_PROP_LAST + 1,
+  PROP_KEEP_ASPECT
 };
 
 
@@ -72,6 +73,11 @@ gimp_crop_options_class_init (GimpCropOp
                                     FALSE,
                                     GIMP_PARAM_STATIC_STRINGS);
 
+  GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_KEEP_ASPECT,
+                                    "keep-aspect", NULL,
+                                    FALSE,
+                                    GIMP_PARAM_STATIC_STRINGS);
+
   gimp_rectangle_options_install_properties (object_class);
 }
 
@@ -97,6 +103,10 @@ gimp_crop_options_set_property (GObject 
       GIMP_CROP_OPTIONS (object)->layer_only = g_value_get_boolean (value);
       break;
 
+    case PROP_KEEP_ASPECT:
+      GIMP_CROP_OPTIONS (object)->keep_aspect = g_value_get_boolean (value);
+      break;
+
     default:
       gimp_rectangle_options_set_property (object, property_id, value, pspec);
       break;
@@ -115,6 +125,10 @@ gimp_crop_options_get_property (GObject 
       g_value_set_boolean (value, GIMP_CROP_OPTIONS (object)->layer_only);
       break;
 
+    case PROP_KEEP_ASPECT:
+      g_value_set_boolean (value, GIMP_CROP_OPTIONS (object)->keep_aspect);
+      break;
+
     default:
       gimp_rectangle_options_get_property (object, property_id, value, pspec);
       break;
@@ -135,6 +149,12 @@ gimp_crop_options_gui (GimpToolOptions *
   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
   gtk_widget_show (button);
 
+  /*  keep aspect toggle  */
+  button = gimp_prop_check_button_new (config, "keep-aspect",
+                                       _("Keep aspect ratio"));
+  gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+  gtk_widget_show (button);
+
   /*  rectangle options  */
   vbox_rectangle = gimp_rectangle_options_gui (tool_options);
   gtk_box_pack_start (GTK_BOX (vbox), vbox_rectangle, FALSE, FALSE, 0);
Index: app/tools/gimpcropoptions.h
===================================================================
--- app/tools/gimpcropoptions.h	(revision 22904)
+++ app/tools/gimpcropoptions.h	(arbetskopia)
@@ -39,6 +39,7 @@ struct _GimpCropOptions
   GimpToolOptions  parent_instence;
 
   gboolean         layer_only;
+  gboolean         keep_aspect;
 };
 
 
Index: app/tools/gimprectangletool.c
===================================================================
--- app/tools/gimprectangletool.c	(revision 22904)
+++ app/tools/gimprectangletool.c	(arbetskopia)
@@ -110,6 +110,11 @@ struct _GimpRectangleToolPrivate
   gint                    center_x_on_fixed_center;
   gint                    center_y_on_fixed_center;
 
+  /* Holds the aspect ratio of the rectangle when the a rectangle modification
+   * started. Used for implementing 'keep-aspect'.
+   */
+  gdouble                 original_aspect;
+
   /* The rest of the members are internal state variables, that is, variables
    * that might change during the manipulation session of the rectangle. Make
    * sure these variables are in consistent states.
@@ -122,6 +127,8 @@ struct _GimpRectangleToolPrivate
 
   GimpRectangleConstraint constraint; /* how to constrain rectangle     */
 
+  gboolean                keep_aspect; /* Whether or not to keep aspect.  */
+
   gint                    lastx;      /*  previous x coord               */
   gint                    lasty;      /*  previous y coord               */
 
@@ -423,6 +430,19 @@ gimp_rectangle_tool_get_constraint (Gimp
 }
 
 void
+gimp_rectangle_tool_set_keep_aspect (GimpRectangleTool *rectangle_tool,
+                                     gboolean           keep_aspect)
+{
+  GimpRectangleToolPrivate *private;
+
+  g_return_if_fail (GIMP_IS_RECTANGLE_TOOL (rectangle_tool));
+
+  private = GIMP_RECTANGLE_TOOL_GET_PRIVATE (rectangle_tool);
+
+  private->keep_aspect = keep_aspect;
+}
+
+void
 gimp_rectangle_tool_get_press_coords (GimpRectangleTool *rectangle,
                                       gint              *pressx_ptr,
                                       gint              *pressy_ptr)
@@ -590,6 +610,22 @@ gimp_rectangle_tool_button_press (GimpTo
                     NULL);
 
       gimp_rectangle_tool_start (rectangle, display);
+
+      /* When a new rectangle is created, let keep-aspect be initialized with
+       * what fixed-aspect would give.
+       */
+      private->original_aspect = options_private->aspect_numerator /
+                                 options_private->aspect_denominator;
+    }
+  else
+    {
+      /* There is an existing rectangle, setup original_aspect based on that. */
+      gint    w = (private->x2 - private->x1);
+      gdouble h = (private->y2 - private->y1);
+
+      h = CLAMP (h, 1, GIMP_MAX_IMAGE_SIZE);
+
+      private->original_aspect = fabs (w / h);
     }
 
   /* save existing shape in case of cancellation */
@@ -3063,12 +3099,15 @@ gimp_rectangle_tool_update_with_coord (G
     constraint_to_use = GIMP_RECTANGLE_CONSTRAIN_IMAGE;
 
   /* fixed_aspect and fixed_width/height are mutually exclusive. */
-  if (options_private->fixed_aspect)
+  if (options_private->fixed_aspect || private->keep_aspect)
     {
       gdouble aspect;
 
-      aspect = CLAMP (options_private->aspect_numerator /
-                      options_private->aspect_denominator,
+      aspect = private->keep_aspect ? private->original_aspect :
+                                      options_private->aspect_numerator /
+                                      options_private->aspect_denominator;
+
+      aspect = CLAMP (aspect,
                       1.0 / tool->display->image->height,
                       tool->display->image->width);
 
Index: app/tools/gimprectangletool.h
===================================================================
--- app/tools/gimprectangletool.h	(revision 22904)
+++ app/tools/gimprectangletool.h	(arbetskopia)
@@ -125,6 +125,8 @@ void        gimp_rectangle_tool_cancel  
 void        gimp_rectangle_tool_configure           (GimpRectangleTool       *rectangle);
 void        gimp_rectangle_tool_set_constraint      (GimpRectangleTool       *rectangle,
                                                      GimpRectangleConstraint  constraint);
+void        gimp_rectangle_tool_set_keep_aspect     (GimpRectangleTool       *rectangle,
+                                                     gboolean                 keep_aspect);
 GimpRectangleFunction gimp_rectangle_tool_get_function (GimpRectangleTool    *rectangle);
 void        gimp_rectangle_tool_set_function        (GimpRectangleTool       *rectangle,
                                                      GimpRectangleFunction    function);
