GtkComponentPeer.java (insets): New field.
authorThomas Fitzsimmons <fitzsim@redhat.com>
Thu, 2 Oct 2003 18:34:56 +0000 (18:34 +0000)
committerThomas Fitzsimmons <fitzsim@gcc.gnu.org>
Thu, 2 Oct 2003 18:34:56 +0000 (18:34 +0000)
2003-10-02  Thomas Fitzsimmons  <fitzsim@redhat.com>

* gnu/java/awt/peer/gtk/GtkComponentPeer.java (insets): New
field.
(initializeInsets): New method.
(GtkComponentPeer): Call initializeInsets.  Call setCursor and
setBounds unconditionally.
(setBounds): Convert coordinates if parent is a Window.
* gnu/java/awt/peer/gtk/GtkContainerPeer.java (insets): Move
field to GtkComponentPeer.
(GtkContainerPeer): Don't initialize insets.
* gnu/java/awt/peer/gtk/GtkDialogPeer.java (initializeInsets):
New method.
(create): Call new GtkWindowPeer create method.
* gnu/java/awt/peer/gtk/GtkFramePeer.java (initializeInsets):
New method.
(create): Call new GtkWindowPeer create method.
(setBounds): Remove method.
(postConfigureEvent): Likewise.
* gnu/java/awt/peer/gtk/GtkWindowPeer.java: Replace GTK window
type constants with GDK window type constants.
(create(int,boolean,int,int,GtkWindowPeer)): New method.
(create(int,boolean)): Likewise.
(create()): Call create(int,boolean).
(nativeSetBounds): New native method declaration.
(setBounds): Call native method declaration.
(setSize): New native method declaration.
(setBoundsCallback): Likewise.
(postConfigureEvent): Handle change in insets.  Call setSize and
setBoundsCallback methods.
* java/awt/Window.java (Window): Set visible to false.
(setBoundsCallback): New method.
* jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c
(gtkWidgetGetLocationOnScreen): If this component is not a
container, adjust the location returned based on the peer's
allocation.
(set(String,boolean)): Revert change from 2003-09-19.
* jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.c
(awt_event_handler): Fix inset calculation.
* jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMainThread.c: Add JNI
glue for Window.setBoundsCallback.
* jni/gtk-peer/gnu_java_awt_peer_gtk_GtkWindowPeer.c (create):
Set up stacking order, window decorations and window manager
hints.
(setBoundsCallback): New method.
(setSize): New method.
(nativeSetBounds): New method.
* jni/gtk-peer/gtkpeer.h: Declare setBoundsCallbackID.

From-SVN: r72043

12 files changed:
libjava/ChangeLog
libjava/gnu/java/awt/peer/gtk/GtkComponentPeer.java
libjava/gnu/java/awt/peer/gtk/GtkContainerPeer.java
libjava/gnu/java/awt/peer/gtk/GtkDialogPeer.java
libjava/gnu/java/awt/peer/gtk/GtkFramePeer.java
libjava/gnu/java/awt/peer/gtk/GtkWindowPeer.java
libjava/java/awt/Window.java
libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c
libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.c
libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMainThread.c
libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkWindowPeer.c
libjava/jni/gtk-peer/gtkpeer.h

