2004-01-13 Thomas Fitzsimmons <fitzsim@redhat.com>

* gnu/java/awt/peer/gtk/GtkComponentPeer.java
	(initializeInsets): Remove method.
	(GtkComponentPeer): Initialize insets field.  Remove call to
	initializeInsets.
	* gnu/java/awt/peer/gtk/GtkDialogPeer.java (initializeInsets):
	Remove method.
	* gnu/java/awt/peer/gtk/GtkFramePeer.java (initializeInsets):
	Remove method.
	* gnu/java/awt/peer/gtk/GtkWindowPeer.java,
	jni/gtk-peer/gnu_java_awt_peer_gtk_GtkWindowPeer.c:
	(latestInsets): Remove field.
	(native create): Add insets parameter.  Call
	window_get_frame_extents.  Set the window's default size and
	size request based on its frame extents.
	(create): Initialize insets.
	(postInsetsChangedEvent): New method.
	(postConfigureEvent): Remove parameters top, left, bottom,
	right.  Remove insets-related logic.
	(connectJObject): Handle property-notify-event.
	(window_get_frame_extents, request_frame_extents,
	property_notify_predicate, window_property_changed_cb): New
	static functions.
	* jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.c
	(pre_event_handler): Remove insets-related logic for configure
	events.
	* jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMainThread.c (gtkInit):
	Update postConfigureEvent signature.

From-SVN: r75816
This commit is contained in:
Thomas Fitzsimmons 2004-01-13 20:54:46 +00:00 committed by Thomas Fitzsimmons
parent a4d8ec652b
commit db19e39b82
8 changed files with 264 additions and 146 deletions

View file

@ -1,3 +1,33 @@
2004-01-13 Thomas Fitzsimmons <fitzsim@redhat.com>
* gnu/java/awt/peer/gtk/GtkComponentPeer.java
(initializeInsets): Remove method.
(GtkComponentPeer): Initialize insets field. Remove call to
initializeInsets.
* gnu/java/awt/peer/gtk/GtkDialogPeer.java (initializeInsets):
Remove method.
* gnu/java/awt/peer/gtk/GtkFramePeer.java (initializeInsets):
Remove method.
* gnu/java/awt/peer/gtk/GtkWindowPeer.java,
jni/gtk-peer/gnu_java_awt_peer_gtk_GtkWindowPeer.c:
(latestInsets): Remove field.
(native create): Add insets parameter. Call
window_get_frame_extents. Set the window's default size and
size request based on its frame extents.
(create): Initialize insets.
(postInsetsChangedEvent): New method.
(postConfigureEvent): Remove parameters top, left, bottom,
right. Remove insets-related logic.
(connectJObject): Handle property-notify-event.
(window_get_frame_extents, request_frame_extents,
property_notify_predicate, window_property_changed_cb): New
static functions.
* jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.c
(pre_event_handler): Remove insets-related logic for configure
events.
* jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMainThread.c (gtkInit):
Update postConfigureEvent signature.
2004-01-12 Fernando Nasser <fnasser@redhat.com>
* gnu/java/awt/peer/gtk/TestAWT.java (DialogWindow): Add WindowAdapter

View file

