On Mon, 2006-02-20 at 17:47 +0100, Mark Wielaard wrote: > On Mon, 2006-02-20 at 15:20 +0100, Roman Kennke wrote: > > > I don't see how/if 2) ever happens/should happen after a > > > Container.add(Component). The Container is invalid after an add(). > > > When/Where should validate[Tree]() be called after a new component has > > > been added? > > > > This is not performed automatically in AWT. We used to do it in > > setVisible somewhere if I remember correctly, but tests have shown that > > this is not right (and in fact leads to strange interactions with Swing, > > where we _do_ perform validation automatically). > > OK. Thanks. That probably explains why the delayed parenting and > realization did work in the past. > > > The GTK peers therefore > > should initialize correctly even when the component is not validated and > > not try to defer things. (Actually, the AWT itself defers initialization > > of the peers themselves, they are not created with the component, but > > instead when the component receives a call to addNotify). > > Yes. We do defer creation of the gtk-peer till the actual addNotify() > call. But then we also defer the parent/bound-setting if the container > is already visible till the container is actually made valid. This is at > least a problem with (sub) classes of Panel and Canvas where > applications seem to expect to be able to paint on them before they are > actually validated. This is a very strange requirement; they require the ability to draw on a Component that may not be sized correctly? Presumably that component will not be in that invalid state for long, and so will be repainted correctly when it is validated? > > Tom, do you have an example where the delayed realization of the gtk+ > component was necessary/gave strange visual effects? I like to get to > the bottom of this one. Yes, the problem was with adding a container of widgets to another already-showing container. Since we were force-realizing widgets on creation, each widget would be shown at 0,0 with size 1x1, then moved into place and resized upon validation. At the time there were bugs in the peer resizing code that made some widgets, including buttons, show up at their natural sizes. The result was that for a big button box in vte, you'd see all the buttons stack up at 0,0 at their natural sizes, then be moved and resized into the right spot. There are two cases that we must handle when adding a container to another container and both cases must be handled differently when implementing them on GTK: 1) the parent container is not showing 2) the parent container is showing For case 1 forced realization works fine because the widgets aren't actually shown until the parent is showing, and at that point everything is correctly laid out. For case 2 forced realization causes child components to be shown as soon as their peers are created. Container.validateTree does this: ContainerPeer.beginValidate() create peers for all child components in this container do layout, setting the child component and child component peers' bounds validate child containers recursively ContainerPeer.endValidate() With forced realization all the peers are shown when they are first created, *then* moved and resized when layout is called. This was a bug in our AWT implementation which didn't affect other peer sets. In an attempt to solve this, and to be more in-line with GTK conventions, I eliminated forced realization. The idea is that widgets should be realized when GTK decides to realize them: after they've been properly sized and parented. So with the current code, I leave realization up to GTK and I only set bounds and parents on the peer side after all the AWT validation has occurred, in GtkContainerPeer.endValidate(). Unfortunately, as Mark points out, this approach relies on validation to occur before getGraphics is called on a component, which (apparently) isn't guaranteed. In fact, getGraphics must work as soon as addNotify has been called on it which can happen anytime independent of validation. So delayed realization is unworkable and we should change back to forced-realization. Maybe we can solve the original problem using gtk_widget_show/gtk_widget_hide. I wonder how other toolkits (e.g. Sun's Motif implementation) solve this validate-while-showing problem. Perhaps it's not worth worrying about at this point (though I find validating-while-showing very sloppy). Tom