Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Questions] How to check if tray icon is supported and all the libs are ok? #70

Closed
sblantipodi opened this issue Nov 9, 2024 · 20 comments
Labels
question Further information is requested

Comments

@sblantipodi
Copy link

sblantipodi commented Nov 9, 2024

Hi, congratulations for your wonderful lib. I have some questions if possible...

How can I check if the tray icon is fully supported without getting an exception?

I'm sorry if I opened a feature request but the wiki does not answers this question.

Thanks for your great work!

@sblantipodi sblantipodi changed the title [Questions] How to change menu items and the icon at runtime? and some other questions... [Questions] How to check if tray icon is supported and all the libs are ok? Nov 9, 2024
@purejava purejava added question Further information is requested and removed feature-request labels Nov 10, 2024
@purejava
Copy link
Owner

purejava commented Nov 10, 2024

Hi, congratulations for your wonderful lib. I have some questions if possible...

Thank you.

How can I check if the tray icon is fully supported without getting an exception?

The bindings log, whether one of the appindicator shared libs could be loaded. An exception should not occur, unless something is very wrong like the bindings were not working on Fedora before.

I'm sorry if I opened a feature request but the wiki does not answers this question.

That's fine.

@sblantipodi
Copy link
Author

Just last question if possible. I hope to not bother you.

I'm considering integrating this lib into my app but I would like to understand more what there is behind the lib :)
Feel free not to answer, I understand that this is not a "customer care" :)

I am reading your blog here

where did you get
/usr/include/libappindicator3-0.1/libappindicator/app-indicator.h
file?

I can't find that header on my system. Did you downloaded the library from somewhere?
Does that lib works on most Linux distros?
Did you made a lot of "adjustments" to the java code or the code is the one generated from jextract?

Thank you for your time and your work.

@purejava
Copy link
Owner

where did you get /usr/include/libappindicator3-0.1/libappindicator/app-indicator.h file?

I can't find that header on my system. Did you downloaded the library from somewhere?

This is the header file for the libappindicator3-0.1 library. The shared library itself may be installed on your system or not. That depends on the Linux distribution you are using and version of your distribution. The library provides the wanted functionality.

An according header file is probably not installed on your system, as these are normally only needed when you compile source code on your own. Well, on Arch Linux they are, but that depends. On Ubuntu, header files are contained in -dev packages, that have the same file name as the library but the package name ends with a -dev suffix.

Developing an app that is using these bindings does not require the header files. I mentioned the headers in my blog as the post describes on how to use jextract to generate the Java bindings based on the header files.

Does that lib works on most Linux distros?

I hope so. 😄 It is supposed to work on any Linux box, where one of the appindicator libraries is installed, finds them, loads them and so makes it possible for a Java app to access the methods in the C library via the bindings.

Did you made a lot of "adjustments" to the java code or the code is the one generated from jextract?

Not that many. jextract generated "raw" bindings, but do not generate code to load one of the underlying libraries so I added that. And I added logging and a high level API to make it easier to use the bindings with better readable code like Gtk.widgetSetSensitive(gtkMenuItem, false);.

@sblantipodi
Copy link
Author

ok it's all clear now, thank you.
another question. is it possible to listen for a single click or double click on the tray icon to open a window fast for example?

@purejava
Copy link
Owner

No. Single and double clicks on the tray icon open the Gtk.Menu.
See here and here.

@sblantipodi
Copy link
Author

sblantipodi commented Nov 12, 2024

thanks for the answer, I appreciate it.

from your link I see this:
With AppIndicator you can have the following interactions:

Primary action: Show a context menu (which may consist only of regular menu items, no arbitrary widgets can be placed).
Secondary action: Activate one specific item in this context menu (usually middle mouse click on Desktops).
Listen to mouse scroll events on the icon.

if this is true, I should be able to achieve what I want using a middle mouse button, fast access an item on the tray menu.

but I don't know if it's true or not :D

@sblantipodi
Copy link
Author

sblantipodi commented Nov 12, 2024

apart this I have a blocking issue now.
my app works well when launching it via IntelliJ but when I compile it using jpackage I have this error:

[Instance #1] 14:24:17.204 [JavaFX Application Thread] INFO  org.dpsoftware.FireflyLuciferin - ** Log level -> INFO **
Exception in Application start method
Exception in thread "main" java.lang.RuntimeException: Exception in Application start method
	at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:893)
	at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:196)
	at java.base/java.lang.Thread.run(Unknown Source)
Caused by: java.lang.ExceptionInInitializerError
	at org.dpsoftware.gui.TrayIconManager.initTray(TrayIconManager.java:246)
	at org.dpsoftware.FireflyLuciferin.start(FireflyLuciferin.java:261)
	at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:839)
	at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:483)
	at com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:456)
	at java.base/java.security.AccessController.doPrivileged(Unknown Source)
	at com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:455)
	at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
	at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
	at com.sun.glass.ui.gtk.GtkApplication.lambda$runLoop$10(GtkApplication.java:264)
	... 1 more
