
agree @alexharsanyi when I add two buttons to the container, place-children
has only one item and it fires another error container-redraw: result from place-children is not a list of length 1 (matching the input list length) whose elements are lists of length 4 of exact integers
result: '((0 0 0 0) (0 0 0 0))
context...:

place-children
must return a list containing as many elements as there are in its items
parameter passed to it. Also, by using (0 0 0 0)
you place all the widgets in the top left corner of the control and make them 0 width and 0 length, so they would not be visible.
What I think is happening in your code is that you show the frame too early, and place-children
is invoked as soon as you add the first control (when there is one widget in the control). It will also immediately invoked after you add the second one, with two elements this time, since there are now two controls.
You can move the (send frame show #)
call after you add all items, so place-children
is called only once, but in general your place-children
implementation must not assume how many items are in the container and instead rely on the information that it is passed to it.

Bingo @alexharsanyi ty! I moved the frame show to later in the sequence and it worked.
I did set (0, 0, 0, 0) intentionally expecting buttons to not appear. However, what I get is:

if I add pixels to the position it will move vertically but not horizontally. Additionally, the actual sizes dont stick.

It does appear to work though, for example: (define/override (place-children info width height)
(list (list 0 0 0 0) (list 100 50 0 0))
)
does what you would expect. I think there must be some default padding on the pane in the frame.

Each widget has its min-width
and max-width
parameters, defining the minimum sizes of each widget. They also have a strethable-width?
and stretchable-height?
parameters which specify whether they are allowed to use more space than their minimum. The container should take this information into account when it calculates its own size and when it calculates the placement of the child items, otherwise the results are unspecified and I also suspect they will be platform specific….
Note that this information is passed in as the items
parameter to the place-children
and container-size
methods…

Got it. So may very well be macOS issue I can’t reduce size of button. Setting min-width and 0 in place-children or say 10 has no effect. Also, I can’t seem to get rid of this default padding on the pane/frame that is preventing the bottom from being at 0,0

What happens if you create the button like so: (new button% [label "Test"] [parent p] [min-width 10])
?

(define frame (new frame%
[label "Example"]
[width 600]
[height 400]
))
(define grid1 (new grid-pane% [parent frame] [horiz-margin 0] [alignment '(left top)]))
(define btn1 (new button% [parent grid1] [label "test1"] [min-width 10] [horiz-margin 0]))
(define btn2 (new button% [parent grid1] [label "test2"] [min-width 100]))
(new button% [label "Test3"] [parent grid1] [min-width 10])
(send frame show #t)

using (define/override (place-children info width height)
(list (list 0 0 40 0) (list 100 50 200 0) (list 200 100 10 0))
)

I had a look through the racket gui source code and it looks like, when widgets are resized, they also take into consideration the font and other things, presumably so they look acceptable even when the user supplied unrealistic values.
So, while you can write a custom panel to arrange items, and there is some flexibility in doing that, it is not possible to have absolute control over every aspect of the widget placement. Or at least I don’t know how to do that…

@andrew_8 has joined the channel

ty! I think I see it (define MIN-BUTTON-WIDTH 72)
thanks for the help here. This gave me a great starting point.