From 71d15443fc2e012b14cb4c9e3b647738956ed2e2 Mon Sep 17 00:00:00 2001 From: nathan Date: Thu, 29 Oct 2015 02:21:24 +0100 Subject: [PATCH] Changed init order, and how the main loop gets started --- .../dorkbox/util/jna/linux/GtkSupport.java | 78 +++++++++++-------- 1 file changed, 45 insertions(+), 33 deletions(-) diff --git a/Dorkbox-Util/src/dorkbox/util/jna/linux/GtkSupport.java b/Dorkbox-Util/src/dorkbox/util/jna/linux/GtkSupport.java index 655e27c..c703395 100644 --- a/Dorkbox-Util/src/dorkbox/util/jna/linux/GtkSupport.java +++ b/Dorkbox-Util/src/dorkbox/util/jna/linux/GtkSupport.java @@ -20,10 +20,13 @@ import java.util.concurrent.CountDownLatch; public class GtkSupport { public static final boolean isSupported; - private static boolean hasSwt = false; + private static final boolean hasSwt; + + private static volatile boolean started = false; static { boolean hasSupport = false; + boolean hasSWT_ = false; try { if (Gtk.INSTANCE != null && Gobject.INSTANCE != null && GThread.INSTANCE != null) { hasSupport = true; @@ -31,61 +34,70 @@ class GtkSupport { try { Class swtClass = Class.forName("org.eclipse.swt.widgets.Display"); if (swtClass != null) { - hasSwt = true; + hasSWT_ = true; } } catch (Throwable ignore) { } - // If we are using GTK, we need to make sure the event loop is running. There can be multiple/nested loops. + + // prep for the event loop. // since SWT uses one already, it's not necessary to have two. - if (!hasSwt) { + if (!hasSWT_) { Gtk instance = Gtk.INSTANCE; instance.gtk_init(0, null); GThread.INSTANCE.g_thread_init(null); instance.gdk_threads_init(); - - final CountDownLatch blockUntilStarted = new CountDownLatch(1); - - Thread gtkUpdateThread = new Thread() { - @Override - public - void run() { - Gtk instance = Gtk.INSTANCE; - - // notify our main thread to continue - blockUntilStarted.countDown(); - instance.gdk_threads_enter(); - instance.gtk_main(); - // MUST leave as well! - instance.gdk_threads_leave(); - } - }; - gtkUpdateThread.setName("GTK Event Loop"); - gtkUpdateThread.start(); - - try { - // we CANNOT continue until the GTK thread has started! (ignored if SWT is used) - blockUntilStarted.await(); - } catch (InterruptedException e) { - e.printStackTrace(); - } } } } catch (Throwable ignored) { } isSupported = hasSupport; + hasSwt = hasSWT_; } public static - void init() { - // placeholder to init GTK + void startGui() { + // only permit one startup per JVM instance + if (!started) { + started = true; + + // startup the GTK GUI event loop. There can be multiple/nested loops. + // since SWT uses one already, it's not necessary to have two. + if (!hasSwt) { + final CountDownLatch blockUntilStarted = new CountDownLatch(1); + Thread gtkUpdateThread = new Thread() { + @Override + public + void run() { + Gtk instance = Gtk.INSTANCE; + + // notify our main thread to continue + blockUntilStarted.countDown(); + instance.gdk_threads_enter(); + instance.gtk_main(); + // MUST leave as well! + instance.gdk_threads_leave(); + } + }; + gtkUpdateThread.setName("GTK Event Loop"); + gtkUpdateThread.start(); + + try { + // we CANNOT continue until the GTK thread has started! (ignored if SWT is used) + blockUntilStarted.await(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } } public static - void shutdownGTK() { + void shutdownGui() { if (isSupported && !hasSwt) { Gtk.INSTANCE.gtk_main_quit(); + started = false; } } }