Index: app/display/gimpdisplayshell-scroll.c
===================================================================
--- app/display/gimpdisplayshell-scroll.c	(revision 25974)
+++ app/display/gimpdisplayshell-scroll.c	(working copy)
@@ -34,7 +34,15 @@
 #include "gimpdisplayshell-scale.h"
 #include "gimpdisplayshell-scroll.h"
 
+#include "tools/tools-types.h"
+#include "tools/tool_manager.h"
+#include "tools/gimptool.h"
+#include "tools/gimptoolcontrol.h"
 
+#include "tools/gimpcroptool.h"
+
+#define  PAN_RATIO 0.5
+
 gboolean
 gimp_display_shell_scroll (GimpDisplayShell *shell,
                            gint              x_offset,
@@ -43,6 +51,9 @@
   gint old_x;
   gint old_y;
 
+  GimpDisplay *display     = shell->display;
+  GimpTool    *active_tool = tool_manager_get_active (display->gimp);
+
   g_return_val_if_fail (GIMP_IS_DISPLAY_SHELL (shell), FALSE);
 
   old_x = shell->offset_x;
@@ -51,7 +62,9 @@
   shell->offset_x += x_offset;
   shell->offset_y += y_offset;
 
-  gimp_display_shell_scroll_clamp_offsets (shell);
+  /* Clamp if active tool is not crop tool */
+  if (!GIMP_IS_CROP_TOOL (active_tool))
+    gimp_display_shell_scroll_clamp_offsets (shell);
 
   /*  the actual changes in offset  */
   x_offset = (shell->offset_x - old_x);
@@ -99,15 +112,18 @@
       sx = SCALEX (shell, gimp_image_get_width  (shell->display->image));
       sy = SCALEY (shell, gimp_image_get_height (shell->display->image));
 
-      shell->offset_x = CLAMP (shell->offset_x, 0,
-                               MAX (sx - shell->disp_width, 0));
+      shell->offset_x = CLAMP (shell->offset_x, -1 * PAN_RATIO * shell->disp_width,
+                               MAX (MAX (sx, shell->disp_width) - PAN_RATIO * shell->disp_width, 
+                                    -1 * PAN_RATIO * shell->disp_width));
 
-      shell->offset_y = CLAMP (shell->offset_y, 0,
-                               MAX (sy - shell->disp_height, 0));
+      shell->offset_y = CLAMP (shell->offset_y, -1 * PAN_RATIO * shell->disp_height,
+                               MAX (MAX (sy, shell->disp_height) - PAN_RATIO * shell->disp_height, 
+                                    -1 * PAN_RATIO * shell->disp_height));
     }
   else
     {
       shell->offset_x = 0;
       shell->offset_y = 0;
+
     }
 }
Index: app/display/gimpdisplayshell-scale.c
===================================================================
--- app/display/gimpdisplayshell-scale.c	(revision 25974)
+++ app/display/gimpdisplayshell-scale.c	(working copy)
@@ -119,16 +119,43 @@
       sx = image_width;
       sy = image_height;
     }
+  
 
+
   shell->hsbdata->value          = shell->offset_x;
-  shell->hsbdata->upper          = sx;
-  shell->hsbdata->page_size      = MIN (sx, shell->disp_width);
+  shell->hsbdata->page_size      = MIN (sx, shell->disp_width * 2);
+
+  shell->hsbdata->lower          = MIN ( 0, shell->offset_x) - (shell->scale_x * 4);
+  /* The reachable range of a scrollbar is influenced by page bar size.  We
+   * need to take that into account. */
+  if (sx > shell->disp_width) 
+    {
+      shell->hsbdata->upper       = MAX (sx, shell->offset_x + shell->disp_width) +  shell->disp_width + (shell->scale_x * 4);
+    }
+  else
+    {
+      shell->hsbdata->upper       = MAX (sx, sx + shell->offset_x) + (shell->scale_x * 4);
+    }
+ 
   shell->hsbdata->page_increment = shell->disp_width / 2;
   shell->hsbdata->step_increment = shell->scale_x;
+  
+  shell->vsbdata->value          = shell->offset_y;
+ 
+  shell->vsbdata->page_size      = MIN (sy, shell->disp_height * 2);
 
-  shell->vsbdata->value          = shell->offset_y;
-  shell->vsbdata->upper          = sy;
-  shell->vsbdata->page_size      = MIN (sy, shell->disp_height);
+  shell->vsbdata->lower          = MIN ( 0, shell->offset_y) - (shell->scale_y * 4);
+ 
+  /* The reachable range of a scrollbar is influenced by page bar size.  We
+   * need to take that into account. */
+  if (sy > shell->disp_height) 
+    {
+      shell->vsbdata->upper       = MAX (sy, shell->offset_y + shell->disp_height) +  shell->disp_height + (shell->scale_y * 4);
+    }
+  else
+    {
+      shell->vsbdata->upper       = MAX (sy, sy + shell->offset_y) + (shell->scale_y * 4);
+    }
   shell->vsbdata->page_increment = shell->disp_height / 2;
   shell->vsbdata->step_increment = shell->scale_y;
 
