aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Fitzsimmons <fitzsim@redhat.com>2004-01-13 20:54:46 +0000
committerThomas Fitzsimmons <fitzsim@redhat.com>2004-01-13 20:54:46 +0000
commit4064f5efd21694bc703f31435340d34389d80674 (patch)
tree017b0a898a627715d917aa1f6bdaa0447165abbf
parentd13f43d8146b8da82a0377b8525e2d3636b784e9 (diff)
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. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@75816 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--libjava/ChangeLog30
-rw-r--r--libjava/gnu/java/awt/peer/gtk/GtkComponentPeer.java8
-rw-r--r--libjava/gnu/java/awt/peer/gtk/GtkDialogPeer.java12
-rw-r--r--libjava/gnu/java/awt/peer/gtk/GtkFramePeer.java16
-rw-r--r--libjava/gnu/java/awt/peer/gtk/GtkWindowPeer.java107
-rw-r--r--libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.c24
-rw-r--r--libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMainThread.c2
-rw-r--r--libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkWindowPeer.c217
8 files changed, 267 insertions, 149 deletions
diff --git a/libjava/ChangeLog b/libjava/ChangeLog
index 9c8e9abdc0c..cd143a77ca8 100644
--- a/libjava/ChangeLog
+++ b/libjava/ChangeLog
@@ -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
diff --git a/libjava/gnu/java/awt/peer/gtk/GtkComponentPeer.java b/libjava/gnu/java/awt/peer/gtk/GtkComponentPeer.java
index 0a712a0597c..6f71db9f17a 100644
--- a/libjava/gnu/java/awt/peer/gtk/GtkComponentPeer.java
+++ b/libjava/gnu/java/awt/peer/gtk/GtkComponentPeer.java
@@ -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);
diff --git a/libjava/gnu/java/awt/peer/gtk/GtkDialogPeer.java b/libjava/gnu/java/awt/peer/gtk/GtkDialogPeer.java
index 27867321c3c..6aefba608e6 100644
--- a/libjava/gnu/java/awt/peer/gtk/GtkDialogPeer.java
+++ b/libjava/gnu/java/awt/peer/gtk/GtkDialogPeer.java
@@ -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.
diff --git a/libjava/gnu/java/awt/peer/gtk/GtkFramePeer.java b/libjava/gnu/java/awt/peer/gtk/GtkFramePeer.java
index 13d2fc77a25..33d0fccd64f 100644
--- a/libjava/gnu/java/awt/peer/gtk/GtkFramePeer.java
+++ b/libjava/gnu/java/awt/peer/gtk/GtkFramePeer.java
@@ -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.
diff --git a/libjava/gnu/java/awt/peer/gtk/GtkWindowPeer.java b/libjava/gnu/java/awt/peer/gtk/GtkWindowPeer.java
index 4a2d50805a1..7e77e0dcbf0 100644
--- a/libjava/gnu/java/awt/peer/gtk/GtkWindowPeer.java
+++ b/libjava/gnu/java/awt/peer/gtk/GtkWindowPeer.java
@@ -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).
-
- // 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);
-
- // 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;
-
- 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);
- }
- }
+ insets.top = top;
+ insets.left = left;
+ insets.bottom = bottom;
+ insets.right = right;
+ }
+
+ 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;
+
+ 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();
}
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 e8b8702ef15..42f45b4ea0d 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
@@ -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 ();
}
}
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 bad4a516884..0b4c6fee452 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
@@ -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");
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 022677b06a9..c0f528a3983 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
@@ -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;
@@ -365,6 +401,112 @@ Java_gnu_java_awt_peer_gtk_GtkFramePeer_getMenuBarHeight
}
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)),
jobject peer)
@@ -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;
+}