X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=libjava%2Fjni%2Fgtk-peer%2Fgnu_java_awt_peer_gtk_GtkWindowPeer.c;h=184ca56ca654659a5c710e3839120492b815261d;hb=33428c2bca50262cc4ca98e92fd72c40e325dc79;hp=619b48d593a8d008baaccda1dcbc71692710558f;hpb=c46fe9ae1d9ea21a7d4c53737a7d3c11bcd9e855;p=pf3gnuchains%2Fgcc-fork.git 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 619b48d593a..184ca56ca65 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 @@ -1,5 +1,5 @@ /* gtkwindowpeer.c -- Native implementation of GtkWindowPeer - Copyright (C) 1998, 1999, 2002 Free Software Foundation, Inc. + Copyright (C) 1998, 1999, 2002, 2004 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -37,18 +37,14 @@ exception statement from your version. */ #include "gtkpeer.h" -#include "gnu_java_awt_peer_gtk_GtkComponentPeer.h" #include "gnu_java_awt_peer_gtk_GtkWindowPeer.h" -#include "gnu_java_awt_peer_gtk_GtkFramePeer.h" #include #include #include -static int filter_added = 0; - -static GdkFilterReturn window_wm_protocols_filter (GdkXEvent *xev, - GdkEvent *event, - gpointer data); +/* FIXME: we're currently seeing the double-activation that occurs + with metacity and GTK. See + http://bugzilla.gnome.org/show_bug.cgi?id=140977 for details. */ static void window_get_frame_extents (GtkWidget *window, int *top, int *left, @@ -56,18 +52,27 @@ static void window_get_frame_extents (GtkWidget *window, static void request_frame_extents (GtkWidget *window); -static int property_notify_predicate (Display *xdisplay, - XEvent *event, - XPointer window_id); +static Bool property_notify_predicate (Display *display, + XEvent *xevent, + XPointer arg); static void window_delete_cb (GtkWidget *widget, GdkEvent *event, jobject peer); static void window_destroy_cb (GtkWidget *widget, GdkEvent *event, jobject peer); static void window_show_cb (GtkWidget *widget, jobject peer); -static void window_focus_or_active_state_change_cb (GtkWidget *widget, - GParamSpec *pspec, - jobject peer); +static void window_active_state_change_cb (GtkWidget *widget, + GParamSpec *pspec, + jobject peer); +static void window_focus_state_change_cb (GtkWidget *widget, + GParamSpec *pspec, + jobject peer); +static gboolean window_focus_in_cb (GtkWidget * widget, + GdkEventFocus *event, + jobject peer); +static gboolean window_focus_out_cb (GtkWidget * widget, + GdkEventFocus *event, + jobject peer); static gboolean window_window_state_cb (GtkWidget *widget, GdkEvent *event, jobject peer); @@ -75,31 +80,30 @@ static jint window_get_new_state (GtkWidget *widget); static gboolean window_property_changed_cb (GtkWidget *widget, GdkEventProperty *event, jobject peer); +static void realize_cb (GtkWidget *widget, jobject peer); -/* - * Make a new window. - */ +/* Union used for type punning. */ +union extents_union +{ + guchar **gu_extents; + unsigned long **extents; +}; -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, jintArray jinsets) +union atom_list_union +{ + guchar **gu_extents; + Atom **atom_list; +}; + +JNIEXPORT void JNICALL +Java_gnu_java_awt_peer_gtk_GtkWindowPeer_create + (JNIEnv *env, jobject obj, jint type, jboolean decorated, jobject parent) { GtkWidget *window_widget; GtkWindow *window; void *window_parent; - 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 */ + GtkWidget *fixed; + NSA_SET_GLOBAL_REF (env, obj); gdk_threads_enter (); @@ -120,60 +124,39 @@ Java_gnu_java_awt_peer_gtk_GtkWindowPeer_create gtk_window_group_add_window (global_gtk_window_group, window); - 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_widget), vbox); + fixed = gtk_fixed_new (); + gtk_container_add (GTK_CONTAINER (window_widget), fixed); - gtk_widget_show (layout); - gtk_widget_show (vbox); - gtk_widget_realize (window_widget); + gtk_widget_show (fixed); - if (decorated) - window_get_frame_extents (window_widget, &top, &left, &bottom, &right); + gdk_threads_leave (); - gtk_window_set_default_size (window, - MAX (1, width - left - right), - MAX (1, height - top - bottom)); + NSA_SET_PTR (env, obj, window_widget); +} - /* 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)); +JNIEXPORT void JNICALL +Java_gnu_java_awt_peer_gtk_GtkWindowPeer_gtkWindowSetTitle + (JNIEnv *env, jobject obj, jstring title) +{ + const char *c_title; + void *ptr; + + ptr = NSA_GET_PTR (env, obj); - insets[0] = top; - insets[1] = left; - insets[2] = bottom; - insets[3] = right; + c_title = (*env)->GetStringUTFChars (env, title, NULL); - /* We must filter out WM_TAKE_FOCUS messages. Otherwise we get two - focus in events when a window becomes active and two focus out - events when a window becomes inactive. */ - if (!filter_added) - { - GdkAtom wm_protocols_atom = - gdk_x11_xatom_to_atom (gdk_x11_get_xatom_by_name ("WM_PROTOCOLS")); + gdk_threads_enter (); - gdk_add_client_message_filter (wm_protocols_atom, - window_wm_protocols_filter, - NULL); - filter_added = 1; - } + gtk_window_set_title (GTK_WINDOW (ptr), c_title); gdk_threads_leave (); - (*env)->ReleaseIntArrayElements (env, jinsets, insets, 0); - - NSA_SET_PTR (env, obj, window_widget); + (*env)->ReleaseStringUTFChars (env, title, c_title); } JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GtkWindowPeer_nativeSetVisible - (JNIEnv *env, jobject obj, jboolean visible) +Java_gnu_java_awt_peer_gtk_GtkWindowPeer_gtkWindowSetResizable + (JNIEnv *env, jobject obj, jboolean resizable) { void *ptr; @@ -181,48 +164,42 @@ Java_gnu_java_awt_peer_gtk_GtkWindowPeer_nativeSetVisible gdk_threads_enter (); - if (visible) - gtk_widget_show (GTK_WIDGET (ptr)); - else - gtk_widget_hide (GTK_WIDGET (ptr)); - - XFlush (GDK_DISPLAY ()); + gtk_window_set_policy (GTK_WINDOW (ptr), resizable, resizable, FALSE); gdk_threads_leave (); } JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GtkWindowPeer_connectJObject - (JNIEnv *env, jobject obj) +Java_gnu_java_awt_peer_gtk_GtkWindowPeer_gtkWindowSetModal + (JNIEnv *env, jobject obj, jboolean modal) { void *ptr; - GtkWidget* vbox, *layout; - GList* children; ptr = NSA_GET_PTR (env, obj); gdk_threads_enter (); - children = gtk_container_get_children(GTK_CONTAINER(ptr)); - vbox = children->data; - g_assert (GTK_IS_VBOX(vbox)); + gtk_window_set_modal (GTK_WINDOW (ptr), modal); - children = gtk_container_get_children(GTK_CONTAINER(vbox)); - do - { - layout = children->data; - children = children->next; - } - while (!GTK_IS_LAYOUT (layout) && children != NULL); - g_assert (GTK_IS_LAYOUT(layout)); + gdk_threads_leave (); +} - gtk_widget_realize (layout); +JNIEXPORT void JNICALL +Java_gnu_java_awt_peer_gtk_GtkWindowPeer_nativeSetVisible + (JNIEnv *env, jobject obj, jboolean visible) +{ + void *ptr; - connect_awt_hook (env, obj, 1, GTK_LAYOUT (layout)->bin_window); + ptr = NSA_GET_PTR (env, obj); - gtk_widget_realize (ptr); + gdk_threads_enter (); + + if (visible) + gtk_widget_show (GTK_WIDGET (ptr)); + else + gtk_widget_hide (GTK_WIDGET (ptr)); - connect_awt_hook (env, obj, 1, GTK_WIDGET (ptr)->window); + XFlush (GDK_DISPLAY ()); gdk_threads_leave (); } @@ -231,34 +208,17 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkWindowPeer_connectSignals (JNIEnv *env, jobject obj) { - void *ptr = NSA_GET_PTR (env, obj); - jobject *gref = NSA_GET_GLOBAL_REF (env, obj); - GtkWidget* vbox, *layout; - GList* children; - g_assert (gref); - - gdk_threads_enter (); - - gtk_widget_realize (ptr); + void *ptr; + jobject *gref; - /* Receive events from the GtkLayout too */ - children = gtk_container_get_children(GTK_CONTAINER(ptr)); - vbox = children->data; - g_assert (GTK_IS_VBOX (vbox)); + ptr = NSA_GET_PTR (env, obj); + gref = NSA_GET_GLOBAL_REF (env, obj); - children = gtk_container_get_children(GTK_CONTAINER(vbox)); - do - { - layout = children->data; - children = children->next; - } - while (!GTK_IS_LAYOUT (layout) && children != NULL); - g_assert (GTK_IS_LAYOUT (layout)); + gdk_threads_enter (); - g_signal_connect (GTK_OBJECT (layout), "event", - G_CALLBACK (pre_event_handler), *gref); + g_signal_connect (G_OBJECT (ptr), "event", + G_CALLBACK (pre_event_handler), *gref); - /* Connect signals for window event support. */ g_signal_connect (G_OBJECT (ptr), "delete-event", G_CALLBACK (window_delete_cb), *gref); @@ -268,8 +228,17 @@ Java_gnu_java_awt_peer_gtk_GtkWindowPeer_connectSignals g_signal_connect (G_OBJECT (ptr), "show", G_CALLBACK (window_show_cb), *gref); - g_signal_connect (G_OBJECT (ptr), "notify", - G_CALLBACK (window_focus_or_active_state_change_cb), *gref); + g_signal_connect (G_OBJECT (ptr), "notify::is-active", + G_CALLBACK (window_active_state_change_cb), *gref); + + g_signal_connect (G_OBJECT (ptr), "notify::has-toplevel-focus", + G_CALLBACK (window_focus_state_change_cb), *gref); + + g_signal_connect (G_OBJECT (ptr), "focus-in-event", + G_CALLBACK (window_focus_in_cb), *gref); + + g_signal_connect (G_OBJECT (ptr), "focus-out-event", + G_CALLBACK (window_focus_out_cb), *gref); g_signal_connect (G_OBJECT (ptr), "window-state-event", G_CALLBACK (window_window_state_cb), *gref); @@ -277,15 +246,21 @@ Java_gnu_java_awt_peer_gtk_GtkWindowPeer_connectSignals g_signal_connect (G_OBJECT (ptr), "property-notify-event", G_CALLBACK (window_property_changed_cb), *gref); - gdk_threads_leave (); + g_signal_connect_after (G_OBJECT (ptr), "realize", + G_CALLBACK (realize_cb), *gref); - /* Connect the superclass signals. */ - Java_gnu_java_awt_peer_gtk_GtkComponentPeer_connectSignals (env, obj); -} + g_signal_connect_after (G_OBJECT (ptr), "realize", + G_CALLBACK (connect_awt_hook_cb), *gref); + + + /* Realize the window here so that its frame extents are known now. + That way Window.pack can operate with the accurate insets + returned by the window manager rather than the default + estimates. */ + gtk_widget_realize (GTK_WIDGET (ptr)); -/* - * Lower the z-level of a window. - */ + gdk_threads_leave (); +} JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkWindowPeer_toBack (JNIEnv *env, @@ -295,16 +270,13 @@ Java_gnu_java_awt_peer_gtk_GtkWindowPeer_toBack (JNIEnv *env, ptr = NSA_GET_PTR (env, obj); gdk_threads_enter (); + gdk_window_lower (GTK_WIDGET (ptr)->window); + gdk_flush (); - XFlush (GDK_DISPLAY ()); gdk_threads_leave (); } -/* - * Raise the z-level of a window. - */ - JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkWindowPeer_toFront (JNIEnv *env, jobject obj) @@ -313,9 +285,10 @@ Java_gnu_java_awt_peer_gtk_GtkWindowPeer_toFront (JNIEnv *env, ptr = NSA_GET_PTR (env, obj); gdk_threads_enter (); + gdk_window_raise (GTK_WIDGET (ptr)->window); + gdk_flush (); - XFlush (GDK_DISPLAY ()); gdk_threads_leave (); } @@ -326,7 +299,7 @@ Java_gnu_java_awt_peer_gtk_GtkWindowPeer_setBoundsCallback { /* Circumvent package-private access to call Window's setBoundsCallback method. */ - (*gdk_env)->CallVoidMethod (gdk_env, window, setBoundsCallbackID, + (*gdk_env())->CallVoidMethod (gdk_env(), window, setBoundsCallbackID, x, y, width, height); } @@ -341,7 +314,9 @@ Java_gnu_java_awt_peer_gtk_GtkWindowPeer_setSize height = (height < 1) ? 1 : height; gdk_threads_enter (); + gtk_widget_set_size_request (GTK_WIDGET(ptr), width, height); + gdk_threads_leave (); } @@ -356,7 +331,23 @@ Java_gnu_java_awt_peer_gtk_GtkWindowPeer_nativeSetBounds height = (height < 1) ? 1 : height; gdk_threads_enter (); + gtk_window_move (GTK_WINDOW(ptr), x, y); + /* The call to gdk_window_move is needed in addition to the call to + gtk_window_move. If gdk_window_move isn't called, then the + following set of operations doesn't give the expected results: + + 1. show a window + 2. manually move it to another position on the screen + 3. hide the window + 4. reposition the window with Component.setLocation + 5. show the window + + Instead of being at the position set by setLocation, the window + is reshown at the position to which it was moved manually. */ + if (GTK_WIDGET (ptr)->window != NULL) + gdk_window_move (GTK_WIDGET (ptr)->window, 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 @@ -366,160 +357,12 @@ Java_gnu_java_awt_peer_gtk_GtkWindowPeer_nativeSetBounds gdk_threads_leave (); } -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GtkFramePeer_removeMenuBarPeer - (JNIEnv *env, jobject obj) -{ - void *wptr; - GtkWidget *box; - GtkWidget *mptr; - GList* children; - - wptr = NSA_GET_PTR (env, obj); - - gdk_threads_enter (); - - box = GTK_BIN (wptr)->child; - - children = gtk_container_get_children (GTK_CONTAINER (box)); - - while (children != NULL && !GTK_IS_MENU_SHELL (children->data)) - { - children = children->next; - } - - /* If there isn't a MenuBar in this Frame's list of children - then we can just return. */ - if (!GTK_IS_MENU_SHELL (children->data)) - return; - else - mptr = children->data; - - /* This will actually destroy the MenuBar. By removing it from - its parent, the reference count for the MenuBar widget will - decrement to 0. The widget will be automatically destroyed - by Gtk. */ - gtk_container_remove (GTK_CONTAINER (box), GTK_WIDGET (mptr)); - - gdk_threads_leave(); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GtkFramePeer_setMenuBarPeer - (JNIEnv *env, jobject obj, jobject menubar) -{ - void *wptr; - GtkWidget *mptr; - GtkWidget *box; - - wptr = NSA_GET_PTR (env, obj); - mptr = NSA_GET_PTR (env, menubar); - - gdk_threads_enter (); - - box = GTK_BIN (wptr)->child; - gtk_box_pack_start (GTK_BOX (box), mptr, 0, 0, 0); - - gtk_widget_show (mptr); - - - gdk_threads_leave (); -} - -JNIEXPORT jint JNICALL -Java_gnu_java_awt_peer_gtk_GtkFramePeer_getMenuBarHeight - (JNIEnv *env, jobject obj __attribute__((unused)), jobject menubar) -{ - GtkWidget *ptr; - jint height; - GtkRequisition gtkreq; - - ptr = NSA_GET_PTR (env, menubar); - - gdk_threads_enter (); - gtk_widget_size_request (ptr, >kreq); - - height = gtkreq.height; - gdk_threads_leave (); - return height; -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GtkFramePeer_moveLayout - (JNIEnv *env, jobject obj, jint offset) -{ - void* ptr; - GList* children; - GtkBox* vbox; - GtkLayout* layout; - GtkWidget* widget; - - ptr = NSA_GET_PTR (env, obj); - - gdk_threads_enter (); - - children = gtk_container_get_children (GTK_CONTAINER (ptr)); - vbox = children->data; - g_assert (GTK_IS_VBOX (vbox)); - - children = gtk_container_get_children (GTK_CONTAINER (vbox)); - do - { - layout = children->data; - children = children->next; - } - while (!GTK_IS_LAYOUT (layout) && children != NULL); - g_assert (GTK_IS_LAYOUT (layout)); - children = gtk_container_get_children (GTK_CONTAINER (layout)); - - while (children != NULL) - { - widget = children->data; - gtk_layout_move (layout, widget, widget->allocation.x, - widget->allocation.y+offset); - children = children->next; - } - - gdk_threads_leave (); -} - -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GtkFramePeer_gtkLayoutSetVisible - (JNIEnv *env, jobject obj, jboolean vis) -{ - void* ptr; - GList* children; - GtkBox* vbox; - GtkLayout* layout; - - ptr = NSA_GET_PTR (env, obj); - - gdk_threads_enter (); - - children = gtk_container_get_children (GTK_CONTAINER (ptr)); - vbox = children->data; - g_assert (GTK_IS_VBOX (vbox)); - - children = gtk_container_get_children (GTK_CONTAINER (vbox)); - do - { - layout = children->data; - children = children->next; - } - while (!GTK_IS_LAYOUT (layout) && children != NULL); - g_assert (GTK_IS_LAYOUT (layout)); - - if (vis) - gtk_widget_show (GTK_WIDGET (layout)); - else - gtk_widget_hide (GTK_WIDGET (layout)); - gdk_threads_leave (); -} static void window_get_frame_extents (GtkWidget *window, int *top, int *left, int *bottom, int *right) { unsigned long *extents = NULL; + union extents_union gu_ex; /* Guess frame extents in case _NET_FRAME_EXTENTS is not supported. */ @@ -533,6 +376,7 @@ window_get_frame_extents (GtkWidget *window, request_frame_extents (window); /* Attempt to retrieve window's frame extents. */ + gu_ex.extents = &extents; if (gdk_property_get (window->window, gdk_atom_intern ("_NET_FRAME_EXTENTS", FALSE), gdk_atom_intern ("CARDINAL", FALSE), @@ -542,7 +386,7 @@ window_get_frame_extents (GtkWidget *window, NULL, NULL, NULL, - (guchar **)&extents)) + gu_ex.gu_extents)) { *left = extents [0]; *right = extents [1]; @@ -606,7 +450,7 @@ request_frame_extents (GtkWidget *window) } } -static int +static Bool property_notify_predicate (Display *xdisplay __attribute__((unused)), XEvent *event, XPointer window_id) @@ -616,9 +460,9 @@ property_notify_predicate (Display *xdisplay __attribute__((unused)), if (event->xany.type == PropertyNotify && event->xany.window == *window && event->xproperty.atom == extents_atom) - return True; - - return False; + return True; + else + return False; } static void @@ -626,10 +470,12 @@ window_delete_cb (GtkWidget *widget __attribute__((unused)), GdkEvent *event __attribute__((unused)), jobject peer) { - (*gdk_env)->CallVoidMethod (gdk_env, peer, + gdk_threads_leave (); + (*gdk_env())->CallVoidMethod (gdk_env(), peer, postWindowEventID, (jint) AWT_WINDOW_CLOSING, (jobject) NULL, (jint) 0); + gdk_threads_enter (); } static void @@ -637,53 +483,98 @@ window_destroy_cb (GtkWidget *widget __attribute__((unused)), GdkEvent *event __attribute__((unused)), jobject peer) { - (*gdk_env)->CallVoidMethod (gdk_env, peer, + gdk_threads_leave (); + (*gdk_env())->CallVoidMethod (gdk_env(), peer, postWindowEventID, (jint) AWT_WINDOW_CLOSED, (jobject) NULL, (jint) 0); + gdk_threads_enter (); } static void window_show_cb (GtkWidget *widget __attribute__((unused)), jobject peer) { - (*gdk_env)->CallVoidMethod (gdk_env, peer, + gdk_threads_leave (); + (*gdk_env())->CallVoidMethod (gdk_env(), peer, postWindowEventID, (jint) AWT_WINDOW_OPENED, (jobject) NULL, (jint) 0); + gdk_threads_enter (); } static void -window_focus_or_active_state_change_cb (GtkWidget *widget, - GParamSpec *pspec, - jobject peer) +window_active_state_change_cb (GtkWidget *widget __attribute__((unused)), + GParamSpec *pspec __attribute__((unused)), + jobject peer __attribute__((unused))) { - if (!strcmp (g_param_spec_get_name (pspec), "is-active")) - { - if (GTK_WINDOW (widget)->is_active) - (*gdk_env)->CallVoidMethod (gdk_env, peer, - postWindowEventID, - (jint) AWT_WINDOW_GAINED_FOCUS, - (jobject) NULL, (jint) 0); - else - (*gdk_env)->CallVoidMethod (gdk_env, peer, - postWindowEventID, - (jint) AWT_WINDOW_DEACTIVATED, - (jobject) NULL, (jint) 0); - } - else if (!strcmp (g_param_spec_get_name (pspec), "has-toplevel-focus")) - { - if (GTK_WINDOW (widget)->has_toplevel_focus) - (*gdk_env)->CallVoidMethod (gdk_env, peer, - postWindowEventID, - (jint) AWT_WINDOW_ACTIVATED, - (jobject) NULL, (jint) 0); - else - (*gdk_env)->CallVoidMethod (gdk_env, peer, - postWindowEventID, - (jint) AWT_WINDOW_LOST_FOCUS, - (jobject) NULL, (jint) 0); - } + /* FIXME: not sure if this is needed or not. */ + /* Remove the unused attributes if you fix the below. */ +#if 0 + gdk_threads_leave (); + if (GTK_WINDOW (widget)->is_active) + (*gdk_env())->CallVoidMethod (gdk_env(), peer, + postWindowEventID, + (jint) AWT_WINDOW_GAINED_FOCUS, + (jobject) NULL, (jint) 0); + else + (*gdk_env())->CallVoidMethod (gdk_env(), peer, + postWindowEventID, + (jint) AWT_WINDOW_DEACTIVATED, + (jobject) NULL, (jint) 0); + gdk_threads_enter (); +#endif +} + +static void +window_focus_state_change_cb (GtkWidget *widget, + GParamSpec *pspec __attribute__((unused)), + jobject peer) +{ + gdk_threads_leave (); + if (GTK_WINDOW (widget)->has_toplevel_focus) + (*gdk_env())->CallVoidMethod (gdk_env(), peer, + postWindowEventID, + (jint) AWT_WINDOW_ACTIVATED, + (jobject) NULL, (jint) 0); + else + (*gdk_env())->CallVoidMethod (gdk_env(), peer, + postWindowEventID, + (jint) AWT_WINDOW_DEACTIVATED, + (jobject) NULL, (jint) 0); + gdk_threads_enter (); +} + +static gboolean +window_focus_in_cb (GtkWidget * widget __attribute__((unused)), + GdkEventFocus *event __attribute__((unused)), + jobject peer) +{ + gdk_threads_leave (); + (*gdk_env())->CallVoidMethod (gdk_env(), peer, + postWindowEventID, + (jint) AWT_WINDOW_GAINED_FOCUS, + (jobject) NULL, (jint) 0); + /* FIXME: somewhere after this is handled, the child window is + getting an expose event. */ + gdk_threads_enter (); + return FALSE; +} + +static gboolean +window_focus_out_cb (GtkWidget * widget __attribute__((unused)), + GdkEventFocus *event __attribute__((unused)), + jobject peer) +{ + gdk_threads_leave (); + (*gdk_env())->CallVoidMethod (gdk_env(), peer, + postWindowEventID, + (jint) AWT_WINDOW_LOST_FOCUS, + (jobject) NULL, (jint) 0); + /* FIXME: somewhere after this is handled, the child window is + getting an expose event. */ + gdk_threads_enter (); + return FALSE; } static gboolean @@ -700,18 +591,22 @@ window_window_state_cb (GtkWidget *widget, if (event->window_state.new_window_state & GDK_WINDOW_STATE_ICONIFIED) { /* We've been iconified. */ - (*gdk_env)->CallVoidMethod (gdk_env, peer, + gdk_threads_leave (); + (*gdk_env())->CallVoidMethod (gdk_env(), peer, postWindowEventID, (jint) AWT_WINDOW_ICONIFIED, (jobject) NULL, (jint) 0); + gdk_threads_enter (); } else { /* We've been deiconified. */ - (*gdk_env)->CallVoidMethod (gdk_env, peer, + gdk_threads_leave (); + (*gdk_env())->CallVoidMethod (gdk_env(), peer, postWindowEventID, (jint) AWT_WINDOW_DEICONIFIED, (jobject) NULL, (jint) 0); + gdk_threads_enter (); } } @@ -724,10 +619,12 @@ window_window_state_cb (GtkWidget *widget, new_state |= window_get_new_state (widget); - (*gdk_env)->CallVoidMethod (gdk_env, peer, + gdk_threads_leave (); + (*gdk_env())->CallVoidMethod (gdk_env(), peer, postWindowEventID, (jint) AWT_WINDOW_STATE_CHANGED, (jobject) NULL, new_state); + gdk_threads_enter (); return TRUE; } @@ -741,12 +638,15 @@ window_get_new_state (GtkWidget *widget) gulong atom_count; gulong bytes_after; Atom *atom_list = NULL; + union atom_list_union alu; gulong i; - XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (widget->window), + alu.atom_list = &atom_list; + XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), + GDK_WINDOW_XID (widget->window), gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE"), 0, G_MAXLONG, False, XA_ATOM, &type, &format, &atom_count, - &bytes_after, (guchar **)&atom_list); + &bytes_after, alu.gu_extents); if (type != None) { @@ -775,21 +675,9 @@ window_property_changed_cb (GtkWidget *widget __attribute__((unused)), jobject peer) { unsigned long *extents; + union extents_union gu_ex; - 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"); - id_set = 1; - } - + gu_ex.extents = &extents; if (gdk_atom_intern ("_NET_FRAME_EXTENTS", FALSE) == event->atom && gdk_property_get (event->window, gdk_atom_intern ("_NET_FRAME_EXTENTS", FALSE), @@ -800,26 +688,51 @@ window_property_changed_cb (GtkWidget *widget __attribute__((unused)), 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 */ + gu_ex.gu_extents)) + { + gdk_threads_leave (); + (*gdk_env())->CallVoidMethod (gdk_env(), peer, + postInsetsChangedEventID, + (jint) extents[2], /* top */ + (jint) extents[0], /* left */ + (jint) extents[3], /* bottom */ + (jint) extents[1]); /* right */ + gdk_threads_enter (); + } + return FALSE; } -static GdkFilterReturn -window_wm_protocols_filter (GdkXEvent *xev, - GdkEvent *event __attribute__((unused)), - gpointer data __attribute__((unused))) +static void +realize_cb (GtkWidget *widget, jobject peer) { - XEvent *xevent = (XEvent *)xev; + jint top = 0; + jint left = 0; + jint bottom = 0; + jint right = 0; + jint width = 0; + jint height = 0; + + width = (*gdk_env())->CallIntMethod (gdk_env(), peer, windowGetWidthID); + height = (*gdk_env())->CallIntMethod (gdk_env(), peer, windowGetHeightID); + + window_get_frame_extents (widget, &top, &left, &bottom, &right); + + (*gdk_env())->CallVoidMethod (gdk_env(), peer, + postInsetsChangedEventID, + top, left, bottom, right); - if ((Atom) xevent->xclient.data.l[0] == gdk_x11_get_xatom_by_name ("WM_TAKE_FOCUS")) - return GDK_FILTER_REMOVE; + gtk_window_set_default_size (GTK_WINDOW (widget), + MAX (1, width - left - right), + MAX (1, height - top - bottom)); + + /* set the size like we do in nativeSetBounds */ + gtk_widget_set_size_request (widget, + MAX (1, width - left - right), + MAX (1, height - top - bottom)); - return GDK_FILTER_CONTINUE; + gtk_window_resize (GTK_WINDOW (widget), + MAX (1, width - left - right), + MAX (1, height - top - bottom)); }