2003-10-08 Thomas Fitzsimmons <fitzsim@redhat.com>
+ * gnu/java/awt/peer/gtk/GtkButtonPeer.java (handleEvent): Remove
+ modality check.
+ * gnu/java/awt/peer/gtk/GtkDialogPeer.java (initializeInsets):
+ Initialize insets to use latest insets.
+ * gnu/java/awt/peer/gtk/GtkFramePeer.java: Likewise.
+ * gnu/java/awt/peer/gtk/GtkWindowPeer.java (latestInsets): New
+ field.
+ (postConfigureEvent): Update latestInsets field when insets
+ change. Remove call to setSize. Move validate call outside of
+ if blocks.
+ (setVisible): Call setBounds before showing window.
+ (nativeSetVisible): New native method.
+ * java/awt/Window.java (show): Show visible owned windows.
+ (hide): Hide visible owned windows.
+ * jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.c
+ (awt_event_handler): Implement modality using GTK grabs.
+ * jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMainThread.c
+ (global_gtk_window_group): New global variable.
+ (gtkInit): Initialize global_gtk_window_group.
+ * jni/gtk-peer/gnu_java_awt_peer_gtk_GtkWindowPeer.c (create):
+ Clamp width and height values to at least 1. Add this window to
+ the global GTK window group.
+ (setVisible): Rename to nativeSetVisible.
+ (setup_window): Remove function.
+ (setSize): Clamp width and height values to at least 1.
+ (nativeSetBounds): Likewise.
+ (gdk_window_get_root_geometry): Remove function.
+ * jni/gtk-peer/gtkpeer.h: Remove gdk_window_get_root_geometry
+ and setup_window declarations. Declare global_gtk_window_group.
+
* gnu/java/awt/peer/gtk/GtkButtonPeer.java,
jni/gtk-peer/gnu_java_awt_peer_gtk_GtkButtonPeer.c
(gtkSetFont): Handle BOLD and ITALIC style specifiers.
public void handleEvent (AWTEvent e)
{
- if (e.getID () == MouseEvent.MOUSE_CLICKED && isEnabled ()
- && !modalHasGrab ())
+ if (e.getID () == MouseEvent.MOUSE_CLICKED && isEnabled ())
{
MouseEvent me = (MouseEvent) e;
if (!me.isConsumed ()
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);
+ synchronized (latestInsets)
+ {
+ insets = new Insets (latestInsets.top,
+ latestInsets.left,
+ latestInsets.bottom,
+ latestInsets.right);
+ }
}
void create ()
// 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);
+ synchronized (latestInsets)
+ {
+ insets = new Insets (latestInsets.top,
+ latestInsets.left,
+ latestInsets.bottom,
+ latestInsets.right);
+ }
}
void create ()
static protected final int GDK_WINDOW_TYPE_HINT_DOCK = 6;
static protected final int GDK_WINDOW_TYPE_HINT_DESKTOP = 7;
+ // 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);
set ("title", title);
}
+ native void setSize (int width, int height);
+
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);
+ 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);
insets.bottom = bottom;
insets.right = right;
- awtComponent.validate();
+ synchronized (latestInsets)
+ {
+ latestInsets.top = top;
+ latestInsets.left = left;
+ latestInsets.bottom = bottom;
+ latestInsets.right = right;
+ }
}
else
{
frame_y,
frame_width,
frame_height);
-
- if (frame_width != awtComponent.getWidth()
- || frame_height != awtComponent.getHeight())
- setSize (width, height);
-
- awtComponent.validate();
}
}
+ awtComponent.validate();
}
- native public void setVisible (boolean b);
+ native void nativeSetVisible (boolean b);
+ public void setVisible (boolean b)
+ {
+ // Prevent the window manager from automatically placing this
+ // window when it is shown.
+ if (b)
+ setBounds (awtComponent.getX(),
+ awtComponent.getY(),
+ awtComponent.getWidth(),
+ awtComponent.getHeight());
+ nativeSetVisible (b);
+ }
}
}
/**
- * Makes this window visible and brings it to the front.
+ * Shows on-screen this window and any of its owned windows for whom
+ * isVisible returns true.
*/
public void show()
{
if (peer == null)
addNotify();
+ // Show visible owned windows.
+ synchronized (ownedWindows)
+ {
+ Iterator e = ownedWindows.iterator();
+ while(e.hasNext())
+ {
+ Window w = (Window)(((Reference) e.next()).get());
+ if (w != null)
+ {
+ if (w.isVisible())
+ w.getPeer().setVisible(true);
+ }
+ else
+ // Remove null weak reference from ownedWindows.
+ // Unfortunately this can't be done in the Window's
+ // finalize method because there is no way to guarantee
+ // synchronous access to ownedWindows there.
+ e.remove();
+ }
+ }
validate();
super.show();
toFront();
public void hide()
{
+ // Hide visible owned windows.
synchronized (ownedWindows)
{
Iterator e = ownedWindows.iterator();
{
Window w = (Window)(((Reference) e.next()).get());
if (w != null)
- w.hide();
+ {
+ if (w.isVisible() && w.getPeer() != null)
+ w.getPeer().setVisible(false);
+ }
else
- // Remove null weak reference from ownedWindows.
- // Unfortunately this can't be done in the Window's
- // finalize method because there is no way to guarantee
- // synchronous access to ownedWindows there.
e.remove();
}
}
-
super.hide();
}
void
awt_event_handler (GdkEvent *event)
{
- jobject *obj_ptr;
+ jobject *event_obj_ptr;
static guint32 button_click_time = 0;
static GdkWindow *button_window = NULL;
static guint button_number = -1;
NULL,
NULL,
NULL,
- (guchar **)&obj_ptr))
+ (guchar **)&event_obj_ptr))
{
+ GtkWidget *event_widget;
+ GtkWidget *grab_widget;
+ jobject *grab_obj_ptr = NULL;
+ void *ptr;
+
+ /* Implement modality using GTK grabs. */
+ g_assert (global_gtk_window_group);
+ if (global_gtk_window_group->grabs)
+ {
+ grab_widget = global_gtk_window_group->grabs->data;
+ g_assert (grab_widget);
+
+ gdk_property_get (grab_widget->window,
+ gdk_atom_intern ("_GNU_GTKAWT_ADDR", FALSE),
+ gdk_atom_intern ("CARDINAL", FALSE),
+ 0,
+ sizeof (jobject),
+ FALSE,
+ NULL,
+ NULL,
+ NULL,
+ (guchar **)&grab_obj_ptr);
+
+ ptr = NSA_GET_PTR (gdk_env, *event_obj_ptr);
+ event_widget = GTK_WIDGET(ptr);
+
+ if (GTK_WIDGET_IS_SENSITIVE (event_widget) &&
+ gtk_widget_is_ancestor (event_widget, grab_widget))
+ {
+ g_free (grab_obj_ptr);
+
+ grab_obj_ptr = event_obj_ptr;
+ }
+ }
+ else
+ grab_obj_ptr = event_obj_ptr;
+
switch (event->type)
{
case GDK_BUTTON_PRESS:
- (*gdk_env)->CallVoidMethod (gdk_env, *obj_ptr, postMouseEventID,
+ (*gdk_env)->CallVoidMethod (gdk_env, *grab_obj_ptr, postMouseEventID,
AWT_MOUSE_PRESSED,
(jlong)event->button.time,
state_to_awt_mods (event->button.state) |
/* if (--grab_counter == 0)
gdk_pointer_ungrab (event->button.time);
*/
- (*gdk_env)->CallVoidMethod (gdk_env, *obj_ptr, postMouseEventID,
+ (*gdk_env)->CallVoidMethod (gdk_env, *grab_obj_ptr,
+ postMouseEventID,
AWT_MOUSE_RELEASED,
(jlong)event->button.time,
state_to_awt_mods (event->button.state) |
&& event->button.y >= 0
&& event->button.x <= width
&& event->button.y <= height)
- (*gdk_env)->CallVoidMethod (gdk_env, *obj_ptr, postMouseEventID,
+ (*gdk_env)->CallVoidMethod (gdk_env, *grab_obj_ptr,
+ postMouseEventID,
AWT_MOUSE_CLICKED,
(jlong)event->button.time,
state_to_awt_mods (event->button.state) |
}
break;
case GDK_MOTION_NOTIFY:
- (*gdk_env)->CallVoidMethod (gdk_env, *obj_ptr, postMouseEventID,
+ (*gdk_env)->CallVoidMethod (gdk_env, *grab_obj_ptr, postMouseEventID,
AWT_MOUSE_MOVED,
(jlong)event->motion.time,
state_to_awt_mods (event->motion.state),
| GDK_BUTTON4_MASK
| GDK_BUTTON5_MASK))
{
- (*gdk_env)->CallVoidMethod (gdk_env, *obj_ptr, postMouseEventID,
+ (*gdk_env)->CallVoidMethod (gdk_env, *grab_obj_ptr,
+ postMouseEventID,
AWT_MOUSE_DRAGGED,
(jlong)event->motion.time,
state_to_awt_mods (event->motion.state),
}
break;
case GDK_ENTER_NOTIFY:
- (*gdk_env)->CallVoidMethod (gdk_env, *obj_ptr, postMouseEventID,
+ (*gdk_env)->CallVoidMethod (gdk_env, *grab_obj_ptr, postMouseEventID,
AWT_MOUSE_ENTERED,
(jlong)event->crossing.time,
state_to_awt_mods (event->crossing.state),
break;
case GDK_LEAVE_NOTIFY:
if (event->crossing.mode == GDK_CROSSING_NORMAL)
- (*gdk_env)->CallVoidMethod (gdk_env, *obj_ptr, postMouseEventID,
+ (*gdk_env)->CallVoidMethod (gdk_env, *grab_obj_ptr,
+ postMouseEventID,
AWT_MOUSE_EXITED,
(jlong)event->crossing.time,
state_to_awt_mods (event->crossing.state),
bottom = r.height - h - y;
right = r.width - w - x;
- (*gdk_env)->CallVoidMethod (gdk_env, *obj_ptr,
+ (*gdk_env)->CallVoidMethod (gdk_env, *event_obj_ptr,
postConfigureEventID,
(jint) event->configure.x,
(jint) event->configure.y,
break;
case GDK_EXPOSE:
{
- (*gdk_env)->CallVoidMethod (gdk_env, *obj_ptr,
+ (*gdk_env)->CallVoidMethod (gdk_env, *event_obj_ptr,
postExposeEventID,
(jint)event->expose.area.x,
(jint)event->expose.area.y,
NULL,
NULL,
NULL,
- (guchar **)&obj_ptr);
+ (guchar **)&grab_obj_ptr);
- (*gdk_env)->CallVoidMethod (gdk_env, *obj_ptr,
+ (*gdk_env)->CallVoidMethod (gdk_env, *grab_obj_ptr,
postKeyEventID,
(jint) AWT_KEY_PRESSED,
(jlong) event->key.time,
keysym_to_awt_keylocation (event));
if (generates_key_typed_event (event, window->focus_widget))
- (*gdk_env)->CallVoidMethod (gdk_env, *obj_ptr,
+ (*gdk_env)->CallVoidMethod (gdk_env, *grab_obj_ptr,
postKeyEventID,
(jint) AWT_KEY_TYPED,
(jlong) event->key.time,
- state_to_awt_mods (event->key.state),
+ state_to_awt_mods (event->key.state),
VK_UNDEFINED,
keyevent_to_awt_keychar (event),
AWT_KEY_LOCATION_UNKNOWN);
NULL,
NULL,
NULL,
- (guchar **)&obj_ptr);
+ (guchar **)&grab_obj_ptr);
- (*gdk_env)->CallVoidMethod (gdk_env, *obj_ptr,
+ (*gdk_env)->CallVoidMethod (gdk_env, *grab_obj_ptr,
postKeyEventID,
(jint) AWT_KEY_RELEASED,
(jlong) event->key.time,
}
break;
case GDK_FOCUS_CHANGE:
- (*gdk_env)->CallVoidMethod (gdk_env, *obj_ptr,
+ (*gdk_env)->CallVoidMethod (gdk_env, *event_obj_ptr,
postFocusEventID,
(jint) (event->focus_change.in) ?
AWT_FOCUS_GAINED : AWT_FOCUS_LOST,
default:
break;
}
- g_free (obj_ptr);
+ g_free (event_obj_ptr);
}
gtk_main_do_event (event);
JavaVM *gdk_vm;
#endif
+GtkWindowGroup *global_gtk_window_group;
+
/*
* Call gtk_init. It is very important that this happen before any other
* gtk calls.
postTextEventID = (*env)->GetMethodID (env, gtktextcomponentpeer,
"postTextEvent",
"()V");
+ global_gtk_window_group = gtk_window_group_new ();
}
/*
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
gtk_window_set_type_hint (window, type);
+ 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);
NSA_SET_PTR (env, obj, window_widget);
}
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkWindowPeer_setVisible
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkWindowPeer_nativeSetVisible
(JNIEnv *env, jobject obj, jboolean visible)
{
void *ptr;
gdk_threads_leave ();
}
-void
-setup_window (JNIEnv *env, jobject obj, GtkWidget *window, jint width,
- jint height, jboolean visible)
-{
- GtkWidget *layout, *vbox;
-
- gdk_threads_enter();
- gtk_window_set_policy (GTK_WINDOW (window), 1, 1, 0);
- gtk_widget_set_usize (window, width, height);
-
- 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_widget_realize (layout);
- connect_awt_hook (env, obj, 1, GTK_LAYOUT(layout)->bin_window);
- gtk_widget_show (layout);
- gtk_widget_show (vbox);
-
- gtk_widget_realize (window);
-
- connect_awt_hook (env, obj, 1, window->window);
- set_visible (window, visible);
- gdk_threads_leave ();
-}
-
/*
* Set a frame's title
*/
{
void *ptr = NSA_GET_PTR (env, obj);
+ // Avoid GTK runtime assertion failures.
+ width = (width < 1) ? 1 : width;
+ height = (height < 1) ? 1 : height;
+
gdk_threads_enter ();
gtk_widget_set_size_request (GTK_WIDGET(ptr), width, height);
gdk_threads_leave ();
{
void *ptr = NSA_GET_PTR (env, obj);
+ // Avoid GTK runtime assertion failures.
+ width = (width < 1) ? 1 : width;
+ height = (height < 1) ? 1 : height;
+
gdk_threads_enter ();
gtk_window_move (GTK_WINDOW(ptr), x, y);
/* Need to change the widget's request size. */
return height;
}
-
-
-void
-gdk_window_get_root_geometry (GdkWindow *window,
- gint *x,
- gint *y,
- gint *width,
- gint *height,
- gint *border,
- gint *depth)
-{
- GdkWindow *private;
-
- g_return_if_fail (window != NULL);
-
- private = (GdkWindow*) window;
- if (x)
- *x = 0;
- if (y)
- *y = 0;
- if (width)
- *width = 0;
- if (height)
- *height = 0;
- if (border)
- *border = 0;
- if (depth)
- *depth = 0;
-
- if (GDK_WINDOW_DESTROYED (private))
- return;
-
- private = gdk_window_get_toplevel (private);
- if (GDK_WINDOW_DESTROYED(private))
- return;
-
- gdk_window_get_geometry (private, x, y, width, height, depth);
-
-}
-
extern jmethodID gdkColorID;
extern JNIEnv *gdk_env;
-void
-gdk_window_get_root_geometry (GdkWindow *window,
- gint *x,
- gint *y,
- gint *width,
- gint *height,
- gint *border,
- gint *depth);
+extern GtkWindowGroup *global_gtk_window_group;
void awt_event_handler (GdkEvent *event);
void set_visible (GtkWidget *widget, jboolean visible);
void set_parent (GtkWidget *widget, GtkContainer *parent);
GtkLayout *find_gtk_layout (GtkWidget *parent);
-void setup_window (JNIEnv *env, jobject obj, GtkWidget *window, jint width,
- jint height, jboolean visible);
jint keyevent_state_to_awt_mods (GdkEvent *event);