Hi Tom,

On Mon, 2006-02-20 at 15:50 -0500, Thomas Fitzsimmons wrote:
> On Mon, 2006-02-20 at 17:47 +0100, Mark Wielaard wrote:
> > 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?

I am not sure it is an requirement. But there are clearly programs that
call paint(), update() and/or getGraphics() on Components at the
weirdest times.

> > 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.
>
> 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.

OK, I did this and I tried to make the impact as little as possible.
This patch handles the most common case where the Component bounds have
not been set yet (so are zero) then it wont show the component yet. This
doesn't solve all the cases as seen with vte when a Component is set to
a particular size before being added though. (It does solve one other
issue I was seeing where my app was "hiding" an Component by setting its
size to 0, previously we would ignore such a reshape call...)

I think this is the best we can do for now without doing something much
more tricky such hooking into things like endLayout which we don't
currently seem to support anyway. And it solve the crashes I was seeing
which I think is a more important issue then the "jumping components"
problem.

2006-03-03  Mark Wielaard  <[EMAIL PROTECTED]>

    * gnu/java/awt/peer/gtk/GtkComponentPeer.java (GtkComponentPeer):
    Always call setParentAndBounds().
    (setComponentBounds): Always call setBounds().
    (setBounds): Call setVisible().
    (setVisible): If no pixels are showing then don't make it visible.
    * gnu/java/awt/peer/gtk/GtkContainerPeer.java (endValidate): No need
    to call setParentAndBounds() anymore.

What do you think?
The hsqldb, VTE and MegaMek seem to look and work fine with this.

Cheers,

Mark
Index: gnu/java/awt/peer/gtk/GtkComponentPeer.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/java/awt/peer/gtk/GtkComponentPeer.java,v
retrieving revision 1.106
diff -u -r1.106 GtkComponentPeer.java
--- gnu/java/awt/peer/gtk/GtkComponentPeer.java	23 Feb 2006 19:22:24 -0000	1.106
+++ gnu/java/awt/peer/gtk/GtkComponentPeer.java	3 Mar 2006 20:05:56 -0000
@@ -145,12 +145,7 @@
 
     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 (awtComponent instanceof Window
-        || (parent != null && ! parent.isShowing ()))
-      setParentAndBounds ();
+    setParentAndBounds ();
 
     setNativeEventMask ();
 
@@ -201,11 +196,6 @@
   void setComponentBounds ()
   {
     Rectangle bounds = awtComponent.getBounds ();
-
-    if (bounds.x == 0 && bounds.y == 0
-        && bounds.width == 0 && bounds.height == 0)
-      return;
-
     setBounds (bounds.x, bounds.y, bounds.width, bounds.height);
   }
 
@@ -487,6 +477,10 @@
       }
 
     setNativeBounds (new_x, new_y, width, height);
+
+    // If the height or width were (or are now) smaller than zero
+    // then we want to adjust the visibility.
+    setVisible(awtComponent.isVisible());
   }
 
   void setCursor ()
@@ -537,6 +531,13 @@
 
   public void setVisible (boolean b)
   {
+    // Only really set visible when component is bigger than zero pixels.
+    if (b)
+      {
+        Rectangle bounds = awtComponent.getBounds();
+	b = (bounds.width > 0) && (bounds.height > 0);
+      }
+
     if (Thread.currentThread() == GtkToolkit.mainThread)
       setVisibleNativeUnlocked (b);
     else
Index: gnu/java/awt/peer/gtk/GtkContainerPeer.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/java/awt/peer/gtk/GtkContainerPeer.java,v
retrieving revision 1.33
diff -u -r1.33 GtkContainerPeer.java
--- gnu/java/awt/peer/gtk/GtkContainerPeer.java	19 Feb 2006 22:32:45 -0000	1.33
+++ gnu/java/awt/peer/gtk/GtkContainerPeer.java	3 Mar 2006 20:05:56 -0000
@@ -65,32 +65,6 @@
 
   public void endValidate ()
   {
-    Component parent = awtComponent.getParent ();
-
-    // We only set our parent on the GTK side if our parent on the AWT
-    // side is not showing in the constuctor.  Otherwise the gtk peer will
-    // be shown  before we've had a chance to position and size it properly.
-    // So we set it here at the end of validation.
-    if ((parent != null && parent.isShowing())
-	|| (awtComponent instanceof Window
-	    && ((Window) awtComponent).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 ();
-          }
-
-        // GTK windows don't have parents.
-        if (!(awtComponent instanceof Window))
-          setParentAndBounds ();
-      }
   }
 
   public Insets getInsets() 

Attachment: signature.asc
Description: This is a digitally signed message part

Reply via email to