Added support for detecting if javaFX already started the GTK event loop (and hooking into the right places for shutdown if it does).
This commit is contained in:
parent
2e692733b3
commit
56f4bac16a
|
@ -58,7 +58,7 @@ interface Gtk extends Library {
|
|||
}
|
||||
}
|
||||
|
||||
void gtk_init(int argc, String[] argv);
|
||||
boolean gtk_init_check(int argc, String[] argv);
|
||||
|
||||
/**
|
||||
* Runs the main loop until gtk_main_quit() is called. You can nest calls to gtk_main(). In that case gtk_main_quit() will make the
|
||||
|
@ -66,6 +66,10 @@ interface Gtk extends Library {
|
|||
*/
|
||||
void gtk_main();
|
||||
|
||||
|
||||
/** sks for the current nesting level of the main loop. Useful to determine (at startup) if GTK is already runnign */
|
||||
int gtk_main_level();
|
||||
|
||||
/**
|
||||
* Makes the innermost invocation of the main loop return when it regains control. ONLY CALL FROM THE GtkSupport class, UNLESS you know
|
||||
* what you're doing!
|
||||
|
@ -74,8 +78,8 @@ interface Gtk extends Library {
|
|||
|
||||
void gdk_threads_init();
|
||||
|
||||
// tricky business. This should only be in the dispatch thread
|
||||
void gdk_threads_enter();
|
||||
|
||||
void gdk_threads_leave();
|
||||
|
||||
Pointer gtk_menu_new();
|
||||
|
|
|
@ -44,15 +44,17 @@ class GtkSupport {
|
|||
|
||||
public static volatile boolean isGtk2 = false;
|
||||
|
||||
private static volatile boolean alreadyRunningGTK = false;
|
||||
|
||||
/**
|
||||
* Helper for GTK, because we could have v3 or v2.
|
||||
*
|
||||
* Observations: SWT & JavaFX both use GTK2, and we can't load GTK3 if GTK2 symbols are loaded
|
||||
* Observations: JavaFX uses GTK2, and we can't load GTK3 if GTK2 symbols are loaded
|
||||
*/
|
||||
@SuppressWarnings("Duplicates")
|
||||
public static
|
||||
Gtk get() {
|
||||
Object library;
|
||||
Gtk library;
|
||||
|
||||
boolean shouldUseGtk2 = GtkSupport.FORCE_GTK2;
|
||||
|
||||
|
@ -60,10 +62,14 @@ class GtkSupport {
|
|||
if (shouldUseGtk2) {
|
||||
try {
|
||||
gtk_status_icon_position_menu = Function.getFunction("gtk-x11-2.0", "gtk_status_icon_position_menu");
|
||||
library = Native.loadLibrary("gtk-x11-2.0", Gtk.class);
|
||||
library = (Gtk) Native.loadLibrary("gtk-x11-2.0", Gtk.class);
|
||||
if (library != null) {
|
||||
isGtk2 = true;
|
||||
return (Gtk) library;
|
||||
|
||||
// when running inside of JavaFX, this will be '1'. All other times this should be '0'
|
||||
// when it's '1', it means that someone else has stared GTK -- so we DO NOT NEED TO.
|
||||
alreadyRunningGTK = library.gtk_main_level() != 0;
|
||||
return library;
|
||||
}
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
|
@ -74,9 +80,12 @@ class GtkSupport {
|
|||
// appindicator3 requires GTK3
|
||||
try {
|
||||
gtk_status_icon_position_menu = Function.getFunction("libgtk-3.so.0", "gtk_status_icon_position_menu");
|
||||
library = Native.loadLibrary("libgtk-3.so.0", Gtk.class);
|
||||
library = (Gtk) Native.loadLibrary("libgtk-3.so.0", Gtk.class);
|
||||
if (library != null) {
|
||||
return (Gtk) library;
|
||||
// when running inside of JavaFX, this will be '1'. All other times this should be '0'
|
||||
// when it's '1', it means that someone else has stared GTK -- so we DO NOT NEED TO.
|
||||
alreadyRunningGTK = library.gtk_main_level() != 0;
|
||||
return library;
|
||||
}
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
|
@ -84,10 +93,14 @@ class GtkSupport {
|
|||
// appindicator1 requires GTK2
|
||||
try {
|
||||
gtk_status_icon_position_menu = Function.getFunction("gtk-x11-2.0", "gtk_status_icon_position_menu");
|
||||
library = Native.loadLibrary("gtk-x11-2.0", Gtk.class);
|
||||
library = (Gtk) Native.loadLibrary("gtk-x11-2.0", Gtk.class);
|
||||
if (library != null) {
|
||||
isGtk2 = true;
|
||||
return (Gtk) library;
|
||||
|
||||
// when running inside of JavaFX, this will be '1'. All other times this should be '0'
|
||||
// when it's '1', it means that someone else has stared GTK -- so we DO NOT NEED TO.
|
||||
alreadyRunningGTK = library.gtk_main_level() != 0;
|
||||
return library;
|
||||
}
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
|
@ -99,9 +112,12 @@ class GtkSupport {
|
|||
// start with version 3
|
||||
try {
|
||||
gtk_status_icon_position_menu = Function.getFunction("libgtk-3.so.0", "gtk_status_icon_position_menu");
|
||||
library = Native.loadLibrary("libgtk-3.so.0", Gtk.class);
|
||||
library = (Gtk) Native.loadLibrary("libgtk-3.so.0", Gtk.class);
|
||||
if (library != null) {
|
||||
return (Gtk) library;
|
||||
// when running inside of JavaFX, this will be '1'. All other times this should be '0'
|
||||
// when it's '1', it means that someone else has stared GTK -- so we DO NOT NEED TO.
|
||||
alreadyRunningGTK = library.gtk_main_level() != 0;
|
||||
return library;
|
||||
}
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
|
@ -109,10 +125,14 @@ class GtkSupport {
|
|||
// now version 2
|
||||
try {
|
||||
gtk_status_icon_position_menu = Function.getFunction("gtk-x11-2.0", "gtk_status_icon_position_menu");
|
||||
library = Native.loadLibrary("gtk-x11-2.0", Gtk.class);
|
||||
library = (Gtk) Native.loadLibrary("gtk-x11-2.0", Gtk.class);
|
||||
if (library != null) {
|
||||
isGtk2 = true;
|
||||
return (Gtk) library;
|
||||
|
||||
// when running inside of JavaFX, this will be '1'. All other times this should be '0'
|
||||
// when it's '1', it means that someone else has stared GTK -- so we DO NOT NEED TO.
|
||||
alreadyRunningGTK = library.gtk_main_level() != 0;
|
||||
return library;
|
||||
}
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
|
@ -127,6 +147,7 @@ class GtkSupport {
|
|||
if (!started) {
|
||||
started = true;
|
||||
|
||||
// GTK specifies that we ONLY run from a single thread. This guarantees that.
|
||||
gtkDispatchThread = new Thread() {
|
||||
@Override
|
||||
public
|
||||
|
@ -151,23 +172,30 @@ class GtkSupport {
|
|||
|
||||
|
||||
// startup the GTK GUI event loop. There can be multiple/nested loops.
|
||||
|
||||
// If JavaFX/SWT is used, this is UNNECESSARY
|
||||
if (!alreadyRunningGTK) {
|
||||
// only necessary if we are the only GTK instance running...
|
||||
final CountDownLatch blockUntilStarted = new CountDownLatch(1);
|
||||
Thread gtkUpdateThread = new Thread() {
|
||||
@Override
|
||||
public
|
||||
void run() {
|
||||
Gtk instance = Gtk.INSTANCE;
|
||||
Gtk gtk = Gtk.INSTANCE;
|
||||
|
||||
// prep for the event loop.
|
||||
instance.gdk_threads_init();
|
||||
instance.gtk_init(0, null);
|
||||
GThread.INSTANCE.g_thread_init(null);
|
||||
gtk.gdk_threads_init();
|
||||
gtk.gdk_threads_enter();
|
||||
|
||||
gtk.gtk_init_check(0, null);
|
||||
|
||||
// notify our main thread to continue
|
||||
blockUntilStarted.countDown();
|
||||
|
||||
// blocks unit quit
|
||||
instance.gtk_main();
|
||||
// gtk.gtk_main();
|
||||
|
||||
gtk.gdk_threads_leave();
|
||||
}
|
||||
};
|
||||
gtkUpdateThread.setName("GTK Event Loop (Native)");
|
||||
|
@ -181,6 +209,7 @@ class GtkSupport {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Best practices for GTK, is to call EVERYTHING for it on a SINGLE THREAD. This accomplishes that.
|
||||
|
@ -196,7 +225,10 @@ class GtkSupport {
|
|||
|
||||
public static
|
||||
void shutdownGui() {
|
||||
// If JavaFX/SWT is used, this is UNNECESSARY (an will break SWT/JavaFX shutdown)
|
||||
if (!alreadyRunningGTK) {
|
||||
Gtk.INSTANCE.gtk_main_quit();
|
||||
}
|
||||
|
||||
started = false;
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user