index d65c26acb4a3f7d5395260a834c862bcc066c59a..a5184f5a956ab784484a885f86421fed1cc902ec 100644 (file)
@@ -1,3 +1,52 @@
+2003-10-02  Thomas Fitzsimmons  <fitzsim@redhat.com>
+
+       * gnu/java/awt/peer/gtk/GtkComponentPeer.java (insets): New
+       field.
+       (initializeInsets): New method.
+       (GtkComponentPeer): Call initializeInsets.  Call setCursor and
+       setBounds unconditionally.
+       (setBounds): Convert coordinates if parent is a Window.
+       * gnu/java/awt/peer/gtk/GtkContainerPeer.java (insets): Move
+       field to GtkComponentPeer.
+       (GtkContainerPeer): Don't initialize insets.
+       * gnu/java/awt/peer/gtk/GtkDialogPeer.java (initializeInsets):
+       New method.
+       (create): Call new GtkWindowPeer create method.
+       * gnu/java/awt/peer/gtk/GtkFramePeer.java (initializeInsets):
+       New method.
+       (create): Call new GtkWindowPeer create method.
+       (setBounds): Remove method.
+       (postConfigureEvent): Likewise.
+       * gnu/java/awt/peer/gtk/GtkWindowPeer.java: Replace GTK window
+       type constants with GDK window type constants.
+       (create(int,boolean,int,int,GtkWindowPeer)): New method.
+       (create(int,boolean)): Likewise.
+       (create()): Call create(int,boolean).
+       (nativeSetBounds): New native method declaration.
+       (setBounds): Call native method declaration.
+       (setSize): New native method declaration.
+       (setBoundsCallback): Likewise.
+       (postConfigureEvent): Handle change in insets.  Call setSize and
+       setBoundsCallback methods.
+       * java/awt/Window.java (Window): Set visible to false.
+       (setBoundsCallback): New method.
+       * jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c
+       (gtkWidgetGetLocationOnScreen): If this component is not a
+       container, adjust the location returned based on the peer's
+       allocation.
+       (set(String,boolean)): Revert change from 2003-09-19.
+       * jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.c
+       (awt_event_handler): Fix inset calculation.
+       * jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMainThread.c: Add JNI
+       glue for Window.setBoundsCallback.
+       * jni/gtk-peer/gnu_java_awt_peer_gtk_GtkWindowPeer.c (create):
+       Set up stacking order, window decorations and window manager
+       hints.
+       (setBoundsCallback): New method.
+       (setSize): New method.
+       (nativeSetBounds): New method.
+       * jni/gtk-peer/gtkpeer.h: Declare setBoundsCallbackID.
+
 2003-10-02  Tom Tromey  <tromey@redhat.com>
 
        * java/lang/VMClassLoader.java (loadClass): Now native.
index ac092c8f4d152bf69cbb213d7193f5d5058c15f8..0f97d533cf76f6488561041f225668bf58178068 100644 (file)
@@ -72,6 +72,8 @@ public class GtkComponentPeer extends GtkGenericPeer
 {
   Component awtComponent;
 
+  Insets insets;
+
   /* this isEnabled differs from Component.isEnabled, in that it
      knows if a parent is disabled.  In that case Component.isEnabled 
      may return true, but our isEnabled will always return false */
@@ -90,6 +92,11 @@ public class GtkComponentPeer extends GtkGenericPeer
     throw new RuntimeException ();
   }
 
+  void initializeInsets ()
+  {
+    insets = new Insets (0, 0, 0, 0);
+  }
+
   native void connectHooks ();
 
   protected GtkComponentPeer (Component awtComponent)
@@ -115,13 +122,13 @@ public class GtkComponentPeer extends GtkGenericPeer
       //       c.setFont (cp.getFont ());
       if (awtComponent.getFont() != null)
        setFont(awtComponent.getFont());
-      
-      if (! (awtComponent instanceof Window))
-       {
-         setCursor (awtComponent.getCursor ());
-         Rectangle bounds = awtComponent.getBounds ();
-         setBounds (bounds.x, bounds.y, bounds.width, bounds.height);
-       }
+
+      initializeInsets ();
+
+      setCursor (awtComponent.getCursor ());
+      Rectangle bounds = awtComponent.getBounds ();
+      setBounds (bounds.x, bounds.y, bounds.width, bounds.height);
+
     } catch (RuntimeException ex) { ; }
   }
 
