This is the mail archive of the java@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Bug (possibly only with xlib, but I doubt it): addNotifynotalways called for AWT components


I tried the test again with the "merge from java-gui-20050128-branch to
trunk" code (main branch from 2005-02-17), with both xlib and gtk.

Running the GTK version, I now get almost the same problem I had before with
xlib - addNotify doesn't get called for the second and subsequent Component
added to the CardLayout.  For some reason, with GTK, the things still paint
properly.  I don't understand that, because they have isLightWeight()=false,
so you'd think they'd be treated as heavyweights, sending a paint event to
the peer rather than painting on the parent container.  Since the peer is
only created from addNotify, there shouldn't be a peer, so like I say,
I don't see why it works.

It seems to me that there are two possible explanations for these symptoms:
either there's a bug in the addNotify thing, but GTK peers somehow work
around it, or XLIB peers are supposed to somehow work even if
addNotify isn't called.

What am I missing?

The xlib side needs some work, as events don't go where they're supposed to
at the moment.  I have a partial fix for that, but it's not right yet.  FYI:
the partial fix consists of getting XToolkit.iterateNativeQueue to
return when an event comes in, rather than continuing to loop.  At
the moment, I'm finding that XEventLoop deadlocks when I call an
event-posting Component method from the timer run function.  I am
wondering if iterateNativeQueue is supposed to return after a little
while even if there are no native events.

----- Original Message ----- 
From: "Thomas Fitzsimmons" <fitzsim@redhat.com>
To: "Scott Gilbertson" <scottg@mantatest.com>
Cc: <java@gcc.gnu.org>
Sent: Wednesday, January 26, 2005 10:01 AM
Subject: Re: Bug (possibly only with xlib, but I doubt it):
addNotifynotalways called for AWT components


