GTK now starts up when on linux/unix, regardless of tray type.

This commit is contained in:
nathan 2017-06-25 23:50:22 +02:00
parent c70c96b5d9
commit 9dbee8cfc5
5 changed files with 163 additions and 195 deletions

View File

@ -89,18 +89,12 @@ class SystemTray {
} }
@Property @Property
/** Enables auto-detection for the system tray. This should be mostly successful. /** Enables auto-detection for the system tray. This should be mostly successful. */
* <p>
* Auto-detection will use DEFAULT_TRAY_SIZE as a 'base-line' for determining what size to use.
* <p>
* If auto-detection fails and the incorrect size is detected or used, disable this and specify the correct DEFAULT_TRAY_SIZE or
* DEFAULT_MENU_SIZE instead
*/
public static boolean AUTO_SIZE = true; public static boolean AUTO_SIZE = true;
@Property @Property
/** Forces the system tray to always choose GTK2 (even when GTK3 might be available). */ /** Forces the system tray to always choose GTK2 (even when GTK3 might be available). */
public static boolean FORCE_GTK2 = false; public static boolean FORCE_GTK2 = true;
@Property @Property
/** /**
@ -108,7 +102,7 @@ class SystemTray {
* <p> * <p>
* This is an advanced feature, and it is recommended to leave at AutoDetect. * This is an advanced feature, and it is recommended to leave at AutoDetect.
*/ */
public static TrayType FORCE_TRAY_TYPE = TrayType.Swing; public static TrayType FORCE_TRAY_TYPE = TrayType.AutoDetect;
@Property @Property
/** /**
@ -264,9 +258,9 @@ class SystemTray {
return; return;
} }
// Windows can ONLY use Swing (non-native) - AWT/native looks absolutely horrid // Windows can ONLY use Swing (non-native) - AWT/native looks absolutely horrid and is not an option
// OSx can use Swing (non-native) or AWT (native) . // OSx can use Swing (non-native) or AWT (native) .
// Linux can use Swing (non-native) menus + (native Icon via GTK or AppIndicator), GtkStatusIcon (native), or AppIndicator (native) // Linux can use Swing (non-native), AWT (native), GtkStatusIcon (native), or AppIndicator (native)
if (OS.isWindows()) { if (OS.isWindows()) {
if (FORCE_TRAY_TYPE != TrayType.AutoDetect && FORCE_TRAY_TYPE != TrayType.Swing) { if (FORCE_TRAY_TYPE != TrayType.AutoDetect && FORCE_TRAY_TYPE != TrayType.Swing) {
// windows MUST use swing only! // windows MUST use swing only!
@ -282,102 +276,96 @@ class SystemTray {
} }
} }
else if (OS.isLinux() || OS.isUnix()) { else if (OS.isLinux() || OS.isUnix()) {
// kablooie if SWT/JavaFX or Swing is not configured in a way that works with us. // NOTE: if the UI uses the 'getSystemLookAndFeelClassName' and is on Linux, this will cause GTK2 to get loaded first,
if (FORCE_TRAY_TYPE != TrayType.Swing) { // which will cause conflicts if one tries to use GTK3
// NOTE: if the UI uses the 'getSystemLookAndFeelClassName' and is on Linux, this will cause GTK2 to get loaded first, if (!FORCE_GTK2 && !isJavaFxLoaded && !isSwtLoaded) {
// which will cause conflicts if one tries to use GTK3
if (!FORCE_GTK2 && !isJavaFxLoaded && !isSwtLoaded) {
String currentUI = UIManager.getLookAndFeel() String currentUI = UIManager.getLookAndFeel()
.getClass() .getClass()
.getName(); .getName();
boolean mustForceGtk2 = false; boolean mustForceGtk2 = false;
if (currentUI.equals(GTKLookAndFeel.class.getCanonicalName())) { if (currentUI.equals(GTKLookAndFeel.class.getCanonicalName())) {
// this means our look and feel is the GTK look and feel... THIS CREATES PROBLEMS! // this means our look and feel is the GTK look and feel... THIS CREATES PROBLEMS!
// THIS IS NOT DOCUMENTED ANYWHERE... // THIS IS NOT DOCUMENTED ANYWHERE...
String swingGtkVersion = java.security.AccessController.doPrivileged(new GetPropertyAction("swing.gtk.version")); String swingGtkVersion = java.security.AccessController.doPrivileged(new GetPropertyAction("swing.gtk.version"));
mustForceGtk2 = swingGtkVersion == null || swingGtkVersion.startsWith("2"); mustForceGtk2 = swingGtkVersion == null || swingGtkVersion.startsWith("2");
}
if (mustForceGtk2) {
// we are NOT using javaFX/SWT and our UI is GTK2 and we want GTK3
// JavaFX/SWT can be GTK3, but Swing can not be GTK3.
if (AUTO_FIX_INCONSISTENCIES) {
// we must use GTK2 because Swing is configured to use GTK2
logger.warn("Forcing GTK2 because the Swing UIManager is GTK2");
FORCE_GTK2 = true;
} else {
logger.error("Unable to use the SystemTray when the Swing UIManager is configured to use the native L&F, which " +
"uses GTK2. This is incompatible with GTK3. " +
"Please set `SystemTray.AUTO_FIX_INCONSISTENCIES=true;` to automatically fix this problem.");
systemTrayMenu = null;
systemTray = null;
return;
}
}
} }
if (mustForceGtk2) {
// we are NOT using javaFX/SWT and our UI is GTK2 and we want GTK3
// JavaFX/SWT can be GTK3, but Swing can not be GTK3.
if (isSwtLoaded) { if (AUTO_FIX_INCONSISTENCIES) {
// 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 // we must use GTK2 because Swing is configured to use GTK2
// System.setProperty("SWT_GTK3", "0"); logger.warn("Forcing GTK2 because the Swing UIManager is GTK2");
FORCE_GTK2 = true;
} else {
logger.error("Unable to use the SystemTray when the Swing UIManager is configured to use the native L&F, which " +
"uses GTK2. This is incompatible with GTK3. " +
"Please set `SystemTray.AUTO_FIX_INCONSISTENCIES=true;` to automatically fix this problem.");
// was SWT forced? systemTrayMenu = null;
String swt_gtk3 = System.getProperty("SWT_GTK3"); systemTray = null;
boolean isSwt_GTK3 = swt_gtk3 != null && !swt_gtk3.equals("0");
if (!isSwt_GTK3) {
// check a different property
String property = System.getProperty("org.eclipse.swt.internal.gtk.version");
isSwt_GTK3 = property != null && !property.startsWith("2.");
} }
}
}
else 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");
if (isSwt_GTK3 && FORCE_GTK2) { // was SWT forced?
logger.error("Unable to use the SystemTray when SWT is configured to use GTK3 and the SystemTray is configured to use " + String swt_gtk3 = System.getProperty("SWT_GTK3");
"GTK2. Please configure SWT to use GTK2, via `System.setProperty(\"SWT_GTK3\", \"0\");` before SWT is " + boolean isSwt_GTK3 = swt_gtk3 != null && !swt_gtk3.equals("0");
"initialized, or set `SystemTray.FORCE_GTK2=false;`"); if (!isSwt_GTK3) {
// check a different property
String property = System.getProperty("org.eclipse.swt.internal.gtk.version");
isSwt_GTK3 = property != null && !property.startsWith("2.");
}
if (isSwt_GTK3 && FORCE_GTK2) {
logger.error("Unable to use the SystemTray when SWT is configured to use GTK3 and the SystemTray is configured to use " +
"GTK2. Please configure SWT to use GTK2, via `System.setProperty(\"SWT_GTK3\", \"0\");` before SWT is " +
"initialized, or set `SystemTray.FORCE_GTK2=false;`");
systemTrayMenu = null;
systemTray = null;
return;
} else if (!isSwt_GTK3 && !FORCE_GTK2 && AUTO_FIX_INCONSISTENCIES) {
// we must use GTK2, because SWT is GTK2
logger.warn("Forcing GTK2 because SWT is GTK2");
FORCE_GTK2 = true;
}
}
else 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+.
boolean isJava_GTK3_Possible = OS.javaVersion >= 9 && System.getProperty("jdk.gtk.version", "2").equals("3");
if (isJava_GTK3_Possible && FORCE_GTK2) {
// if we are java9, then we can change it -- otherwise we cannot.
if (OS.javaVersion == 9 && AUTO_FIX_INCONSISTENCIES) {
logger.warn("Unable to use the SystemTray when JavaFX is configured to use GTK3 and the SystemTray is " +
"configured to use GTK2. Please configure JavaFX to use GTK2 (via `System.setProperty(\"jdk.gtk.version\", \"3\");`) " +
"before JavaFX is initialized, or set `SystemTray.FORCE_GTK2=false;` Undoing `FORCE_GTK2`.");
FORCE_GTK2 = false;
} else {
logger.error("Unable to use the SystemTray when JavaFX is configured to use GTK3 and the SystemTray is configured to use " +
"GTK2. Please set `SystemTray.FORCE_GTK2=false;` if that is not possible then it will not work.");
systemTrayMenu = null; systemTrayMenu = null;
systemTray = null; systemTray = null;
return; return;
} else if (!isSwt_GTK3 && !FORCE_GTK2 && AUTO_FIX_INCONSISTENCIES) {
// we must use GTK2, because SWT is GTK2
logger.warn("Forcing GTK2 because SWT is GTK2");
FORCE_GTK2 = true;
}
}
else 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+.
boolean isJava_GTK3_Possible = OS.javaVersion >= 9 && System.getProperty("jdk.gtk.version", "2").equals("3");
if (isJava_GTK3_Possible && FORCE_GTK2) {
// if we are java9, then we can change it -- otherwise we cannot.
if (OS.javaVersion == 9 && AUTO_FIX_INCONSISTENCIES) {
logger.warn("Unable to use the SystemTray when JavaFX is configured to use GTK3 and the SystemTray is " +
"configured to use GTK2. Please configure JavaFX to use GTK2 (via `System.setProperty(\"jdk.gtk.version\", \"3\");`) " +
"before JavaFX is initialized, or set `SystemTray.FORCE_GTK2=false;` Undoing `FORCE_GTK2`.");
FORCE_GTK2 = false;
} else {
logger.error("Unable to use the SystemTray when JavaFX is configured to use GTK3 and the SystemTray is configured to use " +
"GTK2. Please set `SystemTray.FORCE_GTK2=false;` if that is not possible then it will not work.");
systemTrayMenu = null;
systemTray = null;
return;
}
} else if (!isJava_GTK3_Possible && !FORCE_GTK2 && AUTO_FIX_INCONSISTENCIES) {
// we must use GTK2, because JavaFX is GTK2
logger.warn("Forcing GTK2 because JavaFX is GTK2");
FORCE_GTK2 = true;
} }
} else if (!isJava_GTK3_Possible && !FORCE_GTK2 && AUTO_FIX_INCONSISTENCIES) {
// we must use GTK2, because JavaFX is GTK2
logger.warn("Forcing GTK2 because JavaFX is GTK2");
FORCE_GTK2 = true;
} }
} }
} }
@ -420,13 +408,14 @@ class SystemTray {
} }
} }
else if (OS.isMacOsX()) { else if (OS.isMacOsX()) {
// macosx doesn't respond to all buttons (but should) if (SystemTray.FORCE_TRAY_TYPE != TrayType.AutoDetect) {
SystemTrayFixes.fixMacOS(); // macos can ONLY use the AWT tray indicator, if you want it to follow the L&F of the OS. If we force a specific type,
// then allow that.
try { try {
trayType = selectType(TrayType.AWT); trayType = selectType(TrayType.AWT);
} catch (Throwable e) { } catch (Throwable e) {
logger.error("You might need to grant the AWTPermission `accessSystemTray` to the SecurityManager."); logger.error("You might need to grant the AWTPermission `accessSystemTray` to the SecurityManager.");
}
} }
} }
else if ((OS.isLinux() || OS.isUnix())) { else if ((OS.isLinux() || OS.isUnix())) {
@ -635,36 +624,34 @@ class SystemTray {
// fallback... // fallback...
if (trayType == null) { if (trayType == null) {
trayType = selectTypeQuietly(TrayType.GtkStatusIcon); logger.warn("Unable to determine the system window manager type. Using the Swing Tray type instead.");
logger.warn("Unable to determine the system window manager type. Falling back to GtkStatusIcon.");
trayType = selectTypeQuietly(TrayType.Swing);
} }
// this is bad... // this is bad...
if (trayType == null) { if (trayType == null) {
logger.error("SystemTray initialization failed. Unable to load the system tray native libraries. Please write an issue " + logger.error("SystemTray initialization failed. Unable to load the system tray native libraries. " +
"and include your OS type and configuration"); "Using the Swing Tray type instead. Please write an issue and include your OS type and configuration");
systemTrayMenu = null; trayType = selectTypeQuietly(TrayType.Swing);
systemTray = null;
return;
} }
if (isTrayType(trayType, TrayType.AppIndicator) && OSUtil.Linux.isRoot()) { if (isTrayType(trayType, TrayType.AppIndicator) && OSUtil.Linux.isRoot()) {
// if are we running as ROOT, there can be issues (definitely on Ubuntu 16.04, maybe others)! // if are we running as ROOT, there can be issues (definitely on Ubuntu 16.04, maybe others)!
logger.error("Attempting to load the SystemTray as the 'root/sudo' user. This will likely not work because of dbus " + logger.error("Attempting to load the SystemTray as the 'root/sudo' user. This will likely not work because of dbus " +
"restrictions."); "restrictions. Using the Swing Tray type instead.");
trayType = selectTypeQuietly(TrayType.Swing);
} }
} }
if (trayType == null) { if (trayType == null) {
// unsupported tray, or unknown type trayType = selectTypeQuietly(TrayType.Swing);
logger.error("SystemTray initialization failed. (Unable to discover which implementation to use). Something is seriously wrong.");
systemTrayMenu = null; // unsupported tray, or unknown type
systemTray = null; logger.error("SystemTray initialization failed. (Unable to discover which implementation to use). Falling back to the Swing Tray.");
return;
} }
final AtomicReference<Tray> reference = new AtomicReference<Tray>(); final AtomicReference<Tray> reference = new AtomicReference<Tray>();
@ -674,17 +661,17 @@ class SystemTray {
CacheUtil.tempDir = "SysTray"; CacheUtil.tempDir = "SysTray";
try { try {
if ((OS.isLinux() || OS.isUnix()) && (isTrayType(trayType, TrayType.GtkStatusIcon) || isTrayType(trayType, TrayType.AppIndicator))) { // at this point, the tray type is what it should be. If there are failures or special cases, all types will fall back to
// Swing.
if (OS.isLinux() || OS.isUnix()) {
// NOTE: appindicator1 -> GTk2, appindicator3 -> GTK3. // NOTE: appindicator1 -> GTk2, appindicator3 -> GTK3.
// appindicator3 doesn't support menu icons via GTK2!! // appindicator3 doesn't support menu icons via GTK2!!
if (!Gtk.isLoaded) { if (!Gtk.isLoaded) {
logger.error("Unable to initialize GTK! Something is severely wrong!"); logger.error("Unable to initialize GTK! Something is severely wrong! Using the Swing Tray type instead.");
systemTrayMenu = null; trayType = selectTypeQuietly(TrayType.Swing);
systemTray = null;
return;
} }
else if (OSUtil.Linux.isArch()) {
if (OSUtil.Linux.isArch()) {
// arch linux is fun! // arch linux is fun!
if (isTrayType(trayType, TrayType.AppIndicator)) { if (isTrayType(trayType, TrayType.AppIndicator)) {
@ -696,47 +683,31 @@ class SystemTray {
if (!AppIndicator.isLoaded) { if (!AppIndicator.isLoaded) {
if (Gtk.isGtk2) { if (Gtk.isGtk2) {
logger.error("Unable to initialize AppIndicator for Arch linux, it requires GTK2! " + logger.error("Unable to initialize AppIndicator for Arch linux, it requires GTK2! " +
"Please install libappindicator, for example: 'sudo pacman -S libappindicator'"); "Please install libappindicator, for example: 'sudo pacman -S libappindicator'. " +
systemTrayMenu = null; "Using the Swing Tray type instead.");
systemTray = null;
return;
} else { } else {
logger.error("Unable to initialize AppIndicator for Arch linux, it requires GTK3! " + logger.error("Unable to initialize AppIndicator for Arch linux, it requires GTK3! " +
"Please install libappindicator3, for example: 'sudo pacman -S libappindicator3'"); // GTK3 "Please install libappindicator3, for example: 'sudo pacman -S libappindicator3'. " +
systemTrayMenu = null; "Using the Swing Tray type instead."); // GTK3
systemTray = null;
return;
} }
trayType = selectTypeQuietly(TrayType.Swing);
} }
} }
} }
else if (isTrayType(trayType, TrayType.AppIndicator)) {
if (isTrayType(trayType, TrayType.AppIndicator)) {
if (Gtk.isGtk2 && AppIndicator.isVersion3) { if (Gtk.isGtk2 && AppIndicator.isVersion3) {
try { logger.warn("AppIndicator3 detected with GTK2, falling back to GTK2 system tray type. " +
trayType = selectType(TrayType.GtkStatusIcon); "Please install libappindicator1 OR GTK3, for example: 'sudo apt-get install libappindicator1'. " +
logger.warn("AppIndicator3 detected with GTK2, falling back to GTK2 system tray type. " + "Using the Swing Tray type instead.");
"Please install libappindicator1 OR GTK3, for example: 'sudo apt-get install libappindicator1'");
} catch (Throwable e) {
if (DEBUG) {
logger.error("Cannot initialize _GtkStatusIconTray", e);
}
logger.error("AppIndicator3 detected with GTK2 and unable to fallback to using GTK2 system tray type." +
"AppIndicator3 requires GTK3 to be fully functional, and while this will work -- " +
"the menu icons WILL NOT be visible." +
" Please install libappindicator1 OR GTK3, for example: 'sudo apt-get install libappindicator1'");
systemTrayMenu = null; trayType = selectTypeQuietly(TrayType.Swing);
systemTray = null;
return;
}
} }
else if (!AppIndicator.isLoaded) {
if (!AppIndicator.isLoaded) {
// YIKES. Try to fallback to GtkStatusIndicator, since AppIndicator couldn't load. // YIKES. Try to fallback to GtkStatusIndicator, since AppIndicator couldn't load.
logger.warn("Unable to initialize the AppIndicator correctly, falling back to GtkStatusIcon type"); logger.warn("Unable to initialize the AppIndicator correctly. Using the Swing Tray type instead.");
trayType = selectTypeQuietly(TrayType.GtkStatusIcon);
trayType = selectTypeQuietly(TrayType.Swing);
} }
} }
} }
@ -753,6 +724,35 @@ class SystemTray {
Swt.init(); Swt.init();
} }
if (OS.isLinux() || OS.isUnix()) {
// linux/unix need access to GTK, so load it up before the tray is loaded!
Gtk.startGui();
Gtk.waitForEventsToComplete();
}
// initialize tray/menu image sizes. This must be BEFORE the system tray has been created
int trayImageSize = SizeAndScalingUtil.getTrayImageSize(trayType);
SizeAndScalingUtil.getMenuImageSize(trayType);
// this logic has to be before we create the system Tray
if (OS.isWindows()) {
// windows hard-codes the image size
SystemTrayFixes.fixWindows(trayImageSize);
}
else if (OS.isMacOsX()) {
// macosx doesn't respond to all buttons (but should)
SystemTrayFixes.fixMacOS();
}
else if ((OS.isLinux() || OS.isUnix())) {
// linux/mac doesn't have transparent backgrounds for swing
SystemTrayFixes.fixLinux(trayImageSize);
}
if ((isJavaFxLoaded || isSwtLoaded) && SwingUtilities.isEventDispatchThread()) { if ((isJavaFxLoaded || isSwtLoaded) && SwingUtilities.isEventDispatchThread()) {
// oh boy! This WILL NOT WORK. Let the dev know // oh boy! This WILL NOT WORK. Let the dev know
@ -764,19 +764,6 @@ class SystemTray {
return; return;
} }
// this logic has to be JUST before we create the system Tray
if (OS.isWindows()) {
// windows hard-codes the image size
SystemTrayFixes.fixWindows(SizeAndScalingUtil.getTrayImageSize(trayType));
} else if (OS.isMacOsX()) {
// macosx doesn't respond to all buttons (but should)
SystemTrayFixes.fixMacOS();
}
// initialize tray/menu image sizes
SizeAndScalingUtil.getTrayImageSize(trayType);
SizeAndScalingUtil.getMenuImageSize(trayType);
// javaFX and SWT should not start on the EDT!! // javaFX and SWT should not start on the EDT!!
// if it's linux + native menus must not start on the EDT! // if it's linux + native menus must not start on the EDT!

View File

@ -129,15 +129,8 @@ class Gtk {
_isLoaded = true; _isLoaded = true;
} }
// we can force the system to use the swing indicator, which WORKS, but doesn't support transparency in the icon. // we can force the system to use the swing indicator, which WORKS, but doesn't support transparency in the icon. However, there
if (!_isLoaded && // are certain GTK functions we might want to use (even if we are Swing or AWT), so we load GTK anyways...
(SystemTray.FORCE_TRAY_TYPE == SystemTray.TrayType.Swing || SystemTray.FORCE_TRAY_TYPE == SystemTray.TrayType.AWT)) {
if (SystemTray.DEBUG) {
logger.debug("Not loading GTK for Swing or AWT");
}
shouldLoadGtk = false;
_isLoaded = true;
}
// in some cases, we ALWAYS want to try GTK2 first // in some cases, we ALWAYS want to try GTK2 first
String gtk2LibName = "gtk-x11-2.0"; String gtk2LibName = "gtk-x11-2.0";
@ -341,10 +334,10 @@ class Gtk {
void gtk_main(); void gtk_main();
/** /**
* Waits for the GUI to finish loading * Waits for the all posted events to GTK to finish loading
*/ */
public static public static
void waitForStartup() { void waitForEventsToComplete() {
final CountDownLatch blockUntilStarted = new CountDownLatch(1); final CountDownLatch blockUntilStarted = new CountDownLatch(1);
dispatch(new Runnable() { dispatch(new Runnable() {
@ -360,7 +353,7 @@ class Gtk {
try { try {
if (!blockUntilStarted.await(10, TimeUnit.SECONDS)) { if (!blockUntilStarted.await(10, TimeUnit.SECONDS)) {
if (SystemTray.DEBUG) { if (SystemTray.DEBUG) {
SystemTray.logger.error("Something is very wrong. The waitForStartup took longer than expected.", SystemTray.logger.error("Something is very wrong. The waitForEventsToComplete took longer than expected.",
new Exception("")); new Exception(""));
} }
} }
@ -386,7 +379,7 @@ class Gtk {
try { try {
if (!blockUntilStarted.await(10, TimeUnit.SECONDS)) { if (!blockUntilStarted.await(10, TimeUnit.SECONDS)) {
if (SystemTray.DEBUG) { if (SystemTray.DEBUG) {
SystemTray.logger.error("Something is very wrong. The waitForStartup took longer than expected.", SystemTray.logger.error("Something is very wrong. The waitForEventsToComplete took longer than expected.",
new Exception("")); new Exception(""));
} }
} }
@ -409,7 +402,7 @@ class Gtk {
try { try {
if (!blockUntilStarted.await(10, TimeUnit.SECONDS)) { if (!blockUntilStarted.await(10, TimeUnit.SECONDS)) {
if (SystemTray.DEBUG) { if (SystemTray.DEBUG) {
SystemTray.logger.error("Something is very wrong. The waitForStartup took longer than expected.", SystemTray.logger.error("Something is very wrong. The waitForEventsToComplete took longer than expected.",
new Exception("")); new Exception(""));
} }
} }

View File

@ -99,8 +99,6 @@ class _AppIndicatorNativeTray extends Tray implements NativeUI {
_AppIndicatorNativeTray(final SystemTray systemTray) { _AppIndicatorNativeTray(final SystemTray systemTray) {
super(); super();
Gtk.startGui();
// we override various methods, because each tray implementation is SLIGHTLY different. This allows us customization. // we override various methods, because each tray implementation is SLIGHTLY different. This allows us customization.
final GtkMenu gtkMenu = new GtkMenu() { final GtkMenu gtkMenu = new GtkMenu() {
/** /**
@ -108,6 +106,7 @@ class _AppIndicatorNativeTray extends Tray implements NativeUI {
* *
* ALWAYS CALLED ON THE EDT * ALWAYS CALLED ON THE EDT
*/ */
@Override
protected final protected final
void onMenuAdded(final Pointer menu) { void onMenuAdded(final Pointer menu) {
// see: https://code.launchpad.net/~mterry/libappindicator/fix-menu-leak/+merge/53247 // see: https://code.launchpad.net/~mterry/libappindicator/fix-menu-leak/+merge/53247
@ -227,7 +226,7 @@ class _AppIndicatorNativeTray extends Tray implements NativeUI {
} }
}); });
Gtk.waitForStartup(); Gtk.waitForEventsToComplete();
bind(gtkMenu, null, systemTray); bind(gtkMenu, null, systemTray);
} }

View File

@ -62,8 +62,6 @@ class _GtkStatusIconNativeTray extends Tray implements NativeUI {
_GtkStatusIconNativeTray(final SystemTray systemTray) { _GtkStatusIconNativeTray(final SystemTray systemTray) {
super(); super();
Gtk.startGui();
// we override various methods, because each tray implementation is SLIGHTLY different. This allows us customization. // we override various methods, because each tray implementation is SLIGHTLY different. This allows us customization.
gtkMenu = new GtkMenu() { gtkMenu = new GtkMenu() {
@Override @Override
@ -170,7 +168,7 @@ class _GtkStatusIconNativeTray extends Tray implements NativeUI {
} }
}); });
Gtk.waitForStartup(); Gtk.waitForEventsToComplete();
// we have to be able to set our title, otherwise the gnome-shell extension WILL NOT work // we have to be able to set our title, otherwise the gnome-shell extension WILL NOT work
Gtk.dispatch(new Runnable() { Gtk.dispatch(new Runnable() {

View File

@ -61,11 +61,6 @@ class _SwingTray extends Tray implements SwingUI {
"type and configuration"); "type and configuration");
} }
if (OS.isLinux() || OS.isUnix()) {
// linux/unix need access to GTK, so load it up!
Gtk.startGui();
}
// we override various methods, because each tray implementation is SLIGHTLY different. This allows us customization. // we override various methods, because each tray implementation is SLIGHTLY different. This allows us customization.
final SwingMenu swingMenu = new SwingMenu(null, null) { final SwingMenu swingMenu = new SwingMenu(null, null) {
@Override @Override
@ -194,17 +189,13 @@ class _SwingTray extends Tray implements SwingUI {
if (OS.isLinux() || OS.isUnix()) { if (OS.isLinux() || OS.isUnix()) {
// does not need to be called on the dispatch (it does that) // does not need to be called on the dispatch (it does that). Startup happens in the SystemTray (in a special block),
// because we MUST startup the system tray BEFORE to access GTK before we create the swing version (to get size info)
Gtk.shutdownGui(); Gtk.shutdownGui();
} }
} }
}; };
if (OS.isLinux() || OS.isUnix()) {
// linux/unix need access to GTK, so load it up!
Gtk.waitForStartup();
}
bind(swingMenu, null, systemTray); bind(swingMenu, null, systemTray);
} }