@@ -278,11 +285,11 @@ public class GtkComponentPeer extends GtkGenericPeer
   {
     Component parent = awtComponent.getParent ();
     
-    if (parent instanceof Frame)
+    if (parent instanceof Window)
       {
-       Insets insets = ((Frame)parent).getInsets ();
-       /* convert Java's coordinate space into GTK+'s coordinate space */
-       setNativeBounds (x-insets.left, y-insets.top, width, height);
+       Insets insets = ((Window) parent).getInsets ();
+       // Convert from Java coordinates to GTK coordinates.
+       setNativeBounds (x - insets.left, y - insets.top, width, height);
       }
     else
       setNativeBounds (x, y, width, height);
index 7e2c5492d29099ec0e6a9c2377348ed6e781cac4..5225ccc5f1433a918ecbb6c6d7b33add6431d73f 100644 (file)
@@ -48,14 +48,12 @@ import java.awt.peer.ContainerPeer;
 public class GtkContainerPeer extends GtkComponentPeer
   implements ContainerPeer
 {
-  Insets insets;
   Container c;
 
   public GtkContainerPeer(Container c)
   {
     super (c);
     this.c = c;
-    insets = new Insets (0, 0, 0, 0);
   }
 
   public void beginValidate() 
index 8c0f5ee510f95134a0273a93d4ae798938266e8d..e7b047ea2e2b9d3b320ca6f414b707e954beccf6 100644 (file)
@@ -41,6 +41,7 @@ package gnu.java.awt.peer.gtk;
 import java.awt.AWTEvent;
 import java.awt.Component;
 import java.awt.Dialog;
+import java.awt.Insets;
 import java.awt.peer.DialogPeer;
 
 public class GtkDialogPeer extends GtkWindowPeer
@@ -51,11 +52,19 @@ public class GtkDialogPeer extends GtkWindowPeer
     super (dialog);
   }
 
+  void initializeInsets ()
+  {
+    // Unfortunately, X does not provide a clean way to calculate the
+    // dimensions of a dialog's borders before it has been displayed.
+    // So we guess and then fix the dimensions upon receipt of the
+    // first configure event.
+    insets = new Insets (20, 6, 6, 6);
+  }
+
   void create ()
   {
-    create (GTK_WINDOW_TOPLEVEL,
-           awtComponent.getWidth(),
-           awtComponent.getHeight());
+    // Create a decorated dialog window.
+    create (GDK_WINDOW_TYPE_HINT_DIALOG, true);
   }
 
   public void getArgs (Component component, GtkArgList args)
index 043c08276db69b252b29337723f3af3c28416b7a..b44a02d13dbe2a7096c7b51278bd7b3e360b4cbd 100644 (file)
@@ -42,6 +42,7 @@ import java.awt.Component;
 import java.awt.Frame;
 import java.awt.Graphics;
 import java.awt.Image;
+import java.awt.Insets;
 import java.awt.MenuBar;
 import java.awt.Rectangle;
 import java.awt.event.PaintEvent;
@@ -69,9 +70,19 @@ public class GtkFramePeer extends GtkWindowPeer
     super (frame);
   }
 
+  void initializeInsets ()
+  {
+    // Unfortunately, X does not provide a clean way to calculate the
+    // dimensions of a frame's borders before it has been displayed.
+    // So we guess and then fix the dimensions upon receipt of the
+    // first configure event.
+    insets = new Insets (20, 6, 6, 6);
+  }
+
   void create ()
   {
-    create (GTK_WINDOW_TOPLEVEL);
+    // Create a normal decorated window.
+    create (GDK_WINDOW_TYPE_HINT_NORMAL, true);
   }
 
   public void getArgs (Component component, GtkArgList args)
@@ -97,26 +108,8 @@ public class GtkFramePeer extends GtkWindowPeer
     return g;
   }
 
