--- FL/Fl_Scroll.H.original	2008-03-14 10:49:51.000000000 -0300
+++ FL/Fl_Scroll.H	2008-03-14 06:25:02.000000000 -0300
@@ -43,6 +43,7 @@
 
 protected:
 
+  void init_scrollbars();
   void bbox(int&,int&,int&,int&);
   void draw();
 
@@ -70,6 +71,11 @@
   int yposition() const {return yposition_;}
   void position(int, int);
   void clear();
+
+  void end();
+  void add(Fl_Widget &w) {add(&w);}
+  void add(Fl_Widget *w);
+  void init_sizes();
 };
 
 #endif
--- src/Fl_Scroll.cxx.original	2008-03-14 10:50:04.000000000 -0300
+++ src/Fl_Scroll.cxx	2008-03-14 11:17:29.000000000 -0300
@@ -92,6 +92,74 @@
   fl_pop_clip();
 }
 
+void Fl_Scroll::init_scrollbars() {
+  int X,Y,W,H; bbox(X,Y,W,H);
+
+  // accumulate bounding box of children:
+  int l = X; int r = X; int t = Y; int b = Y;
+  Fl_Widget*const* a = array();
+  for (int i=children()-2; i--;) {
+    Fl_Object* o = *a++;
+    if (o->x() < l) l = o->x();
+    if (o->y() < t) t = o->y();
+    if (o->x()+o->w() > r) r = o->x()+o->w();
+    if (o->y()+o->h() > b) b = o->y()+o->h();
+  }
+
+  // turn the scrollbars on and off as necessary:
+  // See if children would fit if we had no scrollbars...
+  X = x()+Fl::box_dx(box());
+  Y = y()+Fl::box_dy(box());
+  W = w()-Fl::box_dw(box());
+  H = h()-Fl::box_dh(box());
+  int vneeded = 0;
+  int hneeded = 0;
+  if (type() & VERTICAL) {
+    if ((type() & ALWAYS_ON) || t < Y || b > Y+H) {
+      vneeded = 1;
+      W -= scrollbar.w();
+      if (scrollbar.align() & FL_ALIGN_LEFT) X += scrollbar.w();
+    }
+  }
+  if (type() & HORIZONTAL) {
+    if ((type() & ALWAYS_ON) || l < X || r > X+W) {
+      hneeded = 1;
+      H -= hscrollbar.h();
+      if (scrollbar.align() & FL_ALIGN_TOP) Y += hscrollbar.h();
+      // recheck vertical since we added a horizontal scrollbar
+      if (!vneeded && (type() & VERTICAL)) {
+	if ((type() & ALWAYS_ON) || t < Y || b > Y+H) {
+	  vneeded = 1;
+	  W -= scrollbar.w();
+	  if (scrollbar.align() & FL_ALIGN_LEFT) X += scrollbar.w();
+	}
+      }
+    }
+  }
+  // Now that we know what's needed, make it so.
+  if (vneeded && !scrollbar.visible()) {
+    scrollbar.set_visible();
+  }
+  else if (!vneeded && scrollbar.visible()) {
+    scrollbar.clear_visible();
+  }
+  if (hneeded && !hscrollbar.visible()) {
+    hscrollbar.set_visible();
+  }
+  else if (!hneeded && hscrollbar.visible()) {
+    hscrollbar.clear_visible();
+  }
+
+  scrollbar.resize(scrollbar.align()&FL_ALIGN_LEFT ? X-scrollbar.w() : X+W,
+		   Y, scrollbar.w(), H);
+  scrollbar.value(oldy = yposition_ = (Y-t), H, 0, b-t);
+
+  hscrollbar.resize(X,
+		    scrollbar.align()&FL_ALIGN_TOP ? Y-hscrollbar.h() : Y+H,
+		    W, hscrollbar.h());
+  hscrollbar.value(oldx = xposition_ = (X-l), W, 0, r-l);
+}
+
 void Fl_Scroll::bbox(int& X, int& Y, int& W, int& H) {
   X = x()+Fl::box_dx(box());
   Y = y()+Fl::box_dy(box());
@@ -245,6 +313,9 @@
     o->position(o->x()+X-x(), o->y()+Y-y());
   }
   Fl_Widget::resize(X,Y,W,H);
