diff --git a/src/dorkbox/util/JavaFX.java b/src/dorkbox/util/JavaFX.java index 9e99c9f..3c1c907 100644 --- a/src/dorkbox/util/JavaFX.java +++ b/src/dorkbox/util/JavaFX.java @@ -27,55 +27,81 @@ import org.slf4j.LoggerFactory; */ public class JavaFX { + public final static boolean isLoaded; + public final static boolean isGtk3; + // Methods are cached for performance private static final Method dispatchMethod; private static final Method isEventThreadMethod; private static final Object isEventThreadObject; + static { + boolean isJavaFxLoaded_ = false; + boolean isJavaFxGtk3_ = false; + + try { + // this is important to use reflection, because if JavaFX is not being used, calling getToolkit() will initialize it... + java.lang.reflect.Method m = ClassLoader.class.getDeclaredMethod("findLoadedClass", String.class); + m.setAccessible(true); + ClassLoader cl = ClassLoader.getSystemClassLoader(); + + // JavaFX Java7,8 is GTK2 only. Java9 can have it be GTK3 if -Djdk.gtk.version=3 is specified + // see http://mail.openjdk.java.net/pipermail/openjfx-dev/2016-May/019100.html + isJavaFxLoaded_ = (null != m.invoke(cl, "com.sun.javafx.tk.Toolkit")) || (null != m.invoke(cl, "javafx.application.Application")); + + if (isJavaFxLoaded_) { + // JavaFX Java7,8 is GTK2 only. Java9 can MAYBE have it be GTK3 if `-Djdk.gtk.version=3` is specified + // see + // http://mail.openjdk.java.net/pipermail/openjfx-dev/2016-May/019100.html + // https://docs.oracle.com/javafx/2/system_requirements_2-2-3/jfxpub-system_requirements_2-2-3.htm + // from the page: JavaFX 2.2.3 for Linux requires gtk2 2.18+. + + isJavaFxGtk3_ = OS.javaVersion >= 9 && System.getProperty("jdk.gtk.version", "2").equals("3"); + } + } catch (Throwable e) { + LoggerFactory.getLogger(Framework.class).debug("Error detecting if JavaFX is loaded", e); + } + + isLoaded = isJavaFxLoaded_; + isGtk3 = isJavaFxGtk3_; + + Method _isEventThreadMethod = null; Method _dispatchMethod = null; Object _isEventThreadObject = null; - try { - Class clazz = Class.forName("javafx.application.Platform"); - _dispatchMethod = clazz.getMethod("runLater", Runnable.class); + if (isJavaFxLoaded_) { + try { + Class clazz = Class.forName("javafx.application.Platform"); + _dispatchMethod = clazz.getMethod("runLater", Runnable.class); - // JAVA 7 - // javafx.application.Platform.isFxApplicationThread(); + // JAVA 7 + // javafx.application.Platform.isFxApplicationThread(); - // JAVA 8 - // com.sun.javafx.tk.Toolkit.getToolkit().isFxUserThread(); - if (OS.javaVersion <= 7) { - clazz = Class.forName("javafx.application.Platform"); - _isEventThreadMethod = clazz.getMethod("isFxApplicationThread"); - _isEventThreadObject = null; - } else { - clazz = Class.forName("com.sun.javafx.tk.Toolkit"); - _isEventThreadMethod = clazz.getMethod("getToolkit"); + // JAVA 8 + // com.sun.javafx.tk.Toolkit.getToolkit().isFxUserThread(); + if (OS.javaVersion <= 7) { + clazz = Class.forName("javafx.application.Platform"); + _isEventThreadMethod = clazz.getMethod("isFxApplicationThread"); + _isEventThreadObject = null; + } else { + clazz = Class.forName("com.sun.javafx.tk.Toolkit"); + _isEventThreadMethod = clazz.getMethod("getToolkit"); - _isEventThreadObject = _isEventThreadMethod.invoke(null); - _isEventThreadMethod = _isEventThreadObject.getClass() - .getMethod("isFxUserThread", (java.lang.Class[])null); + _isEventThreadObject = _isEventThreadMethod.invoke(null); + _isEventThreadMethod = _isEventThreadObject.getClass() + .getMethod("isFxUserThread", (java.lang.Class[])null); + } + } catch (Throwable e) { + LoggerFactory.getLogger(JavaFX.class).error("Cannot initialize JavaFX", e); } - } catch (Throwable e) { - LoggerFactory.getLogger(JavaFX.class).error("Cannot initialize JavaFX", e); } dispatchMethod = _dispatchMethod; isEventThreadMethod = _isEventThreadMethod; isEventThreadObject = _isEventThreadObject; - } - - public static - void init() { - if (dispatchMethod == null || isEventThreadMethod == null) { - LoggerFactory.getLogger(JavaFX.class) - .error("Unable to initialize JavaFX! Please create an issue with your OS and Java " + - "version so we may further investigate this issue."); - } - } - +} public static void dispatch(final Runnable runnable) { diff --git a/src/dorkbox/util/Swt.java b/src/dorkbox/util/Swt.java index f84888f..66c848b 100644 --- a/src/dorkbox/util/Swt.java +++ b/src/dorkbox/util/Swt.java @@ -15,76 +15,194 @@ */ package dorkbox.util; +import java.lang.reflect.Method; + import org.slf4j.LoggerFactory; +import javassist.ClassPool; +import javassist.CtClass; +import javassist.CtField; +import javassist.CtMethod; +import javassist.CtNewMethod; +import javassist.Modifier; + /** - * Utility methods for SWT. This will by written by {@link SwtBytecodeOverride}, via Javassist so we don't require a hard dependency on - * SWT. + * Utility methods for SWT. Some of the methods will be overwritten via Javassist so we don't require a hard dependency on SWT. *

- * The methods/fields that this originated from * are commented out. - *

- * SWT system tray types are just GTK trays. + * SWT system tray types are GtkStatusIcon trays (so we don't want to use them) */ +@SuppressWarnings("Convert2Lambda") public class Swt { - private static final org.eclipse.swt.widgets.Display currentDisplay; - private static final Thread currentDisplayThread; + public final static boolean isLoaded; + public final static boolean isGtk3; - static { - // we MUST save this, otherwise it is "null" when methods are run from the swing EDT. - currentDisplay = org.eclipse.swt.widgets.Display.getCurrent(); + private static final Object currentDisplay; + private static final Thread currentDisplayThread; - currentDisplayThread = currentDisplay.getThread(); + // Methods are cached for performance + private static final Method syncExecMethod; + + static { + boolean isSwtLoaded_ = false; + boolean isSwtGtk3_ = false; + + try { + // this is important to use reflection, because if JavaFX is not being used, calling getToolkit() will initialize it... + java.lang.reflect.Method m = ClassLoader.class.getDeclaredMethod("findLoadedClass", String.class); + m.setAccessible(true); + ClassLoader cl = ClassLoader.getSystemClassLoader(); + + // maybe we should load the SWT version? (In order for us to work with SWT, BOTH must be the same!! + // SWT is GTK2, but if -DSWT_GTK3=1 is specified, it can be GTK3 + isSwtLoaded_ = null != m.invoke(cl, "org.eclipse.swt.widgets.Display"); + + if (isSwtLoaded_) { + // Necessary for us to work with SWT based on version info. We can try to set us to be compatible with whatever it is set to + // System.setProperty("SWT_GTK3", "0"); (or -DSWT_GTK3=1) + + // was SWT forced? + String swt_gtk3 = System.getProperty("SWT_GTK3"); + isSwtGtk3_ = swt_gtk3 != null && !swt_gtk3.equals("0"); + if (!isSwtGtk3_) { + // check a different property + String property = System.getProperty("org.eclipse.swt.internal.gtk.version"); + isSwtGtk3_ = property != null && !property.startsWith("2."); + } + } + } catch (Throwable e) { + LoggerFactory.getLogger(Framework.class).debug("Error detecting if SWT is loaded", e); + } + + isLoaded = isSwtLoaded_; + isGtk3 = isSwtGtk3_; + + // we MUST save this now, otherwise it is "null" when methods are run from the swing EDT. + // + // currentDisplay = org.eclipse.swt.widgets.Display.getCurrent(); + // currentDisplayThread = currentDisplay.getThread(); + + Object _currentDisplay = null; + Thread _currentDisplayThread = null; + + Method _syncExecMethod = null; + + if (isSwtLoaded_) { + try { + Class clazz = Class.forName("org.eclipse.swt.widgets.Display"); + Method getCurrentMethod = clazz.getMethod("getCurrent"); + Method getThreadMethod = clazz.getMethod("getThread"); + _syncExecMethod = clazz.getDeclaredMethod("syncExec", Runnable.class); + + _currentDisplay = getCurrentMethod.invoke(null); + _currentDisplayThread = (Thread) getThreadMethod.invoke(_currentDisplay); + + + // re-write the part that is heavily SWT dependent, that cannot be done via reflection. + byte[] bytes; + String body; + CtMethod method; + CtField ctField; + + ClassPool pool = ClassPool.getDefault(); + CtClass swtOverriedClass = pool.get("dorkbox.util.Swt$SwtOverride"); + + // the abstractions for listener are REQUIRED by javassist. + { + CtClass listener = pool.makeClass("dorkbox.util.Swt_listener"); + listener.addInterface(pool.get("org.eclipse.swt.widgets.Listener")); + + ctField = new CtField(pool.get("java.lang.Runnable"), "runnable", listener); + ctField.setModifiers(Modifier.PROTECTED); + listener.addField(ctField); + + method = CtNewMethod.make(CtClass.voidType, "handleEvent", + new CtClass[]{pool.get("org.eclipse.swt.widgets.Event")}, null, + "{" + + " this.runnable.run();" + + "}", listener); + listener.addMethod(method); + bytes = listener.toBytecode(); + ClassLoaderUtil.defineClass(bytes); + } + + method = swtOverriedClass.getDeclaredMethod("onShutdown"); + body = "{" + + "org.eclipse.swt.widgets.Display currentDisplay = (org.eclipse.swt.widgets.Display)$1;" + + "Runnable runnable = $2;" + + + "dorkbox.util.Swt_listener listener = new dorkbox.util.Swt_listener();" + + "listener.runnable = runnable;" + + + "org.eclipse.swt.widgets.Shell shell = currentDisplay.getShells()[0];" + + "shell.addListener(org.eclipse.swt.SWT.Close, listener);" + + "}"; + method.setBody(body); + bytes = swtOverriedClass.toBytecode(); + + // define this new class in our current classloader + ClassLoaderUtil.defineClass(bytes); + } catch (Throwable e) { + LoggerFactory.getLogger(Swt.class).error("Cannot initialize SWT", e); + } + } + + currentDisplay = _currentDisplay; + currentDisplayThread = _currentDisplayThread; + syncExecMethod = _syncExecMethod; } + + // this class is over-written via Javassist, because reflection cannot create anonymous classes. Javassist can, with caveats. + @SuppressWarnings("unused") public static - void init() { - if (currentDisplay == null) { - LoggerFactory.getLogger(Swt.class) - .error("Unable to get the current display for SWT. Please create an issue with your OS and Java " + - "version so we may further investigate this issue."); - } -// throw new RuntimeException("This should never happen, as this class is over-written at runtime."); + class SwtOverride { + static + void onShutdown(final Object currentDisplay, final Runnable runnable) { + // currentDisplay.getShells() must only be called inside the event thread! + +// org.eclipse.swt.widgets.Shell shell = currentDisplay.getShells()[0]; +// shell.addListener(org.eclipse.swt.SWT.Close, new org.eclipse.swt.widgets.Listener() { +// @Override +// public +// void handleEvent(final org.eclipse.swt.widgets.Event event) { +// runnable.run(); +// } +// }); + throw new RuntimeException("This should never happen, as this class is over-written at runtime."); + } } public static void dispatch(final Runnable runnable) { - currentDisplay.syncExec(runnable); -// throw new RuntimeException("This should never happen, as this class is over-written at runtime."); +// currentDisplay.syncExec(runnable); + try { + syncExecMethod.invoke(currentDisplay, runnable); + } catch (Throwable e) { + LoggerFactory.getLogger(Swt.class) + .error("Unable to execute JavaFX runLater(). Please create an issue with your OS and Java " + + "version so we may further investigate this issue."); + } } public static boolean isEventThread() { return Thread.currentThread() == currentDisplayThread; -// throw new RuntimeException("This should never happen, as this class is over-written at runtime."); } public static void onShutdown(final Runnable runnable) { - // currentDisplay.getShells() can only happen inside the event thread! - if (isEventThread()) { - currentDisplay.getShells()[0].addListener(org.eclipse.swt.SWT.Close, new org.eclipse.swt.widgets.Listener() { - @Override - public - void handleEvent(final org.eclipse.swt.widgets.Event event) { - runnable.run(); - } - }); + // currentDisplay.getShells() must only be called inside the event thread! + if (isEventThread()) { + SwtOverride.onShutdown(currentDisplay, runnable); } else { dispatch(new Runnable() { @Override public void run() { - currentDisplay.getShells()[0].addListener(org.eclipse.swt.SWT.Close, new org.eclipse.swt.widgets.Listener() { - @Override - public - void handleEvent(final org.eclipse.swt.widgets.Event event) { - runnable.run(); - } - }); + SwtOverride.onShutdown(currentDisplay, runnable); } }); } -// throw new RuntimeException("This should never happen, as this class is over-written at runtime."); } } diff --git a/src/dorkbox/util/SwtBytecodeOverride.java b/src/dorkbox/util/SwtBytecodeOverride.java deleted file mode 100644 index cdf95e4..0000000 --- a/src/dorkbox/util/SwtBytecodeOverride.java +++ /dev/null @@ -1,269 +0,0 @@ -/* - * Copyright 2016 dorkbox, llc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package dorkbox.util; - -import static org.objectweb.asm.Opcodes.AALOAD; -import static org.objectweb.asm.Opcodes.ACC_FINAL; -import static org.objectweb.asm.Opcodes.ACC_PRIVATE; -import static org.objectweb.asm.Opcodes.ACC_PUBLIC; -import static org.objectweb.asm.Opcodes.ACC_STATIC; -import static org.objectweb.asm.Opcodes.ACC_SUPER; -import static org.objectweb.asm.Opcodes.ACC_SYNTHETIC; -import static org.objectweb.asm.Opcodes.ALOAD; -import static org.objectweb.asm.Opcodes.ARETURN; -import static org.objectweb.asm.Opcodes.BIPUSH; -import static org.objectweb.asm.Opcodes.DUP; -import static org.objectweb.asm.Opcodes.GETSTATIC; -import static org.objectweb.asm.Opcodes.GOTO; -import static org.objectweb.asm.Opcodes.ICONST_0; -import static org.objectweb.asm.Opcodes.ICONST_1; -import static org.objectweb.asm.Opcodes.IFEQ; -import static org.objectweb.asm.Opcodes.IFNONNULL; -import static org.objectweb.asm.Opcodes.IF_ACMPNE; -import static org.objectweb.asm.Opcodes.INVOKEINTERFACE; -import static org.objectweb.asm.Opcodes.INVOKESPECIAL; -import static org.objectweb.asm.Opcodes.INVOKESTATIC; -import static org.objectweb.asm.Opcodes.INVOKEVIRTUAL; -import static org.objectweb.asm.Opcodes.IRETURN; -import static org.objectweb.asm.Opcodes.NEW; -import static org.objectweb.asm.Opcodes.PUTSTATIC; -import static org.objectweb.asm.Opcodes.RETURN; - -import org.objectweb.asm.AnnotationVisitor; -import org.objectweb.asm.ClassWriter; -import org.objectweb.asm.FieldVisitor; -import org.objectweb.asm.Label; -import org.objectweb.asm.MethodVisitor; -import org.objectweb.asm.Opcodes; -import org.objectweb.asm.Type; - - -/** - * Utility methods for SWT. This will override {@link Swt} methods, and is written in Javassist. This is so we don't require a hard - * dependency on SWT. - *

- * The methods/fields that this originated from are commented out in the {@link Swt} class. - */ -public -class SwtBytecodeOverride { - static { - try { -// byte[] swtClassBytes = getSwtBytes(); -// -// // whoosh, past the classloader and directly into memory. This will take precedence over the "proper" Swt class -// BootStrapClassLoader.defineClass(swtClassBytes); - - // now we have to load various classes into the classloader - Class aClass = Class.forName("org.eclipse.swt.widgets.Display"); - Swt.init(); - } catch (Exception e) { - e.printStackTrace(); - } - } - - public static - void init() { - // placeholder to initialize the class. - } - - private static - byte[] getSwtBytes() throws Exception { - ClassWriter cw = new ClassWriter(0); - FieldVisitor fv; - MethodVisitor mv; - AnnotationVisitor av0; - - cw.visit(52, ACC_PUBLIC + ACC_SUPER, "dorkbox/util/Swt", null, "java/lang/Object", null); - - cw.visitSource("Swt.java", null); - - cw.visitInnerClass("dorkbox/util/Swt$1", null, null, 0); - - cw.visitInnerClass("dorkbox/util/Swt$2", null, null, 0); - - { - fv = cw.visitField(ACC_PRIVATE + ACC_FINAL + ACC_STATIC, "currentDisplay", "Lorg/eclipse/swt/widgets/Display;", null, null); - fv.visitEnd(); - } - { - fv = cw.visitField(ACC_PRIVATE + ACC_FINAL + ACC_STATIC, "currentDisplayThread", "Ljava/lang/Thread;", null, null); - fv.visitEnd(); - } - { - mv = cw.visitMethod(ACC_STATIC, "", "()V", null, null); - mv.visitCode(); - Label l0 = new Label(); - mv.visitLabel(l0); - mv.visitLineNumber(35, l0); - mv.visitMethodInsn(INVOKESTATIC, "org/eclipse/swt/widgets/Display", "getCurrent", "()Lorg/eclipse/swt/widgets/Display;", false); - mv.visitFieldInsn(PUTSTATIC, "dorkbox/util/Swt", "currentDisplay", "Lorg/eclipse/swt/widgets/Display;"); - Label l1 = new Label(); - mv.visitLabel(l1); - mv.visitLineNumber(37, l1); - mv.visitFieldInsn(GETSTATIC, "dorkbox/util/Swt", "currentDisplay", "Lorg/eclipse/swt/widgets/Display;"); - mv.visitMethodInsn(INVOKEVIRTUAL, "org/eclipse/swt/widgets/Display", "getThread", "()Ljava/lang/Thread;", false); - mv.visitFieldInsn(PUTSTATIC, "dorkbox/util/Swt", "currentDisplayThread", "Ljava/lang/Thread;"); - Label l2 = new Label(); - mv.visitLabel(l2); - mv.visitLineNumber(38, l2); - mv.visitInsn(RETURN); - mv.visitMaxs(1, 0); - mv.visitEnd(); - } - { - mv = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null); - mv.visitCode(); - Label l0 = new Label(); - mv.visitLabel(l0); - mv.visitLineNumber(29, l0); - mv.visitVarInsn(ALOAD, 0); - mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V", false); - mv.visitInsn(RETURN); - Label l1 = new Label(); - mv.visitLabel(l1); - mv.visitLocalVariable("this", "Ldorkbox/util/Swt;", null, l0, l1, 0); - mv.visitMaxs(1, 1); - mv.visitEnd(); - } - { - mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "init", "()V", null, null); - mv.visitCode(); - Label l0 = new Label(); - mv.visitLabel(l0); - mv.visitLineNumber(42, l0); - mv.visitFieldInsn(GETSTATIC, "dorkbox/util/Swt", "currentDisplay", "Lorg/eclipse/swt/widgets/Display;"); - Label l1 = new Label(); - mv.visitJumpInsn(IFNONNULL, l1); - Label l2 = new Label(); - mv.visitLabel(l2); - mv.visitLineNumber(43, l2); - mv.visitLdcInsn(Type.getType("Ldorkbox/util/Swt;")); - mv.visitMethodInsn(INVOKESTATIC, "org/slf4j/LoggerFactory", "getLogger", "(Ljava/lang/Class;)Lorg/slf4j/Logger;", false); - Label l3 = new Label(); - mv.visitLabel(l3); - mv.visitLineNumber(44, l3); - mv.visitLdcInsn("Unable to get the current display for SWT. Please create an issue with your OS and Java version so we may further investigate this issue."); - mv.visitMethodInsn(INVOKEINTERFACE, "org/slf4j/Logger", "error", "(Ljava/lang/String;)V", true); - mv.visitLabel(l1); - mv.visitLineNumber(48, l1); - mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); - mv.visitInsn(RETURN); - mv.visitMaxs(2, 0); - mv.visitEnd(); - } - { - mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "dispatch", "(Ljava/lang/Runnable;)V", null, null); - mv.visitCode(); - Label l0 = new Label(); - mv.visitLabel(l0); - mv.visitLineNumber(52, l0); - mv.visitFieldInsn(GETSTATIC, "dorkbox/util/Swt", "currentDisplay", "Lorg/eclipse/swt/widgets/Display;"); - mv.visitVarInsn(ALOAD, 0); - mv.visitMethodInsn(INVOKEVIRTUAL, "org/eclipse/swt/widgets/Display", "syncExec", "(Ljava/lang/Runnable;)V", false); - Label l1 = new Label(); - mv.visitLabel(l1); - mv.visitLineNumber(54, l1); - mv.visitInsn(RETURN); - Label l2 = new Label(); - mv.visitLabel(l2); - mv.visitLocalVariable("runnable", "Ljava/lang/Runnable;", null, l0, l2, 0); - mv.visitMaxs(2, 1); - mv.visitEnd(); - } - { - mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "isEventThread", "()Z", null, null); - mv.visitCode(); - Label l0 = new Label(); - mv.visitLabel(l0); - mv.visitLineNumber(58, l0); - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Thread", "currentThread", "()Ljava/lang/Thread;", false); - mv.visitFieldInsn(GETSTATIC, "dorkbox/util/Swt", "currentDisplayThread", "Ljava/lang/Thread;"); - Label l1 = new Label(); - mv.visitJumpInsn(IF_ACMPNE, l1); - mv.visitInsn(ICONST_1); - mv.visitInsn(IRETURN); - mv.visitLabel(l1); - mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); - mv.visitInsn(ICONST_0); - mv.visitInsn(IRETURN); - mv.visitMaxs(2, 0); - mv.visitEnd(); - } - { - mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "onShutdown", "(Ljava/lang/Runnable;)V", null, null); - mv.visitCode(); - Label l0 = new Label(); - mv.visitLabel(l0); - mv.visitLineNumber(65, l0); - mv.visitMethodInsn(INVOKESTATIC, "dorkbox/util/Swt", "isEventThread", "()Z", false); - Label l1 = new Label(); - mv.visitJumpInsn(IFEQ, l1); - Label l2 = new Label(); - mv.visitLabel(l2); - mv.visitLineNumber(66, l2); - mv.visitFieldInsn(GETSTATIC, "dorkbox/util/Swt", "currentDisplay", "Lorg/eclipse/swt/widgets/Display;"); - mv.visitMethodInsn(INVOKEVIRTUAL, "org/eclipse/swt/widgets/Display", "getShells", "()[Lorg/eclipse/swt/widgets/Shell;", false); - mv.visitInsn(ICONST_0); - mv.visitInsn(AALOAD); - mv.visitIntInsn(BIPUSH, 21); - mv.visitTypeInsn(NEW, "dorkbox/util/Swt$1"); - mv.visitInsn(DUP); - mv.visitVarInsn(ALOAD, 0); - mv.visitMethodInsn(INVOKESPECIAL, "dorkbox/util/Swt$1", "", "(Ljava/lang/Runnable;)V", false); - mv.visitMethodInsn(INVOKEVIRTUAL, - "org/eclipse/swt/widgets/Shell", - "addListener", - "(ILorg/eclipse/swt/widgets/Listener;)V", - false); - Label l3 = new Label(); - mv.visitLabel(l3); - mv.visitLineNumber(73, l3); - Label l4 = new Label(); - mv.visitJumpInsn(GOTO, l4); - mv.visitLabel(l1); - mv.visitLineNumber(74, l1); - mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); - mv.visitTypeInsn(NEW, "dorkbox/util/Swt$2"); - mv.visitInsn(DUP); - mv.visitVarInsn(ALOAD, 0); - mv.visitMethodInsn(INVOKESPECIAL, "dorkbox/util/Swt$2", "", "(Ljava/lang/Runnable;)V", false); - mv.visitMethodInsn(INVOKESTATIC, "dorkbox/util/Swt", "dispatch", "(Ljava/lang/Runnable;)V", false); - mv.visitLabel(l4); - mv.visitLineNumber(89, l4); - mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); - mv.visitInsn(RETURN); - Label l5 = new Label(); - mv.visitLabel(l5); - mv.visitLocalVariable("runnable", "Ljava/lang/Runnable;", null, l0, l5, 0); - mv.visitMaxs(5, 1); - mv.visitEnd(); - } - { - mv = cw.visitMethod(ACC_STATIC + ACC_SYNTHETIC, "access$0", "()Lorg/eclipse/swt/widgets/Display;", null, null); - mv.visitCode(); - Label l0 = new Label(); - mv.visitLabel(l0); - mv.visitLineNumber(30, l0); - mv.visitFieldInsn(GETSTATIC, "dorkbox/util/Swt", "currentDisplay", "Lorg/eclipse/swt/widgets/Display;"); - mv.visitInsn(ARETURN); - mv.visitMaxs(1, 0); - mv.visitEnd(); - } - cw.visitEnd(); - - return cw.toByteArray(); - } -} diff --git a/src/dorkbox/util/jna/linux/GtkEventDispatch.java b/src/dorkbox/util/jna/linux/GtkEventDispatch.java index ae318ff..0c53360 100644 --- a/src/dorkbox/util/jna/linux/GtkEventDispatch.java +++ b/src/dorkbox/util/jna/linux/GtkEventDispatch.java @@ -27,7 +27,6 @@ import org.slf4j.LoggerFactory; import com.sun.jna.Pointer; -import dorkbox.util.Framework; import dorkbox.util.JavaFX; import dorkbox.util.Swt; @@ -36,9 +35,6 @@ class GtkEventDispatch { static boolean FORCE_GTK2 = false; static boolean DEBUG = false; - private static final boolean isSwtLoaded = Framework.isSwtLoaded; - private static final boolean isJavaFxLoaded = Framework.isJavaFxLoaded; - // have to save these in a field to prevent GC on the objects (since they go out-of-scope from java) private static final LinkedList gtkCallbacks = new LinkedList(); @@ -135,7 +131,7 @@ class GtkEventDispatch { } }); - if (isJavaFxLoaded) { + if (JavaFX.isLoaded) { if (!JavaFX.isEventThread()) { try { if (!blockUntilStarted.await(10, TimeUnit.SECONDS)) { @@ -161,7 +157,7 @@ class GtkEventDispatch { } } } - else if (isSwtLoaded) { + else if (Swt.isLoaded) { if (!Swt.isEventThread()) { // we have to WAIT until all events are done processing, OTHERWISE we have initialization issues try { @@ -219,7 +215,7 @@ class GtkEventDispatch { public static void dispatch(final Runnable runnable) { if (GtkLoader.alreadyRunningGTK) { - if (isJavaFxLoaded) { + if (JavaFX.isLoaded) { // JavaFX only if (JavaFX.isEventThread()) { // Run directly on the JavaFX event thread @@ -232,7 +228,7 @@ class GtkEventDispatch { return; } - if (isSwtLoaded) { + if (Swt.isLoaded) { if (Swt.isEventThread()) { // Run directly on the SWT event thread. If it's not on the dispatch thread, we can use raw GTK to put it there runnable.run(); diff --git a/src/dorkbox/util/jna/linux/GtkLoader.java b/src/dorkbox/util/jna/linux/GtkLoader.java index 74ecfc0..fdad4d2 100644 --- a/src/dorkbox/util/jna/linux/GtkLoader.java +++ b/src/dorkbox/util/jna/linux/GtkLoader.java @@ -22,8 +22,8 @@ import org.slf4j.LoggerFactory; import com.sun.jna.Function; import com.sun.jna.NativeLibrary; -import dorkbox.util.Framework; import dorkbox.util.OS; +import dorkbox.util.Swt; import dorkbox.util.jna.JnaHelper; /** @@ -170,7 +170,7 @@ class GtkLoader { // depending on how the system is initialized, SWT may, or may not, have the gtk_main loop running. It will EVENTUALLY run, so we // do not want to run our own GTK event loop. - _alreadyRunningGTK |= Framework.isSwtLoaded; + _alreadyRunningGTK |= Swt.isLoaded; alreadyRunningGTK = _alreadyRunningGTK; isGtk2 = _isGtk2; diff --git a/src/dorkbox/util/jna/linux/GtkTheme.java b/src/dorkbox/util/jna/linux/GtkTheme.java index 2945e8f..da43324 100644 --- a/src/dorkbox/util/jna/linux/GtkTheme.java +++ b/src/dorkbox/util/jna/linux/GtkTheme.java @@ -35,10 +35,10 @@ import com.sun.jna.Pointer; import com.sun.jna.ptr.PointerByReference; import dorkbox.util.FileUtil; -import dorkbox.util.Framework; import dorkbox.util.MathUtil; import dorkbox.util.OS; import dorkbox.util.OSUtil; +import dorkbox.util.Swt; import dorkbox.util.jna.linux.structs.GtkRequisition; import dorkbox.util.jna.linux.structs.GtkStyle; import dorkbox.util.jna.linux.structs.PangoRectangle; @@ -413,7 +413,7 @@ My ratio is 1.47674, that means I have no scaling at all when there is a 1.5 fac final AtomicInteger traySize = new AtomicInteger(); - if (Framework.isSwtLoaded) { + if (Swt.isLoaded) { } else { GtkEventDispatch.dispatchAndWait(new Runnable() { @Override