How can I reduce the time taken to login by postponing/delaying some startup applications?

I have setup some applications to startup on each login (e.g., redshift-gtk, gtg) automatically but after adding these to startup applications (System -> Preferences -> Startup Applications) obviously the time taken to login has increased. Due to all this the time it takes for my panels, desktop etc to appear is too long - until which I am forced to wait.

I don't need these apps to be available immediately, but it would be good if they startup eventually, meanwhile the ubuntu menu/panel is available for running other apps that I might need to.

I tried using at command, with the intention of editing all startup applications to put the commands in the at queue, but this didn't work since the apps don't get the necessary environment variables (like DISPLAY).

Is this what nice command is used for? Any other ideas how I can accomplish this? If possible, I would like to avoid editing the startup applications commands, since this would mean a lot of effort to replicate on other machines I use.


Solution 1:

The number of seconds needed to wait for your desktop to load is arbitrary and can change depending on the situation. Instead of sleep, try using the following to run startup applications as soon as the system load has declined:

(Edit: Added koushik's suggestion.)

#!/bin/bash
# 
# Delays running an application until the system load has declined.
# 
# Usage:
#   run-when-load-low 'your command here'

echo "export DISPLAY=$DISPLAY; $1 &" | batch

exit 0

Save it as ~/bin/run-when-load-low and add run-when-load-low 'COMMAND' in Startup Applications Preferences.

Notes on this method:

  • The script above is what has worked for me. It passes only the DISPLAY environment variable to the application. For most desktop applications this will be all you need. With that said, be sure to consider any special cases and keep this fact in mind when troubleshooting anything that isn't behaving correctly. A good place to start if you think an application might need other environment variables passed is printenv and the application's documentation, though I personally haven't run into this problem yet.
  • My understanding of the system "load" value is that it does take into account IO waits, so delayed applications should not accidentally start too soon during the CPU usage lulls caused by desktop processes waiting on IO. This is not an area I know much about though, so please correct me if I am wrong here.
  • batch only affects when applications are run; it does not alter their priority/niceness.
  • This should go without saying, but if your system always has a high load, applications scheduled using this method might never run.
  • If you need to run an application with a parameter that contains spaces, you can escape them using the backslash: run-when-load-low 'gedit My\ Notes.txt'. If you really need to pass single-quoted parameters to your application, you'll have to use double quotes in the startup command: run-when-load-low "gedit 'My Notes.txt'". For anything more complicated than this, you're probably best off just modifying a copy of the script with your command hard-coded.

Solution 2:

I found that just using sleep 10 && COMMAND as the command name didn't work. I had issues with both conky and xchat loading too early and getting corrupted somehow. I had to write a little script called ~/bin/startup and put this in it:

#!/bin/bash
sleep 10
xchat &
conky &

You need change its permissions to be allowed to be executed with chmod +x ~/bin/startup and then just replace the start-up applications entry with the command startup and it'll fire off everything in the script.

You could have one file for each application if you were that way inclined.

Solution 3:

Use the 'sleep' command.

In System -> Preferences -> Startup Applications, edit the command for the programs you want to delay to:

sleep 10 && COMMAND

Replace 10 with the number of seconds you want it to wait and COMMAND with what was in the command box originally.