1-Line of Bash to add Apps to the System Tray

Putting your commonly used apps and scripts into the Linux system tray could be quite useful.

In this blog I’ll look at two approaches:

  • alltray – a command line utility to dock any program into the system tray
  • yad – (Yet Another Dialog) tool is a Bash GUI builder that also supports trays notifications.

The alltray approach is dead simple and it works for any linux application or script. The yad utility offers a little more functionality by adding the ability to create command line dialogs and it can dynamically change the tray icon, actions, menus and tool tip.

Alltray

To install alltray in Debian/Raspian/Ubuntu:

sudo apt install alltray

An simple alltray example that calls an xterm window with the top utility (to show top running processes):

# Use alltray to put a terminal window app in the the tray
#  usage: alltray [options] ["] <program_name> [parameters] ["]
#
alltray  "xterm -hold -T 'Top Processes' -e 'top'"

As a default alltray will use the icon of the command that is being called.

For this example I used xterm to open a new terminal with the options of: -hold (keep teminal open) , -t ( add title) and -e (execute a command).

If you want to change the font name and size, use the -fa and -fs options, for example:

xterm -hold -fa Monospace -fs 14  -T "Top Processes" -e  "top"

Alltray also supports a custom icon and right-click menus, an example of this would be:

# Show a tray item with a custom icon and right-click menu options
#   syntax for adding menus is: --menu "menu-label: command"
#
alltray  "xterm -hold -T 'Top Processes' -e  'top'" \
  -i /usr/share/icons/Adwaita/256x256/legacy/face-glasses.png \
  --menu "Disk Usage:xterm -hold -T 'df' -e 'df'" \
  --menu "Sensors:xterm -hold -T 'Sensors' -e 'sensors' " 

For this example a custom icon (face-glasses.png) is added along with 2 right-click menu options.

YAD – Yet Another Dialog

The yad utility is a command line dialog tool that supports a good selection of different dialog types, also yad can be configured for system tray applications without needing alltray.

For Debian/Raspian and Ubuntu systems yad can be installed by:

sudo apt install yad

Yad has a lot of options, (see the man pages or help for more details). To create a simple two button dialog:

# Show a simple YAD dialog
yad  --text="SOME TEXT"  --title="My Dialog"

To put this simple yad dialog on the system tray with a custom icon:

# Create a YAD system tray item to call a YALL dialog
#
yad --notification --image="gtk-execute" \ 
  --command="yad --text='SOME TEXT' --title='My Dialog' " \
  --text="My Tooltip"

Icons are fairly easy to manage using the yad tool: yad-icon-browser .

Like alltray, yad supports menus, below is a menu example:

# Create a YAD system tray item with a right-click menu
#
yad --notification --image="gtk-execute" \
 --command="yad --text='SOME TEXT' --title='My Dialog'" \
 --menu="Memory! yad --text='$(vmstat)' --title=VMSTAT \
        | Sensors! yad --text='$(sensors)' --title=Sensors \
        | USB ! yad --text='$(lsusb)' --title=USB \
        | Quit ! killall yad" \
 --text="My Tooltip"

The syntax for menus is:

menu=STRING
              STRING must be in the form:
              menu_label1[! action1[! icon1]]|label2[! action2[! icon2]]....   
              Menus are separated with `|' or --separator  argument.
              Menu items are separated with `!' or --item-separator argument.

For this menuing example I passed the output from command line tools like vmstat, sensors and lsusb to the yad –text parameter.

Unlike alltray, yad doesn’t have a built in quit menu option, but this functionality can be added with:

Quit ! killall yad

Remotely Change a YAD Tray Item

The yad notification option has a –listen parameter that allows commands to be sent from stdin (standard input) to yad in the form command:args. Possible commands are icon, tooltip, visible, action, menu and quit.

The yad stdio can be redirected a named pipe and this will enable other bash scripts to be able to send it commands. Below is a basic Bash script that creates a named pipe variable (mytraypipe=”/tmp/tray1.pipe”) and then it creates the named pipe if it doesn’t exist.

The Bash command: exec 1<> $mytraypipe , redirects stdio (file 1) to the named pipe. The final step is to call the yad with <&1 , to redirect the stdio into the command.

#!/bin/bash
#
# dyn_tray.sh - create a system tray item that can be modified
#             - write changes to the named pipe: $mytraypipe 
#
mytraypipe="/tmp/tray1.pipe"

# Make the pipe if required
if ! test -e "$mytraypipe"; then
  mkfifo $mytraypipe
fi

# redirect the stdio (file 1) to the named pipe
exec 1<> $mytraypipe

# create the notification icon
yad --notification                  \
    --listen                        \
    --image="emblem-colors-grey"              \
    --text="Dummy tooltip"   \
    --command="yad --text='Test Tray App' " <&1

Below is an example that changes the icon and tool tip for the earlier Bash script. This first step is to define a variable with the correct named pipe, after this commands can be send with an echo statement to the named pipe.

Summary

If you are looking for a quick way to pull together some commonly used apps and scripts both alltray and yad offer a simple 1 line of Bash solution.

If you want to dynamically change the tray item then yad is the tool for you.