This is the mail archive of the
java@gcc.gnu.org
mailing list for the Java project.
Re: Bug (possibly only with xlib, but I doubt it): addNotifynotalways called for AWT components
- From: "Scott Gilbertson" <scottg at mantatest dot com>
- To: "Thomas Fitzsimmons" <fitzsim at redhat dot com>
- Cc: <java at gcc dot gnu dot org>
- Date: Fri, 25 Feb 2005 15:19:11 -0500
- Subject: Re: Bug (possibly only with xlib, but I doubt it): addNotifynotalways called for AWT components
- References: <16bd01c50013$5aa182c0$3c16a8c0@mantatest.com> <1106687016.26208.188.camel@tortoise.toronto.redhat.com> <300901c50340$60ed93a0$3c16a8c0@mantatest.com> <1106751708.2858.11.camel@localhost.localdomain>
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>
>