--- ltk.lisp.orig	2008-03-14 00:05:38.000000000 +0100
+++ ltk.lisp	2008-03-14 01:16:35.000000000 +0100
@@ -1841,8 +1841,8 @@
    (vscroll :accessor vscroll)
    ))
 
-(defmethod initialize-instance :after ((sf scrolled-frame) &key)
-  (let ((f (make-instance 'frame :master sf)))
+(defmethod initialize-instance :after ((sf scrolled-frame) &key width height)
+  (let ((f (make-instance 'frame :master sf :width width :height height)))
     (setf (scrolled-frame-display sf) f)
     (setf (interior sf) (make-instance 'frame :master f))
     (setf (hscroll sf) (make-instance 'scrollbar :master sf :orientation "horizontal"))
@@ -1855,52 +1855,111 @@
     (grid-rowconfigure sf 0 "weight" 1)
     (grid-rowconfigure sf 1 "weight" 0)
     (place (interior sf) 0 0)
-    (send-wish (format nil "~a set  0.1 0.5" (widget-path (hscroll sf))))
-    (send-wish (format nil "~a set  0.1 0.5" (widget-path (vscroll sf))))
     (send-wish (format nil "~a configure -command ~axv" (widget-path (hscroll sf)) (name sf)))
     (send-wish (format nil "~a configure -command ~ayv" (widget-path (vscroll sf)) (name sf)))
-    (send-wish (format nil "
-proc ~axv {{com moveto} {val 0} {unit 0}} {
-set x [winfo x ~a]
-set y [winfo y ~a]
-set wx [winfo width ~a]
-set w [winfo width ~a]
-if {$val < 0} {set val 0}
-if {$val > [expr 1.0*($wx-$w)/$wx]} {set val  [expr 1.0*($wx-$w)/$wx]}
-place ~a -x [expr -($val * $wx)] -y $y
-set x [winfo x ~a]
-~a set [expr -1.0*$x/$wx] [expr 1.0*($w-$x)/$wx]
+    (format-wish "
+proc update~2@*~A_bars {} {
+	set x [winfo x ~0@*~A]
+	set y [winfo y ~0@*~A]
+	set wx [winfo width ~0@*~A]
+	set w [winfo width ~1@*~A]
+	set wy [winfo height ~0@*~A]
+	set h [winfo height ~1@*~A]
+	set newx $x
+	set newy $y
+	if [expr $w < $wx] {
+		if [expr $x > 0] {
+			set newx 0
+		} elseif [expr ($x + $wx) < $w] {
+			set newx [expr $w - $wx]
+		}
+	} else {
+		set newx [expr ($w - $wx)/2]
+	}
+	if [expr $h < $wy] {
+		if [expr $y > 0] {
+			set new 0
+		} elseif [expr ($y + $wy) < $h] {
+			set newy [expr $h - $wy]
+		}
+	} else {
+		set newy [expr ($h - $wy)/2]
+	}
+	if [expr ($x != $newx) || ($y != $newy)] {
+		place ~0@*~A -x $newx -y $newy
+	}
+	~3@*~A set [expr -1.0*$newx/$wx] [expr 1.0*($w-$newx)/$wx]
+	~4@*~A set [expr -1.0*$newy/$wy] [expr 1.0*($h-$newy)/$wy]
 }
-proc ~ayv {{com moveto} {val 0} {unit 0}} {
-set x [winfo x ~a]
-set y [winfo y ~a]
-set wy [winfo height ~a]
-set h [winfo height ~a]
-if {$val < 0} {set val 0}
-if {$val > [expr 1.0*($wy-$h)/$wy]} {set val  [expr 1.0*($wy-$h)/$wy]}
-place ~a -x $x -y [expr -($val * $wy)]
-set y [winfo y ~a]
-~a set [expr -1.0*$y/$wy] [expr 1.0*($h-$y)/$wy]
+bind ~1@*~A <Configure> update~2@*~A_bars
+bind ~0@*~A <Configure> update~2@*~A_bars
+    "
+    (widget-path (interior sf))
+    (widget-path f)
+    (substitute #\_ #\. (widget-path (interior sf)))
+    (widget-path (hscroll sf))
+    (widget-path (vscroll sf)))
+    ;; There are no {h,v}scroll set [expr ...] [expr ...] in ~0@*~Axv and
+    ;; ~&@*~Ayv because the `place ~1@*~A -x ... -y ...' commands trigger
+    ;; a <Configure> event that will update the scrollbars.  Note that when
+    ;; the frame is packed the first time, a <Configure> event is generated,
+    ;; too: this makes that the scrollbars are correct from the beginning!
+    (format-wish "
+proc ~0@*~Axv {{com moveto} {val 0} {unit 0}} {
+	set x [winfo x ~1@*~A]
+	set y [winfo y ~1@*~A]
+	set wx [winfo width ~1@*~A]
+	set w [winfo width ~2@*~A]
+	if [expr {$wx < $w}] {
+		place ~1@*~A -x [expr ($w-$wx)/2] -y $y
+	} elseif [expr [string compare $com \"moveto\"] == 0] {
+		if {$val < 0} {set val 0}
+		if {$val > [expr 1.0*($wx-$w)/$wx]} {set val  [expr 1.0*($wx-$w)/$wx]}
+		place ~1@*~A -x [expr -($val * $wx)] -y $y
+		set x [winfo x ~1@*~A]
+	} else {
+		if [expr [string compare $unit \"units\"] == 0] {
+			set x [expr $x - $val]
+		} else {
+			set x [expr $x - $val*$wx/10]
+		}
+		if [expr (($x + $wx) < $w)] {
+			set x [expr $w - $wx]
+		} elseif [expr $x > 0] {
+			set x 0
+		}
+		place ~1@*~A -x $x -y $y
+	}
 }
-
-" (name sf)
-  (widget-path (interior sf))
-  (widget-path (interior sf))
-  (widget-path (interior sf))
-  (widget-path f)
-  (widget-path (interior sf))
-  (widget-path (interior sf))		   
-  (widget-path (hscroll sf))
-  
-  (name sf)
-  (widget-path (interior sf))
-  (widget-path (interior sf))
-  (widget-path (interior sf))
-  (widget-path f)
-  (widget-path (interior sf))
-  (widget-path (interior sf))		   
-  (widget-path (vscroll sf))
-  ))))
+proc ~0@*~Ayv {{com moveto} {val 0} {unit 0}} {
+	set x [winfo x ~1@*~A]
+	set y [winfo y ~1@*~A]
+	set wy [winfo height ~1@*~A]
+	set h [winfo height ~2@*~A]
+	if [expr {$wy < $h}] {
+		place ~1@*~A -x $x -y [expr ($h-$wy)/2]
+	} elseif [expr [string compare $com \"moveto\"] == 0] {
+		if {$val < 0} {set val 0}
+		if {$val > [expr 1.0*($wy-$h)/$wy]} {set val  [expr 1.0*($wy-$h)/$wy]}
+		place ~1@*~A -x $x -y [expr -($val * $wy)]
+		set y [winfo y ~1@*~A]
+	} else {
+		if [expr [string compare $unit \"units\"] == 0] {
+			set y [expr $y - $val]
+		} else {
+			set y [expr $y - $val*$wy/10]
+		}
+		if [expr (($y + $wy) < $h)] {
+			set y [expr $h - $wy]
+		} elseif [expr $y > 0] {
+			set y 0
+		}
+		place ~1@*~A -x $x -y $y
+	}
+}"
+      (name sf)
+      (widget-path (interior sf))
+      (widget-path f))))
 
 ;;; canvas widget
 
@@ -2394,7 +2453,8 @@
 (defmethod place (widget x y &key width height)
   (format-wish "place ~A -x ~A -y ~A~@[ -width ~a~]~@[ -height ~a~]" (widget-path widget)
                (tk-number x) (tk-number y)
-               (tk-number width) (tk-number height))
+               (and (numberp width) (tk-number width))
+               (and (numberp width) (tk-number height)))
   widget)
 
 (defgeneric place-forget (widget))