@ -96,11 +96,6 @@ public class GtkComponentPeer extends GtkGenericPeer
throw new RuntimeException ();
}
void initializeInsets ()
{
insets = new Insets (0, 0, 0, 0);
}
native void connectJObject ();
native void connectSignals ();
@ -108,6 +103,7 @@ public class GtkComponentPeer extends GtkGenericPeer
{
super (awtComponent);
this.awtComponent = awtComponent;
insets = new Insets (0, 0, 0, 0);
/* temporary try/catch block until all peers use this creation method */
try {
@ -127,8 +123,6 @@ public class GtkComponentPeer extends GtkGenericPeer
if (awtComponent.getFont() != null)
setFont(awtComponent.getFont());
initializeInsets ();
setCursor (awtComponent.getCursor ());
Rectangle bounds = awtComponent.getBounds ();
setBounds (bounds.x, bounds.y, bounds.width, bounds.height);

View file

@ -41,7 +41,6 @@ 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
@ -52,17 +51,6 @@ public class GtkDialogPeer extends GtkWindowPeer
super (dialog);
}
void initializeInsets ()
{
synchronized (latestInsets)
{
insets = new Insets (latestInsets.top,
latestInsets.left,
latestInsets.bottom,
latestInsets.right);
}
}
void create ()
{
// Create a decorated dialog window.

View file

@ -43,7 +43,6 @@ import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Insets;
import java.awt.MenuBar;
import java.awt.Rectangle;
import java.awt.event.PaintEvent;
@ -71,21 +70,6 @@ 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.
synchronized (latestInsets)
{
insets = new Insets (latestInsets.top,
latestInsets.left,
latestInsets.bottom,
latestInsets.right);
}
}
void create ()
{
// Create a normal decorated window.

View file

@ -40,7 +40,6 @@ 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.Frame;
import java.awt.event.WindowEvent;
@ -61,30 +60,30 @@ public class GtkWindowPeer extends GtkContainerPeer
private boolean hasBeenShown = false;
private int oldState = Frame.NORMAL;
// Unfortunately, X does not provide a clean way to calculate the
// dimensions of a window's borders before it has been displayed.
// So when creating the application's first window we guess the
// border dimensions. Then if need be for that window, we fix the
// dimensions upon receipt of the first configure event. Windows
// created after the first one will use the latest inset values
// received in postConfigureEvent.
static Insets latestInsets = new Insets (20, 6, 6, 6);
native void create (int type, boolean decorated,
int width, int height,
GtkWindowPeer parent);
GtkWindowPeer parent,
int[] insets);
void create (int type, boolean decorated)
{
GtkWindowPeer parent_peer = null;
Component parent = awtComponent.getParent();
int[] insets = new int [] { 0, 0, 0, 0 };
if (parent != null)
parent_peer = (GtkWindowPeer) awtComponent.getParent().getPeer();
create (type, decorated,
awtComponent.getWidth(),
awtComponent.getHeight(),
parent_peer);
parent_peer,
insets);
this.insets.top = insets [0];
this.insets.left = insets [1];
this.insets.bottom = insets [2];
this.insets.right = insets [3];
}
void create ()
@ -132,7 +131,7 @@ public class GtkWindowPeer extends GtkContainerPeer
// 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);
awtComponent.getHeight() - insets.top - insets.bottom);
set ("allow_shrink", resizable);
set ("allow_grow", resizable);
}
@ -141,67 +140,29 @@ public class GtkWindowPeer extends GtkContainerPeer
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)
protected void postInsetsChangedEvent (int top, int left,
int bottom, int right)
{
// 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).
insets.top = top;
insets.left = left;
insets.bottom = bottom;
insets.right = 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)
{
// 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);
protected void postConfigureEvent (int x, int y, int width, int height)
{
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;
// 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));
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);
insets.top = top;
insets.left = left;
insets.bottom = bottom;
insets.right = right;
synchronized (latestInsets)
{
latestInsets.top = top;
latestInsets.left = left;
latestInsets.bottom = bottom;
latestInsets.right = right;
}
}
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);
}
}
awtComponent.validate();
}

View file

@ -989,40 +989,18 @@ pre_event_handler (GtkWidget *widget, GdkEvent *event, jobject peer)
if (widget && GTK_WIDGET_TOPLEVEL (widget))
{
gint top, left, right, bottom;
/* 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 ();
/* FIXME: hard-code these values for now. */
if (GTK_IS_PLUG (widget))
{
top = 0;
left = 0;
bottom = 0;
right = 0;
}
else
{
top = 20;
left = 6;
bottom = 6;
right = 6;
}
(*gdk_env)->CallVoidMethod (gdk_env, peer,
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.height);
gdk_threads_enter ();
}
}

View file

@ -168,7 +168,7 @@ Java_gnu_java_awt_peer_gtk_GtkMainThread_gtkInit (JNIEnv *env, jclass clazz)
postMouseEventID = (*env)->GetMethodID (env, gtkcomponentpeer,
"postMouseEvent", "(IJIIIIZ)V");
postConfigureEventID = (*env)->GetMethodID (env, gtkwindowpeer,
"postConfigureEvent", "(IIIIIIII)V");
"postConfigureEvent", "(IIII)V");
postWindowEventID = (*env)->GetMethodID (env, gtkwindowpeer,
"postWindowEvent",
"(ILjava/awt/Window;I)V");

View file

