Modify menus in Gnome

When graphical desktops were first being developed, some very clever people found that menus mapped perfectly onto the file system that was there already. Putting menu items in a menu can readily be implemented through putting icon files into icon folders. Moving an item from one folder to the next is really no different from dragging a icon file from one folder to the next. Subfolders inside folders, submenus inside menus. By leveraging the file system that was fully developed, menus could be implemented in an exceedingly reliable and user-friendly way. It worked great!

That made it unacceptable to Linux. Linux has a simple motto. "If it works, change it. If it does not, file a bug report." Something that works great is the diametrical opposite of everything that Linux stands for.

An international committee was formed with the greatest brains in Linux. They came up with a gigantic menu implementation scheme that was absolutely brilliant in its complexity and unworkability. Moving a menu item into a new submenu requires a PhD. Thick books of dry theory must be read and assimilated. Linux is again safe for now.

Since you probably have better things to do than get a PhD in Menu Management, this page gives a Cliff's Notes version about how to go about the most simple things.

Adding menu items

Consider first the example of creating a menu item for the script ~/bin/settim that sets the computer time from the network. The script itself is of no importance. Here only the way to add it to the menu will be discussed.

To create the menu item, first find some suitable small picture for it that can be put next to the name in the menu as an icon. Of course, the picture that you find will almost certainly be a .gif or a .jpg. Needless to say, the menu system does not accept either one. It demands the .png format, though it will also accept .xpm or. .svg if you ask nicely. Don't ask what any of these weird formats are; .png was created to replace .jpg and .gif and failed miserably. The only thing you need to know is that gthumb will convert .jpg and .gif in .png in a user-friendly way. I found a picture of a clock in openclipart, and used gthumb to convert it into a .png called clock.png. Place clock.png in folder ~/.icons

Next put a file that describes the menu item in ~/.local/share/applications/. (Isn't that a great name for a folder that holds files that are not shared and are not applications but descriptions of menu items. Admit it, it is brilliant.) The file must have a filetype .desktop because it is a menu description. I named mine ntptime.desktop because ntptime is the underlying program that does the actual work. If you click on the link, you see what is in the file. There are three lines of particular interest.

  1. The Icon= line gives the name, but not the filetype, of the icon.
  2. The line Exec= gives the command that the operating system must execute to set the time; it must run script settim in the /home/username/bin folder; replace username by your username, or replace /home/username by /root if you login as root.
  3. The Categories=Settings;Clock implicitly tells the system in which submenu to put the menu item. In particular, it ends up in System/ Preferences/ because of the Settings category. There is a list of categories in: http://standards.freedesktop.org/menu-spec/menu-spec-1.0.html
Look for examples of .desktop files in /usr/share/applications/. Copy the one closest to what you want to ~/.local/share/applications/ with an appropriate name and change it for your item.

To return to the icon file, if you do not want to create one for your application, you can reuse an icon that is already there. Just find the corresponding .desktop file and look in it for the name of the icon.

Changing the menu layout

If you want to change the menu structure itself, it is xml programming time. This cumbersome format is just the thing needed to make the process as counter-intuitive and error-prone as possible.

Since I have quite a lot of games installed, dumping them all in one big menu is unwieldy and confusing. I wanted to have them arranged in submenus; arcade games, board games, card games, etcetera. To do so, start by editing the file ~/.config/menus/applications.menu. Back the file up before you change anything! My file contained only the lines

<!DOCTYPE Menu
  PUBLIC '-//freedesktop//DTD Menu 1.0//EN'
  'http://standards.freedesktop.org/menu-spec/menu-1.0.dtd'>
<Menu>
  <Name>Applications</Name>
  <MergeFile type="parent">/etc/xdg/menus/applications.menu</MergeFile>
</Menu>
There is not much that you can change in that. So I took out the MergeFile line and instead included the contents of /etc/xdg/menus/applications.menu directly. Then I edited that to put in the submenus. What I did was add <Menu>...</Menu> subblocks inside the Games <Menu>...</Menu> block. The result is here. You will get the idea, or else you should maybe leave well enough alone. See http://standards.freedesktop.org/menu-spec/menu-spec-1.0.html for more.

Note that each submenu block, like "ActionGames" for example, needs a corresponding file, ActionGames.directory, that describes the submenu. Fortunately, there is already a file ActionGames.directory in /usr/share/desktop-directories/

Unfortunately, I needed a submenu "Other" to hold "none of the above game types", and there was no corresponding directory file. So I created a file Other.directory and put it in ~/.local/share/desktop-directories/. (What better name than "directory" for a submenu description?) Note that I reused the Games menu icon for the Other submenu rather than create my own.

Note: Menus update instantly. You do not have to logout to see the changes.

Note: There is some tool "Main Menu" under preferences. Do not use it, it makes a mess of your various menu subdirectories and most of the time it does not manage to make the change. I am sure eventually a humongous program will be able to perform simple menu changes. At that time the menu specification will be changed.


Applies to software obtained May 2009.
Return to Linux on Lifebook S6520