dustinkredmond / FXTrayIcon

Tray Icon implementation for JavaFX applications. Say goodbye to using AWT's SystemTray icon, instead use a JavaFX Tray Icon.
MIT License
327 stars 26 forks source link

Test on MacOS, ensure cross-platform function #2

Closed dustinkredmond closed 3 years ago

dustinkredmond commented 3 years ago

FXTrayIcon is mostly built and tested on Windows 10. Theoretically, FXTrayIcon should work on any OS and desktop environment that supports the AWT SystemTray functionality.

I do not readily have access to MacOS, but am aware that some features of FXTrayIcon work differently (or not at all) on MacOS. If anyone's primary machine runs MacOS, I could use the help in testing functionality and making any necessary changes to facilitate better operation.

One such issue:

setOnAction() does not cause the event to be triggered on double-click of the icon, this problem only exists on MacOS (to my knowledge) setOnClick() does work on MacOS for allowing single-click of the icon.

In this case, maybe we could throw an UnsupportedOperationException or call into new code that would ameliorate the lack of functionality.

Oliver-Loeffler commented 3 years ago

A quick test with Java 15 and JavaFX 15 on macOS HighSierra 10.13.6 showed that basically everything works. Showing icon/hiding it dynamically worls. The icon appears in the Finder notification area and vanishes if wanted.

TrayIcon

Also messages (generic ones, warnings, infos, errors) do work. The images used in there appear blurry, well guess those are very low res.

Adding menu items works, executing action from within the menu also works. If desired, the application closes properly.

2 fingers kept pressing on touch pad triggers the action defined in setOnAction() method. After releasing the 2 fingers the action defined in setOnClick() is executed, When just clicking on the icon with one finger, the menu opens, the activity passed in setOnClick() is not executed. At least on macOS HighSierra this behaves differently than expected.

There is the Spotlight icon, when clicking there no menu appears but spotlight opens. May be to achieve similar functionality on FXTrayIcon a different approach is needed.

dustinkredmond commented 3 years ago

@Oliver-Loeffler Thank you so much for testing this. This is a big help. I was aware that the setOnAction() and setOnClick() methods appear to not work as expected. This is an issue with how AWT handles these events on MacOS, but I believe I can create a workaround. I'm curious if the behaviour is the same on MacOS 11.1 (Big Sur).

The issue that you mentioned about the icons being blurry I was not aware of. The icons, unfortunately are provided directly by the AWT API and are system-dependent. The icons look differently on Windows than they do on Linux. I may try to instead use the same icons that are used by the JavaFX Alert class. These also have info, warn, error styles. The only issue in doing that is that I would have to select the icons based on the modena.css stylesheet for JavaFX, and this may change in future releases. I'll give this some thought, but am open to suggestion as well.

I'm planning on testing FXTrayIcon this afternoon with a few different Linux distributions (varying desktop environments). Depending on the behaviour of FXTrayIcon in these environments, I will try to implement a fix and comment back here. Thanks again for so promptly testing this and reporting back.

dustinkredmond commented 3 years ago

@Oliver-Loeffler, I just upgraded my old MacBook Air (2017ish model) to the "Big Sur" update, and I found some interesting issues. It looks like the TrayIcon itself is shown without issue and the MenuItems seem to be added without issue. Their onAction() methods also seem to work, but I noticed some strange behavior when I attempted to set an EventHandler for the showMessage methods of FXTrayIcon, the application becomes unresponsive, perhaps a threading issue. I will work on this a little more and try to determine exactly what is happening.

EasyG0ing1 commented 3 years ago

@dustinkredmond

I had a thought concerning this problem. As you might remember, macs started out with single-button mice. And the popular way to use it was to - for example - click and hold on a menu then after it pops down, you drag to a selection then let go of the mouse button. Since macs were always intended to be "simpler" in the user interface, do you think it's possible that the operating system doesn't even listen for double clicks in the System Tray?

dustinkredmond commented 3 years ago

@Oliver-Loeffler, the displayMessage methods were not calling the EventQueue.invokeLater() method to run on the proper AWT thread. I've pushed a commit which fixes this. The notifications work, but do not display the proper icons, so I'm thinking I will have to do some more work there, I'm thinking that going with the JavaFX built-in icons may be a good idea in the case of MacOS, I may even design some custom icons, but want them to look as close to native JavaFX as possible.

I'm still investigating the best way to handle the setOnAction and setOnClick, as @EasyG0ing1 mentions, this behavior may have been intended to be slightly different for MacOS, so I'm open to pull requests and ideas unless I hack up something in the next few hours before bed. 😅

EasyG0ing1 commented 3 years ago

@dustinkredmond, Forgive my ignorance, but why the need for setOnAction when setOnClick works just fine? Is it just the principle of the matter (write once run anywhere should work, darnit!) or is there some benefit to one method over the other?

dustinkredmond commented 3 years ago

@EasyG0ing1, the only reason for this was to implement single vs. double click. I'm assuming that folks using MacOS are more used to single clicking icons, while with Windows and certain Linux desktop environments, certain programs offer different actions for single and double click.

I'd like to offer both options, but if I can't come up with a viable workaround for MacOS, I may just get rid of the setOnClick() method and have setOnAction() trigger on single click for both MacOS and Windows. Maybe there is a way to listen for the click count like in JavaFX, but I will have to examine the AWT API later today.

dustinkredmond commented 3 years ago

@EasyG0ing1 & @Oliver-Loeffler. On MacOS Big Sur, a two finger click will activate both setOnAction() and setOnClick() EventHandlers. I cannot seem to independently activate one or the other. I'm thinking I will keep a setOnAction() method that will be activated by a single-click on Windows and two-finger click on MacOS. This should keep things pretty cross platform. MacOS will display the context menu on single finger click. Since FXTrayIcon relies on AWT, there is no great workaround. I'm starting a new project NotiFX that will handle native implementation of tray icons, notifications, etc without the reliance on AWT. I already have a few people wanting to contribute, so expect something in that future from that. As for FXTrayIcon, we have to stick with that old nasty AWT API internally.

I will try to get the commit to remove setOnClick() and revamp setOnAction() for cross-platform behavior in tonight. If you have any suggestions, feel free to leave them here or shoot me an email. My contact info is available from my GitHub profile main page (near the bottom).

Also, @Oliver-Loeffler, I didn't see your SQL joke in the displayMessage() notification until now. I let out a good chuckle from that. Thank you. 😄

dustinkredmond commented 3 years ago

Note that setOnClick() has been annotated as Deprecated, and will be removed in a further release. Closing this issue for now until, as other behavior of FXTrayIcon is predictable and acceptable on both MacOS, Windows, and Linux distributions that do not use AppIndicator.