The configuration file
Defining menu items
Defining icons
The 'app' element
The 'separator' element
The 'submenu' element
The 'monitor' element
The 'daemon' element
The 'cpu' element
Example configuration
The configuration file
StateMenu reads its configuration from an XML file. It first checks for ~/.statemenu.xml and then, if that does not exist, looks for /etc/statemenu.xml. If the file is changed while StateMenu is running, StateMenu will automatically reload its configuration the next time it gets a mouse button event.
The toplevel element of the config file should be named statemenu and does not take any attributes. The next nested level must contain menu elements which need the button attribute in order to map a menu to a particular mouse button:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE statemenu> <statemenu> <menu button="2"> ... </menu> <menu button="3">. .... </menu> </statemenu>
This defines a menu to be displayed when the middle mouse button (2) is clicked and a different menu to be displayed when the right mouse button (3) is clicked.
Defining menu items
Defining icons
The 'app' element
The 'separator' element
The 'submenu' element
The 'monitor' element
The 'daemon' element
The 'cpu' element
A menu's items are specified by the following elements:
- app
- separator
- submenu
- monitor
- daemon
- cpu
Except for the separator element, all of these support icons. Let's look at the typical way to define icons (the monitor, daemon, and cpu elements are a little different).
Defining icons
Icons are defined with the icon and icon_size attributes. icon can refer to a image file (.png, .svg, .jpg, .gif, etc. - whatever your GTK2 installation is capable of loading), it can specify a pre-defined color ("red", "green", "blue", "yellow", "orange", "purple", "brown", "black", or "white"), or it can specify an arbitrary color like #12ffa8. When a color is specified the icon is simply a colored circle - this is included mostly for showing the status of daemons and other system resources, which we'll get to later. The optional icon_size attribute can be used to specify the size of the icon. So if you wanted to define a submenu with an icon it might look something like this:
<statemenu> <menu button="2"> <submenu name="Applications" icon="/path/to/icon.png" icon_size="16"> ... </submenu> </menu> </statemenu>
Now let's look the menu item elements individually
The 'app' element
This element defines a command to execute when the menu item is selected. It supports the name attribute, the cmd attribute, and the icon and icon_size attributes:
<app name="Terminal" cmd="gnome-terminal" icon="/usr/share/pixmaps/gnome-terminal.png"/>
The app element contains no nested elements.
The 'separator' element
The separator element is the simplest element - it has no attributes and no nested elements. It is used to draw a separator line in the menu (or submenu).
<separator/>
The 'submenu' element
The submenu element, as one might expect, defines a nested submenu of a main popup menu (or another submenu). It supports the name, icon, and icon_size attributes and supports any nested elements that a menu element supports.
<submenu name="Applications"> <submenu name="Utilities"> icon="/usr/share/pixmaps/gnome-util.png"> <app name="Terminal" cmd="gnome-terminal" icon="/usr/share/pixmaps/gnome-terminal.png"/> </submenu> </submenu>
The 'monitor' element
Here we get into what StateMenu is really for. The monitor element allows you to define a generic resource monitor, and it allows you to easily change that resource's state. Basically you need to tell StateMenu how to check the resource's state, what states the resource can have, and how to switch to a particular state.
The first attribute you need to define for a monitor is the name atribute. This name will show up in the menu. The next attribute is the script attribute. This is the path to the command to execute in order to check the resource's state. This can be an init script, a simple script you write yourself - basically any command that can check status of a resource. The optional status_cmd is an argument that should be passed to the script to check its status
There are a few more optional attributes that you might want to use. The sudo attribute is a boolean attribute (set it to "true", "FALSE", "Yes", "no", etc.) that will tell StateMenu to execute the command with the 'sudo' program. This will run the command under the 'root' user. The user that StateMenu runs under will have to be in the sudoers file and will need to be configured to not require a password. Something like the line
[username] ALL=NOPASSWD: ALL
should do it. Another optional attribute is the frequency attribute. This tells StateMenu how often (in seconds) to check the resource's status. The default is every 15 seconds. The compact attribute is a boolean attribute (default value is false) that specifies how the monitor should be displayed in the menu. In 'compact' mode, the monitor shows up as a single menu item. Selecting it switches to the next state. Otherwise, the monitor shows up as a menu item, but all of its states are shown in submenu items. To understand this, have a look at this screenshot. The Firewall, CUPS, and acpid items are in compact mode, while the CPU Policy item is not.
The monitor element supports nested state element to define the possible states of a resource. A state element supports a number of attributes. The name attribute gives the state a name to display in the menu. The optional action_name allows you to differentiate between the state's name when it is the current state and the string to display for the action of transitioning into that state. This is simpler than it sounds: When my network is up I might want StateMenu to show the string "Network: Up", but I might want the subitem for starting the network to show "Start" rather than "Up". The optional script attribute is for when the script to transition into a particular state is different fromt the script to check the resource's state (in the parent monitor element). If it is not defined the same script is used. The cmd attribute specifies the argument for transitioning into this state.
You need to somehow tell StateMenu how to determine this state from the status script specified in the monitor element. There are four ways to do this. The code attribute says that a particular exit code from the status script means that this state is the current state. not_code means that any code except this code matches this state. Alternatively, you can specify the output attribute to match the script's stdout to this sting, or you can specify the not_output which means that this state matches when the output of the script does not match the value of this attributes. The output and not_output values can also be regular expressions, just surround them with /'s (e.g., output="/[Rr]unning/"). The state elements also support the sudo attribute and the icon and icon_size attributes individually. Hopefully an example will make all of this clearer:
<monitor name="Firewall" script="/etc/rc.d/init.d/iptables" status_cmd="status" frequency="30"> <state name="Up" action_name="Start" cmd="start" sudo="true" icon="green" output="/is running/"/> <state name="Down" action_name="Stop" cmd="stop" sudo="true" icon="red" not_output="/is running/"/> </monitor>
This defines a "Firewall" monitor. StateMenu will, every 30 seconds, run the command "/etc/rc.d/init.d/iptables status" (the script plus, in this case, the status_cmd attributes). Because the defined states use the output and not_output attributes, StateMenu will look at the output of the command. If it matches the regular expression /is running/ then the first state, "Up", will match, and StateMenu will display this in the menu. If it does not match the regular expression /is running/, because the second state defines it as its not_output, the "Down" state will match and this will be displayed in the menu. The submenu item for the "Up" state will be named "Start". If selected, StateMenu will run the command "/etc/rc.d/init.d/iptables start" and immediately check the state again. The icon of the curren state will also be displayed in the parent monitor item ("Firwall: Up").
Any number of states can be defined. However, they must all either be "exit code-based" or "output-based". Statemnu contains a couple additional elements to make configuration simpler. Let's look at these now.
The 'daemon' element
This element is just a specialized monitor. In the simplest case you'll only need to define the name attribute. StateMenu will try to find an init script to use (right not it only looks in /etc/rc.d/init.d and /etc/init.d - so le me know if your distro stores init scripts somewhere else and I'll add it). You can also capitalize the name and StateMenu should still be able to find the script. The resource will automatically be given an "Up" state and a "Down" state with green and red icons, respectively. The default behavior is to look at the exit code of the script. You can override this by setting the default use_output attribute to true. Then StateMenu will try to match the string "is running" (case-insensitive) to determine the state. The daemon element displays itself in compact form. Also, you'll need to have sudo set up correctly (see above).
<daemon name="CUPS"/>
The 'cpu' element
If you have sysfs and cpu frequency scaling support in your kernel, this element will show the current scaling governor and allow you to select from available governors. It discovers everything automatically so there are no attributes you have to define. You can, however, optionally specify icons for the various scaling governors by prepending the governor name to "_icon". My cpu element configurtion on my laptop looks like:
<cpu ondemand_icon="blue" powersave_icon="yellow" performance_icon="green" userspace_icon="gray" icon_size="16"/>
Again, the icons are optional. So you could just specify:
<cpu/>
Like the daemon element, this element requires sudo (see above).
Example configuration
Here is the example configuration that comes with the source package.