-  public void setBounds (int x, int y, int width, int height)
-  {
-    super.setBounds (0, 0, width - insets.left - insets.right,
-                    height - insets.top - insets.bottom + menuBarHeight);
-  }
-
-  protected void postConfigureEvent (int x, int y, int width, int height,
-                                    int top, int left, int bottom, int right)
-  {
-    if (((Frame)awtComponent).getMenuBar () != null)
-      {
-       menuBarHeight = getMenuBarHeight ();
-       top += menuBarHeight;
-      }
-
-    super.postConfigureEvent (0, 0,
-                             width + left + right,
-                             height + top + bottom - menuBarHeight,
-                             top, left, bottom, right);
-  }
+  // FIXME: When MenuBars work, override postConfigureEvent and
+  // setBounds to account for MenuBar dimensions.
 
   protected void postMouseEvent(int id, long when, int mods, int x, int y, 
                                int clickCount, boolean popupTrigger)
@@ -128,8 +121,6 @@ public class GtkFramePeer extends GtkWindowPeer
 
   protected void postExposeEvent (int x, int y, int width, int height)
   {
-//      System.out.println ("x + insets.left:" + (x + insets.left));
-//      System.out.println ("y + insets.top :" + (y + insets.top));
     q.postEvent (new PaintEvent (awtComponent, PaintEvent.PAINT,
                                 new Rectangle (x + insets.left, 
                                                y + insets.top, 
index 08b2bf67e90d2fe62eb7ef80026fe7201053c205..be615042524d4c6819ce9aa54fecea57fbe6f563 100644 (file)
@@ -40,29 +40,43 @@ package gnu.java.awt.peer.gtk;
 
 import java.awt.Component;
 import java.awt.Dimension;
+import java.awt.Insets;
 import java.awt.Window;
 import java.awt.peer.WindowPeer;
 
 public class GtkWindowPeer extends GtkContainerPeer
   implements WindowPeer
 {
-  static protected final int GTK_WINDOW_TOPLEVEL = 0;
-  static protected final int GTK_WINDOW_POPUP = 1;
-
-  native void create (int type, int width, int height);
-
-  void create (int type)
+  static protected final int GDK_WINDOW_TYPE_HINT_NORMAL = 0;
+  static protected final int GDK_WINDOW_TYPE_HINT_DIALOG = 1;
+  static protected final int GDK_WINDOW_TYPE_HINT_MENU = 2;
+  static protected final int GDK_WINDOW_TYPE_HINT_TOOLBAR = 3;
+  static protected final int GDK_WINDOW_TYPE_HINT_SPLASHSCREEN = 4;
+  static protected final int GDK_WINDOW_TYPE_HINT_UTILITY = 5;
+  static protected final int GDK_WINDOW_TYPE_HINT_DOCK = 6;
+  static protected final int GDK_WINDOW_TYPE_HINT_DESKTOP = 7;
+
+  native void create (int type, boolean decorated,
+                     int width, int height,
+                     GtkWindowPeer parent);
+
+  void create (int type, boolean decorated)
   {
-    create (type,
+    GtkWindowPeer parent_peer = null;
+    Component parent = awtComponent.getParent();
+    if (parent != null)
+      parent_peer = (GtkWindowPeer) awtComponent.getParent().getPeer();
+
+    create (type, decorated,
            awtComponent.getWidth(),
-           awtComponent.getHeight());
+           awtComponent.getHeight(),
+           parent_peer);
   }
 
   void create ()
   {
-    create (GTK_WINDOW_POPUP,
-           awtComponent.getWidth(),
-           awtComponent.getHeight());
+    // Create a normal undecorated window.
+    create (GDK_WINDOW_TYPE_HINT_NORMAL, false);
   }
 
   native void connectHooks ();
@@ -81,7 +95,14 @@ public class GtkWindowPeer extends GtkContainerPeer
   native public void toBack ();
   native public void toFront ();
 
-  native public void setBounds (int x, int y, int width, int height);
+  native void nativeSetBounds (int x, int y, int width, int height);
+
+  public void setBounds (int x, int y, int width, int height)
+  {
+    nativeSetBounds (x, y,
+                    width - insets.left - insets.right,
+                    height - insets.top - insets.bottom);
+  }
 
   public void setTitle (String title)
   {
@@ -90,34 +111,82 @@ public class GtkWindowPeer extends GtkContainerPeer
 
   public void setResizable (boolean resizable)
   {
+    // Call setSize; otherwise when resizable is changed from true to
+    // false the window will shrink to the dimensions it had before it
+    // was resizable.
+    setSize (awtComponent.getWidth() - insets.left - insets.right,
+            awtComponent.getHeight() - insets.top - insets.bottom);
     set ("allow_shrink", resizable);
     set ("allow_grow", resizable);
   }
 
+  native void setSize (int width, int height);
+  native void setBoundsCallback (Window window,
+                                int x, int y,
+                                int width, int height);
+
   protected void postConfigureEvent (int x, int y, int width, int height,
                                     int top, int left, int bottom, int right)
   {
-    /* 
-       If our borders change (which often happens when we opaque resize),
-       we need to make sure that a new layout will happen, since Sun
-       forgets to handle this case.
-    */
+    // Configure events tell us the location and dimensions of the
+    // window within the frame borders, and the dimensions of the
+    // frame borders (top, left, bottom, right).
+
+    // If our borders change we need to make sure that a new layout
+    // will happen, since Sun forgets to handle this case.
     if (insets.top != top
        || insets.left != left
        || insets.bottom != bottom
        || insets.right != right)
       {
-       awtComponent.invalidate ();
+       // When our insets change, we receive a configure event with
+       // the new insets, the old window location and the old window
+       // dimensions.  We update our Window object's location and
+       // size using our old inset values.
+       setBoundsCallback ((Window) awtComponent,
+                          x - insets.left,
+                          y - insets.top,
+                          width + insets.left + insets.right,
+                          height + insets.top + insets.bottom);
+
+       // The peer's dimensions do not get updated automatically when
+       // insets change so we need to do it manually.
+       setSize (width + (insets.left - left) + (insets.right - right),
+                height + (insets.top - top) + (insets.bottom - bottom));
+
+       insets.top = top;
+       insets.left = left;
+       insets.bottom = bottom;
+       insets.right = right;
+
+       awtComponent.validate();
+      }
+    else
+      {
+       int frame_x = x - insets.left;
+       int frame_y = y - insets.top;
+       int frame_width = width + insets.left + insets.right;
+       int frame_height = height + insets.top + insets.bottom;
+
+       if (frame_x != awtComponent.getX()
+           || frame_y != awtComponent.getY()
+           || frame_width != awtComponent.getWidth()
+           || frame_height != awtComponent.getHeight())
+         {
+           setBoundsCallback ((Window) awtComponent,
+                              frame_x,
+                              frame_y,
+                              frame_width,
+                              frame_height);
+
+           if (frame_width != awtComponent.getWidth()
+               || frame_height != awtComponent.getHeight())
+             setSize (width, height);
+
+           awtComponent.validate();
+         }
       }
-    
-    insets.top = top;
-    insets.left = left;
-    insets.bottom = bottom;
-    insets.right = right;
-
-    awtComponent.setBounds (x, y, width, height);
-    awtComponent.validate ();
   }
-  
+
   native public void setVisible (boolean b);
 }
index 9f102751230c94d059744303e725f50737480314..3554bf5e581a610650fab367a8b95e65d9ab0e3d 100644 (file)
@@ -90,6 +90,7 @@ public class Window extends Container implements Accessible
    */
   Window()
   {
+    visible = false;
     setLayout(new BorderLayout());
   }
 
@@ -727,4 +728,28 @@ public class Window extends Container implements Accessible
   {
     this.focusableWindowState = focusableWindowState;
   }
+
+  // setBoundsCallback is needed so that when a user moves a window,
+  // the Window's location can be updated without calling the peer's
+  // setBounds method.  When a user moves a window the peer window's
+  // location is updated automatically and the windowing system sends
+  // a message back to the application informing it of its updated
+  // dimensions.  We must update the AWT Window class with these new
+  // dimensions.  But we don't want to call the peer's setBounds
+  // method, because the peer's dimensions have already been updated.
+  // (Under X, having this method prevents Configure event loops when
+  // moving windows: Component.setBounds -> peer.setBounds ->
+  // postConfigureEvent -> Component.setBounds -> ...  In some cases
+  // Configure event loops cause windows to jitter back and forth
+  // continuously).
+  void setBoundsCallback (int x, int y, int w, int h)
+  {
+    if (this.x == x && this.y == y && width == w && height == h)
+      return;
+    invalidate();
+    this.x = x;
+    this.y = y;
+    width = w;
+    height = h;
+  }
 }
index ed94b7d753928ff929ccc2e2682997bb368ca77a..455af68f2bc51a9cdfcaeac55ea9be1d83cb8ec3 100644 (file)
@@ -172,7 +172,15 @@ Java_gnu_java_awt_peer_gtk_GtkComponentPeer_gtkWidgetGetLocationOnScreen
   point = (*env)->GetIntArrayElements (env, jpoint, 0);
 
   gdk_threads_enter ();
+
   gdk_window_get_origin (GTK_WIDGET (ptr)->window, point, point+1);
+
+  if (!GTK_IS_CONTAINER (ptr))
+    {
+      *point += GTK_WIDGET(ptr)->allocation.x;
+      *(point+1) += GTK_WIDGET(ptr)->allocation.y;
+    }
+
   gdk_threads_leave ();
 
   (*env)->ReleaseIntArrayElements(env, jpoint, point, 0);
@@ -508,18 +516,14 @@ Java_gnu_java_awt_peer_gtk_GtkComponentPeer_set__Ljava_lang_String_2Ljava_lang_S
 }
 
 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkComponentPeer_set__Ljava_lang_String_2Z
-  (JNIEnv *env, jobject obj, jstring jname, jboolean jvalue)
+  (JNIEnv *env, jobject obj, jstring jname, jboolean value)
 {
   const char *name;
-  gboolean value;
   void *ptr;
 
   ptr = NSA_GET_PTR (env, obj);
 
   name = (*env)->GetStringUTFChars (env, jname, NULL);
-  /* Apparently a jboolean can have a value greater than 1.  gboolean
-     variables may only contain the value TRUE or FALSE. */
-  value = jvalue ? TRUE : FALSE;
 
   gdk_threads_enter();
   g_object_set(ptr, name, value, NULL);
index cdcd72e187cbc08e2ff29fb7b358d09169942f9e..481fadf9d7365b6ef448d9e3d7deaf582c7540d1 100644 (file)
@@ -981,31 +981,40 @@ awt_event_handler (GdkEvent *event)
            if (widget && GTK_WIDGET_TOPLEVEL (widget))
              {
                gint top, left, right, bottom;
-               gint x, y, w, h, wb, d;
+               gint x, y, w, h, d;
+               GdkRectangle r;
 
-               /* calculate our insets */
-               gdk_window_get_root_geometry (event->any.window, 
-                                             &x, &y, &w, &h, &wb, &d);
+               /* Configure events are not posted to the AWT event
+                  queue, and as such, the gdk/gtk peer functions will
+                  be called back before postConfigureEvent
+                  returns. */
+               gdk_threads_leave ();
 
-               /* We used to compute these based on the configure
-                  event's fields.  However, that gives strange and
-                  apparently incorrect results.  */
-               top = left = bottom = right = 0;
+               /* Calculate our insets. */
 
-               /* configure events are not posted to the AWT event queue,
-                  and as such, gdk/gtk will be called back before
-                  postConfigureEvent returns */
-               gdk_threads_leave ();
-               (*gdk_env)->CallVoidMethod (gdk_env, *obj_ptr, 
+               /* When called from within the gdk_threads critical
+                  section these functions seem to return strange
+                  results, so we call them after
+                  gdk_threads_leave. */
+               gdk_window_get_geometry (event->any.window,
+                                        &x, &y, &w, &h, &d);
+               gdk_window_get_frame_extents (event->any.window, &r);
+
+               top = y;
+               left = x;
+               bottom = r.height - h - y;
+               right = r.width - w - x;
+
+               (*gdk_env)->CallVoidMethod (gdk_env, *obj_ptr,
                                            postConfigureEventID,
-                                           (jint)event->configure.x,
-                                           (jint)event->configure.y,
-                                           (jint)event->configure.width,
-                                           (jint)event->configure.height,
-                                           (jint)top,
-                                           (jint)left,
-                                           (jint)bottom,
-                                           (jint)right);
+                                           (jint) event->configure.x,
+                                           (jint) event->configure.y,
+                                           (jint) event->configure.width,
+                                           (jint) event->configure.height,
+                                           (jint) top,
+                                           (jint) left,
+                                           (jint) bottom,
+                                           (jint) right);
                gdk_threads_enter ();
              }
          }
index f67845a794fe8983496dbff76fdaa1a06e57eec3..03566f228e4bca01644b7989ae9e5d80484e76f9 100644 (file)
@@ -44,6 +44,8 @@ exception statement from your version. */
   struct state_table *native_state_table;
 #endif
 
+jmethodID setBoundsCallbackID;
+
 jmethodID postActionEventID;
 jmethodID postMenuActionEventID;
 jmethodID postMouseEventID;
@@ -74,7 +76,7 @@ Java_gnu_java_awt_peer_gtk_GtkMainThread_gtkInit (JNIEnv *env, jclass clazz)
   char *homedir, *rcpath = NULL;
 /*    jclass gtkgenericpeer; */
   jclass gtkcomponentpeer, gtkwindowpeer, gtkscrollbarpeer, gtklistpeer,
-    gtkmenuitempeer, gtktextcomponentpeer;
+    gtkmenuitempeer, gtktextcomponentpeer, window;
 
   NSA_INIT (env, clazz);
 
@@ -127,6 +129,9 @@ Java_gnu_java_awt_peer_gtk_GtkMainThread_gtkInit (JNIEnv *env, jclass clazz)
   /* setup cached IDs for posting GTK events to Java */
 /*    gtkgenericpeer = (*env)->FindClass (env,  */
 /*                                   "gnu/java/awt/peer/gtk/GtkGenericPeer"); */
+
+  window = (*env)->FindClass (env, "java/awt/Window");
+
   gtkcomponentpeer = (*env)->FindClass (env,
                                     "gnu/java/awt/peer/gtk/GtkComponentPeer");
   gtkwindowpeer = (*env)->FindClass (env,
@@ -145,6 +150,10 @@ Java_gnu_java_awt_peer_gtk_GtkMainThread_gtkInit (JNIEnv *env, jclass clazz)
 /*                                        "postActionEvent",  */
 /*                                        "(Ljava/lang/String;I)V"); */
 
+  setBoundsCallbackID = (*env)->GetMethodID (env, window,
+                                            "setBoundsCallback",
+                                            "(IIII)V");
+
   postMenuActionEventID = (*env)->GetMethodID (env, gtkmenuitempeer,
                                               "postMenuActionEvent",
                                               "()V");
index 982a5cb605202509d515847555c12ff0851e3eed..692c50ecc180d2bb0703d105b0869b36fb167a30 100644 (file)
@@ -43,20 +43,24 @@ exception statement from your version. */
 #include <gdk/gdkx.h>
 
 /*
- * Make a new window (any type)
+ * Make a new window.
  */
 
 JNIEXPORT void JNICALL 
 Java_gnu_java_awt_peer_gtk_GtkWindowPeer_create 
-  (JNIEnv *env, jobject obj, jint type, jint width, jint height)
+  (JNIEnv *env, jobject obj, jint type, jboolean decorated,
+   jint width, jint height, jobject parent)
 {
-  GtkWidget *window;
+  GtkWidget *window_widget;
+  GtkWindow *window;
+  void *window_parent;
   GtkWidget *vbox, *layout;
 
   gdk_threads_enter ();
-  window = gtk_window_new (type);
+  window_widget = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  window = GTK_WINDOW (window_widget);
 
-  gtk_window_set_default_size (GTK_WINDOW(window), width, height);
+  gtk_window_set_default_size (window, width, height);
 
   /* We must set this window's size requisition.  Otherwise when a
      resize is queued (when gtk_widget_queue_resize is called) the
@@ -65,17 +69,28 @@ Java_gnu_java_awt_peer_gtk_GtkWindowPeer_create
      when their resizable property changes. */
   gtk_widget_set_size_request (window, width, height);
 
+  /* Keep this window in front of its parent, if it has one. */
+  if (parent)
+    {
+      window_parent = NSA_GET_PTR (env, parent);
+      gtk_window_set_transient_for (window, GTK_WINDOW(window_parent));
+    }
+
+  gtk_window_set_decorated (window, decorated);
+
+  gtk_window_set_type_hint (window, type);
+
   vbox = gtk_vbox_new (0, 0);
   layout = gtk_layout_new (NULL, NULL);
   gtk_box_pack_end (GTK_BOX (vbox), layout, 1, 1, 0);
-  gtk_container_add (GTK_CONTAINER (window), vbox);
+  gtk_container_add (GTK_CONTAINER (window_widget), vbox);
 
   gtk_widget_show (layout);
   gtk_widget_show (vbox);
 
   gdk_threads_leave ();
 
-  NSA_SET_PTR (env, obj, window);
+  NSA_SET_PTR (env, obj, window_widget);
 }
 
 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkWindowPeer_setVisible
@@ -218,20 +233,42 @@ Java_gnu_java_awt_peer_gtk_GtkWindowPeer_toFront (JNIEnv *env,
   gdk_threads_leave ();
 }
 
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkWindowPeer_setBounds
-  (JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height)
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkWindowPeer_setBoundsCallback
+  (JNIEnv *env, jobject obj, jobject window,
+   jint x, jint y, jint width, jint height)
 {
-  void *ptr;
-  GtkWidget *widget;
+  /* Circumvent package-private access to call Window's
+     setBoundsCallback method. */
+  (*gdk_env)->CallVoidMethod (gdk_env, window, setBoundsCallbackID,
+                             x, y, width, height);
+}
 
-  ptr = NSA_GET_PTR (env, obj);
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkWindowPeer_setSize
+  (JNIEnv *env, jobject obj, jint width, jint height)
+{
+  void *ptr = NSA_GET_PTR (env, obj);
 
   gdk_threads_enter ();
+  gtk_widget_set_size_request (GTK_WIDGET(ptr), width, height);
+  gdk_threads_leave ();
+}
 
-  widget = GTK_WIDGET (ptr);
-  gtk_widget_set_size_request (widget, width, height);
-  gtk_window_resize (GTK_WINDOW(widget), width, height);
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkWindowPeer_nativeSetBounds
+  (JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height)
+{
+  void *ptr = NSA_GET_PTR (env, obj);
 
+  gdk_threads_enter ();
+  gtk_window_move (GTK_WINDOW(ptr), x, y);
+  /* Need to change the widget's request size. */
+  gtk_widget_set_size_request (GTK_WIDGET(ptr), width, height);
+  /* Also need to call gtk_window_resize.  If the resize is requested
+     by the program and the window's "resizable" property is true then
+     the size request will not be honoured. */
+  gtk_window_resize (GTK_WINDOW (ptr), width, height);
   gdk_threads_leave ();
 }
 
index 2aa7109725a40c4fac773b1889ecfca97924a758..8f3895362272e6c75c13eb868d08b2e417f69a5a 100644 (file)
@@ -343,6 +343,8 @@ struct graphics
 #define AWT_FOCUS_LOST 1004
 #define AWT_FOCUS_GAINED 1005
 
+extern jmethodID setBoundsCallbackID;
+
 extern jmethodID postActionEventID;
 extern jmethodID postMenuActionEventID;
 extern jmethodID postMouseEventID;