Closed dorkbox closed 7 years ago
JavaFX uses GTK2 for Java <8, and GTK2 or GTK3 for Java 9+. We try to autodetect this, and are mostly successful. In some situations where it doesn't work. Please set SystemTray.FORCE_GTK2=true;
, or to change JavaFX (9+), use -Djdk.gtk.version=3
to solve this.
SWT can use GTK2 or GTK3. If you want to use GTK2 you must force SWT into GTK2 mode via System.setProperty("SWT_GTK3", "0");
before SWT is initialized and only if there are problems with the autodetection, you can also set SystemTray.FORCE_GTK2=true;
.
AppIndicators under Ubuntu 16.04 (and possibly other distro's) will not work as a different user (ie: as a sudo'd user to root
), since AppIndicators require a dbus connection to the current user's window manager -- and this cannot happen between different user accounts. There is no workaround.
MacOSX is a special snowflake in how it handles GUI events, and so there are some bizzaro combinations of SWT, JavaFX, and Swing that do not work together (see the Notes
below for the details.)
Gnome3 (Fedora, Manjaro, Arch, etc) environments by default do not allow the SystemTray icon to be shown. This has been worked around (it will be placed next to the clock) for most Gnome environments, except for Arch linux. Another workaround is to install the Top Icons plugin plugin which moves icons from the notification drawer (it is normally collapsed) at the bottom left corner of the screen to the menu panel next to the clock.
✓
=supported, -
= not supported, +
= see notes
OS | Swing | JavaFX | SWT |
---|---|---|---|
XUbuntu 16.04 | ✓ | ✓ | ✓ |
Ubuntu 16.04 | ✓ | + | ✓ |
UbuntuGnome 16.04 | ✓ | + | ✓ |
Fedora 23 | ✓ | ✓ | ✓ |
Fedora 24 | ✓ | ✓ | ✓ |
Fedora 25 | ✓ | ✓ | ✓ |
Fedora 25 KDE | ✓ | ✓ | ✓ |
LinuxMint 18 | ✓ | ✓ | ✓ |
Elementary OS 0.3.2 | - | ✓ | ✓ |
Elementary OS 0.4 | - | ✓ | ✓ |
Arch Linux + Gnome3 | ✓ | ✓ | ✓ |
FreeBSD 11 + Gnome3 | ✓ | ✓ | + |
Debian 8.5 + Gnome3 | - | - | - |
Debian 8.6 + Gnome3 | - | - | - |
MacOSx | ✓ | + | + |
Win XP | ✓ | ✓ | ✓ |
Win 7 | ✓ | ✓ | ✓ |
Win 8.1 | ✓ | ✓ | ✓ |
Win 10 | ✓ | ✓ | ✓ |
Ubuntu 16.04+ with JavaFX require libappindicator1
because of JavaFX GTK and indicator panel incompatibilities. See more details.
MacOSX JavaFX (Java7) is incompatible with the SystemTray by default. See issue details.
-Djavafx.macosx.embedded=true
as a JVM parameterSystem.setProperty("javafx.macosx.embedded", "true");
before JavaFX is initialized, used, or accessed. NOTE: You may need to change the class (that your main method is in) so it does NOT extend the JavaFX Application
class.MacOSX SWT + Swing menus are incompatible with each other by (Apple's) design for all versions of Java. What will happen in this combination is that the Swing EDT hangs. The only solution is to use native
menus in this specific combination; which is automatically handled during SystemTray initialization.
SWT for FreeBSD builds do not exist.
ElementaryOS does some really bizzare things when it comes to System Tray icons/menus, and as such - the Swing
menu implementation is not supported on that OS. The library will auto-switch to a native menu in this situation.
@dorkbox will this be a drop-in replacement for Java's existing ActionListeners? Also, would you consider an AWT wrapper addition as optional parameter?
If so, I think we can go live with this 3.0 in January which would give you real-world test results. The windows icon fix alone is reason to implement it. We're currently integrating version 2.2.0, but if you've already written the wrappers, 3.0 is a much more attractive option.
@tresf what do you mean by AWT wrapper as a parameter? For adding menu entries? I'm a little confused.
As for using ActionListeners, yea - that could probably happen. It might be a little tricky since for linux/mac, I'm basically writing C code in Java to muck around in GTK/AppIndicator libraries (literally rewrote the implementation of tray icons from scratch, using JNA).
How would you imagine it happening? Just adding a new Menu Entry, but passing it an ActionListener instead?
@dorkbox sorry I'm mixing around terms... I meant JMenuItem
wrapper as AWT is natively supported on Apple and the menu looks perfect, but it will fragment code. For this reason, we wrote a small AWT wrapper with a recursive MenuItem
function to essentially destroy the swing JMenuItems
and create an awt MenuItem
equivalent. This maps mneumonics and recurses through submenus. Thus, someone who wants native menus on Mac can have them without fragmenting the codebase.
@tresf Ahh. Yea, I can probably do something like that. Would you be willing to license your wrapper/recursive function as Apache 2.0 for me, that way I don't have to re-do what you've already done? e: formatting/grammar
We're working to integrate 2.2.0 now, but what would make this integration easier is a method for wrapping a JPopupMenu
or JMenu
into the appropriate platform-specific workaround. This way the listener code won't have to be fragmented. It would truly be a one-size-fits-all solution.
From what I understand AppIndicator
has its own caveats (listeners are bound to a string value) but we'll be wrapping all of this anyway (probably HashMap the strings and throw exception if a duplicate exists). The swing objects are pretty inexpensive to construct so it would allow GUI developers to code the way they're used to while allowing the library to to the heavy lifting (so to speak).
What I'm hoping for is that application developers don't have to do any OS/platform workarounds... :D
willing to license your wrapper/recursive function as Apache 2.0 for me that way I don't have to re-do what you've already done?
Consider this written permission to release AWTMenuWrapper.java
and ClassicTrayIcon.java
-- which I am the sole author -- in whole, part of modified form under the Apache 2.0 license.
willing to license your wrapper/recursive function as Apache 2.0 for me that way I don't have to re-do what you've already done?
Consider this written permission to release AWTMenuWrapper.java and ClassicTrayIcon.java -- which I am the sole author -- in whole, part of modified form under the Apache 2.0 license.
Awesome. I'll go about adding that functionality as soon as I get some bugs worked out.
@dyorgio I should also mention, this won't work with gnome-shell installed AFTER Ubuntu is installed... all I know is that it has something to do with Unity messing things up. It does work flawlessly with UbuntuGnome though.
@dyorgio reproducing the error/crash. Now to figure out what's going on...
@dorkbox tks for your hard work! :) What do you think to create a incredible massive verbose debug version to us? It can help to find the complete stack trace of lib on our systems.
@dyorgio I have some more detailed library debugging (currently off). I'll tie it into the general "debug" flag, so you can see what's getting checked/loaded during started.
Just as a note, there have been some slight API changes, I think for the better. The changes (for the most part) have all been to simpler method names, IE: a change from SystemTray.getSystemTray()
to SystemTray.get()
. It's not a huge difference, but makes the calls less verbose.
Additionally, I have not been able to test (or debug) what is wrong with JavaFX on MacOSx. I suspect it might be a threading issue -- or, as I've read online, JavaFX on a Mac can only run on physical hardware (there are problems with it running in a VM.).
https://bugs.openjdk.java.net/browse/JDK-8154148 http://stackoverflow.com/questions/34016061/javafx-on-mac-os-x-yosemite-crashes
Just as a note, there have been some slight API changes, I think for the better. The changes (for the most part) have all been to simpler method names, IE: a change from SystemTray.getSystemTray() to SystemTray.get(). It's not a huge difference, but makes the calls less verbose.
Was this meant to mirror the Java API?
JavaFX on a Mac can only run on physical hardware (there are problems with it running in a VM.).
I have both VM as well as physical hardware to test on. VMs are 10.7, 10.8, 10.10, 10.11. Physical: 10.11 and I have a colleague (@klabarge) that can test on 10.12 (physical).
Can you identify what you want tested so that we can provide results?
I suspect it might be a threading issue -- or, as I've read online, JavaFX on a Mac can only run on physical hardware (there are problems with it running in a VM.).
We offer a product which uses JavaFX on MacOS and we test it on virtual hardware through VMWare Fusion with success. We use the classic-style system tray through the AWT wrapper, which I would like to collaborate with you on leveraging a more comprehensive wrapper for (such as adding, removing, disabling items).
@tresf further investigating Mac OSX issues, I'll change the backed to support AWT for Mac (since it looks good + works). I can likely do byte-code injection to make the tray-icon respond to any click with the mouse.
The screen-shot you provided for what the "default" tray looks like on OSX is pretty compelling. The only major feature remaining is to add Mnemonic/Accelerator support.
I can likely do byte-code injection to make the tray-icon respond to any click with the mouse.
👍
If I provide an IntelliJ project, would you be able to step debug through it to see where it breaks?
Yes. Would it help to track these as separate issues? The backtraces could start to fill up this meta-issue.
We'll need a bit of hand-holding in regards to which components to test. We're comfortable with IntelliJ but the items/entry points you want unit tested should be spelled out. The fact that you offer multiple testing JARs suggests the main(...)
is changing.
Note also, the product we are implementing with has a service contract with Oracle, if that helps.
@tresf I've got wrappers in place for JMenuItem's (I didn't do heavy testing on these, however they are simple enough I don't think I messed it up). ActionListeners are now used the same was as the Sun/Oracle systemtray, so you won't need to do any extra work for those. However, there is an API change from 2.x to 3, just FYI.
The only gotcha remaining is how mnemonics work -- it is completely different between linux/windows/macos native implementation (surprise, surprise). Everything right now works fine as long as it's only ACSII being used. 3.0 release should have it completely working the same across swing/native menus for characters that are not ascii.
@dorkbox I can only find 4 versions (normal & javafx) x (get & get_native), am I missing something?
Also, I checked those 4 versions:
JavaFX | Normal | |
---|---|---|
get | works | works |
get_native | works | crash |
I attached logs and screenshots of all 4 versions (including the core dump).
My system info: Arch amd64 (4.8.6-1), running i3 WM (4.12-1) (system tray implementation should be according to the normal feedesktop systemtray). I can re-run the test with other WMs if that helps.
dorkbox_SystemTray_Arch_amd64.zip
Edit: Since the crash seems to be related to GTK: GTK2: 2.24.31, GTK3: 3.22.2 Java: Oracle JDK 8u112
@dorkbox just out of curiosity: I played around a little with the source in the SystemTray_project.zip but I got the impression that the code differs from the test JARs. What is the difference in configuration between the get() and the get_native() version? Are they built upon the source version in the project.zip?
@vlow The project has an older source code in it than the test jars. The bundled source with get
and get_native
versions are always built together.
For the developer/end-user, there is no difference besides calling get()
or getNative()
- the changes are all in the implementation.
The difference between get
and getNative
is that get
creates a swing-based popup-menu, and getNative
creates a native (gtk/appindicator/awt/swing) native popup-menu depending on the platform. Of note, with the native-popups, there are some subtle differences in what each platform supports (icons in the menu, text styling in the menu, etc). The preferred popup is swing via get()
, and getNative()
is provided for those that want to use native menus.
I think I got the other issues fixed in my repo, though I would suggest implementing the fixes yourself. All that remains now is getting checkbox to start working. I also tested get() and it works great, the only issue is that first click, it looks like the popdown covers the cursor and steals the focus.
On a side note, this issue is massive. It may be time to close it and open a compatibility matrix issue with a guide on how to test it on a new os, and open the individual problems as issues that give reference to the matrix issue post that posed them.
@dorkbox I hope you don't mind me chiming in here a bit... When the new matrix is created, I have some recommendations:
Simplify
"Ubuntu 16.04 requires an extra plugin to work with JavaFX (libappindicator1), because Cannonical removed the "application status" indicator panel and removed GTK2 AppIndicator support. As a result of these changes, GtkStatusIcon and GTK2 AppIndicator do not work, since JavaFX only works with GTK2 (Java9 provides GTK3 bindings), and libappindicator1 provides GTK2 bindings for AppIndicators. After the installation of libappindicator1, JavaFX will work as expected."
Can be shortened to:
"Ubuntu 16.04 + JavaFX requires
libappindicator1
"
Reduce Test Matrix Scope
Because if you want more testing results, your compatibility matrix will help drive it.
j
vs J
is confusing-
dash or something to denote it's not worth testing or impossible.VCS
Finally, I'd really like to see a quick check-out-and-build process. I think you'll have many more pull requests once we can all easily hack against the codebase instead of burdening you with building a Jar each time. 👍 👍
Release Candidate jars are on my server, and it should pass all OS combinations in the Compatibility Matrix.
@vlow Can you verify the Release Candidate on Arch? I've done a lot of work for OS/DE detection, with a few work-arounds, so it should be working correctly now.
JavaFX | Normal | SWT | |
---|---|---|---|
get | works | works | works |
get_native | works | works | works |
:+1: Wow dorkbox, great job! The native menus look amazing. I'm really looking forward to the final release so I can use your library in production. Thanks for all the effort you put into this.
@dorkbox we use JavaFX + Oracle Java 8 and when testing on ElementaryOS 0.3.2 x64 and RC5 crashes when JavaFX is invoked. Details available here: https://github.com/qzind/tray/pull/149#issuecomment-269579604
... Edt: Also a minor cosmetic issue (same OS + Java)... I notice a significant flicker when a submenu pops-up. It draws a black box about 30% larger than the size of the submenu, then draws the submenu. Native submenus don't seem to draw this artifact. I'm not sure if you've noticed this on any other platforms.
I do ID detection for most linux OS types, depending on the desktop env, and it looks like ElementaryOS changed their OS ID between releases.... I'll investigate further.
Additionally, the artifact you see is because ElementaryOS changed the threading model for GUI event dispatch (beats me why.. but it exposed a number of bugs that @Vzor- helped find/fix). The work-around is to force native menus (and emit a warning) -- which is what happens for 0.4
I'll update the logic to choose the appropriate menu type when the SystemTray loads.
@tresf Also, FreeBSD doesn't work -- I'm fixing it right now as well.
@dorkbox testing Debian Jessie 8.5 x64 + Gnome3, I don't see the icon in the bottom drawer like I'd expect. Please let me know if you'd prefer this tracked in a separate bug report.
16:24:11.654 [AWT-EventQueue-0] DEBUG dorkbox.systemTray.SystemTray - GTK: libgtk-3.so.0
16:24:11.656 [AWT-EventQueue-0] DEBUG dorkbox.systemTray.SystemTray - Is the system already running GTK? false
16:24:11.784 [AWT-EventQueue-0] DEBUG dorkbox.systemTray.SystemTray - OS: Linux
16:24:11.784 [AWT-EventQueue-0] DEBUG dorkbox.systemTray.SystemTray - Arch: amd64
16:24:11.784 [AWT-EventQueue-0] DEBUG dorkbox.systemTray.SystemTray - Oracle Corporation Java HotSpot(TM) 64-Bit Server VM 1.8.0_111
16:24:11.785 [AWT-EventQueue-0] DEBUG dorkbox.systemTray.SystemTray - Is AutoTraySize? true
16:24:11.785 [AWT-EventQueue-0] DEBUG dorkbox.systemTray.SystemTray - Is JavaFX detected? false
16:24:11.785 [AWT-EventQueue-0] DEBUG dorkbox.systemTray.SystemTray - Is SWT detected? false
16:24:11.785 [AWT-EventQueue-0] DEBUG dorkbox.systemTray.SystemTray - Is using native menus? true
16:24:11.785 [AWT-EventQueue-0] DEBUG dorkbox.systemTray.SystemTray - Forced tray type: AutoDetect
16:24:11.785 [AWT-EventQueue-0] DEBUG dorkbox.systemTray.SystemTray - FORCE_GTK2: false
16:24:11.806 [AWT-EventQueue-0] DEBUG dorkbox.systemTray.SystemTray - Currently using the 'GNOME' desktop
16:24:11.806 [AWT-EventQueue-0] DEBUG dorkbox.systemTray.SystemTray - Currently using the 'default' session type
16:24:11.846 [AWT-EventQueue-0] WARN dorkbox.systemTray.SystemTray - Unable to determine the system window manager type. Falling back to GtkStatusIcon.
16:24:11.855 [AWT-EventQueue-0] DEBUG dorkbox.systemTray.SystemTray - Checking scaling factor for GTK environment, should start with 'uint32', value: 'uint32 0'
16:24:11.866 [AWT-EventQueue-0] DEBUG dorkbox.systemTray.SystemTray - Scaling Factor factor is '0', tray icon size is '16'.
16:24:11.866 [AWT-EventQueue-0] DEBUG dorkbox.systemTray.SystemTray - Scaling Factor factor is '0', tray menu size is '16'.
16:24:11.882 [GTK Native Event Loop] DEBUG dorkbox.systemTray.SystemTray - Running GTK Native Event Loop
16:24:12.109 [AWT-EventQueue-0] INFO dorkbox.systemTray.SystemTray - Successfully Loaded: _GtkStatusIconNativeTray
@tresf Debian 8.5 and 8.6 don't appear to support tray icons at all: neither GtkStatusIcon
nor AppIndicator
. The error i'm getting in the gnome-shell logs is tray.STANDARD_TRAY_ICON_IMPLEMENTATIONS is undefined
@dorkbox Fair enough. Perhaps we should probably put a note about it in the compat chart.
I just finished reading this: https://wiki.gnome.org/Design/Whiteboards/StatusIcons
I have elementaryOS 0.3.2 and FreeBSD 11 + Gnome3 working, I'll update the matrix. Should I make another RC?
Fixed issues with GTK checkboxes signaling the callback when changing the checked state. This no longer happens. Additionally, there is an API change from SystemTray.get()
-> SystemTray.getSwing()`.
I expect this to be the final release candidate, pending feedback from QZ-Tray.
The last remaining issue was #45 before the 3.0 release. Just checking with @Vzor- and @tresf to verify.
It looks good now.
3.0 is now released. Available under Github releases and maven.
Dependency bug:
I needed to include dependency on my project:
<dependency>
<groupId>javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.12.1.GA</version>
</dependency>
The lib doesn't contains any maven dependency information...
Ah, I'll add this. Thanks for the info.
Current Release Candidate: 10
For system compatibility on release, please use the system_tray_3.0.jar -- this file is the same format that the release will be in. For all-in-one "FAT" jars, use the RCx.jars.
RC10: Fixed issue/added support for Swing UI menu/entry customization independent of system L&F.
RC9: Removed
getNative()
andgetSwing()
. There is onlyget()
, which will choose native,Swing, or AWT depending on OS. This can be customized (see readme)RC8: Fixed crash on Windows java 32bit with injecting bytecode.
RC7: Small API changes from RC6 -> RC7:
SystemTray.get()
is nowSystemTray.getSwing()
to indicate it's menu type (Similarly togetNative()
), and to indicate that there is no library preference between the two different methods.The Release Candidate downloads is released as a "all-in-one" jar, for a variety of different tray types and configurations. Please note that SWT testing will require you to download the SWT native library and add it to the classpath when you launch the jar. If you use SWT, you should be familiar with this, otherwise don't worry about it.
There shouldn't be any issues for any of the OS' listed in the Compatibility Matrix. If you are testing this and your OS isn't listed, please open a new issue for it.
Finally, the jars can be tested via
java -jar SystemTray_RC2_normal.jar
(as an example).EDIT: I've cleaned up this thread a bit, it was becoming big. After the Release Candidate passes, this issue will be closed.