The preferred option
If an application offers the option to start up in tray, no doubt that is the preferred option.
If not however, you either need to edit the application's code and recompile (not the most obvious option), or you need to "repair" the behaviour of the startup procedure. A slightly edited version of this script can do the job in that case.
About this answer
I am deliberately ignoring the line in your question:
"not closing these applications to the system tray"
Since closing the window after it came into existence, leaving the icon in tray, simply is the only option we have. Effectively you won't notice the difference however.
Explanation
The script starts up the application, running the command you gave as first argument.
Then the script checks the window list (with the help of wmctrl
) for windows, with the pid of the application you started.
If the window appears, it is immediately closed gracefully, with the help of the wmctrl
command:
wmctrl -ic <window_id>
The result:

without a transmission (in this example) window at all. Obviously the image is from Unity, but it works the same on lxde
.
To prevent an endless loop if the window might not appear for some reason, the script practices a time limit of 30 seconds for the window to appear.
Note
No need to mention that the script will only startup the application in system tray if the application has a system tray icon, else it will simply close the application completely if ist only window is closed.
The script
#!/usr/bin/env python3
import subprocess
import sys
import time
command = sys.argv[1]
command_check = command.split("/")[-1]
subprocess.Popen(["/bin/bash", "-c", command])
t = 1
while t < 30:
try:
w_list = [l.split() for l in subprocess.check_output(["wmctrl", "-lp"]).decode("utf-8").splitlines()]
proc = subprocess.check_output(["pgrep", "-f", command_check]).decode("utf-8").strip().split()
match = sum([[l[0] for l in w_list if p in l] for p in proc], [])
subprocess.Popen(["wmctrl", "-ic", match[0]])
break
except (IndexError, subprocess.CalledProcessError):
pass
t += 1
time.sleep(1)
How to use
The script needs wmctrl
:
sudo apt-get install wmctrl
Copy the script into an empty file, save it as run_intray.py
Test- run the script with the application as argument, e.g in the transmission
example:
python3 /path/to/run_intray.py transmission-gtk
If all works fine, you can add it to Startup Application, but note that you most likely will have to add a small break before the command, for the desktop to build up completely first:
/bin/bash -c "sleep 15 && python3 /path/to/run_intray.py transmission-gtk"