On Tue, 2006-02-21 at 10:28 -0500, Lillian Angel wrote:
> Hello,
> 
> Tom F. and I worked on changing how we handle Container lightweights and
> Component lightweights. This bug showed up in MegaMek and several test
> cases. It appeared that Containers should be handled differently.
> 
> When a Container was placed in a Window, and contained Heavyweight
> components, the location of the components were always being set at
> (0,0), relative to the Window. This is because the components were not
> aware of the bounds of the Container. Now, GtkLightweightPeer is similar
> to a GtkPanelPeer.
> 
> GtkLightweightPeer extends GtkContainerPeer. This fixes the problem. We
> discovered that we could not completely get rid of GLightweightPeer
> because Components still depended on its constructor.
> 
> I tested this with the swing demo and MegaMek. The painting seems to
> work fine still... 
> 
> Feel free to give me feedback before I commit this.

I'll provide background as to why this change makes sense.

Some AWT applications pack heavyweight components in lightweight
containers.  MegaMek is one such application but we've seen other
examples.  For a heavyweight component packed in a lightweight
container, the native peers are missing offset information about that
heavyweight's peer's location, because the native peers have no
knowledge of the lightweight container.

For example:

(0, 0)  ---------------------------------------------
        |  HW CONTAINER                             |
        |                                           |
        |     (40, 10) ---------------------------- |
        |              | LW CONTAINER             | |
        |              |  (20, 15)  ------------- | |
        |              |            | HW BUTTON | | |
        |              |            ------------- | |
        |              ---------------------------- |
        ---------------------------------------------

This case isn't handled correctly by our GTK peers currently.  The
button will be displayed at 20, 15 in the heavyweight container, because
GTK has no knowledge of the lightweight container.  To address this,
Lillian's patch peers the lightweight container to a windowless
GtkFixed.  Because the GtkFixed is windowless it provides exactly what
is needed and nothing more: it gives GTK information about the location
and size of the lightweight container, and does not add a new screen
resource to every lightweight container.

The advantage of this approach is that it eliminates any special casing
we need to do in ComponentPeer.setBounds.  Previously we were handling
this case in the GTK peers by climbing the component hierarchy in
GtkComponentPeer.setBounds, accounting for any lightweight ancestors'
coordinates but this code was fragile and buggy.

Note that GLightweightPeer is still needed for lightweight components
that are not containers.  Lightweight components truly need no native
representation because they cannot contain other heavyweights.
GLightweightPeer should probably be renamed to LightweightComponentPeer
though, and GtkLightweightPeer should be GtkLightweightContainerPeer.

The patch as-posted is not complete.  We need to change
GtkLightweightContainerPeer so that it is more like
LightweightComponentPeer -- for example, it should never call paint on
its awtComponent.

At this point I'm more concerned that people critique the approach to
solving the heavyweight-in-lightweight-container problem rather than the
patch-as-posted.

Comments?
Tom



Reply via email to