Caused by: java.lang.IllegalCallerException: Illegal native access from: unnamed module @6b927fb
	at java.base/java.lang.Module.ensureNativeAccess(Unknown Source)
	at java.base/java.lang.System$2.ensureNativeAccess(Unknown Source)
	at java.base/jdk.internal.reflect.Reflection.ensureNativeAccess(Unknown Source)
	at java.base/jdk.internal.foreign.layout.ValueLayouts$OfAddressImpl.withTargetLayout(Unknown Source)
	at org.purejava.appindicator.app_indicator_h_21.<clinit>(app_indicator_h_21.java:55)
	... 11 more

any idea?

EDIT: adding --enable-native-access=ALL-UNNAMED
fixed the issue but it's weird...

@sblantipodi
Copy link
Author

sblantipodi commented Nov 12, 2024

another issue with this is that we cannot reference an image for the tray icon from java.
when you compile a java app, you create a jar file.
in java you can get the path of the image with something like this:
Objects.requireNonNull(this.getClass().getResource(IMAGE_RELATIVE_PATH)).getPath()

but when you create the jar the image is inside the jar file and then it doesn't work with the binding that requires an absolute path to the image.

is there a fix for this? thanks

@purejava
Copy link
Owner

is there a fix for this? thanks

It's not the binding, that requires the absolute path for the icon, but the underlying appindicator library.

You only have two options here: the absolute path or you reference the icon by its name like done in the wiki example. "indicator-message" is an icon, that is installed on the system as part of one of the icon-themes and has a filename like indicator-message.svg or something like that.

We solved that for an application that is distributed as an AppImage by reading an environment variable that is provided by the running AppImage and points to the absolute path, where the temporary files of the running AppImage are located on your system so you can create the absolute path for the icon of "/" + "env var" + "icon file name". I don't know, whether there is something like this for an app distributed as a jar file.

@sblantipodi
Copy link
Author

ok thanks for the patience in answering all my questions, I really, really appreciate it.

@sblantipodi
Copy link
Author

sblantipodi commented Nov 12, 2024

@purejava I hope to not bother you but isn't it better to avoid creating the static initializers

and simply pass -l to jextract like this?

 * jextract -l ayatana-appindicator3 \
 ....

I think that this way is better and you can avoid that initializers.
Using -l will generate a code like this:

    static final SymbolLookup SYMBOL_LOOKUP = SymbolLookup.libraryLookup(System.mapLibraryName("ayatana-appindicator3"), LIBRARY_ARENA)
            .or(SymbolLookup.loaderLookup())
            .or(Linker.nativeLinker().defaultLookup());

that will do the trick for you

@sblantipodi sblantipodi reopened this Nov 12, 2024
@purejava
Copy link
Owner

In theory yes, but the - l option isn't sufficient here, as the library paths differs from system to system or distribution. And flatpak is another story. Given, that the bindings should work on all these, some static code trying to load the underlying libraries hard is needed.

@sblantipodi
Copy link
Author

sblantipodi commented Nov 13, 2024

ook thanks for the answer, again.
this is really, really my last question.

from libappindicator documentation it seems that app_indicator_set_secondary_activate_target should do the trick of executing a callback once the middle mouse button is clicked on the tray.

I tried this

var menuSecondActivate = gtk_menu_item_new_with_label(arena.allocateFrom(Constants.ACTIVATE_EVENT));
g_signal_connect_object(menuSecondActivate, arena.allocateFrom("activate"), GCallback.allocate(() -> {
    log.info("middle mouse clicked");
}, arena), menuSecondActivate, 0);
app_indicator_set_secondary_activate_target(indicator, menuSecondActivate);
            

but it doesn't work.

it seems that @ghost succeded in doing so here

@purejava
Copy link
Owner

I don't see, what's wrong with your code.

Maybe the menuSecondActivate menuItem needs to be bound to the appindicator with .setMenu.

And watch the arena scope. In most cases, auto is a good choice, so that widgets do no get garbage collected before use.

@sblantipodi
Copy link
Author

it doesn't work here, if I'll found a solution I'll write here.
app_indicator_set_secondary_activate_target seems to do nothing here.

@sblantipodi
Copy link
Author

another question if possible.
do you have any idea why if I run it native it looks like this:

image

and if I run it via flatpak it looks like this?

image

@purejava
Copy link
Owner

another question if possible. do you have any idea why if I run it native it looks like this:

What do you mean? The different color or spacing or both?

I've no idea. From my point of view, running it as a Flatpak app should make no difference, als long as you use the Flatpak libappindicator shared-module.

@sblantipodi
Copy link
Author

What do you mean? The different color or spacing or both?

I mean both

I've no idea. From my point of view, running it as a Flatpak app should make no difference, als long as you use the Flatpak libappindicator shared-module.

I'm using their shared-module and this is the result.
tray, looks completely different.

@sblantipodi
Copy link
Author

probably we need to set the right GTK theme/appearance in flatpak, but how to do it ?

@purejava
Copy link
Owner

probably we need to set the right GTK theme/appearance in flatpak, but how to do it ?

Gtk theming is independent from Flatpak. Use the not -minimal bindings, depending on what native shared library you are using and you have all Gtk styling methods. At least they should be included.

I am closing this now as this is off topic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants