moses-palmer / pystray

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

Pystray does not work in subprocess if the module is imported in the parent process #87

Open user202729 opened 3 years ago

user202729 commented 3 years ago

Code:

from threading import Thread
from PIL import Image
import multiprocessing

import pystray
# import gi.overrides.Gtk or gi.repository.Gtk
 works too

def f():
    import pystray
    #from importlib import reload; reload(pystray)
    icon=pystray.Icon("Plover")
    icon.icon=Image.new("RGB", (10, 10), (255, 255, 255))
    icon.visible=True
    icon.run()

p=multiprocessing.Process(target=f)
p.start()
p.join()

Backend: PYSTRAY_BACKEND=appindicator

Issue: the icon is not displayed. However if the first import pystray line is commented out, the icon will be displayed.

importlib.reload doesn't fix the issue.

Version: latest git. Python version: 3.9.

Example run:

$ ./a.py 

[hang, doesn't show any tray icon. Interrupt the program]

^CTraceback (most recent call last):
  File "/tmp/./a.py", line 23, in <module>
    p.join()
  File "/usr/lib/python3.9/multiprocessing/process.py", line 149, in join
    res = self._popen.wait(timeout)
  File "/usr/lib/python3.9/multiprocessing/popen_fork.py", line 43, in wait
    return self.poll(os.WNOHANG if timeout == 0.0 else 0)
  File "/usr/lib/python3.9/multiprocessing/popen_fork.py", line 27, in poll
    pid, sts = os.waitpid(self.pid, flag)
KeyboardInterrupt
^CError in atexit._run_exitfuncs:
Traceback (most recent call last):
  File "/usr/lib/python3.9/multiprocessing/popen_fork.py", line 27, in poll
    pid, sts = os.waitpid(self.pid, flag)
KeyboardInterrupt

[After the process is interrupted and the cursor returns to the shell, wait for a long while...]

$ Traceback (most recent call last):
  File "/usr/lib/python3.9/site-packages/gi/_error.py", line 31, in __init__
    def __init__(self, message='unknown error', domain='pygi-error', code=0):
KeyboardInterrupt
Process Process-1:
Traceback (most recent call last):
  File "/usr/lib/python3.9/multiprocessing/process.py", line 315, in _bootstrap
    self.run()
  File "/usr/lib/python3.9/multiprocessing/process.py", line 108, in run
    self._target(*self._args, **self._kwargs)
  File "/tmp/./a.py", line 19, in f
    icon.run()
  File "/tmp/pystray/lib/pystray/_base.py", line 192, in run
    self._run()
  File "/tmp/pystray/lib/pystray/_util/gtk.py", line 64, in _run
    self._notifier = notify_dbus.Notifier()
  File "/tmp/pystray/lib/pystray/_util/notify_dbus.py", line 40, in __init__
    self._notify = Gio.DBusProxy.new_sync(
RuntimeError: Converting the GError failed
user202729 commented 3 years ago

Since the hang is caused by importing the modules, I'm not sure if anything can be done on the pystray side except only importing them when they're really required.

However, it still won't allow the parent process and the subprocess to both have a tray icon.