+
+  // update scrollbars state
+  init_scrollbars();
 }
 
 void Fl_Scroll::position(int X, int Y) {
@@ -292,6 +363,33 @@
   return Fl_Group::handle(event);
 }
 
+void Fl_Scroll::end() {
+  Fl_Group::end();
+
+  // child widgets may have been added
+  // fix scrollbars order and update scrollbars state.
+  fix_scrollbar_order();
+  init_scrollbars();
+}
+
+void Fl_Scroll::add(Fl_Widget *w) {
+  Fl_Group::add(w);
+
+  // child widget added
+  // fix scrollbars order and update scrollbars state.
+  fix_scrollbar_order();
+  init_scrollbars();
+}
+
+void Fl_Scroll::init_sizes() {
+  Fl_Group::init_sizes();
+
+  // children may have been rearrange
+  // fix scrollbars order and update scrollbars state.
+  fix_scrollbar_order();
+  init_scrollbars();
+}
+
 //
 // End of "$Id: Fl_Scroll.cxx 5547 2006-11-16 23:17:13Z mike $".
 //
--- documentation/Fl_Scroll.html.original	2006-10-29 10:16:03.000000000 -0400
+++ documentation/Fl_Scroll.html	2008-03-14 12:40:26.000000000 -0300
@@ -58,7 +58,9 @@
 <UL>
 <LI><A href=#Fl_Scroll.Fl_Scroll>Fl_Scroll</A></LI>
 <LI><A href=#Fl_Scroll.~Fl_Scroll>~Fl_Scroll</A></LI>
+<LI><A href=#Fl_Scroll.bbox>bbox</A></LI>
 <LI><A href=#Fl_Scroll.align>align</A></LI>
+<LI><A href=#Fl_Scroll.init_sizes>init_sizes</A></LI>
 <LI><A href=#Fl_Scroll.position>position</A></LI>
 <LI><A href=#Fl_Scroll.type>type</A></LI>
 <LI><A href=#Fl_Scroll.xposition>xposition</A></LI>
@@ -90,12 +92,21 @@
  horizontal always off. </LI>
 <LI><TT>Fl_Scroll::BOTH_ALWAYS</TT> - Both always on. </LI>
 </UL>
+<H4><A name="Fl_Scroll.bbox"><b>[protected]</b>&nbsp;void Fl_Scroll::bbox(int &amp;X, int &amp;Y, int &amp;W, int &amp;H)</A></H4>
+This is a <b>protected</b> method. Widgets derived from <TT>Fl_Scroll</TT> should call this
+to retrieve the current viewable dimensions. The position and dimensions specify the viewable area of the <TT>Fl_Scroll</TT>
+and do not include any visible scrollbars.
 <H4><A name=Fl_Scroll.align>void Fl_Scroll::scrollbar.align(int)
 <BR> void Fl_Scroll::hscrollbar.align(int)</A></H4>
  This is used to change what side the scrollbars are drawn on.  If the <TT>
 FL_ALIGN_LEFT</TT> bit is on, the vertical scrollbar is on the left.
  If the <TT>FL_ALIGN_TOP</TT> bit is on, the horizontal scrollbar is on
 the top.
+<H4><A name="Fl_Scroll.init_sizes">void Fl_Scroll::init_sizes()</A></H4>
+If the child widgets' position and&#047;or size are manipulated, call this function.
+Doing so will register the changes with the base <TT>Fl_Group</TT> as well as update the
+state of scrollbars.<br>
+If <TT>init_sizes()</TT> is not called, the scrollbars will be updated on the next redraw.
 <H4><A name=Fl_Scroll.xposition>int Fl_Scroll::xposition() const</A></H4>
  Gets the current horizontal scrolling position.
 <H4><A name=Fl_Scroll.yposition>int Fl_Scroll::yposition() const</A></H4>
