Hello,

Our original idea of changing GLightweightPeer and creating a new class,
GtkLightweightContainerPeer, has failed. Ultimately, we came up with a
simpler solution that fixes our problem- and does not break anything
else.

* What was changed:
- I applied Scott Gilbertson's patch, it is included.
- setBounds in GtkComponentPeer was fixed, so that the offsets for all
components were adjusted appropriately, by checking all component's
parents. We had been skipping the component's immediate parent, and then
adjusting its location. This is fixed to set the location of the
component by using its parent's location (and its grandparent.. etc).
Also, the location of the component should always be adjusted if there
is a menu bar, there should be no boolean check to prevent this.
- reshape in Component was fixed. invalidate() was only being called on
the component if it has moved or has been resized. But the problem is
that a component could be moved, because its parent moved, and the
component would not know about it. 
invalidate() should always be called on the component when reshape (or
setBounds) is called. This way, all components are invalidated, in case
they have been moved or resized because of their parent.

* We struggled with a few ideas on how to fix this, but this seemed to
be the most fool-proof, simplest fix. Other than this fix, we thought
about:
-> Lighweight Container Peers: Changing the way we handled Lightweight
Container peers, relative to Lightweight Component peers. We could give
the lightweight container peer a backing widget to track its bounds and
location, but it would still be lightweight because it did not allocate
screen resources. This _did_ fix our problem, but it caused an annoying
paint problem with Swing. The painting in swing was not reliable and it
began to flicker because too many calls to setVisible. setVisible caused
show() to be called in GtkComponentPeer, which caused Swing to paint too
often. We should be able to call setVisible (show/hide) as many times as
we want, without any side-effects (like Sun)... though it does not make
that much sense to do so. The GLightweightPeer's show/hide
implementation did nothing, so this was not a problem before. This would
have been the cleanest (and best) fix, but it just didn't work :(
-> Creating a Listener: We could have created a listener for the
component's parent that had a peer which was lightweight. This would
have been an package-private inner class in Component that was
initialized from addNotify. It would act as a ComponentListener and a
ContainerListener for the parent whose peer was lightweight. For
instance, when show/hide were called, the listener would perform
show/hide code on the parent. If the parent was resized, then the
listener would call setBounds on the parent using the updated location
and size. This would work, but it may have cause asynchronous behaviour
with all the listeners and components. In the long term, possibly
causing race conditions that would be hard to track later. 

Your feedback is welcome. This patch has been committed.
Thanks everyone for you input and help.

2006-02-23  Lillian Angel  <[EMAIL PROTECTED]>

        * gnu/java/awt/peer/GLightweightPeer.java
        (repaint): Scott's proposed fix. Send repaint to the
        component's parent.
        * gnu/java/awt/peer/gtk/GtkComponentPeer.java
        (setBounds): Removed next_parent, not needed. Removed
        lightweightChild, we always need to compensate for the
        menu bar's height.
        * java/awt/Component.java
        (reshape): Removed check. Caused lots of problems, because 
        some components were not being invalidated. Components should be
        invalidated when they are resized or moved, and in some cases,
        when a parent is resized/moved, the components do not know
        about it and do not adjust.
        * java/awt/Graphics.java
        (hitClip): Scott's proposed fix. Added check to handle a
        null clip.



On Wed, 2006-02-22 at 15:11 -0500, Scott Gilbertson wrote:
> > I agree with Scott that we need to add a LightweightContainerPeer class.
> > I fixed up Toolkit, as well.
> >  I also added the painting methods to GtkLightweightContainerPeer (those
> > that override ComponentPeer).
> >
> > This is the updated ChangeLog. The newest patch is attached.
> >
> > 2006-02-22  Lillian Angel  <[EMAIL PROTECTED]>
> > ...
> 
> I can't really comment on the GTK-specific parts, but I like the rest,
> assuming it all works (which I think it will).
> 
> It should now run the attached program properly.  Running that program, you
> should see a yellow box moving along, once per second, with the label text
> under the box changing each time.  It stops after about 10 seconds.  The
> program creates lightweight Components that aren't Containers, and uses the
> individual Component's repaint method rather than repainting the Container.
> It doesn't paint unless you resize the Frame or whatever, using the latest
> Classpath code from CVS.
Index: gnu/java/awt/peer/GLightweightPeer.java
===================================================================
RCS file: /sources/classpath/classpath/gnu/java/awt/peer/GLightweightPeer.java,v
retrieving revision 1.6
diff -u -r1.6 GLightweightPeer.java
--- gnu/java/awt/peer/GLightweightPeer.java	19 Aug 2005 01:29:26 -0000	1.6
+++ gnu/java/awt/peer/GLightweightPeer.java	23 Feb 2006 19:13:14 -0000
@@ -227,7 +227,12 @@
 
   public void print(Graphics graphics) {}
 
