This should fix PR #16203, and also make for a general improvement.
In short: The main GTK loop is not started statically in GtkToolkit,
but rather on creating the first window peer. (as it should be).
In long:
On destroying the last window peer, we call gtk to end the main
loop and the thread exits. If a new window is opened, we create
a new thread object and restart the main gtk loop.
I also moved all the stuff related to this (except native methods)
out from GtkToolkit and into a new GtkMainThread class. This should
help reduce the clutter in the already ugly GtkToolkit class.
It seems to work just fine for me, but being a rather central thing
I'd like some feedback and testing before committing it.
(Obviously not intended for the 0.92 release)
/Sven
2006-08-03 Sven de Marothy <[EMAIL PROTECTED]>
* gnu/java/awt/peer/gtk/GtkMainThread.java
New file.
* gnu/java/awt/peer/gtk/GtkChoicePeer.java
* gnu/java/awt/peer/gtk/GtkComponentPeer.java
Replace occurances of GtkToolkit.mainThread to GtkMainThread.mainThread.
* gnu/java/awt/peer/gtk/GtkToolkit.java
Minor style fixes; removed unused fields,
set fields to private where possible.
(createDialog, createFrame, createWindow, createEmbeddedWindow):
Call GtkMainThread.createWindow().
* gnu/java/awt/peer/gtk/GtkWindowPeer.java
(dispose): New method.
* include/gnu_java_awt_peer_gtk_GtkToolkit.h
* native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkToolkit.c
(gtkQuit): New native method.
Index: gnu/java/awt/peer/gtk/GtkChoicePeer.java
===================================================================
RCS file: /sources/classpath/classpath/gnu/java/awt/peer/gtk/GtkChoicePeer.java,v
retrieving revision 1.27
diff -U3 -r1.27 GtkChoicePeer.java
--- gnu/java/awt/peer/gtk/GtkChoicePeer.java 3 Aug 2006 04:31:03 -0000 1.27
+++ gnu/java/awt/peer/gtk/GtkChoicePeer.java 3 Aug 2006 06:01:21 -0000
@@ -84,7 +84,7 @@
public void select (int position)
{
- if (Thread.currentThread() == GtkToolkit.mainThread)
+ if (Thread.currentThread() == GtkMainThread.mainThread)
selectNativeUnlocked (position);
else
selectNative (position);
Index: gnu/java/awt/peer/gtk/GtkComponentPeer.java
===================================================================
RCS file: /sources/classpath/classpath/gnu/java/awt/peer/gtk/GtkComponentPeer.java,v
retrieving revision 1.119
diff -U3 -r1.119 GtkComponentPeer.java
--- gnu/java/awt/peer/gtk/GtkComponentPeer.java 26 Jul 2006 19:09:50 -0000 1.119
+++ gnu/java/awt/peer/gtk/GtkComponentPeer.java 3 Aug 2006 06:01:21 -0000
@@ -514,7 +514,7 @@
y = 0;
}
- if (Thread.currentThread() == GtkToolkit.mainThread)
+ if (Thread.currentThread() == GtkMainThread.mainThread)
gtkWidgetSetCursorUnlocked(cursor.getType(), image, x, y);
else
gtkWidgetSetCursor(cursor.getType(), image, x, y);
@@ -562,7 +562,7 @@
b = (bounds.width > 0) && (bounds.height > 0);
}
- if (Thread.currentThread() == GtkToolkit.mainThread)
+ if (Thread.currentThread() == GtkMainThread.mainThread)
setVisibleNativeUnlocked (b);
else
setVisibleNative (b);
Index: gnu/java/awt/peer/gtk/GtkToolkit.java
===================================================================
RCS file: /sources/classpath/classpath/gnu/java/awt/peer/gtk/GtkToolkit.java,v
retrieving revision 1.92
diff -U3 -r1.92 GtkToolkit.java
--- gnu/java/awt/peer/gtk/GtkToolkit.java 24 Jul 2006 10:21:59 -0000 1.92
+++ gnu/java/awt/peer/gtk/GtkToolkit.java 3 Aug 2006 06:01:21 -0000
@@ -131,37 +131,30 @@
public class GtkToolkit extends gnu.java.awt.ClasspathToolkit
{
- Hashtable containers = new Hashtable();
- static EventQueue q;
- static Thread mainThread;
+ private static EventQueue q;
static native void gtkInit(int portableNativeSync);
+ static native void gtkMain();
+
+ static native void gtkQuit();
+
static
{
System.loadLibrary("gtkpeer");
-
+
int portableNativeSync;
String portNatSyncProp =
System.getProperty("gnu.classpath.awt.gtk.portable.native.sync");
-
+
if (portNatSyncProp == null)
portableNativeSync = -1; // unset
else if (Boolean.valueOf(portNatSyncProp).booleanValue())
portableNativeSync = 1; // true
else
portableNativeSync = 0; // false
-
+
gtkInit(portableNativeSync);
-
- mainThread = new Thread ("GTK main thread")
- {
- public void run ()
- {
- gtkMain ();
- }
- };
- mainThread.start ();
}
public GtkToolkit ()
@@ -169,6 +162,7 @@
}
public native void beep();
+
private native void getScreenSizeDimensions(int[] xy);
public int checkImage (Image image, int width, int height,
@@ -462,6 +456,7 @@
protected DialogPeer createDialog (Dialog d)
{
+ GtkMainThread.createWindow();
return new GtkDialogPeer (d);
}
@@ -472,6 +467,7 @@
protected FramePeer createFrame (Frame f)
{
+ GtkMainThread.createWindow();
return new GtkFramePeer (f);
}
@@ -532,11 +528,13 @@
protected WindowPeer createWindow (Window w)
{
+ GtkMainThread.createWindow();
return new GtkWindowPeer (w);
}
public EmbeddedWindowPeer createEmbeddedWindow (EmbeddedWindow w)
{
+ GtkMainThread.createWindow();
return new GtkEmbeddedWindowPeer (w);
}
@@ -661,8 +659,6 @@
GdkPixbufDecoder.registerSpis(reg);
}
- public static native void gtkMain();
-
protected MouseInfoPeer getMouseInfoPeer()
{
return new GtkMouseInfoPeer();
Index: gnu/java/awt/peer/gtk/GtkWindowPeer.java
===================================================================
RCS file: /sources/classpath/classpath/gnu/java/awt/peer/gtk/GtkWindowPeer.java,v
retrieving revision 1.52
diff -U3 -r1.52 GtkWindowPeer.java
--- gnu/java/awt/peer/gtk/GtkWindowPeer.java 26 Jul 2006 19:09:50 -0000 1.52
+++ gnu/java/awt/peer/gtk/GtkWindowPeer.java 3 Aug 2006 06:01:22 -0000
@@ -75,6 +75,12 @@
native boolean gtkWindowHasFocus();
native void realize ();
+ public void dispose()
+ {
+ super.dispose();
+ GtkMainThread.destroyWindow();
+ }
+
/** Returns the cached width of the AWT window component. */
int getX ()
{
Index: include/gnu_java_awt_peer_gtk_GtkToolkit.h
===================================================================
RCS file: /sources/classpath/classpath/include/gnu_java_awt_peer_gtk_GtkToolkit.h,v
retrieving revision 1.12
diff -U3 -r1.12 gnu_java_awt_peer_gtk_GtkToolkit.h
--- include/gnu_java_awt_peer_gtk_GtkToolkit.h 15 Jul 2006 08:02:23 -0000 1.12
+++ include/gnu_java_awt_peer_gtk_GtkToolkit.h 3 Aug 2006 06:01:24 -0000
@@ -17,6 +17,7 @@
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkToolkit_sync (JNIEnv *env, jobject);
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkToolkit_loadSystemColors (JNIEnv *env, jobject, jintArray);
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkToolkit_gtkMain (JNIEnv *env, jclass);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkToolkit_gtkQuit (JNIEnv *env, jclass);
JNIEXPORT jint JNICALL Java_gnu_java_awt_peer_gtk_GtkToolkit_getMouseNumberOfButtons (JNIEnv *env, jobject);
#ifdef __cplusplus
Index: native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkToolkit.c
===================================================================
RCS file: /sources/classpath/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkToolkit.c,v
retrieving revision 1.28
diff -U3 -r1.28 gnu_java_awt_peer_gtk_GtkToolkit.c
--- native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkToolkit.c 15 Jul 2006 16:55:07 -0000 1.28
+++ native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkToolkit.c 3 Aug 2006 06:01:33 -0000
@@ -329,6 +329,17 @@
gdk_threads_leave ();
}
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkToolkit_gtkQuit
+(JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)))
+{
+ gdk_threads_enter ();
+
+ gtk_main_quit ();
+
+ gdk_threads_leave ();
+}
+
static jint gdk_color_to_java_color (GdkColor color);
/* GtkMainThread.java -- Wrapper for the GTK main thread, and some utilities.
Copyright (C) 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.awt.peer.gtk;
public class GtkMainThread extends Thread
{
/** Count of the number of open windows */
private static int numberOfWindows = 0;
/** Lock for the above */
private static Object nWindowsLock = new Object();
/** The main thread instance (singleton) */
public static GtkMainThread mainThread;
/** Constructs a main thread */
private GtkMainThread()
{
super("GTK main thread");
}
public void run ()
{
GtkToolkit.gtkMain ();
}
private static void startMainThread()
{
if( mainThread == null )
{
mainThread = new GtkMainThread();
mainThread.start();
}
}
private static void endMainThread()
{
if( mainThread != null )
GtkToolkit.gtkQuit();
}
public static void createWindow()
{
synchronized( nWindowsLock )
{
if( numberOfWindows == 0 )
startMainThread();
numberOfWindows++;
}
}
public static void destroyWindow()
{
synchronized( nWindowsLock )
{
numberOfWindows--;
if( numberOfWindows == 0 )
endMainThread();
}
}
}