+ bind .i <<IconConfigure>> {
+ applet::subwindow-need-recreate
+ }
+}
+
+#----- subprocess -----
+
+variable subproc none
+variable ratelimit {}
+
+proc setup-subproc {w get_cmdline} {
+ variable subproc_get_cmdline $get_cmdline
+ setup-subwindow $w applet::subproc-destroying applet::subproc-ready
+}
+
+proc subproc-destroying {} {
+ variable subproc
+ puts "DESTROYING $subproc"
+ switch -exact $subproc {
+ none { }
+ old { }
+ default { kill $subproc; set subproc old }
+ }
+}
+
+proc subproc-ready {} {
+ variable subproc
+ puts "READY $subproc"
+
+ frame .i.i.b.c -container 1 -background orange
+ pack .i.i.b.c -fill both -side left -expand 1
+
+ switch -exact $subproc {
+ none {
+ run-child
+ }
+ old {
+ # wait for it to die
+ }
+ default {
+ error "unexpected state $subproc"
+ }
+ }
+ puts "READY-done $subproc"
+}
+
+proc run-child {} {
+ variable subproc
+ variable ratelimit
+ variable subproc_get_cmdline
+
+ set id [winfo id .i.i.b.c]
+ set cmd [uplevel #0 [concat [list $subproc_get_cmdline] $id]]
+
+ puts "RUN-CHILD $subproc"
+ set now [clock seconds]
+ lappend ratelimit $now
+ while {[lindex $ratelimit 0] < {$now - 10}} {
+ set ratelimit [lrange $ratelimit 1 end]
+ }
+ if {[llength $ratelimit] > 10} {
+ puts stderr "crashing repeatedly, quitting $ratelimit"
+ exit 127
+ }
+
+ set subproc none
+ set subproc [subproc::fork applet::child-died {
+ execl [lindex $cmd 0] [lrange $cmd 1 end]
+ }]
+ puts "FORKED $subproc"
+}
+
+proc child-died {how how2} {
+ puts "DIED $how $how2"
+ variable subproc
+ switch -exact $subproc {
+ old {
+ set subproc none
+ run-child
+ }
+ default {
+ set subproc none
+ subwindow-need-recreate
+ }
+ }
+}
+