moses-palmer / pystray

GNU General Public License v3.0
461 stars 57 forks source link

`run_detached` not showing icon #117

Closed cycool29 closed 2 years ago

cycool29 commented 2 years ago

The title says it all.

I ran it without any argument. It just shows a blank entry on the system tray, both left and right clicks aren't working.

moses-palmer commented 2 years ago

Thank you for your.

Can you please provide a code sample exhibiting the problem, along with information about your platform and versions of components?

cycool29 commented 2 years ago

Can you please provide a code sample exhibiting the problem, along with information about your platform and versions of components?

Here is the GitHub repository, simply clone it and run the coffeetime.py file. (You need to have Tkinter and PIL installed) When you close the window, there should have an icon shown on your system tray, but it will just show a blank entry.

https://github.com/cycool29/CoffeeTime/blob/5fc17f3a7408ba5c7560e2d534f57d782cca9deb/coffeetime.py#L46

I am on Raspberry Pi OS bullseye, using the latest pystray (0.19.3).

moses-palmer commented 2 years ago

I have had a look at your application, and I have a hypothesis what the problem might be.

run_detached is used to integrate with other libraries that also have a mainloop. Instead of blocking on run, the mainloop of another library is used. There is one caveat though---the mainloops must be compatible.

On some backends, such as win32 and darwin, this is not an issue, as all libraries likely use the same operating system calls for the mainloop, but backends used on Linux do not generally have any shared code. Your application explicitly requires the gtk backend, and that would require a glib mainloop, something which Tkinter does not provide.

I managed to get you application to work by forcing the xorg backend; Tkinter does have an X loop running. This does have the drawback that the menu does not work; clicking the icon invokes the default action, which appears to be showing the window.

So, the problem is a consequence of the underlying technology, and I see no way to solve it without restructuring your application. Perhaps you could let Tkinter and pystray run alternating? If you do not intend to target macOS, you could start the icon from a dedicated thread and run it in a blocking fashion, as the limitation that the icon must be run from the main thread only applies to this operating system.

I will now close this issue.