-  public void repaint(long tm, int x, int y, int width, int height) {}
+  public void repaint(long tm, int x, int y, int width, int height)
+  {
+    Component p = comp.getParent();
+    if (p != null)
+      p.repaint(tm, x + comp.getX(), y + comp.getY(), width, height);
+  }
 
   public void requestFocus() {}
 
Index: gnu/java/awt/peer/gtk/GtkComponentPeer.java
===================================================================
RCS file: /sources/classpath/classpath/gnu/java/awt/peer/gtk/GtkComponentPeer.java,v
retrieving revision 1.105
diff -u -r1.105 GtkComponentPeer.java
--- gnu/java/awt/peer/gtk/GtkComponentPeer.java	17 Feb 2006 19:53:06 -0000	1.105
+++ gnu/java/awt/peer/gtk/GtkComponentPeer.java	23 Feb 2006 19:13:14 -0000
@@ -445,8 +447,7 @@
     int new_y = y;
 
     Component parent = awtComponent.getParent ();
-    Component next_parent;
-
+    
     // Heavyweight components that are children of one or more
     // lightweight containers have to be handled specially.  Because
     // calls to GLightweightPeer.setBounds do nothing, GTK has no
@@ -457,24 +458,19 @@
     // so we need to continue adding offsets until we reach a
     // container whose position GTK knows -- that is, the first
     // non-lightweight.
-    boolean lightweightChild = false;
-    Insets i;
+    Insets i;    
     while (parent.isLightweight())
       {
-        lightweightChild = true;
-
-        next_parent = parent.getParent();
-
         i = ((Container) parent).getInsets();
+        
         new_x += parent.getX() + i.left;
         new_y += parent.getY() + i.top;
-
-        parent = next_parent;
+        
+        parent = parent.getParent();
       }
-
     // We only need to convert from Java to GTK coordinates if we're
     // placing a heavyweight component in a Window.
-    if (parent instanceof Window && !lightweightChild)
+    if (parent instanceof Window)
       {
         GtkWindowPeer peer = (GtkWindowPeer) parent.getPeer ();
         // important: we want the window peer's insets here, not the
@@ -486,9 +482,10 @@
         int menuBarHeight = 0;
         if (peer instanceof GtkFramePeer)
           menuBarHeight = ((GtkFramePeer) peer).getMenuBarHeight ();
-
-        new_x = x - insets.left;
-        new_y = y - insets.top + menuBarHeight;
+        
+        new_x -= insets.left;
+        new_y -= insets.top;
+        new_y += menuBarHeight;
       }
 
     setNativeBounds (new_x, new_y, width, height);
Index: java/awt/Component.java
===================================================================
RCS file: /sources/classpath/classpath/java/awt/Component.java,v
retrieving revision 1.101
diff -u -r1.101 Component.java
--- java/awt/Component.java	21 Feb 2006 16:37:30 -0000	1.101
+++ java/awt/Component.java	23 Feb 2006 19:13:14 -0000
@@ -1390,18 +1392,16 @@
     int oldy = this.y;
     int oldwidth = this.width;
     int oldheight = this.height;
-
-    if (this.x == x && this.y == y
-        && this.width == width && this.height == height)
-      return;
-    invalidate ();
+    
+   invalidate ();
+    
     this.x = x;
     this.y = y;
     this.width = width;
     this.height = height;
     if (peer != null)
       peer.setBounds (x, y, width, height);
-
+    
     // Erase old bounds and repaint new bounds for lightweights.
     if (isLightweight() && isShowing())
       {
Index: java/awt/Graphics.java
===================================================================
RCS file: /sources/classpath/classpath/java/awt/Graphics.java,v
retrieving revision 1.15
diff -u -r1.15 Graphics.java
--- java/awt/Graphics.java	10 Oct 2005 12:18:05 -0000	1.15
+++ java/awt/Graphics.java	23 Feb 2006 19:13:14 -0000
@@ -617,6 +617,9 @@
    */
   public boolean hitClip(int x, int y, int width, int height)
   {
+    Shape clip = getClip();
+    if (clip == null)
+      return true;
     return getClip().intersects(x, y, width, height);
   }
 

Reply via email to