• How do I update geometry?

    From Luc@luc@sep.invalid to comp.lang.tcl on Fri Feb 13 21:57:16 2026
    From Newsgroup: comp.lang.tcl

    Hi.

    I've been working on a new project and I am struggling with positioning panedwindows.

    I tried a lot of things that ChatGPT suggested, but ChatGPT is even
    worse at Tcl/Tk than me. Maybe because Tcl is not popular enough so it
    doesn't have enough code to draw from.

    The code below draws the layout the way I want it except that the larger portion on the left shoud be split in two, with a sash. That is not
    really working.

    Note that the 6 last lines are commented out. The layout only looks right
    if I uncomment them. If you do, you should see a blue pane on the left
    and a green pane on the right.

    So it works?

    Kind of. There are two problems with it:

    1. I have no idea why it works. I just kept trying everything I could
    until it "worked."

    2. Working or not, the code looks terrible. I'm sure there is a correct
    way of achieving it.

    Can someone please enlighten me?

    TIA



    code here: https://pastebin.com/7WJjBdts

    or here:
    ---------------------------------------------------
    if {1} { # GLOBALS
    set ::SELFDIR [file dirname [info script]]
    set ::PANEL_IS_ON_RIGHT 1
    set ::MENU_IS_ON_TOP 0
    set ::NOTES_PANEL_IS_ON_RIGHT 1
    set ::LARGER_PANEL_WEIGHT 180
    set ::BOXFOG "#000000"
    set ::BOXBKG "#DBE7E8"
    set ::BOXBKG "#FFFFED"
    set ::BOXFONT {Arial 16}
    set ::BOXRELIEF ridge
    set ::MENUFONT {Arial 24}
    set ::MENUFOG "#ffffff"
    set ::MENUBKG "#DBE7E8"
    set ::MENUBKG "#A52A2A"
    set ::CONFIG_PANESIDE "right"
    set ::CONFIG_SHOWBOXES 2
    #raised, sunken, flat, ridge, solid, and groove
    }
    proc p.begin {} {
    package require Tcl 8.6
    package require Tk
    package require tile

    # --- Toplevel window ---
    wm withdraw .
    set ::w [toplevel .proto -background #c0c0c0]
    wm title $::w "Prototype 142"
    tk appname "Prototype 142"
    wm geometry $::w 400x160+20+20
    wm resizable $::w 1 1
    if {$::tcl_platform(platform) == "unix"} {wm attributes $::w -zoomed 1}
    if {$::tcl_platform(platform) == "windows"} {wm state $::w -zoomed 1}

    bind $::w <Escape> {exit 0}
    wm protocol $::w WM_DELETE_WINDOW {exit 0}
    # end of proc p.begin ====================
    }
    proc p.build_skeleton_part1 {} {
    set ::of $::w.outerframe
    frame $::of -background #FFC0CB
    grid rowconfigure $::w 0 -weight 1
    grid columnconfigure $::w 0 -weight 1
    grid $::of -row 0 -column 0 -sticky nsew

    # --- Main horizontal paned window (unified vertical sash)
    ttk::style configure Sash -sashpad 1 -sashthickness 3 -sashrelief solid -handlepad 200 -handlesize 200 -bordercolor blue
    ttk::panedwindow $::of.pw_maincontainer -orient horizontal
    grid $::of.pw_maincontainer -row 0 -column 0 -sticky nsew
    ttk::panedwindow $::of.pw_left -orient vertical
    ttk::panedwindow $::of.pw_right -orient vertical
    $::of.pw_maincontainer add $::of.pw_left -weight 1
    $::of.pw_maincontainer add $::of.pw_right -weight 100

    set ::MAINCONTENTFRAME $::of.maincontentframe
    set ::SIDEPANEFRAME $::of.sidepaneframe
    frame $::MAINCONTENTFRAME -background #c0c0c0
    frame $::SIDEPANEFRAME -background #1E90FF

    if {$::PANEL_IS_ON_RIGHT == 1} {
    $::of.pw_left add $::MAINCONTENTFRAME -weight 1
    $::of.pw_right add $::SIDEPANEFRAME -weight 1
    }
    if {$::PANEL_IS_ON_RIGHT == 0} {
    $::of.pw_right add $::MAINCONTENTFRAME -weight 1
    $::of.pw_left add $::SIDEPANEFRAME -weight 1
    }

    grid rowconfigure $::of 0 -weight 1
    grid columnconfigure $::of 0 -weight 1
    grid $::of.pw_maincontainer -row 0 -column 0 -sticky nsew

    # IF NO BOXES, RETURN =========================
    if {$::CONFIG_SHOWBOXES < 1} {
    $::MAINCONTENTFRAME configure -background $::MENUBKG
    return
    }
    # IF IT HAS BOXES
    if {$::PANEL_IS_ON_RIGHT == 1} {set parentPW $::of.pw_right}
    if {$::PANEL_IS_ON_RIGHT == 0} {set parentPW $::of.pw_left}
    panedwindow $parentPW.lower -orient vertical
    $parentPW add $parentPW.lower -weight 1
    if {$::MENU_IS_ON_TOP == 1} {
    set ::MENUFRAME $::SIDEPANEFRAME
    set ::BOXFRAME $parentPW.lower
    }
    if {$::MENU_IS_ON_TOP == 0} {
    set ::MENUFRAME $parentPW.lower
    set ::BOXFRAME $::SIDEPANEFRAME
    }
    $::MENUFRAME configure -background darkred
    $::BOXFRAME configure -background #c0c0c0

    # BUILD SIDE PANE
    # BUILD MENU
    set rowcount 0
    foreach {k v} {
    entry_1 "Entry 1"
    entry_2 "Entry 2"
    entry_3 "Entry 3"
    entry_4 "Entry 4"
    entry_5 "Entry 5"
    } {
    grid rowconfigure $::MENUFRAME $rowcount
    ttk::style configure Sidebar.TButton -font $::MENUFONT -foreground $::MENUFOG -background $::MENUBKG -pady 2000 -bd 0 -relief flat
    ttk::style map Sidebar.TButton \
    -background "active $::MENUBKG pressed #b8b8b8" \
    -foreground "focus $::MENUFOG disabled $::MENUBKG"
    ttk::button $::MENUFRAME.button_$k -style Sidebar.TButton
    $::MENUFRAME.button_$k configure -text $v
    grid $::MENUFRAME.button_$k -row $rowcount -column 0 -sticky sew
    incr rowcount 2
    }

    for {set i 1} {$i < $rowcount} {incr i 2} {
    grid rowconfigure $::MENUFRAME $i -weight 1
    }
    for {set i 0} {$i < $rowcount} {incr i 2} {
    grid rowconfigure $::MENUFRAME $i -weight 0
    }
    grid columnconfigure $::MENUFRAME 0 -weight 1

    # FIRST BOX
    set _box1name "BOX 1"
    label $::BOXFRAME.top
    $::BOXFRAME.top configure -font {Arial 12}
    $::BOXFRAME.top configure -text "BOX 1"
    $::BOXFRAME.top configure -background white -foreground black
    $::BOXFRAME.top configure -bd 2 -relief ridge
    $::BOXFRAME.top configure -padx 100 -pady 100
    grid $::BOXFRAME.top -row 0 -column 0 -sticky new
    set ::CLBOX_TOP $::BOXFRAME.boxtop
    label $::CLBOX_TOP
    $::CLBOX_TOP configure -font {Arial 12}
    $::CLBOX_TOP configure -background lightgreen -foreground black
    grid $::CLBOX_TOP -row 1 -column 0 -sticky n

    ## SECOND BOX
    set _box2name "BOX 2"
    grid rowconfigure $::BOXFRAME 2
    grid rowconfigure $::BOXFRAME 3
    label $::BOXFRAME.bottom
    $::BOXFRAME.bottom configure -font {Arial 12}
    $::BOXFRAME.bottom configure -text "BOX 2"
    $::BOXFRAME.bottom configure -background white -foreground black
    $::BOXFRAME.bottom configure -bd 2 -relief ridge
    grid $::BOXFRAME.bottom -row 2 -column 0 -sticky new
    $::BOXFRAME.bottom configure -padx 100 -pady 100
    set ::CLBOX_BOTTOM $::BOXFRAME.boxbottom
    label $::CLBOX_BOTTOM
    $::CLBOX_BOTTOM configure -font {Arial 12}
    $::CLBOX_BOTTOM configure -background white -foreground black
    $::CLBOX_BOTTOM configure -relief ridge

    grid $::CLBOX_BOTTOM -row 3 -column 0 -sticky s

    update idletasks
    set w [winfo reqwidth $::BOXFRAME]
    set sw [winfo screenwidth .]
    if {$::PANEL_IS_ON_RIGHT == 0} {
    $::of.pw_maincontainer sashpos 0 $w
    }
    if {$::PANEL_IS_ON_RIGHT == 1} {
    set w [expr {$sw - $w}]
    $::of.pw_maincontainer sashpos 0 $w
    }
    set h [winfo reqheight $::BOXFRAME]
    $::of.pw_right sashpos 0 $h
    update idletasks
    }

    proc p.buildpw {parent parentname orient nameA nameB} {
    # Paths
    set pw $parent.$parentname
    set fA $pw.$nameA
    set fB $pw.$nameB

    # Panedwindow (structure only)
    ttk::panedwindow $pw -orient $orient

    # Content frames (these ARE the panes)
    frame $fA -background #ADD8E6
    frame $fB -background #D5FFD5

    # Add frames as panes
    $pw add $fA -weight 1
    $pw add $fB -weight 1

    # Layout
    grid $pw -row 0 -column 0 -sticky nsew
    grid rowconfigure $parent 0 -weight 1
    grid columnconfigure $parent 0 -weight 1

    puts "req=[winfo reqwidth $pw]x[winfo reqheight $pw]"
    return [list $pw $fA $fB]
    }

    p.begin
    p.build_skeleton_part1
    puts [p.buildpw $::MAINCONTENTFRAME test horizontal upper lower]

    #wm geometry $::w ""
    #if {$::tcl_platform(platform) == "unix"} {wm attributes $::w -zoomed 0} #if {$::tcl_platform(platform) == "windows"} {wm state $::w -zoomed 0} #update idletasks
    #if {$::tcl_platform(platform) == "unix"} {wm attributes $::w -zoomed 1} $if {$::tcl_platform(platform) == "windows"} {wm state $::w -zoomed 1} ---------------------------------------------------
    --
    Luc


    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From Colin Macleod@user7@newsgrouper.org.invalid to comp.lang.tcl on Sat Feb 14 08:24:20 2026
    From Newsgroup: comp.lang.tcl

    Luc <luc@sep.invalid> posted:

    I've been working on a new project and I am struggling with positioning panedwindows.

    See: https://tkdocs.com/tutorial/index.html

    There is no Royal road to (Tk) geometry.
    --
    Colin Macleod ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ https://cmacleod.me.uk

    FEED HOUSE SAVE FEED HOUSE SAVE FEED HOUSE SAVE
    GAZA GAZA GAZA GAZA GAZA GAZA GAZA GAZA GAZA
    NOW! NOW! NOW! NOW! NOW! NOW! NOW! NOW! NOW!
    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From Luc@luc@sep.invalid to comp.lang.tcl on Sat Feb 14 13:19:06 2026
    From Newsgroup: comp.lang.tcl

    On Sat, 14 Feb 2026 08:24:20 GMT, Colin Macleod wrote:

    Luc <luc@sep.invalid> posted:

    I've been working on a new project and I am struggling with positioning
    panedwindows.

    See: https://tkdocs.com/tutorial/index.html

    There is no Royal road to (Tk) geometry.

    **************************

    That doesn't help someone who has the manual and has been "trying
    everything until it works" and even trying ChatGPT.

    Besides, I can't open it even with two Internet providers.
    Are you blocking countries?
    --
    Luc


    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From et99@et99@rocketship1.me to comp.lang.tcl on Sat Feb 14 16:48:29 2026
    From Newsgroup: comp.lang.tcl

    On 2/14/2026 8:19 AM, Luc wrote:
    On Sat, 14 Feb 2026 08:24:20 GMT, Colin Macleod wrote:

    Luc <luc@sep.invalid> posted:

    I've been working on a new project and I am struggling with positioning
    panedwindows.

    See: https://tkdocs.com/tutorial/index.html

    There is no Royal road to (Tk) geometry.

    **************************

    That doesn't help someone who has the manual and has been "trying
    everything until it works" and even trying ChatGPT.

    Besides, I can't open it even with two Internet providers.
    Are you blocking countries?



    I use Claude.ai and find it works much better with tcl/tk than chatgpt.

    I showed your code to the Claude and we found several issues. For one, on windows (where I tested), you need

    wm state $::w zoomed (or withdrawn)

    not -zoomed 0/1

    But the big problem was you're not waiting for the windows to render before you ask for their sizes. I added some waits and did a full update (not just idletasks).

    Before that, I found a sash on the far right that was hiding all the stuff you put into that panel. Then I changed horizontal to vertical on the panel on the left that needs to be sub-divided.

    Also, everything is so large in that skeleton builder that when it did finally get rendered, the vertical sash was almost all the way to the left, but at least now visible.

    And that last line starts with $if which is likely a typo.

    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From saito@saitology9@gmail.com to comp.lang.tcl on Sat Feb 14 21:57:12 2026
    From Newsgroup: comp.lang.tcl

    On 2/14/2026 7:48 PM, et99 wrote:
    On 2/14/2026 8:19 AM, Luc wrote:

    That doesn't help someone who has the manual and has been "trying
    everything until it works" and even trying ChatGPT.

    Besides, I can't open it even with two Internet providers.
    Are you blocking countries?



    I use Claude.ai and find it works much better with tcl/tk than chatgpt.


    Encouraged by your frequent success stories on these ai bots, I spent a
    lot of time today with them. With minor variations, they all produced
    similar results. But overall, I was left frustrated as I wasted time
    trying their recommendations which included non-existent, imaginary
    command names, packages, and blaring mistakes. Here are a few:

    Overall, they do offer insights into a solution but you must be willing
    to spend time to find it and improve on it. This is more difficult if
    you are new to a domain or a package.

    1) "sock" is undefined:
    proc Direct_Url_/upload/simple {args} {
    global uploadDir
    upvar #0 Httpd$sock data
    ...

    2) this is not how split works in tcl:
    # Split by boundary
    set boundary "--$boundary"
    set parts [split $postData $boundary]


    3) many uses of commands that simply don't exist. But I admit would be
    quite helpful if they did.






    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From et99@et99@rocketship1.me to comp.lang.tcl on Sat Feb 14 20:39:03 2026
    From Newsgroup: comp.lang.tcl

    On 2/14/2026 6:57 PM, saito wrote:
    On 2/14/2026 7:48 PM, et99 wrote:
    On 2/14/2026 8:19 AM, Luc wrote:

    That doesn't help someone who has the manual and has been "trying
    everything until it works" and even trying ChatGPT.

    Besides, I can't open it even with two Internet providers.
    Are you blocking countries?



    I use Claude.ai and find it works much better with tcl/tk than chatgpt.


    Encouraged by your frequent success stories on these ai bots, I spent a lot of time today with them. With minor variations, they all produced similar results.-a But overall, I was left frustrated as I wasted time trying their recommendations which included non-existent, imaginary command names, packages, and blaring mistakes. Here are a few:

    Overall, they do offer insights into a solution but you must be willing to spend time to find it and improve on it. This is more difficult if you are new to a domain or a package.

    1) "sock" is undefined:
    proc Direct_Url_/upload/simple {args} {
    -a-a-a global uploadDir
    -a-a-a upvar #0 Httpd$sock data
    ...

    2) this is not how split works in tcl:
    # Split by boundary
    set boundary "--$boundary"
    set parts [split $postData $boundary]


    3) many uses of commands that simply don't exist. But I admit would be quite helpful if they did.


    I've had to learn how to work with them. Some suggestions:


    1. Keep a cheat sheet of corrections. For example, I've had to tell claude several times that an online comment needs a ;# instead of just #. I also have the markup rules for writing up a wiki page in a sheet (I have a post-it note app I use called stickies). You can then paste in the cheat sheets when starting new.

    2. Tell it to work incrementally and modular. Claude likes to write up everything in one shot. Then it's too difficult to test and debug.

    3. With claude, you can tell it to scan prior conversations to startup a new one but want it to continue.

    4. You need to have patience. They make errors. That's why point 2 is important.

    5. You can paste in code and have it analyze it. I had claude find the problem in the OP's code where he wasn't waiting for rendering before trying to get window parameters. That's a long standing gotcha in Tk code that Claude knew about.

    5. Get it to write up test cases. And once they've written these, they are pretty good at writing a manual since they understand the code better.

    6. Claude is very good at helping to setup a github repository. He can create the readme and the mit license.

    But these AI bots aren't going to take over anytime soon, but can be very helpful.

    -et


    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From Luc@luc@sep.invalid to comp.lang.tcl on Sun Feb 15 02:18:42 2026
    From Newsgroup: comp.lang.tcl

    On Sat, 14 Feb 2026 16:48:29 -0800, et99 wrote:

    I use Claude.ai and find it works much better with tcl/tk than chatgpt.

    I showed your code to the Claude and we found several issues. For one, on >windows (where I tested), you need

    wm state $::w zoomed (or withdrawn)

    not -zoomed 0/1

    But the big problem was you're not waiting for the windows to render
    before you ask for their sizes. I added some waits and did a full update
    (not just idletasks).

    Before that, I found a sash on the far right that was hiding all the stuff >you put into that panel. Then I changed horizontal to vertical on the
    panel on the left that needs to be sub-divided.

    Also, everything is so large in that skeleton builder that when it did >finally get rendered, the vertical sash was almost all the way to the
    left, but at least now visible.

    And that last line starts with $if which is likely a typo.

    **************************

    Your description does not match what I see. Do you mind sharing a
    screenshot and what version of Tcl/Tk you're using?
    --
    Luc


    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From Olivier@user1108@newsgrouper.org.invalid to comp.lang.tcl on Sun Feb 15 11:24:11 2026
    From Newsgroup: comp.lang.tcl


    et99 <et99@rocketship1.me> posted:


    But the big problem was you're not waiting for the windows to render before you ask for their sizes. I added some waits and did a full update (not just idletasks).


    It seemed inextricable, but AI seems useful in this desperate case...
    Is this you or the AI that was able to guess the flow of appearance ? It is puzzling.

    Olivier
    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From Luc@luc@sep.invalid to comp.lang.tcl on Sun Feb 15 16:47:16 2026
    From Newsgroup: comp.lang.tcl

    On Sun, 15 Feb 2026 00:56:19 -0800, et99 wrote:

    Here is a diff of the code. I threw in my wait routine to delay a bit (in
    the event loop, uses vwait) where you were doing an update idletasks and
    use update alone.
    **************************

    This is my one concern here. "A wait routine" to "delay a bit."

    How much is "a bit"? How do we even know how much wait is enough?

    I need some way to make Tk do it right. When it thinks it's right
    should not be my problem, Tk should manage it.

    I forgot to say in my original request, without the last six lines,
    my protoype does not show the blue and green panes. But "restoring"
    the window and maximizing it again would make them appear.

    Thank you for your 'wait' proc, but I'm afraid that is much of a
    hack as my last six lines. There has to be a proper way of doing it.
    --
    Luc


    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From et99@et99@rocketship1.me to comp.lang.tcl on Sun Feb 15 14:10:43 2026
    From Newsgroup: comp.lang.tcl

    On 2/15/2026 3:24 AM, Olivier wrote:

    et99 <et99@rocketship1.me> posted:


    But the big problem was you're not waiting for the windows to render before you ask for their sizes. I added some waits and did a full update (not just idletasks).


    It seemed inextricable, but AI seems useful in this desperate case...
    Is this you or the AI that was able to guess the flow of appearance ? It is puzzling.

    Olivier

    I got interested in this problem when Luc mentioned using chatgpt. Since I've been using Claude with great success, I thought I would give it a shot.

    To be honest, I found Luc's coding style to be a bit forbidding with too much indirection for my tastes, and I didn't want to decipher what the code was doing. So, I sent the code and the post into Claude, who analyzed both. He gave me several things to try. Nothing worked at first. I wasn't seeing the widgets at all.

    Only by using a step debugger and a widget tree display tool, I verified that the main procedure was actually building up a frame inside a new toplevel. The result I was seeing at first was hiding it completely, which threw both me and Claude off track.

    That's when I guessed that maybe there was a sash on the far right side, and moving that successfully revealed the right pane. So, that part was me. I then told Claude of my discovery.

    Not knowing why the pane began hidden, Claude suggested that the large -pad values might be a problem and at some point changing them did reveal something but not what I thought was desired. My earlier post was based on that behavior.

    Next claude suggested the left side panes weren't behaving because they had nothing inside them, and gave me some labels to add (primarily as a debug step to see if they then appeared). I found that keeping the labels seemed to be what was needed - so that's likely a hack. Claude often will suggest adding in debug code, since he can't run the code himself. He needs me to try things and report the results.

    As to Luc's complaint about Tk not knowing when things are rendered and so you don't know when to request the final sizes of things, that is a valid complaint. I don't know what the proper way to do that is. Claude didn't seem to know a better way either.

    The other problem diagnosed by Claude was the use of horizontal instead of vertical, which Claude said was an understandable mistake, since the value "Specifies the orientation of the window panes" not of the sash.


    -et
    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From et99@et99@rocketship1.me to comp.lang.tcl on Sun Feb 15 14:56:33 2026
    From Newsgroup: comp.lang.tcl

    On 2/15/2026 2:44 PM, saito wrote:
    On 2/15/2026 5:10 PM, et99 wrote:

    I got interested in this problem when Luc mentioned using chatgpt. Since I've been using Claude with great success, I thought I would give it a shot.

    To be honest, I found Luc's coding style to be a bit forbidding with too much indirection for my tastes, and I didn't want to decipher what the code was doing.

    I agree with that sentiment. It is difficult to offer help when there is minimal explanation but lots of code.

    So what is it supposed to do?


    I might be wrong, but based on this:

    "The code below draws the layout the way I want it except that the larger portion on the left shoud be split in two, with a sash. That is not
    really working."


    I guessed, and so did Claude, that what he wanted was a left and right pane with the left pane split top and bottom. Maybe we are wrong, but the final result I got was like that. My earlier screenshot shows that result. And in the end, the pane on the right is smaller.

    -et

    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From Luc@luc@sep.invalid to comp.lang.tcl on Sun Feb 15 22:10:07 2026
    From Newsgroup: comp.lang.tcl

    On Sun, 15 Feb 2026 18:41:18 -0500, saito wrote:

    Maybe something like this?

    package req Tk

    **************************

    Your prototype looks good. Thanks. I will study it.

    Two problems, though.

    1. The vertical divider can't be dragged. In my design, it can.

    2. I need the proc to create panedwindows in an arbitray parent
    widget, so I can use it as a kind of reusable building block.
    I am going to be creating a lot of "split" views in this app.
    (One of those blue/green panes will be split, too.)

    If you really want to see what I am trying to achieve, there is
    a video here:

    https://limewire.com/d/Savgx#exppOUDS5H

    Note that I restore and maximize with keyboard shortcuts, so you
    can't see me click anything.

    The final look is perfect, the only problem is I have to restore
    and maximize the app, which is terrible.
    --
    Luc


    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From Rich@rich@example.invalid to comp.lang.tcl on Mon Feb 16 01:30:27 2026
    From Newsgroup: comp.lang.tcl

    saito <saitology9@gmail.com> wrote:
    On 2/15/2026 5:10 PM, et99 wrote:

    I got interested in this problem when Luc mentioned using chatgpt. Since
    I've been using Claude with great success, I thought I would give it a
    shot.

    To be honest, I found Luc's coding style to be a bit forbidding with too
    much indirection for my tastes, and I didn't want to decipher what the
    code was doing.

    I agree with that sentiment. It is difficult to offer help when there is minimal explanation but lots of code.

    I have, IIRC, more than a few times mentioned to Luc that when asking
    for help here that he should post a minimal script that exhibits the
    problem. I have noticed that despite those requests, the "it's broken"
    code examples continue to contain extras that make it hard for us
    (volunteers I might add) to figure out what is going on, much less what
    is going wrong. So for this post of his, I took a short look, saw a
    lot of extraneous code, and decided to move along.

    So what is it supposed to do?

    The best we have is the picture et99 put in dropbox, but that just
    shows what et99 was able to get the code to do, as to "supposed", still
    not sure.
    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From Luc@luc@sep.invalid to comp.lang.tcl on Sun Feb 15 23:55:26 2026
    From Newsgroup: comp.lang.tcl

    On Mon, 16 Feb 2026 01:30:27 -0000 (UTC), Rich wrote:

    I have, IIRC, more than a few times mentioned to Luc that when asking
    for help here that he should post a minimal script that exhibits the >problem. I have noticed that despite those requests, the "it's broken"
    code examples continue to contain extras that make it hard for us >(volunteers I might add) to figure out what is going on, much less what
    is going wrong. So for this post of his, I took a short look, saw a
    lot of extraneous code, and decided to move along.

    **************************

    Fair criticism, but note that it involves Tk (as usual).

    Perhaps you will also remember that I have also been reprimanded
    for not posting enough code. One day, not enough. Another day, too
    much. It's hard to get that right.

    What would a minimal script be like? I am not sure because I don't
    know where the problem is. Is it in the skeleton? Is it the way I
    build the toplevel? Is it the proc that inserts panedwindows and
    splits frames? Is it my use of grid?

    Tk is complicated. To name one problem, order matters. If order
    matters and I don't know what the correct order is, I don't know
    where to draw the line on what to keep and what to remove when asking
    for help. I have no idea where I go wrong. I figure I had better keep everything, so maybe someone will point out I added things in the
    wrong order.

    In my head, the Windows is there. Now, I add panedwindows and...
    Where are they? Why don't they show up? Mystery...
    I tweak, I change, I experiment... and nothing.

    Then, by accident, I restore and maximize and ooops! There are
    the frames I had been looking for! Because the window changed size?
    That's it? I've been a Tcler for more than 20 years and had never
    seen this happen.

    The sad part is, I am always confused but never surprised, because
    Tk has always been complicated. I accomplish things with a lot of
    trial and error, barely understanding why this works and that
    doesn't. I've always preferred pack during all these years, but
    my Tk code has always been kludgy. Now I'm trying to get used to
    grid, and can't make much progress. I see grid is not even a hair
    more intuitive than pack.

    OK, I've vented. Sorry about that. Thank you for the help.
    --
    Luc


    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From Rich@rich@example.invalid to comp.lang.tcl on Mon Feb 16 04:05:31 2026
    From Newsgroup: comp.lang.tcl

    Luc <luc@sep.invalid> wrote:
    On Mon, 16 Feb 2026 01:30:27 -0000 (UTC), Rich wrote:

    I have, IIRC, more than a few times mentioned to Luc that when asking
    for help here that he should post a minimal script that exhibits the >>problem. I have noticed that despite those requests, the "it's broken" >>code examples continue to contain extras that make it hard for us >>(volunteers I might add) to figure out what is going on, much less what
    is going wrong. So for this post of his, I took a short look, saw a
    lot of extraneous code, and decided to move along.

    **************************

    Fair criticism, but note that it involves Tk (as usual).

    Perhaps you will also remember that I have also been reprimanded
    for not posting enough code. One day, not enough. Another day, too
    much. It's hard to get that right.

    What would a minimal script be like? I am not sure because I don't
    know where the problem is.

    I'll shall interpret this as a request for some advice on "how to make
    a minimal script".

    Start with a copy of the script that is not working. The copy is so
    you don't lose the original script.

    Then (and yes, this will involve, sometimes, a fair amount of effort on
    your part) begin removing bits (a small number) at a time from the copy (but... keep track of each bit until after you've done what the next
    sentence suggests). After each deletion of some small bit, rerun the
    script. Does it still exhibit the issue? If yes, remove another small
    bit and repeat.

    If it no longer exhibits the issue, then something in the bit you just
    removed is the cause of the problem. Put that bit back, rerun and
    verify the issue returns. At this point, you may want to look more
    closely at what was removed, as it may illuminate the problem and you
    may find the solution to be staring you in the face once you've found
    the part that was causing the issue. If not, continue removing other
    bits that are not this one. Repeat the same, remove (but hold a copy),
    rerun, verify if issue exists, loop.

    Parts that are candidates for removal early: colors (unless the colors
    are needed to "see" the issue), font size/choices, paddings, margins
    (i.e., anything that's purely a visual item). More often than not,
    none of these will be the cause of the trouble, and so removing them
    makes the script simpler for Usenet readers to digest without losing
    the actual issue that occurs.

    Other candidates: If you are doing a lot of variable indirections,
    consider "indirecting" them directly within the script instead of at
    run time. I.e. if you had something like this:

    set topname .top1
    set childname .child2
    set frame [frame $topname.$childname]

    The consider switching the above to just:

    set frame [frame .top1.child2]

    Yes, this is typically suggested as not great Tk style, because it is difficult to change later without rewriting half the script everywhere.
    But what you want from this effort is something easily digestable on
    Usenet, rather than an example of "perfect Tk future proof
    organization".

    As well, if $frame isn't used much itself, .i.e. it gets used in a pack
    or grid and then is never seen again, then getting rid of the 'frame'
    variable simplifies things yet again:

    frame .top1.child2
    grid .top1.child2

    And, the magic of doing this is, that in the process of "eliminating"
    stuff from the script to shrink it down to something smaller that shows
    the same issue, you'll often discover the one line (or two or three
    lines) where the issue really is, and in the process, sometimes realize
    what you did wrong to cause the issue, and so you can go back to the
    full copy, make a change to those one, two, or three lines, and have
    things work like you expect them to have worked.

    And if not, you'll have removed parts that are not the cause, so there
    is much less for the readers here on the group to have to digest to see
    what the script is attempting to do.
    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From et99@et99@rocketship1.me to comp.lang.tcl on Sun Feb 15 20:31:51 2026
    From Newsgroup: comp.lang.tcl

    On 2/15/2026 5:10 PM, Luc wrote:
    If you really want to see what I am trying to achieve, there is
    a video here:

    https://limewire.com/d/Savgx#exppOUDS5H


    Ah, I see that you actually do want the left 2 panes to be side by side. So, changing that value to vertical, as I did was not needed. However, it also works as horizontal with the panes on top of each other. The problem was really the timing.

    Rich's point about making the code more event-driven, is probably the right thing to do.

    I asked Claude what he thought of that and here is his answer: (notice he still gets the ;# on line comment wrong) - I didn't test this however.


    Yes, the `<Configure>` event approach would work and is actually the **proper** way to handle this in Tcl/Tk! It's more reliable than trying to guess when geometry is ready with `update` calls.

    **How it works:**

    ```tcl
    # Set a flag to prevent multiple repositionings
    set ::sash_positioned 0

    bind $::BOXFRAME <Configure> {
    if {!$::sash_positioned} {
    set ::sash_positioned 1
    # Now we have ACTUAL rendered geometry
    set w [winfo width $::BOXFRAME] # actual width, not reqwidth
    set sw [winfo screenwidth .]
    if {$::PANEL_IS_ON_RIGHT == 1} {
    set w [expr {$sw - $w}]
    $::of.pw_maincontainer sashpos 0 $w
    }
    }
    }
    ```

    **Is it more difficult?**

    Not really - it's actually **cleaner** in some ways:

    **Pros:**
    - Works reliably - you get actual rendered sizes, not guesses
    - No need for multiple `update` calls and waiting
    - Handles window resizing automatically if you want
    - More "correct" event-driven approach

    **Cons:**
    - Slightly different mental model (event-driven vs procedural)
    - Need to guard against multiple firings with a flag
    - Code is split between setup and callback

    For this specific case, I'd say the `<Configure>` approach is actually **simpler and more robust** than the current mess of `update`/`wait` calls. The flag prevents cascading, and you only reposition once when the geometry is actually ready.

    The original code was trying to be procedural in an event-driven GUI framework, which is why it's struggling!



    -et




    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From Rich@rich@example.invalid to comp.lang.tcl on Mon Feb 16 01:24:53 2026
    From Newsgroup: comp.lang.tcl

    Luc <luc@sep.invalid> wrote:
    On Sun, 15 Feb 2026 00:56:19 -0800, et99 wrote:

    Here is a diff of the code. I threw in my wait routine to delay a bit (in >>the event loop, uses vwait) where you were doing an update idletasks and >>use update alone.
    **************************

    This is my one concern here. "A wait routine" to "delay a bit."

    How much is "a bit"? How do we even know how much wait is enough?

    I need some way to make Tk do it right. When it thinks it's right
    should not be my problem, Tk should manage it.

    The usual way that is done is you put your "sizing" code into proc(s)
    that are connected to <Configure> events from the various windows that
    you need the size of, and as each <Configure> event fires, you do what
    you need to do with the new information you have been given.
    "<Configure>" events is how Tk tells you something changed.

    Do note that your <Configure> events may fire more than once, because something else being resized may make Tk resize a window that just
    fired off a <Configure>, and so anoher <Configure> may fire. So be
    careful you don't setup a possible deadlock situation as well.

    Remember, Tk is fully event driven. Putting in "timer waits" is an
    easy workaround, but the real way is to fully embrace the event driven
    aspect and make everything event driven.
    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From Rich@rich@example.invalid to comp.lang.tcl on Mon Feb 16 17:03:50 2026
    From Newsgroup: comp.lang.tcl

    et99 <et99@rocketship1.me> wrote:
    On 2/15/2026 5:10 PM, Luc wrote:
    If you really want to see what I am trying to achieve, there is
    a video here:

    https://limewire.com/d/Savgx#exppOUDS5H


    Ah, I see that you actually do want the left 2 panes to be side by
    side. So, changing that value to vertical, as I did was not needed. However, it also works as horizontal with the panes on top of each
    other. The problem was really the timing.

    Rich's point about making the code more event-driven, is probably the
    right thing to do.

    I asked Claude what he thought of that and here is his answer:
    (notice he still gets the ;# on line comment wrong) - I didn't test
    this however.


    Yes, the `<Configure>` event approach would work and is actually the **proper** way to handle this in Tcl/Tk! It's more reliable than
    trying to guess when geometry is ready with `update` calls.

    **How it works:**

    ```tcl
    # Set a flag to prevent multiple repositionings
    set ::sash_positioned 0

    bind $::BOXFRAME <Configure> {
    if {!$::sash_positioned} {
    set ::sash_positioned 1
    # Now we have ACTUAL rendered geometry
    set w [winfo width $::BOXFRAME] # actual width, not reqwidth
    set sw [winfo screenwidth .]
    if {$::PANEL_IS_ON_RIGHT == 1} {
    set w [expr {$sw - $w}]
    $::of.pw_maincontainer sashpos 0 $w
    }
    }
    }
    ```

    Yeah, I know, responding to "claude" here

    **Is it more difficult?**

    Not really - it's actually **cleaner** in some ways:

    Why most Tk programmers initially think it is more difficult is the "disconnected" manner of how things happen. You lay out you gui at
    lines X-Y of your code, but all the sizing is handled elsewhere, on
    lines G-J, and at a different time. It is difficult when one is
    accustomed to procedural code to think about event driven code and the
    fact that nothing happens in a nice straight linear line.

    **Pros:**
    - Works reliably - you get actual rendered sizes, not guesses
    - No need for multiple `update` calls and waiting
    - Handles window resizing automatically if you want

    True, although claude's example above won't handle resizing because the
    signal variable will prevent future configure calls from this window
    from being executed.

    - More "correct" event-driven approach

    **Cons:**
    - Slightly different mental model (event-driven vs procedural)

    That's a bit of an understatement on claude's part. Almost as big as
    saying an Eagle is a "slightly different Chicken". For programmers
    accustomed to procedural code (i.e., a vast majority) it is a very
    difficult jump to fully understanding event driven code.

    And for quick-n-dirty one-offs (which, sadly, often become not so
    "one-offs") it is way simpler to just stuff in 'updates' to force
    geometry calcualation, and then continue on, in the same code path,
    with adjusting sizes.

    - Need to guard against multiple firings with a flag

    No, that is not 'needed', and in some instances may even be
    detrimental. But one does need to be careful not to accidentally setup
    a deadlock situation.

    - Code is split between setup and callback

    For this specific case, I'd say the `<Configure>` approach is
    actually **simpler and more robust** than the current mess of `update`/`wait` calls. The flag prevents cascading, and you only
    reposition once when the geometry is actually ready.

    The original code was trying to be procedural in an event-driven GUI framework, which is why it's struggling!

    Yep. It's classic square peg into round hole theory.
    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From saito@saitology9@gmail.com to comp.lang.tcl on Mon Feb 16 13:01:30 2026
    From Newsgroup: comp.lang.tcl

    On 2/15/2026 8:10 PM, Luc wrote:
    On Sun, 15 Feb 2026 18:41:18 -0500, saito wrote:

    Maybe something like this?

    package req Tk

    **************************

    Your prototype looks good. Thanks. I will study it.

    Two problems, though.

    1. The vertical divider can't be dragged. In my design, it can.

    2. I need the proc to create panedwindows in an arbitray parent
    widget, so I can use it as a kind of reusable building block.


    The video wasn't clear for me. Is that the code behind your screens or
    are you building an editor?

    In any case, here is a second version that has both horizontal and
    vertical dividers. You can increase/reduce button frame left and right,
    and reduce/increase the two text frames on the left vertically.

    You should be able to make a proc out of this if you want multiple of
    them. You can send them the top widget name.


    ------ start ----------------------------------------
    package req Tk

    if 0 {
    add horizontal sizing
    with two windows side by side
    }

    panedwindow .pane1 -bd 8 \
    -orient horizontal -sashpad 8 \
    -sashrelief ridge

    frame .l -relief raised -bd 4 -bg peachpuff
    frame .r -relief ridge -bd 4 -bg yellow


    .pane1 add .l -minsize 100
    .pane1 add .r -minsize 100

    grid .pane1 -row 1 -column 1 -sticky news
    grid rowconfigure . 1 -weight 1
    grid columnconfigure . 1 -weight 1



    frame .r.f
    button .r.f.b1 -text Save
    button .r.f.b2 -text Print

    pack .r.f.b1 .r.f.b2 -side top -fill x -padx 10 -pady 10
    pack .r.f -fill both -expand 1


    if 0 {
    add vertical sizing
    with two windows on top of each other
    }


    frame .l.f -relief flat
    pack .l.f -fill both -expand 1

    panedwindow .l.f.panel2 -bd 8 \
    -orient vertical -sashpad 8 \
    -sashrelief ridge



    # lefttop frame
    frame .l.f.top
    label .l.f.top.l -text "Hello from a paned window"
    text .l.f.top.t -bg green

    grid .l.f.top.l -row 1 -column 1 -sticky news
    grid .l.f.top.t -row 2 -column 1 -sticky news -pady 10

    grid rowconfigure .l.f.top 1 -weight 0
    grid rowconfigure .l.f.top 2 -weight 1
    grid columnconfigure .l.f.top 1 -weight 1


    # bottom frame
    frame .l.f.bot
    label .l.f.bot.l -text "A different view"
    text .l.f.bot.t -bg blue

    grid .l.f.bot.l -row 1 -column 1 -sticky news
    grid .l.f.bot.t -row 2 -column 1 -sticky news

    grid rowconfigure .l.f.bot 1 -weight 0
    grid rowconfigure .l.f.bot 2 -weight 1
    grid columnconfigure .l.f.bot 1 -weight 1


    grid .l.f.top -row 1 -column 1 -sticky news
    grid .l.f.bot -row 2 -column 1 -sticky news
    grid rowconfigure .l.f 1 -weight 1
    grid rowconfigure .l.f 2 -weight 1
    grid columnconfigure .l.f 1 -weight 1


    .l.f.panel2 add .l.f.top -minsize 100
    .l.f.panel2 add .l.f.bot -minsize 100

    grid .l.f.panel2 -row 1 -column 1 -sticky news

    ------ end----------------------------------------


    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From et99@et99@rocketship1.me to comp.lang.tcl on Mon Feb 16 10:56:53 2026
    From Newsgroup: comp.lang.tcl

    On 2/16/2026 10:01 AM, saito wrote:
    The video wasn't clear for me. Is that the code behind your screens or are you building an editor?

    In any case, here is a second version that has both horizontal and vertical dividers. You can increase/reduce button frame left and right, and reduce/increase the two text frames on the left vertically.

    You should be able to make a proc out of this if you want multiple of them. You can send them the top widget name.


    That is a quite nice example. It demonstrates how one builds frames separate from the panes. It is often useful to have a way to view the hierarchy, and for that I have several tools I use to display the widget tree. Here we can see that there is a nested pained window:

    (hopefully this will indent correctly, in thunderbird it will)

    . - Mystartup
    | .pane1 - Panedwindow
    | .l - Frame
    | | .l.f - Frame
    | | | .l.f.panel2 - Panedwindow
    | | | .l.f.top - Frame
    | | | | .l.f.top.l - Label
    | | | | .l.f.top.t - Text
    | | | .l.f.bot - Frame
    | | | | .l.f.bot.l - Label
    | | | | .l.f.bot.t - Text
    | .r - Frame
    | | .r.f - Frame
    | | | .r.f.b1 - Button Save
    | | | .r.f.b2 - Button Print


    The connection between the pane and it's contents is with he panel "add" commands.

    And this doesn't have any timing problems that I can see.

    Nice!

    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From saito@saitology9@gmail.com to comp.lang.tcl on Mon Feb 16 14:47:36 2026
    From Newsgroup: comp.lang.tcl

    On 2/16/2026 1:56 PM, et99 wrote:
    On 2/16/2026 10:01 AM, saito wrote:
    The video wasn't clear for me. Is that the code behind your screens or
    are you building an editor?

    In any case, here is a second version that has both horizontal and
    vertical dividers. You can increase/reduce button frame left and
    right, and reduce/increase the two text frames on the left vertically.

    You should be able to make a proc out of this if you want multiple of
    them. You can send them the top widget name.


    That is a quite nice example. It demonstrates how one builds frames
    separate from the panes. It is often useful to have a way to view the hierarchy, and for that I have several tools I use to display the widget tree. Here we can see that there is a nested pained window:

    Thanks!

    The tool to print the hierarchy is nice too.

    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From et99@et99@rocketship1.me to comp.lang.tcl on Mon Feb 16 13:23:49 2026
    From Newsgroup: comp.lang.tcl

    On 2/16/2026 11:47 AM, saito wrote:
    The tool to print the hierarchy is nice too.

    proc ltree {{root .} {level 0}} { # list widget tree
    set children [winfo children $root]
    set class [winfo class $root]
    set info ""
    if { $class == "Button" } {
    set info [split [$root cget -text] \n]

    } elseif { $class == "TLabelframe" } {
    set info [split [$root cget -text] \n]

    } elseif { $class == "TButton" } {
    set info [split [$root cget -text] \n]

    } elseif { $class == "TEntry" } {
    set info "var: [$root cget -textvariable]"
    } elseif { $class == "TCheckbutton" } {
    set info [split [$root cget -text] \n]
    } elseif { $class == "TButton2" } {
    set info [split [$root cget -text] \n]
    } else {

    }
    puts "[string repeat " | " $level] $root - $class $info"
    if { $children == "" } {
    return $root
    } else {
    foreach child $children {
    set tout [ltree $child [expr ( $level + 1 )]]
    }

    }
    }

    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From Ralf Fassel@ralfixx@gmx.de to comp.lang.tcl on Tue Feb 17 10:34:43 2026
    From Newsgroup: comp.lang.tcl

    * et99 <et99@rocketship1.me>
    | On 2/16/2026 11:47 AM, saito wrote:
    | > The tool to print the hierarchy is nice too.

    | proc ltree {{root .} {level 0}} { # list widget tree

    Awesome!

    R'
    --- Synchronet 3.21b-Linux NewsLink 1.2
  • From Luc@luc@sep.invalid to comp.lang.tcl on Tue Feb 17 18:19:17 2026
    From Newsgroup: comp.lang.tcl

    On Mon, 16 Feb 2026 13:23:49 -0800, et99 wrote:

    On 2/16/2026 11:47 AM, saito wrote:
    The tool to print the hierarchy is nice too.

    proc ltree {{root .} {level 0}} { # list widget tree

    **************************

    That reminds me of LemonTree by Richard Suchenwirth. It's in the wiki.
    --
    Luc


    --- Synchronet 3.21b-Linux NewsLink 1.2