Compile uses Linux SWT, so we can directly access the internal class. If that fails, then it falls back to the original reflection (and now tries multiple classes)

master
Robinson 2021-03-11 23:28:06 +01:00
parent f0e5f85eeb
commit 4f66c998b8
2 changed files with 39 additions and 31 deletions

View File

@ -28,7 +28,7 @@ gradle.startParameter.warningMode = WarningMode.All
plugins { plugins {
java java
id("com.dorkbox.GradleUtils") version "1.12" id("com.dorkbox.GradleUtils") version "1.15"
id("com.dorkbox.Licensing") version "2.5.4" id("com.dorkbox.Licensing") version "2.5.4"
id("com.dorkbox.VersionUpdate") version "2.1" id("com.dorkbox.VersionUpdate") version "2.1"
id("com.dorkbox.GradlePublish") version "1.9.1" id("com.dorkbox.GradlePublish") version "1.9.1"
@ -48,6 +48,11 @@ object Extras {
const val url = "https://git.dorkbox.com/dorkbox/SwtJavaFx" const val url = "https://git.dorkbox.com/dorkbox/SwtJavaFx"
val buildDate = Instant.now().toString() val buildDate = Instant.now().toString()
// This is really SWT version 4.xx? no idea how the internal versions are tracked
// 4.4 is the oldest version that works with us, and the release of SWT is sPecIaL!
// 3.108.0 is the MOST RECENT version supported by x86. All newer version no longer support x86
const val swtVersion = "3.115.100"
} }
/////////////////////////////// ///////////////////////////////
@ -102,8 +107,8 @@ tasks.jar.get().apply {
dependencies { dependencies {
implementation("org.slf4j:slf4j-api:1.7.30") implementation("org.slf4j:slf4j-api:1.7.30")
// because the eclipse release of SWT is sPecIaL! Version numbers that make sense... Whaaaaaaat? // This is explicitly linux because we access GTK internals (and it's only available on the linux GTK version of SWT)
compileOnly(GradleUtils.getSwtMavenId("3.114.100")) { compileOnly(dorkbox.gradle.SwtType.LINUX_64.fullId(Extras.swtVersion)) {
isTransitive = false isTransitive = false
} }

View File

@ -1,5 +1,6 @@
package dorkbox.swt; package dorkbox.swt;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.security.AccessController; import java.security.AccessController;
import java.security.PrivilegedAction; import java.security.PrivilegedAction;
@ -44,30 +45,20 @@ class SwtAccess {
return SWT.getVersion(); return SWT.getVersion();
} }
/**
* This is only necessary for linux.
*
* @return true if SWT is GTK3. False if SWT is GTK2. If for some reason we DO NOT KNOW, then we return false (GTK2).
*/
static boolean isGtk3() {
boolean isLinux = System.getProperty("os.name", "").toLowerCase(Locale.US).startsWith("linux");
if (!isLinux) {
return false;
}
// required to use reflection, because this is an internal class! private static
final String SWT_INTERNAL_CLASS = "org.eclipse.swt.internal.gtk.OS"; int getViaReflection(String clazz) throws InvocationTargetException, IllegalAccessException {
Class<?> osClass = AccessController.doPrivileged(new PrivilegedAction<Class<?>>() { final Class<?> osClass = AccessController.doPrivileged(new PrivilegedAction<Class<?>>() {
@Override @Override
public public
Class<?> run() { Class<?> run() {
try { try {
return Class.forName(SWT_INTERNAL_CLASS, true, ClassLoader.getSystemClassLoader()); return Class.forName(clazz, true, ClassLoader.getSystemClassLoader());
} catch (Exception ignored) { } catch (Exception ignored) {
} }
try { try {
return Class.forName(SWT_INTERNAL_CLASS, true, Thread.currentThread().getContextClassLoader()); return Class.forName(clazz, true, Thread.currentThread().getContextClassLoader());
} catch (Exception ignored) { } catch (Exception ignored) {
} }
@ -75,36 +66,48 @@ class SwtAccess {
} }
}); });
if (osClass == null) {
return false;
}
final Class<?> clazz = osClass;
Method method = AccessController.doPrivileged(new PrivilegedAction<Method>() { Method method = AccessController.doPrivileged(new PrivilegedAction<Method>() {
@Override @Override
public public
Method run() { Method run() {
try { try {
return clazz.getMethod("gtk_major_version"); return osClass.getMethod("gtk_major_version");
} catch (Exception e) { } catch (Exception e) {
return null; return null;
} }
} }
}); });
if (method == null) { // might throw an exception!
return ((Number)method.invoke(osClass)).intValue();
}
/**
* This is only necessary for linux.
*
* @return true if SWT is GTK3. False if SWT is GTK2 or unknown.
*/
static boolean isGtk3() {
boolean isLinux = System.getProperty("os.name", "").toLowerCase(Locale.US).startsWith("linux");
if (!isLinux) {
return false; return false;
} }
int version = 0;
try { try {
version = ((Number)method.invoke(osClass)).intValue(); return org.eclipse.swt.internal.gtk.GTK.gtk_get_major_version() == 3;
} catch (Exception ignored) { } catch (Exception e) {
// this method doesn't exist. // this might be an older/different version of SWT! Try reflection.
try {
return getViaReflection("org.eclipse.swt.internal.gtk.GTK") == 3;
} catch (Exception e1) {
try {
return getViaReflection("org.eclipse.swt.internal.gtk.OS") == 3;
} catch (Exception ignored) {
}
}
} }
return version == 3; return false;
} }
static static