moses-palmer / pystray

GNU General Public License v3.0
473 stars 59 forks source link

Allow setup to be daemon #89

Closed elibroftw closed 2 years ago

elibroftw commented 3 years ago

Either allow setup callback to be spawned in a daemon thread or create a "is_running" method for Icon.

moses-palmer commented 2 years ago

Thank you for your report.

Although I'm sure it's unintentional, this GitHub issue does not sound like a "Bug report" or "Feature request", but rather as a "Command to maintainer". Without more context, I really have no idea what to do with it.

What are you trying to achieve? Perhaps there is a way to do it with the current feature set.

elibroftw commented 2 years ago

The problem is that the thread spawned in Icon.run is not daemon meaning that I have to start a thread myself so that when the tray is closed and the main thread ends, so too does the background thread.

elibroftw commented 2 years ago

I propose:

def run(self, setup=None, setup_daemon=False):
        ...
        self._setup_thread = threading.Thread(target=setup_handler, daemon=setup_daemon)
        self._setup_thread.start()
        self._run()

But you will have to modify stop to address race conditions. It was just a suggestion but if you don't want to implement it that's fine by me.

moses-palmer commented 2 years ago

The problem is that the thread spawned in Icon.run is not daemon meaning that I have to start a thread myself so that when the tray is closed and the main thread ends, so too does the background thread.

Would you mind expanding a bit on this? As far as I know, the only significance of daemon threads is that the runtime does not join them before terminating but instead abruptly kills them. I suggest that you instead signal your setup thread appropriately when the icon has stopped so that you have a controller termination.

I see no real benefit from pystray handling this; depending on your use case, this could be as simple as a boolean flag, or more involved with queues.

elibroftw commented 2 years ago

In your stop(), you call setup_thread.join(). But since my background thread is a while True loop, that just means the program never ends and I have to keep checking if the tray is running myself which isn't possible since there is no tray.is_running. I'd rather have pytray keep track of the boolean than the client adding the boolean ourselves to the object and checking that way.