From b59b5081384b68e33c1a50ef4d047f95e171c05d Mon Sep 17 00:00:00 2001 From: Thomas Fitzsimmons Date: Thu, 2 Oct 2003 18:34:56 +0000 Subject: [PATCH] GtkComponentPeer.java (insets): New field. 2003-10-02 Thomas Fitzsimmons * 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 --- libjava/ChangeLog | 49 +++++++ .../java/awt/peer/gtk/GtkComponentPeer.java | 29 +++-- .../java/awt/peer/gtk/GtkContainerPeer.java | 2 - .../gnu/java/awt/peer/gtk/GtkDialogPeer.java | 15 ++- .../gnu/java/awt/peer/gtk/GtkFramePeer.java | 37 ++---- .../gnu/java/awt/peer/gtk/GtkWindowPeer.java | 123 ++++++++++++++---- libjava/java/awt/Window.java | 25 ++++ .../gnu_java_awt_peer_gtk_GtkComponentPeer.c | 14 +- .../gnu_java_awt_peer_gtk_GtkEvents.c | 51 +++++--- .../gnu_java_awt_peer_gtk_GtkMainThread.c | 11 +- .../gnu_java_awt_peer_gtk_GtkWindowPeer.c | 67 +++++++--- libjava/jni/gtk-peer/gtkpeer.h | 2 + 12 files changed, 317 insertions(+), 108 deletions(-) diff --git a/libjava/ChangeLog b/libjava/ChangeLog index d65c26acb4a..a5184f5a956 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,52 @@ +2003-10-02 Thomas Fitzsimmons + + * 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 * java/lang/VMClassLoader.java (loadClass): Now native. diff --git a/libjava/gnu/java/awt/peer/gtk/GtkComponentPeer.java b/libjava/gnu/java/awt/peer/gtk/GtkComponentPeer.java index ac092c8f4d1..0f97d533cf7 100644 --- a/libjava/gnu/java/awt/peer/gtk/GtkComponentPeer.java +++ b/libjava/gnu/java/awt/peer/gtk/GtkComponentPeer.java @@ -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); diff --git a/libjava/gnu/java/awt/peer/gtk/GtkContainerPeer.java b/libjava/gnu/java/awt/peer/gtk/GtkContainerPeer.java index 7e2c5492d29..5225ccc5f14 100644 --- a/libjava/gnu/java/awt/peer/gtk/GtkContainerPeer.java +++ b/libjava/gnu/java/awt/peer/gtk/GtkContainerPeer.java @@ -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() diff --git a/libjava/gnu/java/awt/peer/gtk/GtkDialogPeer.java b/libjava/gnu/java/awt/peer/gtk/GtkDialogPeer.java index 8c0f5ee510f..e7b047ea2e2 100644 --- a/libjava/gnu/java/awt/peer/gtk/GtkDialogPeer.java +++ b/libjava/gnu/java/awt/peer/gtk/GtkDialogPeer.java @@ -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) diff --git a/libjava/gnu/java/awt/peer/gtk/GtkFramePeer.java b/libjava/gnu/java/awt/peer/gtk/GtkFramePeer.java index 043c08276db..b44a02d13db 100644 --- a/libjava/gnu/java/awt/peer/gtk/GtkFramePeer.java +++ b/libjava/gnu/java/awt/peer/gtk/GtkFramePeer.java @@ -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, diff --git a/libjava/gnu/java/awt/peer/gtk/GtkWindowPeer.java b/libjava/gnu/java/awt/peer/gtk/GtkWindowPeer.java index 08b2bf67e90..be615042524 100644 --- a/libjava/gnu/java/awt/peer/gtk/GtkWindowPeer.java +++ b/libjava/gnu/java/awt/peer/gtk/GtkWindowPeer.java @@ -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); } diff --git a/libjava/java/awt/Window.java b/libjava/java/awt/Window.java index 9f102751230..3554bf5e581 100644 --- a/libjava/java/awt/Window.java +++ b/libjava/java/awt/Window.java @@ -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; + } } diff --git a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c index ed94b7d7539..455af68f2bc 100644 --- a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c +++ b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c @@ -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); diff --git a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.c b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.c index cdcd72e187c..481fadf9d73 100644 --- a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.c +++ b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.c @@ -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 (); } } diff --git a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMainThread.c b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMainThread.c index f67845a794f..03566f228e4 100644 --- a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMainThread.c +++ b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMainThread.c @@ -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"); diff --git a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkWindowPeer.c b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkWindowPeer.c index 982a5cb6052..692c50ecc18 100644 --- a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkWindowPeer.c +++ b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkWindowPeer.c @@ -43,20 +43,24 @@ exception statement from your version. */ #include /* - * 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 (); } diff --git a/libjava/jni/gtk-peer/gtkpeer.h b/libjava/jni/gtk-peer/gtkpeer.h index 2aa7109725a..8f389536227 100644 --- a/libjava/jni/gtk-peer/gtkpeer.h +++ b/libjava/jni/gtk-peer/gtkpeer.h @@ -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; -- 2.30.2