Added isGtk3, changed static fields to be final.

This commit is contained in:
nathan 2016-12-28 21:41:49 +01:00
parent e3fbec2c55
commit 8dfd2d3317
2 changed files with 87 additions and 47 deletions

View File

@ -23,6 +23,7 @@ import com.sun.jna.Pointer;
import dorkbox.systemTray.SystemTray;
import dorkbox.systemTray.jna.JnaHelper;
import dorkbox.util.OS;
/**
* bindings for libappindicator
@ -32,8 +33,8 @@ import dorkbox.systemTray.jna.JnaHelper;
@SuppressWarnings({"Duplicates", "SameParameterValue", "DanglingJavadoc"})
public
class AppIndicator {
public static boolean isVersion3 = false;
public static boolean isLoaded = false;
public static final boolean isVersion3;
public static final boolean isLoaded;
/**
* Loader for AppIndicator, because it is absolutely mindboggling how those whom maintain the standard, can't agree to what that
@ -44,6 +45,13 @@ class AppIndicator {
* This is so hacky it makes me sick.
*/
static {
boolean _isVersion3 = false;
boolean _isLoaded = false;
if (!OS.isLinux()) {
_isLoaded = true;
}
// objdump -T /usr/lib/x86_64-linux-gnu/libappindicator.so.1 | grep foo
// objdump -T /usr/lib/x86_64-linux-gnu/libappindicator3.so.1 | grep foo
@ -52,22 +60,22 @@ class AppIndicator {
// appindiactor1 is GKT2 only (can't use GTK3 bindings with it)
// appindicator3 doesn't support menu icons via GTK2!!
if (SystemTray.FORCE_TRAY_TYPE == SystemTray.TrayType.GtkStatusIcon) {
if (!_isLoaded && SystemTray.FORCE_TRAY_TYPE == SystemTray.TrayType.GtkStatusIcon) {
// if we force GTK type system tray, don't attempt to load AppIndicator libs
if (SystemTray.DEBUG) {
logger.debug("Forcing GTK tray, not using appindicator");
}
isLoaded = true;
_isLoaded = true;
}
if (!isLoaded && SystemTray.FORCE_GTK2) {
if (!_isLoaded && SystemTray.FORCE_GTK2) {
// if specified, try loading appindicator1 first, maybe it's there?
// note: we can have GTK2 + appindicator3, but NOT ALWAYS.
try {
// deliberately without the "1" at the end.
final NativeLibrary library = JnaHelper.register("appindicator", AppIndicator.class);
if (library != null) {
isLoaded = true;
_isLoaded = true;
}
} catch (Throwable e) {
if (SystemTray.DEBUG) {
@ -87,7 +95,7 @@ class AppIndicator {
}
// start with base version using whatever the OS specifies as the proper symbolic link
if (!isLoaded) {
if (!_isLoaded) {
try {
final NativeLibrary library = JnaHelper.register(nameToCheck1, AppIndicator.class);
String s = library.getFile().getName();
@ -97,10 +105,10 @@ class AppIndicator {
}
if (s.contains("appindicator3")) {
isVersion3 = true;
_isVersion3 = true;
}
isLoaded = true;
_isLoaded = true;
} catch (Throwable e) {
if (SystemTray.DEBUG) {
logger.debug("Error loading library: '{}'. \n{}", nameToCheck1, e.getMessage());
@ -110,7 +118,7 @@ class AppIndicator {
// whoops. Symbolic links are bugged out. Look manually for it...
// Super hacky way to do this.
if (!isLoaded) {
if (!_isLoaded) {
if (Gtk.isGtk2) {
if (SystemTray.DEBUG) {
logger.debug("Checking GTK2 first for appIndicator");
@ -118,7 +126,7 @@ class AppIndicator {
// have to check gtk2 first
for (int i = 0; i <= 10; i++) {
if (!isLoaded) {
if (!_isLoaded) {
try {
final NativeLibrary library = JnaHelper.register("appindicator" + i, AppIndicator.class);
String s = library.getFile().getName();
@ -129,14 +137,14 @@ class AppIndicator {
// version 3 WILL NOT work with icons in the menu. This allows us to show a warning (in the System tray initialization)
if (i == 3 || s.contains("appindicator3")) {
isVersion3 = true;
_isVersion3 = true;
if (SystemTray.DEBUG) {
logger.debug("Unloading library: '{}'", s);
}
Native.unregister(AppIndicator.class);
}
isLoaded = true;
_isLoaded = true;
break;
} catch (Throwable e) {
if (SystemTray.DEBUG) {
@ -149,7 +157,7 @@ class AppIndicator {
} else {
// have to check gtk3 first (maybe it's there?)
for (int i = 10; i >= 0; i--) {
if (!isLoaded) {
if (!_isLoaded) {
try {
final NativeLibrary library = JnaHelper.register("appindicator" + i, AppIndicator.class);
String s = library.getFile().getName();
@ -160,10 +168,10 @@ class AppIndicator {
// version 3 WILL NOT work with icons in the menu. This allows us to show a warning (in the System tray initialization)
if (i == 3 || s.contains("appindicator3")) {
isVersion3 = true;
_isVersion3 = true;
}
isLoaded = true;
_isLoaded = true;
break;
} catch (Throwable e) {
if (SystemTray.DEBUG) {
@ -176,10 +184,10 @@ class AppIndicator {
}
// maybe it's really GTK2 version? who knows...
if (!isLoaded) {
if (!_isLoaded) {
try {
JnaHelper.register("appindicator", AppIndicator.class);
isLoaded = true;
_isLoaded = true;
} catch (Throwable e) {
if (SystemTray.DEBUG) {
logger.debug("Error loading library: '{}'. \n{}", "appindicator", e.getMessage());
@ -199,10 +207,10 @@ class AppIndicator {
}
// another type. who knows...
if (!isLoaded) {
if (!_isLoaded) {
try {
JnaHelper.register(nameToCheck1, AppIndicator.class);
isLoaded = true;
_isLoaded = true;
} catch (Throwable e) {
if (SystemTray.DEBUG) {
logger.debug("Error loading library: '{}'. \n{}", nameToCheck1, e.getMessage());
@ -211,16 +219,24 @@ class AppIndicator {
}
// this is HORRID. such a PITA
if (!isLoaded) {
if (!_isLoaded) {
try {
JnaHelper.register(nameToCheck2, AppIndicator.class);
isLoaded = true;
_isLoaded = true;
} catch (Throwable e) {
if (SystemTray.DEBUG) {
logger.debug("Error loading library: '{}'. \n{}", nameToCheck2, e.getMessage());
}
}
}
if (OS.isLinux()) {
isLoaded = _isLoaded;
isVersion3 = _isVersion3;
} else {
isLoaded = false;
isVersion3 = false;
}
}
// Note: AppIndicators DO NOT support tooltips, as per mark shuttleworth. Rather stupid IMHO.

View File

@ -31,6 +31,7 @@ import dorkbox.systemTray.SystemTray;
import dorkbox.systemTray.jna.JnaHelper;
import dorkbox.systemTray.util.JavaFX;
import dorkbox.systemTray.util.Swt;
import dorkbox.util.OS;
/**
* bindings for gtk 2 or 3
@ -48,13 +49,13 @@ class Gtk {
// https://github.com/syncthing/syncthing-gtk/blob/b7a3bc00e3bb6d62365ae62b5395370f3dcc7f55/syncthing_gtk/statusicon.py
// NOTE: AppIndicator uses this info to figure out WHAT VERSION OF appindicator to use: GTK2 -> appindicator1, GTK3 -> appindicator3
public static volatile boolean isGtk2 = false;
public static boolean isLoaded = false;
public static final boolean isGtk2;
public static final boolean isGtk3;
public static final boolean isLoaded;
public static Function gtk_status_icon_position_menu = null;
private static boolean alreadyRunningGTK = false;
private static final boolean alreadyRunningGTK;
// This is required because the EDT needs to have it's own value for this boolean, that is a different value than the main thread
private static ThreadLocal<Boolean> isDispatch = new ThreadLocal<Boolean>() {
@ -79,26 +80,37 @@ class Gtk {
*/
static {
boolean shouldUseGtk2 = SystemTray.FORCE_GTK2;
boolean _isGtk2 = false;
boolean _isLoaded = false;
boolean _alreadyRunningGTK = false;
if (!OS.isLinux()) {
_isLoaded = true;
}
// we can force the system to use the swing indicator, which WORKS, but doesn't support transparency in the icon.
if (!_isLoaded && SystemTray.FORCE_TRAY_TYPE == SystemTray.TrayType.Swing) {
if (SystemTray.DEBUG) {
logger.debug("Forcing Swing tray, not using GTK");
}
_isLoaded = true;
}
// in some cases, we ALWAYS want to try GTK2 first
String gtk2LibName = "gtk-x11-2.0";
String gtk3LibName = "libgtk-3.so.0";
// we can force the system to use the swing indicator, which WORKS, but doesn't support transparency in the icon.
if (SystemTray.FORCE_TRAY_TYPE == SystemTray.TrayType.Swing) {
isLoaded = true;
}
if (!isLoaded && shouldUseGtk2) {
if (!_isLoaded && shouldUseGtk2) {
try {
JnaHelper.register(gtk2LibName, Gtk.class);
gtk_status_icon_position_menu = Function.getFunction(gtk2LibName, "gtk_status_icon_position_menu");
isGtk2 = true;
_isGtk2 = true;
// 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 started GTK -- so we DO NOT NEED TO.
alreadyRunningGTK = gtk_main_level() != 0;
isLoaded = true;
_alreadyRunningGTK = gtk_main_level() != 0;
_isLoaded = true;
if (SystemTray.DEBUG) {
logger.debug("GTK: {}", gtk2LibName);
@ -113,14 +125,14 @@ class Gtk {
// now for the defaults...
// start with version 3
if (!isLoaded) {
if (!_isLoaded) {
try {
JnaHelper.register(gtk3LibName, Gtk.class);
gtk_status_icon_position_menu = Function.getFunction(gtk3LibName, "gtk_status_icon_position_menu");
// 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 started GTK -- so we DO NOT NEED TO.
alreadyRunningGTK = gtk_main_level() != 0;
isLoaded = true;
_alreadyRunningGTK = gtk_main_level() != 0;
_isLoaded = true;
if (SystemTray.DEBUG) {
logger.debug("GTK: {}", gtk3LibName);
@ -133,16 +145,16 @@ class Gtk {
}
// now version 2
if (!isLoaded) {
if (!_isLoaded) {
try {
JnaHelper.register(gtk2LibName, Gtk.class);
gtk_status_icon_position_menu = Function.getFunction(gtk2LibName, "gtk_status_icon_position_menu");
isGtk2 = true;
_isGtk2 = true;
// 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 started GTK -- so we DO NOT NEED TO.
alreadyRunningGTK = gtk_main_level() != 0;
isLoaded = true;
_alreadyRunningGTK = gtk_main_level() != 0;
_isLoaded = true;
if (SystemTray.DEBUG) {
logger.debug("GTK: {}", gtk2LibName);
@ -154,15 +166,27 @@ class Gtk {
}
}
// 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 |= SystemTray.isSwtLoaded;
isLoaded = _isLoaded;
if (SystemTray.DEBUG) {
logger.debug("Is the system already running GTK? {}", alreadyRunningGTK);
if (_isLoaded) {
// 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 |= SystemTray.isSwtLoaded;
if (SystemTray.DEBUG) {
logger.debug("Is the system already running GTK? {}", _alreadyRunningGTK);
}
alreadyRunningGTK = _alreadyRunningGTK;
isGtk2 = _isGtk2;
isGtk3 = !_isGtk2;
} else {
alreadyRunningGTK = false;
isGtk2 = false;
isGtk3 = false;
}
if (!isLoaded) {
if (OS.isLinux() && !_isLoaded) {
throw new RuntimeException("We apologize for this, but we are unable to determine the GTK library is in use, " +
"or even if it is in use... Please create an issue for this and include your OS type and configuration.");
}