diff options
author | Siep Kroonenberg <siepo@cybercomm.nl> | 2019-06-25 18:37:23 +0000 |
---|---|---|
committer | Siep Kroonenberg <siepo@cybercomm.nl> | 2019-06-25 18:37:23 +0000 |
commit | 51ee301a87deaf031c16009df3816a64474d99e2 (patch) | |
tree | 4a78bcb4e8964440307d5e99025aa2453ec00ac0 /Master/tlpkg | |
parent | f54c4102a4fa80fbfe5d00096fd31ebd13d9ab5c (diff) |
Abort option when loading a repository
git-svn-id: svn://tug.org/texlive/trunk@51454 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/tlpkg')
-rw-r--r-- | Master/tlpkg/installer/install-menu-extl.pl | 4 | ||||
-rwxr-xr-x | Master/tlpkg/installer/install-tl-gui.tcl | 269 | ||||
-rw-r--r-- | Master/tlpkg/tltcl/tltcl.tcl | 220 |
3 files changed, 371 insertions, 122 deletions
diff --git a/Master/tlpkg/installer/install-menu-extl.pl b/Master/tlpkg/installer/install-menu-extl.pl index 8c3d129ad70..926141cf36b 100644 --- a/Master/tlpkg/installer/install-menu-extl.pl +++ b/Master/tlpkg/installer/install-menu-extl.pl @@ -61,9 +61,11 @@ $::deskintdesc[0] = "None"; $::deskintdesc[1] = "Menu shortcuts"; $::deskintdesc[2] = "Launcher"; +do_remote_init(); +print STDOUT "endload\n\n"; + # %vars hash should eventually include each binary, collection and scheme # as individual schalars. -do_remote_init(); # the above sub adds all platforms and collections to %vars # but maybe not schemes so we add these now: diff --git a/Master/tlpkg/installer/install-tl-gui.tcl b/Master/tlpkg/installer/install-tl-gui.tcl index acdac9923a4..4882f749b61 100755 --- a/Master/tlpkg/installer/install-tl-gui.tcl +++ b/Master/tlpkg/installer/install-tl-gui.tcl @@ -63,6 +63,35 @@ if {$::tcl_platform(platform) eq "windows"} { set ::advanced 0 set ::alltrees 0 +proc kill_perl {} { + if $::perlpid { + catch { + if {$::tcl_platform(platform) eq "unix"} { + exec -ignorestderr kill $::perlpid + } else { + exec -ignorestderr taskkill /pid $::perlpid /t /f + } + } + } +} + +proc err_exit {{mess ""}} { + if {$mess eq ""} {set mess "Error"} + append mess "\n" [get_stacktrace] + tk_messageBox -icon error -message $mess + # kill perl process, just in case + if $::perlpid { + catch { + if {$::tcl_platform(platform) eq "unix"} { + exec -ignorestderr kill $::perlpid + } else { + exec -ignorestderr taskkill "/pid" $::perlpid + } + } + } + exit +} ; # err_exit + # warning about non-empty target tree set ::td_warned 0 @@ -101,19 +130,19 @@ proc show_time {s} { # write to a logfile which is shared with the backend. # both parties open, append and close every time. -#if {$::tcl_platform(os) eq "Darwin"} { -# set ::dblfile "$::env(TMPDIR)/dblog" -#} elseif {$::tcl_platform(platform) eq "unix"} { -# set ::dblfile "/tmp/dblog" -#} else { -# set ::dblfile "$::env(TEMP)/dblog.txt" -#} -#proc dblog {s} { -# set db [open $::dblfile a] -# set t [get_stacktrace] -# puts $db "TCL: $s\n$t" -# close $db -#} +if {$::tcl_platform(os) eq "Darwin"} { + set ::dblfile "$::env(TMPDIR)/dblog" +} elseif {$::tcl_platform(platform) eq "unix"} { + set ::dblfile "/tmp/dblog" +} else { + set ::dblfile "$::env(TEMP)/dblog.txt" +} +proc dblog {s} { + set db [open $::dblfile a] + set t [get_stacktrace] + puts $db "TCL: $s\n$t" + close $db +} proc maybe_print_welcome {} { # if the last non-empty line was "All done", then installation is completed. @@ -124,7 +153,7 @@ proc maybe_print_welcome {} { for {set i [.log.tx count -lines 1.0 end]} {$i > 0} {incr i -1} { set l [.log.tx get ${i}.0 ${i}.end] if {$l ne ""} { - puts $l + #puts $l if {[string range $l 0 11] eq "Installed on"} { set all_done 1 } @@ -195,13 +224,30 @@ This should not have happened!" return $l }; # read_line_no_eof +# non-blocking i/o: callback for "readable" while the splash screen is up +# and the back end tries to contact the repository +proc read_line_loading {} { + set l "" ; # will contain the line to be read + if {([catch {chan gets $::inst l} len] || [chan eof $::inst])} { + catch {chan close $::inst} + # note. the normal way to terminate is terminating the GUI shell. + # This closes stdin of the child + } elseif {$len >= 0} { + if {$l eq "endload"} { + chan configure $::inst -blocking 1 + chan event $::inst readable {} + set ::loaded 1 + } + } +}; # read_line_loading + # non-blocking i/o: callback for "readable" during stage 3, installation # ::out_log should no longer be needed proc read_line_cb {} { set l "" ; # will contain the line to be read if {([catch {chan gets $::inst l} len] || [chan eof $::inst])} { catch {chan close $::inst} - # note. the right way to terminate is terminating the GUI shell. + # note. the normal way to terminate is terminating the GUI shell. # This closes stdin of the child .close state !disabled if [winfo exists .abort] {.abort state disabled} @@ -215,14 +261,49 @@ proc read_line_cb {} { } }; # read_line_cb +proc maybe_abort {} { + set ans [tk_messageBox -message [__ "Really abort?"] -type yesno \ + -default no] + if {$ans eq "no"} { + return + } + catch {chan close $::inst} + kill_perl + exit +} + +# restart installer with chosen repository +proc select_mir {m} { + # edit original command line by removing any repository parameter + # and adding a repository parameter $m + set i $::argc + while {$i > 0} { + incr i -1 + set p [lindex $::argv $i] + if {$p eq "-repository"} { + set ::argv [lreplace $::argv $i [expr {$i+1}] ""] + } + } + # compose command line string from $::argv + set i -1 + lappend ::argv "-repository" $m + set cmd [linsert $::argv 0 [info nameofexecutable] [info script] "--"] + + # terminate back end + catch {chan close $::inst} + kill_perl + + # restart install-tl with edited command-line + exec {*}$cmd & + exit +} ; # select_mir + ############################################################## ##### special-purpose uses of main window: splash, log ##### proc make_splash {} { - # wm overrideredirect . true - # picture and logo catch { image create photo tlimage -file \ @@ -235,9 +316,19 @@ proc make_splash {} { # wallpaper pack [ttk::frame .bg -padding 3] -fill both -expand 1 + # buttons: abort button, mirrors dropdown menu + pack [ttk::frame .splfb] -in .bg -side bottom -fill x + ppack [ttk::button .spl_a -text [__ "Abort"] -command maybe_abort] \ + -side right -in .splfb + ppack [mirror_menu .spl_o select_mir] -side right -in .splfb + + # some text ppack [ttk::label .text -text [__ "TeX Live Installer"] \ -font bigfont] -in .bg - ppack [ttk::label .loading -text [__ "Loading..."]] -in .bg + ppack [ttk::label .loading -text [__ "Trying to load %s. + +If this takes too long, press Abort and choose another repository." \ + $::prelocation]] -in .bg wm attributes . -topmost update @@ -249,7 +340,7 @@ proc make_splash {} { proc show_log {{do_abort 0}} { wm withdraw . foreach c [winfo children .] { - destroy $c + catch {destroy $c} } # wallpaper @@ -260,16 +351,7 @@ proc show_log {{do_abort 0}} { ttk::button .close -text [__ "Close"] -command exit ppack .close -in .bottom -side right if $do_abort { - ttk::button .abort -text [__ "Cancel"] -command { - set ans [tk_messageBox -message [__ "Really abort?"] -type yesno \ - -default no] - if {$ans eq "no"} return - catch {chan close $::inst} - if {$::tcl_platform(platform) eq "windows"} { - catch {exec taskkill /pid $::perlpid /t /f} - } - exit - } + ttk::button .abort -text [__ "Abort"] -command maybe_abort ppack .abort -in .bottom -side right } bind . <Escape> { @@ -1133,8 +1215,8 @@ if {$::tcl_platform(platform) ne "windows"} { wm protocol .edsyms WM_DELETE_WINDOW {.edsyms.cancel invoke} wm resizable .edsyms 1 0 place_dlg .edsyms . - } -} + } ; # edit_symlinks +} ; # $::tcl_platform(platform) ne "windows" ############################################################# @@ -1149,12 +1231,12 @@ if {$::tcl_platform(platform) ne "windows"} { proc run_menu {} { if [info exists ::env(dbgui)] { - puts "\ndbgui: run_menu: advanced is now $::advanced" - puts "dbgui: run_menu: alltrees is now $::alltrees" + #puts "\ndbgui: run_menu: advanced is now $::advanced" + #puts "dbgui: run_menu: alltrees is now $::alltrees" } wm withdraw . foreach c [winfo children .] { - destroy $c + catch {destroy $c} } # wallpaper @@ -1181,13 +1263,14 @@ proc run_menu {} { if {!$::advanced} { ppack [ttk::button .adv -text [__ "Advanced"] -command { set ::menu_ans "advanced" - if [info exists ::env(dbgui)] {puts "dbgui: requested advanced"} + #if [info exists ::env(dbgui)] {puts "dbgui: requested advanced"} }] -in .final -side left } pack [ttk::separator .seph1 -orient horizontal] \ -in .bg -side bottom -pady 3 -fill x # directories, selections + # advanced and basic have different frame setups if $::advanced { pack [ttk::frame .left] -in .bg -side left -fill both -expand 1 set curf .left @@ -1196,8 +1279,6 @@ proc run_menu {} { set curf .main } - # labelframes do not look quite right on macos - # directory section pack [ttk::frame .dirf] -in $curf -fill x grid columnconfigure .dirf 1 -weight 1 @@ -1205,6 +1286,8 @@ proc run_menu {} { if $::advanced { incr rw + # labelframes do not look quite right on macos, + # instead, separate label widget for title pgrid [ttk::label .dirftitle -text [__ "Installation root"] \ -font hfont] \ -in .dirf -row $rw -column 0 -columnspan 3 -sticky w @@ -1288,7 +1371,7 @@ proc run_menu {} { if {!$::alltrees} { ttk::button .tmoreb -text [__ "More ..."] -command { set ::menu_ans "alltrees" - if [info exists ::env(dbgui)] {puts "dbgui: requested alltrees"} + #if [info exists ::env(dbgui)] {puts "dbgui: requested alltrees"} } pgrid .tmoreb -in .dirf -row $rw -column 2 -sticky ne } @@ -1363,7 +1446,7 @@ proc run_menu {} { incr rw ttk::label .lsize -text [__ "Disk space required (in MB):"] ttk::label .size_req -textvariable ::vars(total_size) - pgrid .lsize -in $curf -row $rw -column 0 -sticky e + pgrid .lsize -in $curf -row $rw -column 0 -sticky w pgrid .size_req -in $curf -row $rw -column 1 -sticky w ######################################################## @@ -1536,10 +1619,10 @@ proc run_menu {} { if {[is_nonempty $::vars(TEXDIR)] && ! $::td_warned} { td_warn $::vars(TEXDIR) } - if [info exists ::env(dbgui)] {puts "dbgui: unsetting menu_ans"} + #if [info exists ::env(dbgui)] {puts "dbgui: unsetting menu_ans"} unset -nocomplain ::menu_ans vwait ::menu_ans - if [info exists ::env(dbgui)] {puts "dbgui0: menu_ans is $::menu_ans"} + #if [info exists ::env(dbgui)] {puts "dbgui0: menu_ans is $::menu_ans"} return $::menu_ans }; # run_menu @@ -1733,42 +1816,44 @@ proc main_prog {} { wm title . [__ "TeX Live Installer"] wm protocol . WM_DELETE_WINDOW whataboutclose - # check for profile argument whether to put up a splash screen + if {[file exists $::dblfile]} {file delete $::dblfile} + + # handle some command-line arguments. + # the argument list should already be normalized: '--' => '-', "=" => ' ' set i 0 set do_splash 1 + set ::prelocation "..." while {$i < $::argc} { set p [lindex $::argv $i] incr i - if {[string range $p 0 7] eq "-profile" || \ - [string range $p 0 8] eq "--profile"} { + if {$p eq "-profile"} { + # check for profile argument: no splash screen if present set do_splash 0 - break + incr i + } elseif {$p in [list "-location" "-url" "-repository" "-repos" "-repo"]} { + # check for repository argument: bail out if obviously invalid + if {$i<$::argc} { + set p [lindex $::argv $i] + if {$p ne "ctan" && ! [possible_repository $p]} { + tk_messageBox -message [__ "%s not a local or remote repository" $p] \ + -title [__ "Error"] -type ok -icon error + exit + } + set ::prelocation $p + } + incr i } } unset i + if $do_splash make_splash unset do_splash # start install-tl-[tcl] via a pipe. - # the command must be a string, not a list. - # therefore, arguments with spaces must be quoted. - # although we build the command at first as a list, - # it will be joined into a string at a second step - set cmd [list ${::perlbin} "${::instroot}/install-tl" \ - "-from_ext_gui" {*}$::argv] - set i 0 - while {$i<[llength $cmd]} { - set c [lindex $cmd $i] - if {[string first " " $c] >= 0} { - lset cmd $i "\"$c\"" - } - incr i - } - unset i - # tk_messageBox -message [join $cmd " "] -title "debugging" + set cmd [list "|${::perlbin}" "${::instroot}/install-tl" \ + "-from_ext_gui" {*}$::argv 2>@1] show_time "opening pipe" - if [catch {open "|[join $cmd " "] 2>@1" r+} ::inst] { - # "2>@1" ok under Windows >= XP + if [catch {open $cmd r+} ::inst] { err_exit "Error starting Perl backend" } show_time "opened pipe" @@ -1777,40 +1862,69 @@ proc main_prog {} { # for windows < 10: make sure the main window is still on top wm attributes . -topmost - # do not start event-driven, non-blocking io - # until the actual installation starts chan configure $::inst -buffering line -blocking 1 # possible input from perl until the menu starts: # - question about prior canceled installation - # - location (=repository) + # - location (actual repository) # - menu data, help, version, print-platform set ::did_gui 0 set answer "" - while 1 { + unset -nocomplain ::loaded + while 1 { ; # initial perl output set ll [read_line] - if {[lindex $ll 0] < 0} break + if {[lindex $ll 0] < 0} { + break + } set l [lindex $ll 1] # There may be occasion for a dialog if {$l eq "mess_yesno"} { answer_to_perl - } elseif {$l eq "menudata"} { - # we do want a menu, so we expect menu data, - # which may take a while + } elseif [string match "location: ?*" $l] { + # this one comes straight from install-tl, rather than + # from install-tl-extl.pl + # installer about to contact repository, which may + # fail and cause an indefinite delay + chan configure $::inst -blocking 0 + chan event $::inst readable read_line_loading + if [winfo exists .loading] { + .loading configure -text [__ "Trying to load %s. + +If this takes too long, press Abort and choose another repository." \ + [string range $l 10 end]] + update + } + break + } + } + # waiting till the repository has been loaded + vwait ::loaded + unset ::loaded + #puts stderr "done loading" + # resume reading from back end in blocking mode + while 1 { + set ll [read_line] + if {[lindex $ll 0] < 0} { + break + } + set l [lindex $ll 1] + if {$l eq "menudata"} { + # so we do want a menu and expect menu data, + # parsing which may take a while read_menu_data show_time "read menu data from perl" set ::advanced 0 set ::alltrees 0 set answer [run_menu] - if [info exists ::env(dbgui)] {puts "dbgui1: menu_ans is $::menu_ans"} + #if [info exists ::env(dbgui)] {puts "dbgui1: menu_ans is $::menu_ans"} if {$answer eq "advanced"} { # this could only happen if $::advanced was 0 set ::advanced 1 - if [info exists ::env(dbgui)] {puts "dbgui: Setting advanced to 1"} + #if [info exists ::env(dbgui)] {puts "dbgui: Setting advanced to 1"} set answer [run_menu] if {$answer eq "alltrees"} { set ::alltrees 1 - if [info exists ::env(dbgui)] {puts "dbgui: Setting alltrees to 1"} + #if [info exists ::env(dbgui)] {puts "dbgui: Setting alltrees to 1"} set answer [run_menu] } } @@ -1821,13 +1935,6 @@ proc main_prog {} { set ::out_log {} set answer "startinst" break - } elseif [string match "location: ?*" $l] { - # this one comes straight from install-tl, rather than - # from install-tl-extl.pl - if [winfo exists .loading] { - .loading configure -text [__ "Loading from %s" [string range $l 10 end]] - update - } } else { lappend ::out_log $l } diff --git a/Master/tlpkg/tltcl/tltcl.tcl b/Master/tlpkg/tltcl/tltcl.tcl index c7e4fedb481..db0157a6d84 100644 --- a/Master/tlpkg/tltcl/tltcl.tcl +++ b/Master/tlpkg/tltcl/tltcl.tcl @@ -12,11 +12,156 @@ if {$::tcl_platform(platform) eq "unix" && $::tcl_platform(os) ne "Darwin"} { set ::plain_unix 1 } +if $::plain_unix { + # plain_unix: avoid a RenderBadPicture error on quitting. + # 'send' changes the shutdown sequence, + # which avoids triggering the bug. + # 'tk appname <something>' restores 'send' and avoids the bug + bind . <Destroy> { + catch {tk appname appname} + } +} + # process ID of the perl program that will run in the background set ::perlpid 0 +# mirrors + set any_mirror "http://mirror.ctan.org/systems/texlive/tlnet" +# turn name into a string suitable for a widget name +proc mangle_name {n} { + set n [string tolower $n] + set n [string map {" " "_"} $n] + return $n +} ; # mangle_name + +set mirrors [dict create] +proc read_mirrors {} { + if [catch {open [file join $::instroot \ + "tlpkg/installer/ctan-mirrors.pl"] r} fm] { + return 0 + } + set re_geo {^\s*'([^']+)' => \{\s*$} + set re_url {^\s*'(.*)' => ([0-9]+)} + set re_clo {^\s*\},?\s*$} + set starting 1 + set lnum 0 ; # line number for error messages + set ok 1 ; # no errors encountered yet + set countries {} ; # aggregate list of countries + set urls {} ; # aggregate list of urls + set continent "" + set country "" + set u "" + set in_cont 0 + set in_coun 0 + while {! [catch {chan gets $fm} line] && ! [chan eof $fm]} { + incr lnum + if $starting { + if {[string first "\$mirrors =" $line] == 0} { + set starting 0 + continue + } else { + set ok 0 + set msg "Unexpected line '$line' at start" + break + } + } + # starting is now dealt with. + if [regexp $re_geo $line dummy c] { + if {! $in_cont} { + set in_cont 1 + set continent $c + set cont_dict [dict create] + if {$continent in [dict keys $::mirrors]} { + set ok 0 + set msg "Duplicate continent $c at line $lnum" + break + } + } elseif {! $in_coun} { + set in_coun 1 + set country $c + if {$country in $countries} { + set ok 0 + set msg "Duplicate country $c at line $lnum" + break + } + lappend countries $country + dict set cont_dict $country {} + } else { + set ok 0 + set msg "Unexpected continent- or country line $line at line $lnum" + break + } + } elseif [regexp $re_url $line dummy u n] { + if {! $in_coun} { + set ok 0 + set msg "Unexpected url line $line at line $lnum" + break + } elseif {$n ne "1"} { + continue + } + append u "systems/texlive/tlnet" + if {$u in $urls} { + set ok 0 + set msg "Duplicate url $u at line $lnum" + break + } + dict lappend cont_dict $country $u + lappend urls $u + set u "" + } elseif [regexp $re_clo $line] { + if $in_coun { + set in_coun 0 + set country "" + } elseif $in_cont { + set in_cont 0 + dict set ::mirrors $continent $cont_dict + set continent "" + } else { + break ; # should close mirror list + } + } ; # ignore other lines + } + close $fm +} ; # read_mirrors + +# cascading dropdown mirror menu +# parameter cmd should be a proc which does something with the selected url +proc mirror_menu {wnd cmd} { + destroy $wnd.m + if {[dict size $::mirrors] == 0} read_mirrors + if {[dict size $::mirrors] > 0} { + ttk::menubutton $wnd -text [__ "Specific mirror..."] \ + -direction below -menu $wnd.m + menu $wnd.m + dict for {cont d_cont} $::mirrors { + set c_ed [mangle_name $cont] + menu $wnd.m.$c_ed + $wnd.m add cascade -label $cont -menu $wnd.m.$c_ed + dict for {cntr urls} $d_cont { + set n_ed [mangle_name $cntr] + menu $wnd.m.$c_ed.$n_ed + $wnd.m.$c_ed add cascade -label $cntr -menu $wnd.m.$c_ed.$n_ed + foreach u $urls { + $wnd.m.$c_ed.$n_ed add command -label $u -command "$cmd $u" + } + } + } + } else { + ttk::label $wnd -text [__ "No mirror list available"] + } + return $wnd +} + +proc possible_repository {s} { + if [regexp {^(https?|ftp):\/\/.+} $s] {return 1} + if {[string first {file://} $s] == 0} {set s [string range $s 7 end]} + if [file isdirectory [file join $s "archive"]] {return 1} + if [file isdirectory [file join $s "texmf-dist/web2c"]] {return 1} + return 0 +} + proc get_stacktrace {} { set level [info level] set s "" @@ -26,31 +171,29 @@ proc get_stacktrace {} { return $s } ; # get_stacktrace -proc err_exit {{mess ""}} { - if {$mess eq ""} {set mess "Error"} - append mess "\n" [get_stacktrace] - if $::plain_unix { - # plain_unix: avoid a RenderBadPicture error on quitting. - # 'send' changes the shutdown sequence, - # which avoids triggering the bug. - # 'tk appname <something>' restores 'send' and avoids the bug - bind . <Destroy> { - catch {tk appname appname} - } - } - tk_messageBox -icon error -message $mess - # kill perl process, just in case - if $::perlpid { - catch { - if {$::tcl_platform(platform) eq "unix"} { - exec -ignorestderr "kill" $::perlpid - } else { - exec -ignorestderr "taskkill" "/pid" $::perlpid - } +proc normalize_argv {} { + # work back to front, to not disturb indices of unscanned list elements + set i $::argc + while 1 { + incr i -1 + if {$i<0} break + set s [lindex $::argv $i] + if {[string range $s 0 1] eq "--"} { + set s [string range $s 1 end] + set ::argv [lreplace $::argv $i $i $s] } + set j [string first "=" $s] + if {$j > 0} { + set s0 [string range $s 0 [expr {$j-1}]] + set s1 [string range $s [expr {$j+1}] end] + set ::argv [lreplace $::argv $i $i $s0 $s1] + } elseif {$j==0} { + err_exit "Command-line argument $s starting with \"=\"" + } ; # else leave alone } - exit -} ; # err_exit + set ::argc [llength $::argv] +} +normalize_argv # localization support @@ -69,24 +212,11 @@ proc load_translations {} { while {$i < $::argc} { set p [lindex $::argv $i] incr i - if {$p eq "-lang" || $p eq "--lang" || $p eq "-gui-lang" || \ - $p eq "--gui-lang"} { + if {$p eq "-lang" || $p eq "-gui-lang"} { if {$i < $::argc} { set ::lang [lindex $::argv $i] break } - } elseif {[string range $p 0 5] eq "-lang="} { - set ::lang [string range $p 6 end] - break - } elseif {[string range $p 0 6] eq "--lang="} { - set ::lang [string range $p 7 end] - break - } elseif {[string range $p 0 9] eq "-gui-lang="} { - set ::lang [string range $p 10 end] - break - } elseif {[string range $p 0 11] eq "--gui-lang="} { - set ::lang [string range $p 12 end] - break } } unset i @@ -316,6 +446,11 @@ set ::env(NOPERLDOC) 1 # for example code, look at dialog.tcl, part of Tk itself +# widget classes which can be enabled and disabled. +# The text widget class is not included here. + +set ::active_cls [list TButton TCheckbutton TRadiobutton TEntry Treeview] + # global variable for dialog return value, in case the outcome # must be handled by the caller rather than by the dialog itself: set ::dialog_ans {} @@ -358,11 +493,16 @@ proc place_dlg {wnd {p "."}} { grab set $wnd } ; # place_dlg -proc end_dlg {ans wnd} { +# in case pressing the closing button leads to lengthy processing: +proc disable_dlg {wnd} { foreach c [winfo children $wnd] { - # alternative to catch: check type with [winfo class $wnd] - catch {$c state disabled} + if {[winfo class $c] in $::active_cls} { + catch {$c state disabled} + } } +} + +proc end_dlg {ans wnd} { set ::dialog_ans $ans set p [winfo parent $wnd] if {$p eq ""} {set p "."} |