> On Tue, 2005-25-01 at 19:45 -0500, Scott Gilbertson wrote:
> > Thanks for looking at the problem, Tom.
> >
> > > > I found that addNotify isn't called for components under the
following
> > > > conditions:
> > > >   - The component is lightweight AWT
> > > > ...
> > > This is probably caused by changes I made to the order in which
> > > components are shown when added to an already-showing container.
These
> > > changes were necessary to prevent GTK widgets from being shown before
> > > they were properly sized and positioned.  I've attached the relevant
> > > patches to Container.java and GtkContainerPeer.java.  You'll probably
> > > need to make a similar change in the xlib container peer.
> >
> > I kind of get it, but I don't actually see how addNotify (hence
> > Toolkit.createComponent) gets called for a lightweight added to a
Container
> > which has already been displayed.  That would require invalidate() to be
> > called for the Container, so it will do something useful in its
validateTree
> > method.  I haven't been able to see how your GtkContainerPeer patch does
> > that.  What am I missing?
> >
> > > I tried your test on the GTK peers on the java-gui-branch and it works
> > > fine.
> >
> > Does it say " - I can fix that, by calling addNotify()" on stdout?
> > If so, it's not working fine - the app shouldn't have to call addNotify.
> >
>
> I commented out this line:
>
>         cards[activeCard].addNotify ();  // THE PROBLEM: without this
call, the thing doesn't work
>
> and the test looped through showing the cards one by one.  Is that the
> expected behaviour?
>
> I know there are still problems with the display of lightweight
> components in the Acunia tests, though, so there are definitely bugs in
> this area.  Maybe I'm missing something, but it would be better if the
> test case were more minimal (then we could add it to Mauve -- see
> gnu/testlet/java/awt/Robot for other examples of Mauve automated GUI
> tests).
>
> Tom
>
> > ----- Original Message ----- 
> > From: "Thomas Fitzsimmons" <fitzsim@redhat.com>
> > To: "Scott Gilbertson" <scottg@mantatest.com>
> > Cc: <java@gcc.gnu.org>
> > Sent: Tuesday, January 25, 2005 4:03 PM
> > Subject: Re: Bug (possibly only with xlib, but I doubt it): addNotify
> > notalways called for AWT components
> >
> >
> > > On Fri, 2005-01-21 at 18:45 -0500, Scott Gilbertson wrote:
> > > > I have narrowed down the problem in my earlier posting ("AWT app not
> > working
> > > > with latest from cvs, seems to be CardLayout problem").  In my big
> > > > application, some components under a CardLayout were not being
> > displayed.
> > > > The attached code illustrates the problem.
> > > >
> > > > With my old gcc, which was "gcc (GCC) 3.5.0 20040603
(experimental)", on
> > > > linux/x86, the program works OK.  With a recent main branch checkout
> > from
> > > > cvs, called "gcc (GCC) 4.0.0 20050108 (experimental)", I had to add
the
> > > > addNotify call you'll see in there.  I'm using the xlib peers, but I
> > suspect
> > > > the problem will occur with other peers as well.
> > > >
> > > > I found that addNotify isn't called for components under the
following
> > > > conditions:
> > > >   - The component is lightweight AWT
> > > >   - The component is added to a container with a CardLayout
> > > >      (I'm not sure that it has to be CardLayout, but that's what my
app
> > was
> > > > doing)
> > > >   - The container has already been shown on-screen before this
component
> > is
> > > > added.
> > > > That last one's the crux of the thing, I think.  It seems like in
> > Container,
> > > > invalidateTree should clear the valid flag, but it doesn't, so
> > validateTree
> > > > only works the first time it's called, and components added after
that
> > don't
> > > > get an addNotify call.  Since addNotify isn't called, the
component's
> > peer
> > > > is null, and isLightweight returns false, which essentially stops
the
> > > > component from painting.
> > > >
> > > > Would somebody familiar with the validateTree, invalidateTree and
add
> > > > methods in Container be able to take a look?
> > >
> > > This is probably caused by changes I made to the order in which
> > > components are shown when added to an already-showing container.
These
> > > changes were necessary to prevent GTK widgets from being shown before
> > > they were properly sized and positioned.  I've attached the relevant
> > > patches to Container.java and GtkContainerPeer.java.  You'll probably
> > > need to make a similar change in the xlib container peer.
> > >
> > > I tried your test on the GTK peers on the java-gui-branch and it works
> > > fine.
> > >
> > > Hope this helps,
> > > Tom
> > >
> > > --- gnu/java/awt/peer/gtk/GtkContainerPeer.java 6 Jul 2004 14:55:50
> > > -0000 1.8.2.4
> > > +++ gnu/java/awt/peer/gtk/GtkContainerPeer.java 7 Oct 2004 22:08:18
> > > -0000
> > > @@ -45,13 +45,16 @@
> > >  import java.awt.Font;
> > >  import java.awt.Graphics;
> > >  import java.awt.Insets;
> > > +import java.awt.Window;
> > >  import java.awt.event.PaintEvent;
> > > +import java.awt.peer.ComponentPeer;
> > >  import java.awt.peer.ContainerPeer;
> > >
> > >  public class GtkContainerPeer extends GtkComponentPeer
> > >    implements ContainerPeer
> > >  {
> > >    Container c;
> > > +  boolean isValidating;
> > >
> > >    public GtkContainerPeer(Container c)
> > >    {
> > > @@ -59,22 +62,36 @@
> > >      this.c = c;
> > >    }
> > >
> > > -  public void beginValidate()
> > > +  public void beginValidate ()
> > >    {
> > > +    isValidating = true;
> > >    }
> > >
> > > -  public void endValidate()
> > > +  public void endValidate ()
> > >    {
> > > -//      q.postEvent (new PaintEvent (awtComponent, PaintEvent.PAINT,
> > > -//  new Rectangle (x, y, width, height)));
> > > -//      Graphics gc = getGraphics ();
> > > -//      if (gc != null)
> > > -//        {
> > > -//  awtComponent.update (gc);
> > > -//  gc.dispose ();
> > > -//        }
> > > -//      System.out.println ("got here");
> > > -//      awtComponent.repaint ();
> > > +    Component parent = awtComponent.getParent ();
> > > +
> > > +    // Only set our parent on the GTK side if our parent on the AWT
> > > +    // side is not showing.  Otherwise the gtk peer will be shown
> > > +    // before we've had a chance to position and size it properly.
> > > +    if (parent != null && parent.isShowing ())
> > > +      {
> > > +        Component[] components = ((Container)
> > > awtComponent).getComponents ();
> > > +        int ncomponents = components.length;
> > > +
> > > +        for (int i = 0; i < ncomponents; i++)
> > > +          {
> > > +            ComponentPeer peer = components[i].getPeer ();
> > > +
> > > +            // Skip lightweight peers.
> > > +            if (peer instanceof GtkComponentPeer)
> > > +              ((GtkComponentPeer) peer).setParentAndBounds ();
> > > +          }
> > > +
> > > +        setParentAndBounds ();
> > > +      }
> > > +
> > > +    isValidating = false;
> > >    }
> > >
> > >    public Insets getInsets()
> > > --- java/awt/Container.java 27 Sep 2004 15:14:25 -0000 1.34.2.21
> > > +++ java/awt/Container.java 7 Oct 2004 22:08:18 -0000
> > > @@ -42,6 +42,8 @@
> > >  import java.awt.event.ContainerListener;
> > >  import java.awt.event.KeyEvent;
> > >  import java.awt.event.MouseEvent;
> > > +import java.awt.event.KeyEvent;
> > > +import java.awt.peer.ComponentPeer;
> > >  import java.awt.peer.ContainerPeer;
> > >  import java.awt.peer.LightweightPeer;
> > >  import java.beans.PropertyChangeListener;
> > > @@ -340,8 +342,6 @@
> > >          comp.parent = this;
> > >          if (peer != null)
> > >            {
> > > -            comp.addNotify();
> > > -
> > >              if (comp.isLightweight ())
> > >         {
> > >   enableEvents (comp.eventMask);
> > > @@ -555,10 +555,19 @@
> > >          cPeer.beginValidate();
> > >        }
> > >
> > > -    doLayout();
> > >      for (int i = 0; i < ncomponents; ++i)
> > >        {
> > >          Component comp = component[i];
> > > +
> > > +        if (comp.getPeer () == null)
> > > +          comp.addNotify();
> > > +      }
> > > +
> > > +    doLayout ();
> > > +    for (int i = 0; i < ncomponents; ++i)
> > > +      {
> > > +        Component comp = component[i];
> > > +
> > >          if (! comp.isValid())
> > >            {
> > >              if (comp instanceof Container)
> > >
> > >
> >
> -- 
> Thomas Fitzsimmons <fitzsim@redhat.com>
>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]