@ -44,6 +44,16 @@ exception statement from your version. */
#include <gdk/gdkx.h>
#include <X11/Xatom.h>
static void window_get_frame_extents (GtkWidget *window,
int *top, int *left,
int *bottom, int *right);
static void request_frame_extents (GtkWidget *window);
static int property_notify_predicate (Display *xdisplay,
XEvent *event,
XPointer window_id);
static void window_delete_cb (GtkWidget *widget, GdkEvent *event,
jobject peer);
static void window_destroy_cb (GtkWidget *widget, GdkEvent *event,
@ -59,6 +69,9 @@ static gboolean window_window_state_cb (GtkWidget *widget,
GdkEvent *event,
jobject peer);
static jint window_get_new_state (GtkWidget *widget);
static gboolean window_property_changed_cb (GtkWidget *widget,
GdkEventProperty *event,
jobject peer);
/*
* Make a new window.
@ -67,12 +80,21 @@ static jint window_get_new_state (GtkWidget *widget);
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkWindowPeer_create
(JNIEnv *env, jobject obj, jint type, jboolean decorated,
jint width, jint height, jobject parent)
jint width, jint height, jobject parent, jintArray jinsets)
{
GtkWidget *window_widget;
GtkWindow *window;
void *window_parent;
GtkWidget *vbox, *layout;
GtkWidget *vbox;
GtkWidget *layout;
int top = 0;
int left = 0;
int bottom = 0;
int right = 0;
jint *insets;
insets = (*env)->GetIntArrayElements (env, jinsets, 0);
insets[0] = insets[1] = insets[2] = insets[3] = 0;
/* Create global reference and save it for future use */
NSA_SET_GLOBAL_REF (env, obj);
@ -82,19 +104,6 @@ Java_gnu_java_awt_peer_gtk_GtkWindowPeer_create
window_widget = gtk_window_new (GTK_WINDOW_TOPLEVEL);
window = GTK_WINDOW (window_widget);
// Avoid GTK runtime assertion failures.
width = (width < 1) ? 1 : width;
height = (height < 1) ? 1 : 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
window will snap to its default requisition of 0x0. If we omit
this call, Frames and Dialogs shrink to degenerate 1x1 windows
when their resizable property changes. */
gtk_widget_set_size_request (window_widget, width, height);
/* Keep this window in front of its parent, if it has one. */
if (parent)
{
@ -115,9 +124,33 @@ Java_gnu_java_awt_peer_gtk_GtkWindowPeer_create
gtk_widget_show (layout);
gtk_widget_show (vbox);
gtk_widget_realize (window_widget);
if (decorated)
window_get_frame_extents (window_widget, &top, &left, &bottom, &right);
gtk_window_set_default_size (window,
MAX (1, width - left - right),
MAX (1, height - top - bottom));
/* We must set this window's size requisition. Otherwise when a
resize is queued (when gtk_widget_queue_resize is called) the
window will snap to its default requisition of 0x0. If we omit
this call, Frames and Dialogs shrink to degenerate 1x1 windows
when their resizable property changes. */
gtk_widget_set_size_request (window_widget,
MAX (1, width - left - right),
MAX (1, height - top - bottom));
insets[0] = top;
insets[1] = left;
insets[2] = bottom;
insets[3] = right;
gdk_threads_leave ();
(*env)->ReleaseIntArrayElements (env, jinsets, insets, 0);
NSA_SET_PTR (env, obj, window_widget);
}
@ -176,6 +209,9 @@ Java_gnu_java_awt_peer_gtk_GtkWindowPeer_connectJObject
connect_awt_hook (env, obj, 1, GTK_WIDGET (ptr)->window);
g_signal_connect (G_OBJECT (ptr), "property-notify-event",
G_CALLBACK (window_property_changed_cb), obj);
gdk_threads_leave ();
}
@ -291,7 +327,7 @@ Java_gnu_java_awt_peer_gtk_GtkWindowPeer_setSize
{
void *ptr = NSA_GET_PTR (env, obj);
// Avoid GTK runtime assertion failures.
/* Avoid GTK runtime assertion failures. */
width = (width < 1) ? 1 : width;
height = (height < 1) ? 1 : height;
@ -306,7 +342,7 @@ Java_gnu_java_awt_peer_gtk_GtkWindowPeer_nativeSetBounds
{
void *ptr = NSA_GET_PTR (env, obj);
// Avoid GTK runtime assertion failures.
/* Avoid GTK runtime assertion failures. */
width = (width < 1) ? 1 : width;
height = (height < 1) ? 1 : height;
@ -364,6 +400,112 @@ Java_gnu_java_awt_peer_gtk_GtkFramePeer_getMenuBarHeight
return height;
}
static void
window_get_frame_extents (GtkWidget *window,
int *top, int *left, int *bottom, int *right)
{
unsigned long *extents = NULL;
/* Guess frame extents in case _NET_FRAME_EXTENTS is not
supported. */
*top = 23;
*left = 6;
*bottom = 6;
*right = 6;
/* Request that the window manager set window's
_NET_FRAME_EXTENTS property. */
request_frame_extents (window);
/* Attempt to retrieve window's frame extents. */
if (gdk_property_get (window->window,
gdk_atom_intern ("_NET_FRAME_EXTENTS", FALSE),
gdk_atom_intern ("CARDINAL", FALSE),
0,
sizeof (unsigned long) * 4,
FALSE,
NULL,
NULL,
NULL,
(guchar **)&extents))
{
*left = extents [0];
*right = extents [1];
*top = extents [2];
*bottom = extents [3];
}
}
static Atom extents_atom = 0;
/* Requests that the window manager set window's
_NET_FRAME_EXTENTS property. */
static void
request_frame_extents (GtkWidget *window)
{
const char *request_str = "_NET_REQUEST_FRAME_EXTENTS";
GdkAtom request_extents = gdk_atom_intern (request_str, FALSE);
/* Check if the current window manager supports
_NET_REQUEST_FRAME_EXTENTS. */
if (gdk_net_wm_supports (request_extents))
{
GdkDisplay *display = gtk_widget_get_display (window);
Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
GdkWindow *root_window = gdk_get_default_root_window ();
Window xroot_window = GDK_WINDOW_XID (root_window);
Atom extents_request_atom =
gdk_x11_get_xatom_by_name_for_display (display, request_str);
XEvent xevent;
XEvent notify_xevent;
unsigned long window_id = GDK_WINDOW_XID (GDK_DRAWABLE(window->window));
if (!extents_atom)
{
const char *extents_str = "_NET_FRAME_EXTENTS";
extents_atom =
gdk_x11_get_xatom_by_name_for_display (display, extents_str);
}
xevent.xclient.type = ClientMessage;
xevent.xclient.message_type = extents_request_atom;
xevent.xclient.display = xdisplay;
xevent.xclient.window = window_id;
xevent.xclient.format = 32;
xevent.xclient.data.l[0] = 0;
xevent.xclient.data.l[1] = 0;
xevent.xclient.data.l[2] = 0;
xevent.xclient.data.l[3] = 0;
xevent.xclient.data.l[4] = 0;
XSendEvent (xdisplay, xroot_window, False,
(SubstructureRedirectMask | SubstructureNotifyMask),
&xevent);
XIfEvent(xdisplay, &notify_xevent,
property_notify_predicate, (XPointer) &window_id);
}
}
static int
property_notify_predicate (Display *xdisplay __attribute__((unused)),
XEvent *event,
XPointer window_id)
{
unsigned long *window = (unsigned long *) window_id;
if (event->xany.type == PropertyNotify
&& event->xany.window == *window
&& event->xproperty.atom == extents_atom)
return True;
return False;
}
static void
window_delete_cb (GtkWidget *widget __attribute__((unused)),
GdkEvent *event __attribute__((unused)),
@ -514,3 +656,44 @@ window_get_new_state (GtkWidget *widget)
}
return new_state;
}
static gboolean
window_property_changed_cb (GtkWidget *widget __attribute__((unused)),
GdkEventProperty *event,
jobject peer)
{
unsigned long *extents;
static int id_set = 0;
static jmethodID postInsetsChangedEventID;
if (!id_set)
{
jclass gtkwindowpeer = (*gdk_env)->FindClass (gdk_env,
"gnu/java/awt/peer/gtk/GtkWindowPeer");
postInsetsChangedEventID = (*gdk_env)->GetMethodID (gdk_env,
gtkwindowpeer,
"postInsetsChangedEvent",
"(IIII)V");
}
if (gdk_atom_intern ("_NET_FRAME_EXTENTS", FALSE) == event->atom
&& gdk_property_get (event->window,
gdk_atom_intern ("_NET_FRAME_EXTENTS", FALSE),
gdk_atom_intern ("CARDINAL", FALSE),
0,
sizeof (unsigned long) * 4,
FALSE,
NULL,
NULL,
NULL,
(guchar **)&extents))
(*gdk_env)->CallVoidMethod (gdk_env, peer,
postInsetsChangedEventID,
(jint) extents[2], /* top */
(jint) extents[0], /* left */
(jint) extents[3], /* bottom */
(jint) extents[1]); /* right */
return FALSE;
}