Desktop Menu Specification Version 0.5 31 July 2003 Waldo Bastian
bastian@kde.org
Francois Gouget
fgouget@codeweavers.com
Alex Graveley
alex@ximian.com
George Lebl
jirka@5z.com
Havoc Pennington
hp@pobox.com
Introduction This DRAFT document defines how to construct a user-visible hierarchy of applications, typically displayed as a menu. It allows third-party software to add menu items that work for all desktops, and allows system administrators to edit menus in a way that affects all desktops. The basic scheme is very simple. Information about each application (menu item) is stored in a desktop entry (see Desktop Entry Standard). Then an XML configuration file defines the hierarchical arrangement (layout) of menu items, and which menu items are actually displayed. Things are complicated somewhat by the need to support legacy desktop entry hierarchies, and the need to allow third parties to extend the menu layout. Both of these issues are addressed by the idea of merging two menu layouts. File locations Files involved in this specification are located according to the "desktop base directory specification" which can be found on www.freedesktop.org. Here are the files defined by this specification: $XDG_CONFIG_DIRS/menus/applications.menu This file contains the XML definition of the main application menu layout. The first file found in the search path should be used; other files are ignored. This implies that if the user has their own applications.menu, it replaces the systemwide one. (Though the user's menu may explicitly merge the systemwide one.) Other menu files may exist, but are not specified in this document. $XDG_CONFIG_DIRS/menus/menu-file-basename-merged/ One of the default merge directories included in the <DefaultMergeDirs> element. By convention, third parties may add new <Menu> files in this location. menu-file-basename means the "applications" from "applications.menu" for example. So the merge directory would be "applications-merged". $XDG_DATA_DIRS/applications/ This directory contains a .desktop file for each possible menu item. Each directory in the $XDG_DATA_DIRS search path should be used (i.e. desktop entries are collected from all of them, not just the first one that exists). When two desktop entries have the same name, the one appearing earlier in the path is used. The <DefaultAppDirs> element in a menu file indicates that this default list of desktop entry locations should be scanned at that point. If a menu file does not contain <DefaultAppDirs>, then these locations are not scanned. $XDG_DATA_DIRS/desktop-directories/ This directory contains directory entries which may be associated with folders in the menu layout. Each directory in the search path should be used. Only files ending in .directory are used; other files are ignored. The <DefaultDirectoryDirs> element in a menu file indicates that this default list of directory entry locations should be scanned at that point. If a menu file does not contain <DefaultDirectoryDirs>, then these locations are not scanned. Extensions to the desktop entry format This specification adds two new fields to desktop entries: Categories and OnlyShowIn. The Categories field is a list of strings used to classify menu items. For example, applications in the AudioVideo category might end up in the "Sound & Video" submenu. enumerates the standard categories. Categories not in this document must be prefixed by the string "X-" indicating that they are extensions. Categories are case-sensitive. Desktop entries should list all categories that clearly apply. They should not list categories that only vaguely or possibly apply, because the user will end up seeing the same desktop entry in a half-dozen places. But it's typical that several categories will apply to a given desktop entry. The OnlyShowIn field is a list of strings identifying the environments that should display a given menu item. If an OnlyShowIn field is present, a given environment should only display the menu item if the string identifying that environment is present. The strings are case-sensitive. enumerates the strings to use for some common environments. Examples of using <varname>Categories</varname> and <varname>OnlyShowIn</varname> A desktop entry for a Qt-based image viewer might contain this Categories line: Categories=Qt;Graphics;RasterGraphics;Viewer; A desktop entry for Octave, a command-line mathematics program (which would also have the field Terminal=true), might have: Categories=ConsoleOnly;Math; A desktop entry for a GNOME-specific calculator program that should only appear in GNOME might have: Categories=GNOME;Utility; OnlyShowIn=GNOME; Note that the OnlyShowIn field is a list and thus ends in a semicolon. Format of menu files Menu files must be well-formed XML files, conform to the menu file DTD, and end in the extension ".menu". DTD conformance implies that implementation-specific extensions to the file format are not allowed; implementations are expected to stop processing if they encounter XML elements or attributes that are not specified in this document. Doctype Declaration Menu files for this version of the specification must use the following namespace, public and system identifiers: Namespace http://www.freedesktop.org/standards/menu Public Identifier for 1.0 PUBLIC "-//freedesktop//DTD Menu 1.0//EN" System Identifier for 1.0 http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd Here is a sample doctype declaration: <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN" "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd"> All menu files MUST include the doctype declaration, so that implementations can adapt to different versions of this specification (and so implementations can validate the menu file against the DTD). Elements <Menu> The root element is <Menu>. Each <Menu> element may contain any number of nested <Menu> elements, indicating submenus. <AppDir> This element may only appear below <Menu>. The content of this element is a directory name. Desktop entries in this directory are scanned and added to the pool of entries which can be included in this <Menu> and its submenus. Only files ending in ".desktop" should be used, other files are ignored. Desktop entries in the pool of available entries are identified by their desktop-file id (see ). The desktop-file id of a desktop entry is equal to its filename, with any path components removed. So given a <AppDir> /foo/bar and desktop entry /foo/bar/Hello.desktop the desktop entry would get a desktop-file id of Hello.desktop If the directory contains sub-directories then these sub-directories should be (recursively) scanned as well. The name of the subdirectory should be added as prefix to the desktop-file id together with a dash character ("-") So given a <AppDir> /foo/bar and desktop entry /foo/bar/booz/Hello.desktop the desktop entry would get a desktop-file id of booz-Hello.desktop A desktop entry /foo/bar/bo/oz/Hello.desktop would result in a desktop-file id of bo-oz-Hello.desktop <AppDir> elements appearing later in the menu file have priority in case of collisions between desktop-file ids. If the filename given as an <AppDir> is not an absolute path, it should be located relative to the location of the menu file being parsed. Duplicate <AppDir> elements (that specify the same directory) should be ignored, but the last duplicate in the file should be used when establishing the order in which to scan the directories. This is important when merging (see ). The order of <AppDir> elements with respect to <Include> and <Exclude> elements is not relevant, also to facilitate merging. <DefaultAppDirs> This element may only appear below <Menu>. The element has no content. The element should be treated as if it were a list of <AppDir> elements containing the default app dir locations (datadir/applications/ etc.). When expanding <DefaultAppDirs> to a list of <AppDir>, the default locations that are earlier in the search path go later in the <Menu> so that they have priority. <DirectoryDir> This element may only appear below <Menu>. The content of this element is a directory name. Each directory listed in a <DirectoryDir> element will be searched for directory entries to be used when resolving the <Directory> element for this menu and its submenus. If the filename given as a <DirectoryDir> is not an absolute path, it should be located relative to the location of the menu file being parsed. Directory entries in the pool of available entries are identified by their relative path (see ). If two directory entries have duplicate relative paths, the one from the last (furthest down) element in the menu file must be used. Only files ending in the extension ".directory" should be loaded, other files should be ignored. Duplicate <DirectoryDir> elements (that specify the same directory) are handled as with duplicate <AppDir> elements (the last duplicate is used). <DefaultDirectoryDirs> This element may only appear below <Menu>. The element has no content. The element should be treated as if it were a list of <DirectoryDir> elements containing the default desktop dir locations (datadir/desktop-directories/ etc.). The default locations that are earlier in the search path go later in the <Menu> so that they have priority. <Name> Each <Menu> element must have a single <Name> element. The content of the <Name> element is a name to be used when referring to the given menu. Each submenu of a given <Menu> must have a unique name. <Menu> elements can thus be referenced by a menu path, for example "Applications/Graphics." The <Name> field must not contain the slash character ("/"); implementations should discard any name containing a slash. See also . <Directory> Each <Menu> element has any number of <Directory> elements. The content of the <Directory> element is the relative path of a directory entry containing metainformation about the <Menu>, such as its icon and localized name. If no <Directory> is specified for a <Menu>, its <Name> field should be used as the user-visible name of the menu. Duplicate <Directory> elements are allowed in order to simplify menu merging, and allow user menus to override system menus. The last <Directory> element to appear in the menu file "wins" and other elements are ignored, unless the last element points to a nonexistent directory entry, in which case the previous element should be tried instead, and so on. <OnlyUnallocated> and <NotOnlyUnallocated> Each <Menu> may contain any number of <OnlyUnallocated> and <NotOnlyUnallocated> elements. Only the last such element to appear is relevant, as it determines whether the <Menu> can contain any desktop entries, or only those desktop entries that do not match other menus. If neither <OnlyUnallocated> nor <NotOnlyUnallocated> elements are present, the default is <NotOnlyUnallocated>. To handle <OnlyUnallocated>, the menu file must be analyzed in two conceptual passes. The first pass processes <Menu> elements that can match any desktop entry. During this pass, each desktop entry is marked according to whether it was included in some <Menu>. The second pass processes only <Menu> elements that are restricted to unallocated desktop entries. During the second pass, queries may only match desktop entries that were not allocated to some menu during the first pass. See . <Deleted> and <NotDeleted> Each <Menu> may contain any number of <Deleted> and <NotDeleted> elements. Only the last such element to appear is relevant, as it determines whether the <Menu> has been deleted. If neither <Deleted> nor <NotDeleted> elements are present, the default is <NotDeleted>. The purpose of this element is to support menu editing. If a menu contains a <Deleted> element not followed by a <NotDeleted> element, that menu should be ignored. <Include> An <Include> element is a set of rules attempting to match some of the known desktop entries. The <Include> element contains a list of any number of matching rules. Matching rules are specified using the elements <And>, <Or>, <Not>, <All>, <Filename>, and <Category>. Each rule in a list of rules has a logical OR relationship, that is, desktop entries which match any rule are included in the menu. <Include> elements must appear immediately under <Menu> elements. The desktop entries they match are included in the menu. <Include> and <Exclude> elements for a given <Menu> are processed in order, with queries earlier in the file handled first. This has implications for merging, see . See for full details on how to process <Include> and <Exclude> elements. <Exclude> Any number of <Exclude> elements may appear below a <Menu> element. The content of an <Exclude> element is a list of matching rules, just as with an <Include>. However, the desktop entries matched are removed from the list of desktop entries included so far. (Thus an <Exclude> element that appears before any <Include> elements will have no effect, for example, as no desktop entries have been included yet.) <Filename> The <Filename> element is the most basic matching rule. It matches a desktop entry if the desktop entry has the given desktop-file id. See . <Category> The <Category> element is another basic matching predicate. It matches a desktop entry if the desktop entry has the given category in its Categories field. <All> The <All> element is a matching rule that matches all desktop entries. <And> The <And> element contains a list of matching rules. If each of the matching rules inside the <And> element match a desktop entry, then the entire <And> rule matches the desktop entry. <Or> The <Or> element contains a list of matching rules. If any of the matching rules inside the <Or> element match a desktop entry, then the entire <Or> rule matches the desktop entry. <Not> The <Not> element contains a list of matching rules. If any of the matching rules inside the <Not> element matches a desktop entry, then the entire <Not> rule does not match the desktop entry. That is, matching rules below <Not> have a logical OR relationship. <MergeFile> Any number of <MergeFile> elements may be listed below a <Menu> element, giving the name of another menu file to be merged into this one. specifies how merging is done. The root <Menu> of the merged file will be merged into the immediate parent of the <MergeFile> element. The <Name> element of the root <Menu> of the merged file are ignored. If the filename given as a <MergeFile> is not an absolute path, it should be located relative to the location of the menu file being parsed. Duplicate <MergeFile> elements (that specify the same file) are handled as with duplicate <AppDir> elements (the last duplicate is used). <MergeDir> Any number of <MergeDir> elements may be listed below a <Menu> element. A <MergeDir> contains the name of a directory. Each file in the given directory which ends in the ".menu" extension should be merged in the same way that a <MergeFile> would be. If the filename given as a <MergeDir> is not an absolute path, it should be located relative to the location of the menu file being parsed. The files inside the merged directory are not merged in any specified order. Duplicate <MergeDir> elements (that specify the same directory) are handled as with duplicate <AppDir> elements (the last duplicate is used). <DefaultMergeDirs> This element may only appear below <Menu>. The element has no content. The element should be treated as if it were a list of <MergeDir> elements containing the default merge directory locations. When expanding <DefaultMergeDirs> to a list of <MergeDir>, the default locations that are earlier in the search path go later in the <Menu> so that they have priority. <LegacyDir> This element may only appear below <Menu>. The text content of this element is a directory name. Each directory listed in a <LegacyDir> element will be an old-style legacy hierarchy of desktop entries, see for how to load such a hierarchy. Implementations must not load legacy hierarchies that are not explicitly specified in the menu file (because for example the menu file may not be the main menu). If the filename given as a <LegacyDir> is not an absolute path, it should be located relative to the location of the menu file being parsed. Duplicate <LegacyDir> elements (that specify the same directory) are handled as with duplicate <AppDir> elements (the last duplicate is used). The <LegacyDir> element may have one attribute, prefix. Normally, given a <LegacyDir> /foo/bar and desktop entry /foo/bar/baz/Hello.desktop the desktop entry would get a desktop-file id of Hello.desktop. Given a prefix of boo-, it would instead be assigned the desktop-file id boo-Hello.desktop. The prefix should not contain path separator ('/') characters. <KDELegacyDirs> This element may only appear below <Menu>. The element has no content. The element should be treated as if it were a list of <LegacyDir> elements containing the traditional desktop file locations supported by KDE with a hard coded prefix of "kde-". When expanding <KDELegacyDirs> to a list of <LegacyDir>, the locations that are earlier in the search path go later in the <Menu> so that they have priority. The search path can be obtained by running kde-config --path apps <Move> This element may only appear below <Menu>. The <Move> element contains pairs of <Old>/<New> elements indicating how to rename a descendant of the current <Menu>. If the destination path already exists, the moved menu is merged with the destination menu (see for details). <Move> is used primarily to fix up legacy directories. For example, say you are merging a <LegacyDir> with folder names that don't match the current hierarchy; the legacy folder names can be moved to the new names, where they will be merged with the new folders. <Move> may or may not be useful for implementing menu editing, see . Duplicate <Move> elements are merged as specified in . Note that duplicates (two moves of the same path) can be detected easily because of the following rule: a move must reside at the lowest possible point. In other words, all moves have exactly one permissible location in the <Menu> hierarchy. Implementations can trivially detect violations of this rule: the <Old> and <New> paths may never share a common prefix. Moving "Foo/Bar" to "Foo/Baz" must be done with a <Move> element that's a child of the "Foo" <Menu>, i.e. by moving "Bar" to "Baz", not by moving "Foo/Bar" to "Foo/Baz". <Old> This element may only appear below <Move>, and must be followed by a <New> element. The content of both <Old> and <New> should be a menu path (slash-separated concatenation of <Name> fields, see ). Paths are interpreted relative to the menu containing the <Move> element. <New> This element may only appear below <Move>, and must be preceded by an <Old> element. The <New> element specifies the new path for the preceding <Old> element. Merging Sometimes two menu layouts need to be merged. This is done when folding in legacy menu hierarchies (see ) and also for files specified in <MergeFile> elements. A common case is that per-user menu files might merge the system menu file. Merging is also used to avoid cut-and-paste, for example to include a common submenu in multiple menu files. Merging involves a base <Menu> and a merged <Menu>. The base is the "target" menu and the merged <Menu> is being added to it. The result of the merge is termed the "combined menu." As a preparatory step, the goal is to resolve all files into XML elements. To do so, traverse the entire menu tree. For each <MergeFile>, <MergeDir>, or <LegacyDir> element, replace the <MergeFile>, <MergeDir>, or <LegacyDir> element with the child elements of the root <Menu> of the file(s) being merged. As a special exception, remove the <Name> element from the root element of each file being merged. To generate a <Menu> based on a <LegacyDir>, see . Continue processing until no <MergeFile>, <MergeDir>, or <LegacyDir> elements remain, taking care to avoid infinite loops caused by files that reference one another. Once all files have been loaded into a single tree, scan the tree recursively performing these steps: Consolidate child menus. Each group of child <Menu>s with the same name must be consolidated into a single child menu with that name. Concatenate the child elements of all menus with the same name, in the order that they appear, and insert those elements as the children of the last menu with that name. Delete all the newly empty <Menu> elements, keeping the last one. Expand <DefaultAppDirs> and <DefaultDirectoryDirs> elements to <AppDir> and <DirectoryDir> elements. Consolidate duplicate <AppDir>, <DirectoryDir>, and <Directory> elements by keeping the last one. For <Directory> elements that refer to distinct directory entries, all of them should be kept - if the last one points to a nonexistent file, the one before that can be used instead, and so forth. Recurse into each child <Menu>, performing this list of steps for each child in order. Resolve duplicate <Move> operations (with the same origin path) by keeping the last one. Execute <Move> operations in the order that they appear. If the destination path does not exist, simply relocate the origin <Menu> element, and change its <Name> field to match the destination path. If the origin path does not exist, do nothing. If both paths exist, take the origin <Menu> element, delete its <Name> element, and prepend its remaining child elements to the destination <Menu> element. Then, recursively re-run the previous merge steps on the resulting combined <Menu> in order to consolidate duplicates. For each <Menu> containing a <Deleted> element which is not followed by a <NotDeleted> element, remove that menu. Merged menu elements are kept in order because <Include> and <Exclude> elements later in the file override <Include> and <Exclude> elements earlier in the file. This means that if the user's menu file merges the system menu file, the user can always override what the system menu specifies by placing elements after the <MergeFile> that incorporates the system file. To prevent that a desktop entry from one party inadvertently cancels out the desktop entry from another party because both happen to get the same desktop-file id it is recommended that providers of desktop-files ensure that all desktop-file ids start with a vendor prefix. A vendor prefix consists of [a-zA-Z] and is terminated with a dash ("-"). Open Source projects and commercial parties are encouraged to use a word or phrase, preferably their name, as prefix for which they hold a trademark. Open Source applications can also ask to make use of the vendor prefix of another open source project (such as GNOME or KDE) they consider themselves affiliated with, at the discretion of these projects. For example, to ensure that GNOME applications start with a vendor prefix of "gnome-", it could either add "gnome-" to all the desktop files it installs in datadir/applications/ or it could install desktop files in a datadir/applications/gnome subdirectory. When including legacy menu hierarchies the prefix argument of the <LegacyDir> element can be used to specify a prefix. Generating the menus After merging the menus, the result should be a single menu layout description. For each <Menu>, we have a list of directories where desktop entries can be found, a list of directories where directory entries can be found, and a series of <Include> and <Exclude> directives. For each <Menu> element, build a pool of desktop entries by collecting entries found in each <AppDir> for the menu element. If two entries have the same desktop-file id, the entry for the earlier (closer to the top of the file) <AppDir> must be discarded. Next, add to the pool the entries for any <AppDir>s specified by ancestor <Menu> elements. If a parent menu has a duplicate entry (same desktop-file id), the entry for the child menu has priority. Next, walk through all <Include> and <Exclude> statements. For each <Include>, match the rules against the pool of all desktop entries. For each desktop entry that matches one of the rules, add it to the menu to be displayed. For each <Exclude>, match the rules against the currently-included desktop entries. For each desktop entry that matches, remove it again from the menu. Two passes are necessary, once for regular menus, and once for <OnlyUnallocated> menus. The result is a tree of desktop entries, of course. Legacy Menu Hierarchies Traditionally, menus were defined as a filesystem hierarchy, with each filesystem directory corresponding to a submenu. Implementations of this specification must be able to load these old-style hierarchies as specified in this section. The general approach is: the legacy hierarchy is converted into a <Menu>, and then this menu layout is merged with the menu that specified <LegacyDir>. Desktop entries in the legacy hierarchy should be added to the pool of desktop entries as if the <LegacyDir> were an <AppDir>. Directory entries in the legacy hierarchy should be added to the pool of directory entries as if the <LegacyDir> were a <DirectoryDir>. This can be trivially implemented by adding appropriate <AppDir> and <DirectoryDir> statements to the root legacy <Menu>. There is one slight complexity, namely the "prefix" attribute of <LegacyDir>. The menu layout corresponds conceptually to the following, though actually generating the XML is not necessary: For each directory in the legacy hierarchy, a <Menu> is created with the same <Name> as the directory on disk. This menu then contains an <Include> element that includes each desktop entry in the directory. That is, it should have a <Filename>Foo/Bar/foo.desktop</Filename> for each desktop entry in the directory. As a special exception, if a desktop entry in a directory contains a Categories field, that desktop entry should not be included in the legacy menu. That is, no <Include> element should be generated for the entry. This allows a desktop entry to be installed in a legacy location but still work optimally with the menu system specified in this document. If the legacy directory contains a ".directory" file, then a <Directory> element should be generated that points to said ".directory" file. Legacy desktop entries should not be assigned any Categories fields if they didn't have them already, except that all legacy entries should have the "Legacy" category added to allow menu files to treat them specially. (If the same directory is given as both a <LegacyDir> and an <AppDir>, its desktop entries should be labeled "Legacy" only if the <LegacyDir> appears later in the file than the <AppDir>.) For example, say we have the following legacy directory hierarchy: /usr/share/applnk /usr/share/applnk/.directory /usr/share/applnk/bar.desktop /usr/share/applnk/System /usr/share/applnk/System/.directory /usr/share/applnk/System/foo.desktop Conceptually that is converted to the following <Menu>: <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN" "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd"> <Menu> <AppDir>/usr/share/applnk</AppDir> <DirectoryDir>/usr/share/applnk</DirectoryDir> <Directory>.directory</Directory> <Include> <Filename>bar.desktop</Filename> </Include> <Menu> <Name>System</Name> <Directory>System/.directory</Directory> <Include> <Filename>System/foo.desktop</Filename> </Include> </Menu> </Menu> This <Menu> is then merged as if it were in a file and loaded with <MergeFile>. Example Menu File <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN" "http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd"> <Menu> <Name>Applications</Name> <Directory>Applications.directory</Directory> <-- Search the default locations --> <DefaultAppDirs/> <DefaultDirectoryDirs/> <-- Merge third-party submenus --> <MergeDir>applications-merged</MergeDir> <-- Merge legacy hierarchy --> <LegacyDir>/usr/share/applnk</LegacyDir> <-- some random moves, maybe to clean up legacy dirs, maybe from menu editing --> <Move> <Old>Foo</Old> <New>Bar</New> <Old>Faz/Abc</Old> <New>Baz/Xyz</New> </Move> <-- A preferences submenu, kept in a separate file so it can also be used standalone --> <Menu> <Name>Preferences</Name> <Directory>Preferences.directory</Directory> <MergeFile>preferences.menu</MergeFile> </Menu> <-- An Office submenu, specified inline --> <Menu> <Name>Office</Name> <Directory>Office.directory</Directory> <Include> <Category>Office</Category> </Include> <Exclude> <Filename>foo.desktop</Filename> </Exclude> </Menu> </Menu> Registered Categories Remember, these are case-sensitive. Category Description Legacy Keyword that must be added to menu entries merged from legacy locations. May not actually exist in a desktop entry (should be stripped out if found there). If the same directory is given as both a <LegacyDir> and an <AppDir>, its desktop entries should be labeled "Legacy" only if the <LegacyDir> appears later in the file than the <AppDir>. Core Important application, core to the desktop such as a filemanager or a help browser Applet An applet that will run inside a panel or another such application, likely desktop specific TrayIcon An application that is primarily an icon for the "system tray" or "notification area" (apps that open a normal window and just happen to have a tray icon as well should not list this category) Screensaver A screensaver (launching this desktop entry should activate the screensaver) TerminalEmulator A terminal emulator application. Development An application for development GUIDesigner A GUI designer application IDE IDE application TextEditor A text editor Office An office type application Spreadsheet A spreadsheet WordProcessor A word processor Presentation Presentation software Calendar Calendar app Email Email application TODO TODO list application ProjectManagement Project management application Graphics Graphical application VectorGraphics Vector based graphical application (should also include 'Graphics' category) RasterGraphics Raster based graphical application (should also include 'Graphics' category) System System application, "System Tools" such as say a log viewer or network monitor. SystemSetup System setup application, hardware installation, hardware clock setup, kernel setup, X server setup, etc.; i.e. system configuration tools. PackageManager A package manager application, should include the System keyword as well Utility Small utility application, "Accessories" Settings Desktop settings applications (not system settings application, those should be System;SystemSetup;) AdvancedSettings Advanced desktop settings. Accessibility Accessibility settings Network Network application such as a webbrowser Clock A clock application/applet Monitor Monitor application/applet that monitors some resource or activity. AudioVideo A multimedia (audio/video) application Amusement A simple amusement Emulator Emulator of another platform, such as a DOS emulator. Game A game 3DGame A game in 3D ArcadeGame Arcade style game BoardGame A board game CardGame A card game FirstPersonGame First person perspective game PlatformGame Platform style game PuzzleGame Puzzle game SportsGame Sports game StrategyGame Strategy game BlocksGame Falling blocks game Education Educational software Math Math software Astronomy Astronomy software Physics Physics software Chemistry Chemistry software Science Scientific software HamRadio HAM radio software KDE Application based on KDE libraries. GNOME Application based on GNOME libraries. GTK Application based on GTK+ libraries (may also have GNOME category). Qt Application based on Qt libraries (may also have KDE category). Motif Application based on Motif libraries. ConsoleOnly Application that only works inside a terminal (text-based or command line application). Shell A shell (an actual specific shell such as bash or tcsh, not a TerminalEmulator). Registered OnlyShowIn Environments Remember, these are case-sensitive. "KDE" not "kde" should be used. OnlyShowIn Value Environment GNOMEGNOME Desktop KDEKDE Desktop ROXROX Desktop XFCEXFCE Desktop OldLegacy menu systems How to add your application to the menus The short answer for third party applications is: Install desktop entries to datadir/applications/ for each menu item. Please namespace the filename, as in "vendor-foo.desktop", or use a subdirectory of datadir/applications/ so you have "vendor/foo.desktop." Please be sure all desktop entries are valid (see the desktop-file-utils package for a validation utility). Install an XML menu file to sysconfdir/desktop/menus/applications-merged/ to add any submenus, if your desktop entries aren't already included in some common categories. Install any directory entries needed for your submenus to datadir/desktop-directories/, taking care to namespace and validate the directory entries. Also, at least for a good long while, installing a directory hierarchy to the old GNOME/KDE specific locations such as /usr/share/applnk and /usr/share/gnome/apps should work. There are two ways to support both the old and new menu systems at the same time: If you add a Categories line to the desktop entries in the legacy hierarchy, implementations of this specification will ignore their location in the legacy hierarchy, and arrange them according to Categories instead. This allows you to install a single desktop file that works in all cases, though on the down side it's in a legacy location. If you add the line OnlyShowIn=Old; to a desktop entry, then old legacy implementations that ignore OnlyShowIn will still show the desktop entry, but implementations of this specification will not. Thus you can add an "OnlyShowIn=Old;" entry to the legacy hierarchy, and a new-style desktop entry to datadir/applications/, and still get only one entry in the menus. Implementation notes Menu editing To implement menu editing, the intent is that a per-user file is created. The per-user file should specify a <MergeFile> with the systemwide file, so that system changes are inherited. When the user deletes a menu item, you add <Exclude><Filename>foo.desktop</Filename></Exclude>. If the user adds a menu item, you use <Include><Filename>foo.desktop</Filename></Include>. If the user moves a folder, you might try to use <Move> elements to represent that, but it's tricky. (Move A/B/C to D/E/F, then move D/E to D/G, note that D/E/F still contains A/B/C while only the original D/E was moved to D/G.) In order to move a folder, you have to "fix up" all moves that move things into the folder being moved to instead move things into the folder's new location. To delete a folder, simply append the <Deleted> element. Menu editors probably need to do some kind of consolidation/compression to avoid an XML tree that grows infinitely over time. Glossary This glossary defines some of the terms used in this specification. Desktop entry A desktop entry is a file with a name ending in the ".desktop" extension which conforms to the desktop entry specification. It describes a menu item, including a name, an icon, and what to do when the item is selected. Desktop entries are also known as ".desktop files." Desktop-File Id The id to identify a desktop entry with. For example, if /usr/share/applications is specified as an <AppDir>, and /opt/fop as a <LegacyDir> with a prefix of foo- then /usr/share/applications/foo/bar.desktop, /usr/share/applications/foo-bar.desktop and /opt/fop/Settings/bar.desktop all have the same desktop-file id foo-bar.desktop Directory entry A directory entry is a file with a name ending in the ".directory" extension which conforms to the desktop entry specification. It describes gives a localized name and an icon for a submenu. Directory entries are also known as ".directory files." Menu path A "menu path" is the path to a particular menu. Menu paths are always "relative" so never start with a slash character. The path to a menu is simply the <Name> of each parent of the menu, followed by the <Name> of the menu itself. For example, "Foo/Bar/Baz" is a valid menu path. Relative path The canonical path to a directory entry, relative to the <DirectoryDir> containing the entry. For example, if /usr/share/desktop-directories is specified as an <DirectoryDir>, the relative path to /usr/share/desktop-directories/foo/bar.directory is foo/bar.directory.