This fixes a long outstanding AWT issue:
- Frame.set[Extended]State() is now fully supported (save for the
MAXIMIZE_VERT and MAXIMIZE_HORIZ settings, which isn't supported in GTK
yet). This means that an application can now request the AWT to
iconify/maximize a Frame.
- The window state events are now reported correctly and include the
extended states.
2006-10-18 Roman Kennke <[EMAIL PROTECTED]>
PR 27091
* gnu/java/awt/peer/gtk/GtkFramePeer.java
(maximize): New native method.
(unmaximize): New native method.
(iconify): New native method.
(deiconify): New native method.
(getState): Implemented.
(setState): Implemented.
* gnu/java/awt/peer/gtk/GtkWindowPeer.java
(oldState): Rename to windowState and made protected, so that
the FramePeer can access it.
(postWindowEvent): Handle state change events more gently and
correctly.
* java/awt/Frame.java
(getState): Fetch state from getExtendedState().
(setExtendedState): Update the peer. Check if the state change
is actually supported.
(getExtendedState): Update the state from the peer.
* native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFramePeer.c
(maximize): New method.
(unmaximize): New method.
(iconify): New method.
(deiconify): New method.
* native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkWindowPeer.c
(AWT_FRAME_NORMAL): New macro.
(AWT_FRAME_ICONIFIED): New macro.
(AWT_FRAME_MAXIMIZED_BOTH): New macro.
(window_window_state_cb): Rewritten to handle window state changes
more gently (mostly on the java side of the world).
* include/gnu_java_awt_peer_gtk_GtkFramePeer.h: Regenerated.
/Roman
Index: include/gnu_java_awt_peer_gtk_GtkFramePeer.h
===================================================================
RCS file: /cvsroot/classpath/classpath/include/gnu_java_awt_peer_gtk_GtkFramePeer.h,v
retrieving revision 1.13
diff -u -1 -5 -r1.13 gnu_java_awt_peer_gtk_GtkFramePeer.h
--- include/gnu_java_awt_peer_gtk_GtkFramePeer.h 30 Apr 2006 10:37:36 -0000 1.13
+++ include/gnu_java_awt_peer_gtk_GtkFramePeer.h 18 Oct 2006 22:08:07 -0000
@@ -4,22 +4,26 @@
#define __gnu_java_awt_peer_gtk_GtkFramePeer__
#include <jni.h>
#ifdef __cplusplus
extern "C"
{
#endif
JNIEXPORT jint JNICALL Java_gnu_java_awt_peer_gtk_GtkFramePeer_getMenuBarHeight (JNIEnv *env, jobject, jobject);
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkFramePeer_setMenuBarWidthUnlocked (JNIEnv *env, jobject, jobject, jint);
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkFramePeer_setMenuBarWidth (JNIEnv *env, jobject, jobject, jint);
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkFramePeer_setMenuBarPeer (JNIEnv *env, jobject, jobject);
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkFramePeer_removeMenuBarPeer (JNIEnv *env, jobject);
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkFramePeer_gtkFixedSetVisible (JNIEnv *env, jobject, jboolean);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkFramePeer_maximize (JNIEnv *env, jobject);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkFramePeer_unmaximize (JNIEnv *env, jobject);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkFramePeer_iconify (JNIEnv *env, jobject);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkFramePeer_deiconify (JNIEnv *env, jobject);
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkFramePeer_nativeSetIconImage (JNIEnv *env, jobject, jobject);
#ifdef __cplusplus
}
#endif
#endif /* __gnu_java_awt_peer_gtk_GtkFramePeer__ */
Index: native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFramePeer.c
===================================================================
RCS file: /cvsroot/classpath/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFramePeer.c,v
retrieving revision 1.11
diff -u -1 -5 -r1.11 gnu_java_awt_peer_gtk_GtkFramePeer.c
--- native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFramePeer.c 29 May 2006 16:14:59 -0000 1.11
+++ native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFramePeer.c 18 Oct 2006 22:08:07 -0000
@@ -176,15 +176,59 @@
{
void *ptr;
GdkPixbuf *pixbuf = NULL;
gdk_threads_enter ();
pixbuf = cp_gtk_image_get_pixbuf (env, gtkimage);
g_assert (pixbuf != NULL);
ptr = NSA_GET_PTR (env, obj);
gtk_window_set_icon (GTK_WINDOW (ptr), pixbuf);
gdk_threads_leave ();
}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkFramePeer_maximize
+(JNIEnv *env, jobject obj)
+{
+ void *ptr;
+ gdk_threads_enter ();
+ ptr = NSA_GET_PTR (env, obj);
+ gtk_window_maximize (GTK_WINDOW (ptr));
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkFramePeer_unmaximize
+(JNIEnv *env, jobject obj)
+{
+ void *ptr;
+ gdk_threads_enter ();
+ ptr = NSA_GET_PTR (env, obj);
+ gtk_window_unmaximize (GTK_WINDOW (ptr));
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkFramePeer_iconify
+(JNIEnv *env, jobject obj)
+{
+ void *ptr;
+ gdk_threads_enter ();
+ ptr = NSA_GET_PTR (env, obj);
+ gtk_window_iconify (GTK_WINDOW (ptr));
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkFramePeer_deiconify
+(JNIEnv *env, jobject obj)
+{
+ void *ptr;
+ gdk_threads_enter ();
+ ptr = NSA_GET_PTR (env, obj);
+ gtk_window_deiconify (GTK_WINDOW (ptr));
+ gdk_threads_leave ();
+}
Index: native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkWindowPeer.c
===================================================================
RCS file: /cvsroot/classpath/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkWindowPeer.c,v
retrieving revision 1.70
diff -u -1 -5 -r1.70 gnu_java_awt_peer_gtk_GtkWindowPeer.c
--- native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkWindowPeer.c 18 Oct 2006 19:26:20 -0000 1.70
+++ native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkWindowPeer.c 18 Oct 2006 22:08:08 -0000
@@ -42,30 +42,34 @@
#include <gdk/gdkprivate.h>
#include <gdk/gdkx.h>
#include <X11/Xatom.h>
#include <gdk/gdkkeysyms.h>
#define AWT_WINDOW_CLOSING 201
#define AWT_WINDOW_CLOSED 202
#define AWT_WINDOW_ICONIFIED 203
#define AWT_WINDOW_DEICONIFIED 204
#define AWT_WINDOW_ACTIVATED 205
#define AWT_WINDOW_DEACTIVATED 206
#define AWT_WINDOW_GAINED_FOCUS 207
#define AWT_WINDOW_LOST_FOCUS 208
#define AWT_WINDOW_STATE_CHANGED 209
+#define AWT_FRAME_NORMAL 0
+#define AWT_FRAME_ICONIFIED 1
+#define AWT_FRAME_MAXIMIZED_BOTH 6
+
/* Virtual Keys */
/* This list should be kept in the same order as the VK_ field
declarations in KeyEvent.java. */
#define VK_ENTER '\n'
#define VK_BACK_SPACE '\b'
#define VK_TAB '\t'
#define VK_CANCEL 3
#define VK_CLEAR 12
#define VK_SHIFT 16
#define VK_CONTROL 17
#define VK_ALT 18
#define VK_PAUSE 19
#define VK_CAPS_LOCK 20
#define VK_ESCAPE 27
#define VK_SPACE ' '
@@ -1691,65 +1695,48 @@
jobject peer)
{
(*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
postWindowEventID,
(jint) AWT_WINDOW_LOST_FOCUS,
(jobject) NULL, (jint) 0);
return FALSE;
}
static gboolean
window_window_state_cb (GtkWidget *widget __attribute__((unused)),
GdkEvent *event,
jobject peer)
{
- jint new_state;
-
- /* Handle WINDOW_ICONIFIED and WINDOW_DEICONIFIED events. */
- if (event->window_state.changed_mask & GDK_WINDOW_STATE_ICONIFIED)
- {
- /* We've either been iconified or deiconified. */
- if (event->window_state.new_window_state & GDK_WINDOW_STATE_ICONIFIED)
- {
- /* We've been iconified. */
- (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
- postWindowEventID,
- (jint) AWT_WINDOW_ICONIFIED,
- (jobject) NULL, (jint) 0);
- }
- else
- {
- /* We've been deiconified. */
- (*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
- postWindowEventID,
- (jint) AWT_WINDOW_DEICONIFIED,
- (jobject) NULL, (jint) 0);
- }
- }
-
- /* Post a WINDOW_STATE_CHANGED event, passing the new frame state to
- GtkWindowPeer. */
- new_state = AWT_FRAME_STATE_NORMAL;
-
- if (event->window_state.new_window_state & GDK_WINDOW_STATE_ICONIFIED)
- new_state |= AWT_FRAME_STATE_ICONIFIED;
+ jint new_java_state = 0;
+ /* Put together the new state and let the java side figure out what
+ * to post */
+ GdkWindowState new_state = event->window_state.new_window_state;
+ /* The window can be either iconfified, maximized, iconified + maximized
+ * or normal. */
+ if ((new_state & GDK_WINDOW_STATE_ICONIFIED) != 0)
+ new_java_state |= AWT_FRAME_ICONIFIED;
+ if ((new_state & GDK_WINDOW_STATE_MAXIMIZED) != 0)
+ new_java_state |= AWT_FRAME_MAXIMIZED_BOTH;
+ if ((new_state & (GDK_WINDOW_STATE_MAXIMIZED | GDK_WINDOW_STATE_ICONIFIED))
+ == 0)
+ new_java_state = AWT_FRAME_NORMAL;
(*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
postWindowEventID,
(jint) AWT_WINDOW_STATE_CHANGED,
- (jobject) NULL, new_state);
+ (jobject) NULL, new_java_state);
return TRUE;
}
static gboolean
window_property_changed_cb (GtkWidget *widget __attribute__((unused)),
GdkEventProperty *event,
jobject peer)
{
unsigned long *extents;
union extents_union gu_ex;
gu_ex.extents = &extents;
if (gdk_atom_intern ("_NET_FRAME_EXTENTS", FALSE) == event->atom
&& gdk_property_get (event->window,
Index: gnu/java/awt/peer/gtk/GtkFramePeer.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/java/awt/peer/gtk/GtkFramePeer.java,v
retrieving revision 1.48
diff -u -1 -5 -r1.48 GtkFramePeer.java
--- gnu/java/awt/peer/gtk/GtkFramePeer.java 17 Jul 2006 22:41:03 -0000 1.48
+++ gnu/java/awt/peer/gtk/GtkFramePeer.java 18 Oct 2006 22:08:09 -0000
@@ -45,30 +45,35 @@
import java.awt.peer.FramePeer;
import java.awt.peer.MenuBarPeer;
public class GtkFramePeer extends GtkWindowPeer
implements FramePeer
{
private int menuBarHeight;
private MenuBarPeer menuBar;
native int getMenuBarHeight (MenuBarPeer bar);
native void setMenuBarWidthUnlocked (MenuBarPeer bar, int width);
native void setMenuBarWidth (MenuBarPeer bar, int width);
native void setMenuBarPeer (MenuBarPeer bar);
native void removeMenuBarPeer ();
native void gtkFixedSetVisible (boolean visible);
+ private native void maximize();
+ private native void unmaximize();
+ private native void iconify();
+ private native void deiconify();
+
int getMenuBarHeight ()
{
return menuBar == null ? 0 : getMenuBarHeight (menuBar);
}
public void setMenuBar (MenuBar bar)
{
if (bar == null && menuBar != null)
{
// We're removing the menubar.
gtkFixedSetVisible (false);
menuBar = null;
removeMenuBarPeer ();
insets.top -= menuBarHeight;
menuBarHeight = 0;
@@ -187,36 +192,49 @@
// Since insets.top already includes the MenuBar's height, we need
// to subtract the MenuBar's height from the top inset.
int frame_height = height - menuBarHeight;
// Likewise, since insets.top includes the MenuBar height, we need
// to add back the MenuBar height to the frame's y position. If
// no MenuBar exists in this frame, the MenuBar height will be 0.
int frame_y = y + menuBarHeight;
super.postConfigureEvent(x, frame_y, width, frame_height);
}
public int getState ()
{
- return 0;
+ return windowState;
}
public void setState (int state)
{
-
+ switch (state)
+ {
+ case Frame.NORMAL:
+ if ((windowState & Frame.ICONIFIED) != 0)
+ deiconify();
+ if ((windowState & Frame.MAXIMIZED_BOTH) != 0)
+ unmaximize();
+ break;
+ case Frame.ICONIFIED:
+ iconify();
+ break;
+ case Frame.MAXIMIZED_BOTH:
+ maximize();
+ }
}
public void setMaximizedBounds (Rectangle r)
{
}
public void setBoundsPrivate(int x, int y, int width, int height)
{
// TODO Auto-generated method stub
}
public boolean requestWindowFocus()
{
// TODO Auto-generated method stub
Index: gnu/java/awt/peer/gtk/GtkToolkit.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/java/awt/peer/gtk/GtkToolkit.java,v
retrieving revision 1.93
diff -u -1 -5 -r1.93 GtkToolkit.java
--- gnu/java/awt/peer/gtk/GtkToolkit.java 8 Aug 2006 22:23:36 -0000 1.93
+++ gnu/java/awt/peer/gtk/GtkToolkit.java 18 Oct 2006 22:08:09 -0000
@@ -652,18 +652,26 @@
public RobotPeer createRobot (GraphicsDevice screen) throws AWTException
{
return new GdkRobotPeer (screen);
}
public void registerImageIOSpis(IIORegistry reg)
{
GdkPixbufDecoder.registerSpis(reg);
}
protected MouseInfoPeer getMouseInfoPeer()
{
return new GtkMouseInfoPeer();
}
+ public boolean isFrameStateSupported(int state)
+ {
+ // GTK supports ICONFIED, NORMAL and MAXIMIZE_BOTH, but
+ // not (yet?) MAXIMIZE_VERT and MAXIMIZE_HORIZ.
+ return state == Frame.NORMAL || state == Frame.ICONIFIED
+ || state == Frame.MAXIMIZED_BOTH;
+ }
+
public native int getMouseNumberOfButtons();
} // class GtkToolkit
Index: gnu/java/awt/peer/gtk/GtkWindowPeer.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/java/awt/peer/gtk/GtkWindowPeer.java,v
retrieving revision 1.56
diff -u -1 -5 -r1.56 GtkWindowPeer.java
--- gnu/java/awt/peer/gtk/GtkWindowPeer.java 18 Oct 2006 19:26:20 -0000 1.56
+++ gnu/java/awt/peer/gtk/GtkWindowPeer.java 18 Oct 2006 22:08:10 -0000
@@ -52,31 +52,31 @@
import java.awt.event.WindowEvent;
import java.awt.peer.WindowPeer;
public class GtkWindowPeer extends GtkContainerPeer
implements WindowPeer
{
protected static final int GDK_WINDOW_TYPE_HINT_NORMAL = 0;
protected static final int GDK_WINDOW_TYPE_HINT_DIALOG = 1;
protected static final int GDK_WINDOW_TYPE_HINT_MENU = 2;
protected static final int GDK_WINDOW_TYPE_HINT_TOOLBAR = 3;
protected static final int GDK_WINDOW_TYPE_HINT_SPLASHSCREEN = 4;
protected static final int GDK_WINDOW_TYPE_HINT_UTILITY = 5;
protected static final int GDK_WINDOW_TYPE_HINT_DOCK = 6;
protected static final int GDK_WINDOW_TYPE_HINT_DESKTOP = 7;
- private int oldState = Frame.NORMAL;
+ protected int windowState = Frame.NORMAL;
// Cached awt window component location, width and height.
private int x, y, width, height;
native void gtkWindowSetTitle (String title);
native void gtkWindowSetResizable (boolean resizable);
native void gtkWindowSetModal (boolean modal);
native void gtkWindowSetAlwaysOnTop ( boolean alwaysOnTop );
native boolean gtkWindowHasFocus();
native void realize ();
public void dispose()
{
super.dispose();
GtkMainThread.destroyWindow();
@@ -272,35 +272,48 @@
public void show ()
{
x = awtComponent.getX();
y = awtComponent.getY();
width = awtComponent.getWidth();
height = awtComponent.getHeight();
setLocation(x, y);
setVisible (true);
}
void postWindowEvent (int id, Window opposite, int newState)
{
if (id == WindowEvent.WINDOW_STATE_CHANGED)
{
- if (oldState != newState)
+ if (windowState != newState)
{
- q().postEvent (new WindowEvent ((Window) awtComponent, id, opposite,
- oldState, newState));
- oldState = newState;
+ // Post old styleWindowEvent with WINDOW_ICONIFIED or
+ // WINDOW_DEICONIFIED if appropriate.
+ if ((windowState & Frame.ICONIFIED) != 0
+ && (newState & Frame.ICONIFIED) == 0)
+ q().postEvent(new WindowEvent((Window) awtComponent,
+ WindowEvent.WINDOW_DEICONIFIED,
+ opposite, 0, 0));
+ else if ((windowState & Frame.ICONIFIED) == 0
+ && (newState & Frame.ICONIFIED) != 0)
+ q().postEvent(new WindowEvent((Window) awtComponent,
+ WindowEvent.WINDOW_ICONIFIED,
+ opposite, 0, 0));
+ // Post new-style WindowStateEvent.
+ q().postEvent (new WindowEvent ((Window) awtComponent, id,
+ opposite, windowState, newState));
+ windowState = newState;
}
}
else
q().postEvent (new WindowEvent ((Window) awtComponent, id, opposite));
}
/**
* Update the always-on-top status of the native window.
*/
public void updateAlwaysOnTop()
{
gtkWindowSetAlwaysOnTop( ((Window)awtComponent).isAlwaysOnTop() );
}
protected void postExposeEvent (int x, int y, int width, int height)
Index: java/awt/Frame.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/awt/Frame.java,v
retrieving revision 1.39
diff -u -1 -5 -r1.39 Frame.java
--- java/awt/Frame.java 20 Sep 2006 09:12:25 -0000 1.39
+++ java/awt/Frame.java 18 Oct 2006 22:08:10 -0000
@@ -524,47 +524,55 @@
public void setState(int state)
{
int current_state = getExtendedState ();
if (state == NORMAL
&& (current_state & ICONIFIED) != 0)
setExtendedState(current_state | ICONIFIED);
if (state == ICONIFIED
&& (current_state & ~ICONIFIED) == 0)
setExtendedState(current_state & ~ICONIFIED);
}
public int getState()
{
- // FIXME: State might have changed in the peer... Must check.
- return (state & ICONIFIED) != 0 ? ICONIFIED : NORMAL;
+ return (getExtendedState() & ICONIFIED) != 0 ? ICONIFIED : NORMAL;
}
/**
* @since 1.4
*/
public void setExtendedState(int state)
{
- this.state = state;
+ if (getToolkit().isFrameStateSupported(state))
+ {
+ this.state = state;
+ FramePeer p = (FramePeer) peer;
+ if (p != null)
+ p.setState(state);
+ }
}
/**
* @since 1.4
*/
public int getExtendedState()
{
+ FramePeer p = (FramePeer) peer;
+ if (p != null)
+ state = p.getState();
return state;
}
/**
* @since 1.4
*/
public void setMaximizedBounds(Rectangle maximizedBounds)
{
this.maximizedBounds = maximizedBounds;
}
/**
* Returns the maximized bounds of this frame.
*
* @return the maximized rectangle, may be null