GtkComponentPeer realization

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [Linux Kernel]     [Linux Cryptography]     [Fedora]     [Fedora Directory]     [Red Hat Development]

  Powered by Linux