summaryrefslogtreecommitdiffstats
path: root/menu/menu-spec.xml
diff options
context:
space:
mode:
Diffstat (limited to 'menu/menu-spec.xml')
-rw-r--r--menu/menu-spec.xml2392
1 files changed, 2392 insertions, 0 deletions
diff --git a/menu/menu-spec.xml b/menu/menu-spec.xml
new file mode 100644
index 0000000..7bd8568
--- /dev/null
+++ b/menu/menu-spec.xml
@@ -0,0 +1,2392 @@
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
+ <!ENTITY version "1.1-draft">
+ <!ENTITY dtd-version "1.0">
+ ]>
+
+<article id="index">
+ <articleinfo>
+ <title>Desktop Menu Specification</title>
+ <releaseinfo>Version &version;</releaseinfo>
+ <date>31 March 2011</date>
+ <authorgroup>
+ <author>
+ <firstname>Waldo</firstname>
+ <surname>Bastian</surname>
+ <affiliation>
+ <address>
+ <email>waldo.bastian@intel.com</email>
+ </address>
+ </affiliation>
+ </author>
+ <author>
+ <firstname>Francois</firstname>
+ <surname>Gouget</surname>
+ <affiliation>
+ <address>
+ <email>fgouget@codeweavers.com</email>
+ </address>
+ </affiliation>
+ </author>
+ <author>
+ <firstname>Alex</firstname>
+ <surname>Graveley</surname>
+ <affiliation>
+ <address>
+ <email>alex@ximian.com</email>
+ </address>
+ </affiliation>
+ </author>
+ <author>
+ <firstname>George</firstname>
+ <surname>Lebl</surname>
+ <affiliation>
+ <address>
+ <email>jirka@5z.com</email>
+ </address>
+ </affiliation>
+ </author>
+ <author>
+ <firstname>Havoc</firstname>
+ <surname>Pennington</surname>
+ <affiliation>
+ <address>
+ <email>hp@pobox.com</email>
+ </address>
+ </affiliation>
+ </author>
+ <author>
+ <firstname>Heinrich</firstname>
+ <surname>Wendel</surname>
+ <affiliation>
+ <address>
+ <email>h_wendel@cojobo.net</email>
+ </address>
+ </affiliation>
+ </author>
+ </authorgroup>
+ </articleinfo>
+
+ <sect1 id="introduction">
+ <title>Introduction</title>
+ <para>
+ This 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.
+ </para>
+ <para>
+ The basic scheme is very simple. Information about each application (menu
+ item) is stored in a desktop entry (see <ulink
+ url="http://www.freedesktop.org/Standards/desktop-entry-spec">Desktop
+ Entry Standard</ulink>). Then an XML configuration file defines the
+ hierarchical arrangement (layout) of menu items, and which menu items are
+ actually displayed.
+ </para>
+ <para>
+ 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
+ <firstterm>merging</firstterm> two menu layouts.
+ </para>
+ <para>
+ In addition to a strict definition of the contents of each menu this
+ specification also foresees in a number of layout / presentation hints.
+ This part of the specification is optional, implementations may chose to
+ ignore these hints.
+ </para>
+ </sect1>
+ <sect1 id="paths">
+ <title>File locations</title>
+ <para>
+ Files involved in this specification are located according to the <ulink
+ url="http://www.freedesktop.org/Standards/basedir-spec">"desktop
+ base directory specification"</ulink>.
+ </para>
+ <para>
+ Here are the files defined by this specification:
+ <variablelist>
+ <varlistentry>
+
+<term><varname>$XDG_CONFIG_DIRS</varname>/menus/<varname>${XDG_MENU_PREFIX}</varname>applications.menu</term>
+ <listitem>
+ <para>
+ 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 <varname>${XDG_MENU_PREFIX}</varname>applications.menu,
+ it replaces the system wide one.
+ (Though the user's menu may explicitly merge the system wide
+ one.)
+ </para>
+ <para>
+ Systems that offer multiple desktop environments and that want
+ to use distinct menu layouts in the different environments can
+ use differently prefixed .menu files. In this case the
+ <varname>$XDG_MENU_PREFIX</varname> environment variable must
+ be set by the system to reflect the .menu file that is being
+ used.
+ </para>
+ <para>
+ For example if a system contains both the GNOME and the KDE
+ desktop environments it can decide to use
+ gnome-applications.menu as the menu layout in GNOME sessions
+ and kde-applications.menu as the menu layout in KDE sessions.
+ To correctly reflect this, it should set the
+ <varname>$XDG_MENU_PREFIX</varname> environment variable to
+ "gnome-" respectively "kde-".
+ </para>
+ <para>
+ Implementations may chose to use .menu files with other names
+ for tasks or menus other than the main application menu. Such
+ usage is not covered by this specification.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><varname>$XDG_CONFIG_DIRS</varname>/menus/applications-merged/</term>
+ <listitem>
+ <para>
+ The default merge directories included in the
+ &lt;DefaultMergeDirs&gt; element. By convention, third parties
+ may add new &lt;Menu&gt; files in this location to create their
+ own sub-menus.
+ </para>
+ <para>
+ Note that a system that uses either gnome-applications.menu or
+ kde-applications.menu depending on the desktop environment in
+ use must still use applications-merged as the default merge
+ directory in both cases.
+ </para>
+ <para>
+ Implementations may chose to use .menu files with names other
+ than application.menu for tasks or menus other than the main
+ application menu. In that case the first part of the name of
+ the default merge directory is derived from the name of the
+ .menu file.
+ </para>
+ <para>
+ For example in a system that uses a preferences.menu file to
+ describe an additional menu, the default merge directories
+ included in the &lt;DefaultMergeDirs&gt; element in the
+ preferences.menu file would become
+ <varname>$XDG_CONFIG_DIRS</varname>/menus/preferences-merged/
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><varname>$XDG_DATA_DIRS</varname>/applications/</term>
+ <listitem>
+ <para>
+ This directory contains a .desktop file for each possible menu
+ item. Each directory in the <varname>$XDG_DATA_DIRS</varname>
+ 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.
+ </para>
+ <para>
+ The &lt;DefaultAppDirs&gt; 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
+ &lt;DefaultAppDirs&gt;, then these locations are not scanned.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><varname>$XDG_DATA_DIRS</varname>/desktop-directories/</term>
+ <listitem>
+ <para>
+ 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.
+ </para>
+ <para>
+ The &lt;DefaultDirectoryDirs&gt; 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
+ &lt;DefaultDirectoryDirs&gt;, then these locations are not scanned.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </sect1>
+ <sect1 id="desktop-entry-extensions">
+ <title>Extensions to the desktop entry format</title>
+ <para>
+ This specification adds three new fields to <ulink
+ url="http://www.freedesktop.org/Standards/desktop-entry-spec">desktop
+ entries</ulink>: <varname>Categories</varname>,
+ <varname>OnlyShowIn</varname> and <varname>NotShowIn</varname>.
+ </para>
+ <para>
+ The <varname>Categories</varname> field is a list of strings used to
+ classify menu items. For example, applications in the
+ <literal>AudioVideo</literal> category might end up in the
+ "Sound &amp; Video" submenu. <xref linkend="category-registry"/>
+ 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.
+ </para>
+ <para>
+ 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.
+ </para>
+ <para>
+ The <varname>OnlyShowIn</varname> field is a list of strings identifying
+ the environments that should display a given menu item. If an
+ <varname>OnlyShowIn</varname> 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. <xref
+ linkend="onlyshowin-registry"/> enumerates the strings to use for
+ some common environments.
+ </para>
+ <para>
+ The <varname>NotShowIn</varname> field is a list of strings identifying
+ the environments that should not display a given menu item. If an
+ <varname>NotShowIn</varname> field is present, a given environment should
+ only display the menu item if the string identifying that environment is
+ not present. The strings are case-sensitive. <xref
+ linkend="onlyshowin-registry"/> enumerates the strings to use for
+ some common environments.
+ </para>
+ <para>
+ Environments not in this document must be prefixed by the string "X-"
+ indicating that they are extensions. Environments are case-sensitive.
+ </para>
+ <sect2 id="desktop-entry-extensions-examples">
+ <title>Examples of using <varname>Categories</varname> and <varname>OnlyShowIn</varname></title>
+ <para>
+ A desktop entry for a Qt-based image viewer might contain
+ this <varname>Categories</varname> line:
+ <informalexample>
+ <programlisting>
+ Categories=Qt;Graphics;RasterGraphics;Viewer;
+ </programlisting>
+ </informalexample>
+ </para>
+ <para>
+ A desktop entry for Octave, a command-line mathematics program (which
+ would also have the field <literal>Terminal=true</literal>), might have:
+ <informalexample>
+ <programlisting>
+ Categories=ConsoleOnly;Math;
+ </programlisting>
+ </informalexample>
+ </para>
+ <para>
+ A desktop entry for a GNOME-specific calculator program
+ that should only appear in GNOME might have:
+ <informalexample>
+ <programlisting>
+ Categories=GNOME;Utility;
+ OnlyShowIn=GNOME;
+ </programlisting>
+ </informalexample>
+ Note that the <varname>OnlyShowIn</varname> field is a
+ <emphasis>list</emphasis> and thus ends in a semicolon.
+ </para>
+ </sect2>
+ </sect1>
+ <sect1 id="menu-file-format">
+ <title>Format of menu files</title>
+ <para>
+ Menu files must be well-formed XML files and end in the extension
+ ".menu". They should also conform to the menu file DTD which implies
+ that implementation-specific extensions to the file format are not
+ allowed. Implementations may stop processing if they encounter a menu
+ file which does not comply with the associated DTD. Note that the
+ associated DTD may differ in version from the one defined in this document.
+ </para>
+ <para>
+ When an implementation updates an existing menu file it may need to
+ update the identifier to a newer version of the DTD. Implementations
+ should never update the identifier of an existing menu file to an
+ older version. In order to remain compatible with newer versions,
+ implementations should ignore and preserve any XML elements,
+ attributes and attribute values that it does not know how to handle.
+ </para>
+ <sect2 id="menu-file-doctype">
+ <title>Document Type Declaration</title>
+ <para>
+ Menu files for this version of the specification must use the following
+ namespace, public and system identifiers:
+ <variablelist>
+ <varlistentry>
+ <term>Namespace</term>
+ <listitem>
+ <para>
+ <literal>http://www.freedesktop.org/standards/menu</literal>
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Public Identifier for &version;</term>
+ <listitem>
+ <para>
+ <literal>PUBLIC "-//freedesktop//DTD Menu &dtd-version;//EN"</literal>
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>System Identifier for &version;</term>
+ <listitem>
+ <para>
+<literal>http://www.freedesktop.org/standards/menu-spec/menu-&dtd-version;.dtd</literal>
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ Here is a sample document type declaration:
+ <informalexample>
+ <programlisting>
+ &lt;!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu &dtd-version;//EN"
+ "http://www.freedesktop.org/standards/menu-spec/menu-&dtd-version;.dtd"&gt;
+ </programlisting>
+ </informalexample>
+
+ All menu files MUST include the document type declaration, so that
+ implementations can adapt to different versions of this specification
+ (and so implementations can validate the menu file against
+ the DTD).
+ </para>
+ </sect2>
+ <sect2 id="menu-file-elements">
+ <title>Elements</title>
+ <para>
+ <variablelist>
+ <varlistentry>
+ <term>&lt;Menu&gt;</term>
+ <listitem>
+ <para>
+ The root element is &lt;Menu&gt;. Each &lt;Menu&gt; element may
+ contain any number of nested &lt;Menu&gt; elements, indicating submenus.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>&lt;AppDir&gt;</term>
+ <listitem>
+ <para>
+ This element may only appear below &lt;Menu&gt;. 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 &lt;Menu&gt; and its submenus.
+ Only files ending in ".desktop" should be used, other files are
+ ignored.
+ </para>
+ <para>
+ Desktop entries in the pool of available entries are identified
+ by their <firstterm>desktop-file id</firstterm> (see <xref
+ linkend="term-desktop-file-id"/>).
+ The desktop-file id of a desktop entry is equal to its filename,
+ with any path components removed.
+ So given a &lt;AppDir&gt;
+ <filename>/foo/bar</filename> and desktop entry
+ <filename>/foo/bar/Hello.desktop</filename> the desktop
+ entry would get a desktop-file id of <filename>Hello.desktop</filename>
+ </para>
+ <para>
+ 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 &lt;AppDir&gt;
+ <filename>/foo/bar</filename> and desktop entry
+ <filename>/foo/bar/booz/Hello.desktop</filename> the desktop
+ entry would get a desktop-file id of <filename>booz-Hello.desktop</filename>
+ A desktop entry <filename>/foo/bar/bo/oz/Hello.desktop</filename> would result
+ in a desktop-file id of <filename>bo-oz-Hello.desktop</filename>
+ </para>
+ <para>
+ &lt;AppDir&gt; elements appearing later in the menu file have
+ priority in case of collisions between desktop-file ids.
+ </para>
+ <para>
+ If the filename given as an &lt;AppDir&gt; is not an absolute
+ path, it should be located relative to the location of the menu
+ file being parsed.
+ </para>
+ <para>
+ Duplicate &lt;AppDir&gt; elements (that specify the same
+ directory) should be ignored, but the <emphasis>last</emphasis>
+ duplicate in the file should be used when establishing the order
+ in which to scan the directories. This is important when merging
+ (see <xref linkend="merge-algorithm"/>). The order of
+ &lt;AppDir&gt; elements with respect to &lt;Include&gt; and
+ &lt;Exclude&gt; elements is not relevant, also to facilitate
+ merging.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>&lt;DefaultAppDirs&gt;</term>
+ <listitem>
+ <para>
+ This element may only appear below &lt;Menu&gt;. The element has
+ no content. The element should be treated as if it were a list
+ of &lt;AppDir&gt; elements containing the default app dir
+ locations
+ (<replaceable>datadir</replaceable>/applications/ etc.). When expanding
+ &lt;DefaultAppDirs&gt; to a list of &lt;AppDir&gt;, the default
+ locations that are earlier in the search path go later in the
+ &lt;Menu&gt; so that they have priority.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>&lt;DirectoryDir&gt;</term>
+ <listitem>
+ <para>
+ This element may only appear below &lt;Menu&gt;. The content of
+ this element is a directory name. Each directory listed in a
+ &lt;DirectoryDir&gt; element will be searched for directory
+ entries to be used when resolving the &lt;Directory&gt; element
+ for this menu and its submenus.
+ If the filename given as a &lt;DirectoryDir&gt; is not an absolute path,
+ it should be located relative to the location
+ of the menu file being parsed.
+ </para>
+ <para>
+ Directory entries in the pool of available entries are identified
+ by their <firstterm>relative path</firstterm> (see <xref
+ linkend="term-relative-path"/>).
+ </para>
+ <para>
+ 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.
+ </para>
+ <para>
+ Duplicate &lt;DirectoryDir&gt; elements (that specify the same
+ directory) are handled as with duplicate &lt;AppDir&gt;
+ elements (the last duplicate is used).
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>&lt;DefaultDirectoryDirs&gt;</term>
+ <listitem>
+ <para>
+ This element may only appear below &lt;Menu&gt;. The element has
+ no content. The element should be treated as if it were a list
+ of &lt;DirectoryDir&gt; elements containing the default desktop dir
+ locations
+ (<replaceable>datadir</replaceable>/desktop-directories/ etc.). The default
+ locations that are earlier in the search path go later in the
+ &lt;Menu&gt; so that they have priority.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>&lt;Name&gt;</term>
+ <listitem>
+ <para>
+ Each &lt;Menu&gt; element must have a single &lt;Name&gt;
+ element. The content of the &lt;Name&gt; element is a name to
+ be used when referring to the given menu. Each submenu of a
+ given &lt;Menu&gt; must have a unique name. &lt;Menu&gt;
+ elements can thus be referenced by a menu path, for example
+ "Applications/Graphics." The &lt;Name&gt; field must not contain
+ the slash character ("/"); implementations should discard
+ any name containing a slash. See also <xref linkend="term-menu-path"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>&lt;Directory&gt;</term>
+ <listitem>
+ <para>
+ Each &lt;Menu&gt; element has any number of &lt;Directory&gt;
+ elements. The content of the &lt;Directory&gt; element
+ is the relative path of a directory entry containing meta information
+ about the &lt;Menu&gt;, such as its icon and localized name.
+ If no &lt;Directory&gt; is specified for a &lt;Menu&gt;,
+ its &lt;Name&gt; field should be used as the user-visible
+ name of the menu.
+ </para>
+ <para>
+ Duplicate &lt;Directory&gt; elements are allowed in order
+ to simplify menu merging, and allow user menus to override
+ system menus. The last &lt;Directory&gt; 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.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>&lt;OnlyUnallocated&gt; and &lt;NotOnlyUnallocated&gt;</term>
+ <listitem>
+ <para>
+ Each &lt;Menu&gt; may contain any number of
+ &lt;OnlyUnallocated&gt; and &lt;NotOnlyUnallocated&gt;
+ elements. Only the last such element to appear is relevant, as
+ it determines whether the &lt;Menu&gt; can contain any desktop
+ entries, or only those desktop entries that do not match other
+ menus. If neither &lt;OnlyUnallocated&gt; nor
+ &lt;NotOnlyUnallocated&gt; elements are present, the default
+ is &lt;NotOnlyUnallocated&gt;.
+ </para>
+ <para>
+ To handle &lt;OnlyUnallocated&gt;, the menu file must be
+ analyzed in two conceptual passes. The first pass processes
+ &lt;Menu&gt; elements that can match any desktop entry. During
+ this pass, each desktop entry is marked as allocated according
+ to whether it was matched by an &lt;Include&gt; rule in some
+ &lt;Menu&gt;. The second pass processes only &lt;Menu&gt;
+ elements that are restricted to unallocated desktop entries.
+ During the second pass, queries may only match desktop entries
+ that were not marked as allocated during the first pass.
+ See <xref linkend="query-algorithm"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>&lt;Deleted&gt; and &lt;NotDeleted&gt;</term>
+ <listitem>
+ <para>
+ Each &lt;Menu&gt; may contain any number of &lt;Deleted&gt; and
+ &lt;NotDeleted&gt; elements. Only the last such element to
+ appear is relevant, as it determines whether the &lt;Menu&gt;
+ has been deleted. If neither &lt;Deleted&gt; nor
+ &lt;NotDeleted&gt; elements are present, the default is
+ &lt;NotDeleted&gt;. The purpose of this element is to support
+ menu editing. If a menu contains a &lt;Deleted&gt; element
+ not followed by a &lt;NotDeleted&gt; element, that menu
+ should be ignored.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>&lt;Include&gt;</term>
+ <listitem>
+ <para>
+ An &lt;Include&gt; element is a set of rules attempting to match
+ some of the known desktop entries. The &lt;Include&gt; element
+ contains a list of any number of matching rules. Matching rules
+ are specified using the elements &lt;And&gt;, &lt;Or&gt;,
+ &lt;Not&gt;, &lt;All&gt;, &lt;Filename&gt;, and
+ &lt;Category&gt;. 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.
+ </para>
+ <para>
+ &lt;Include&gt; elements must appear immediately under
+ &lt;Menu&gt; elements. The desktop entries they match are
+ included in the menu. &lt;Include&gt; and &lt;Exclude&gt;
+ elements for a given &lt;Menu&gt; are processed in order,
+ with queries earlier in the file handled first. This has
+ implications for merging, see <xref linkend="merge-algorithm"/>.
+ See <xref linkend="query-algorithm"/> for full details on
+ how to process &lt;Include&gt; and &lt;Exclude&gt; elements.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>&lt;Exclude&gt;</term>
+ <listitem>
+ <para>
+ Any number of &lt;Exclude&gt; elements may appear below a
+ &lt;Menu&gt; element. The content of an &lt;Exclude&gt; element
+ is a list of matching rules, just as with an
+ &lt;Include&gt;. However, the desktop entries matched are
+ removed from the list of desktop entries included so far. (Thus
+ an &lt;Exclude&gt; element that appears before any
+ &lt;Include&gt; elements will have no effect, for example, as no
+ desktop entries have been included yet.)
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>&lt;Filename&gt;</term>
+ <listitem>
+ <para>
+ The &lt;Filename&gt; element is the most basic matching rule.
+ It matches a desktop entry if the desktop entry has the given
+ desktop-file id. See <xref linkend="term-desktop-file-id"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>&lt;Category&gt;</term>
+ <listitem>
+ <para>
+ The &lt;Category&gt; element is another basic matching
+ predicate. It matches a desktop entry if the desktop entry has
+ the given category in its <varname>Categories</varname> field.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>&lt;All&gt;</term>
+ <listitem>
+ <para>
+ The &lt;All&gt; element is a matching rule that matches
+ all desktop entries.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>&lt;And&gt;</term>
+ <listitem>
+ <para>
+ The &lt;And&gt; element contains a list of matching rules.
+ If each of the matching rules inside the &lt;And&gt;
+ element match a desktop entry, then the entire
+ &lt;And&gt; rule matches the desktop entry.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>&lt;Or&gt;</term>
+ <listitem>
+ <para>
+ The &lt;Or&gt; element contains a list of matching rules.
+ If any of the matching rules inside the &lt;Or&gt;
+ element match a desktop entry, then the entire
+ &lt;Or&gt; rule matches the desktop entry.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>&lt;Not&gt;</term>
+ <listitem>
+ <para>
+ The &lt;Not&gt; element contains a list of matching rules. If
+ any of the matching rules inside the &lt;Not&gt; element matches
+ a desktop entry, then the entire &lt;Not&gt; rule does
+ <emphasis>not</emphasis> match the desktop entry. That is,
+ matching rules below &lt;Not&gt; have a logical OR relationship.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>&lt;MergeFile [type="path"|"parent"] &gt;</term>
+ <listitem>
+ <para>
+ Any number of &lt;MergeFile&gt; elements may be listed below a
+ &lt;Menu&gt; element, giving the name of another menu file to
+ be merged into this one. <xref linkend="merge-algorithm"/>
+ specifies how merging is done. The root &lt;Menu&gt; of the
+ merged file will be merged into the immediate parent of the
+ &lt;MergeFile&gt; element. The &lt;Name&gt; element of the
+ root &lt;Menu&gt; of the merged file are ignored.
+ </para>
+ <para>
+ If the type attribute is missing or set to "path" then the
+ contents of the &lt;MergeFile&gt; element indicates the
+ file to be merged. If this is not an absolute path then the
+ file to be merged should be located relative to the location
+ of the menu file that contains this &lt;MergeFile&gt; element.
+ </para>
+ <para>
+ Duplicate &lt;MergeFile&gt; elements (that specify the same
+ file) are handled as with duplicate &lt;AppDir&gt;
+ elements (the last duplicate is used).
+ </para>
+ <para>
+ If the type attribute is set to "parent" and the file that
+ contains this &lt;MergeFile&gt; element is located under one
+ of the paths specified by <varname>$XDG_CONFIG_DIRS</varname>,
+ the contents of the element should be ignored and the remaining
+ paths specified by <varname>$XDG_CONFIG_DIRS</varname> are
+ searched for a file with the same relative filename. The first
+ file encountered should be merged. There should be no
+ merging at all if no matching file is found.
+ </para>
+ <para>
+ Compatibility note: The filename specified inside the &lt;MergeFile&gt;
+ element should be ignored if the type attribute is set to "parent",
+ it should however be expected that implementations based on
+ previous versions of this specification will ignore the
+ type attribute and that such implementations will use the
+ filename inside the &lt;MergeFile&gt; element instead.
+ </para>
+ <para>
+ Example 1: If <varname>$XDG_CONFIG_HOME</varname> is "~/.config/" and
+ <varname>$XDG_CONFIG_DIRS</varname> is "/opt/gnome/:/etc/xdg/"
+ and the file ~/.config/menus/applications.menu contains
+ &lt;MergeFile type="parent"&gt;/opt/kde3/etc/xdg/menus/applications.menu&lt;/MergeFile&gt;
+ then the file /opt/gnome/menus/applications.menu
+ should be merged if it exists. If that file does not exists
+ then the file /etc/xdg/menus/applications.menu
+ should be merged instead.
+ </para>
+ <para>
+ Example 2: If <varname>$XDG_CONFIG_HOME</varname> is "~/.config/" and
+ <varname>$XDG_CONFIG_DIRS</varname> is "/opt/gnome/:/etc/xdg/"
+ and the file /opt/gnome/menus/applications.menu contains
+ &lt;MergeFile type="parent"&gt;/opt/kde3/etc/xdg/menus/applications.menu&lt;/MergeFile&gt;
+ then the file /etc/xdg/menus/applications.menu should be merged
+ if it exists.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>&lt;MergeDir&gt;</term>
+ <listitem>
+ <para>
+ Any number of &lt;MergeDir&gt; elements may be listed below a
+ &lt;Menu&gt; element. A &lt;MergeDir&gt; 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
+ &lt;MergeFile&gt; would be. If the filename given as a
+ &lt;MergeDir&gt; 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.
+ </para>
+ <para>
+ Duplicate &lt;MergeDir&gt; elements (that specify the same
+ directory) are handled as with duplicate &lt;AppDir&gt;
+ elements (the last duplicate is used).
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>&lt;DefaultMergeDirs&gt;</term>
+ <listitem>
+ <para>
+ This element may only appear below &lt;Menu&gt;. The element has
+ no content. The element should be treated as if it were a list
+ of &lt;MergeDir&gt; elements containing the default merge
+ directory locations. When expanding &lt;DefaultMergeDirs&gt; to a
+ list of &lt;MergeDir&gt;, the default locations that are earlier
+ in the search path go later in the &lt;Menu&gt; so that they
+ have priority.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>&lt;LegacyDir&gt;</term>
+ <listitem>
+ <para>
+ This element may only appear below &lt;Menu&gt;. The text
+ content of this element is a directory name. Each directory
+ listed in a &lt;LegacyDir&gt; element will be an old-style
+ legacy hierarchy of desktop entries, see <xref
+ linkend="legacy-hierarchies"/> 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 &lt;LegacyDir&gt; is not an absolute path,
+ it should be located relative to the location of the menu file
+ being parsed.
+ </para>
+ <para>
+ Duplicate &lt;LegacyDir&gt; elements (that specify the same
+ directory) are handled as with duplicate &lt;AppDir&gt;
+ elements (the last duplicate is used).
+ </para>
+ <para>
+ The &lt;LegacyDir&gt; element may have one attribute,
+ <literal>prefix</literal>. Normally, given a &lt;LegacyDir&gt;
+ <filename>/foo/bar</filename> and desktop entry
+ <filename>/foo/bar/baz/Hello.desktop</filename> the desktop
+ entry would get a desktop-file id of <filename>Hello.desktop</filename>.
+ Given a prefix of <literal>boo-</literal>, it would instead be
+ assigned the desktop-file id <filename>boo-Hello.desktop</filename>.
+ The prefix should not contain path separator ('/') characters.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>&lt;KDELegacyDirs&gt;</term>
+ <listitem>
+ <para>
+ This element may only appear below &lt;Menu&gt;. The element has
+ no content. The element should be treated as if it were a list
+ of &lt;LegacyDir&gt; elements containing the traditional desktop
+ file locations supported by KDE with a hard coded prefix of "kde-".
+ When expanding &lt;KDELegacyDirs&gt; to a list of &lt;LegacyDir&gt;, the
+ locations that are earlier in the search path go later in the
+ &lt;Menu&gt; so that they have priority.
+ The search path can be obtained by running <filename>kde-config --path apps</filename>
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>&lt;Move&gt;</term>
+ <listitem>
+ <para>
+ This element may only appear below &lt;Menu&gt;. The
+ &lt;Move&gt; element contains pairs of &lt;Old&gt;/&lt;New&gt;
+ elements indicating how to rename a descendant of the current
+ &lt;Menu&gt;. If the destination path already exists, the moved
+ menu is merged with the destination menu (see <xref
+ linkend="merge-algorithm"/> for details).
+ </para>
+ <para>
+ &lt;Move&gt; is used primarily to fix up legacy directories.
+ For example, say you are merging a &lt;LegacyDir&gt; 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.
+ </para>
+ <para>
+ &lt;Move&gt; is also useful for implementing menu
+ editing, see <xref linkend="menu-editing"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>&lt;Old&gt;</term>
+ <listitem>
+ <para>
+ This element may only appear below &lt;Move&gt;, and
+ must be followed by a &lt;New&gt; element. The content of both
+ &lt;Old&gt; and &lt;New&gt; should be a menu path
+ (slash-separated concatenation of &lt;Name&gt; fields, see
+ <xref linkend="term-menu-path"/>).
+ Paths are interpreted relative to the menu containing
+ the &lt;Move&gt; element.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>&lt;New&gt;</term>
+ <listitem>
+ <para>
+ This element may only appear below &lt;Move&gt;, and must
+ be preceded by an &lt;Old&gt; element. The &lt;New&gt; element
+ specifies the new path for the preceding &lt;Old&gt; element.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>&lt;Layout&gt;</term>
+ <listitem>
+ <para>
+ The &lt;Layout&gt; element is an optional part of this specification.
+ Implementations that do not support the &lt;Layout&gt; element should
+ preserve any &lt;Layout&gt; elements and their contents as far as
+ possible.
+ Each &lt;Menu&gt; may optionally contain a &lt;Layout&gt; element.
+ If multiple elements appear then only the last such element is relevant.
+ The purpose of this element is to offer suggestions for the presentation
+ of the menu.
+ If a menu does not contain a &lt;Layout&gt; element or if it contains
+ an empty &lt;Layout&gt; element then the default layout should be used.
+ The &lt;Layout&gt; element may contain &lt;Filename&gt;, &lt;Menuname&gt;,
+ &lt;Separator&gt; and &lt;Merge&gt; elements. The &lt;Layout&gt; element
+ defines a suggested layout for the menu starting from top to bottom.
+ References to desktop entries that are not contained in this
+ menu as defined by the &lt;Include&gt; and &lt;Exclude&gt; elements should
+ be ignored. References to sub-menus that are not directly contained in this
+ menu as defined by the &lt;Menu&gt; elements should be ignored.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>&lt;DefaultLayout [show_empty="false"] [inline="false"] [inline_limit="4"] [inline_header="true"] [inline_alias="false"]&gt;</term>
+ <listitem>
+ <para>
+ The &lt;DefaultLayout&gt; element is an optional part of this specification.
+ Implementations that do not support the &lt;DefaultLayout&gt; element should
+ preserve any &lt;DefaultLayout&gt; elements and their contents as far as
+ possible.
+ Each &lt;Menu&gt; may optionally contain a &lt;DefaultLayout&gt; element
+ which defines the default-layout for the current menu and all its sub-menus.
+ If a menu has a &lt;DefaultLayout&gt; element then this will override
+ any default-layout specified by a parent menu.
+ The default-layout defines the suggested layout if a &lt;Menu&gt; element
+ does either not have &lt;Layout&gt; element or if it has an empty &lt;Layout&gt; element.
+ For explanations of the various attributes see the &lt;Menuname&gt; element.
+ If no default-layout has been specified then the layout as specified by the following
+ elements should be assumed:
+ &lt;DefaultLayout show_empty="false" inline="false" inline_limit="4" inline_header="true" inline_alias="false"&gt;&lt;Merge type="menus"/&gt;&lt;Merge type="files"/&gt;&lt;/DefaultLayout&gt;
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>&lt;Menuname [show_empty="..."] [inline="..."] [inline_limit="..."] [inline_header="..."] [inline_alias="..."]&gt;</term>
+ <listitem>
+ <para>
+ This element may only appear as a child of a &lt;Layout&gt; or &lt;DefaultLayout&gt;
+ menu. Its contents references an immediate sub-menu of the current menu as defined
+ with the &lt;Menu&gt; element, as such it should never contain a slash.
+ If no such sub-menu exists the element should be ignored.
+ This element may have various attributes, the default values are taken from the DefaultLayout key.
+ The show_empty attribute defines whether a menu that contains no desktop
+ entries and no sub-menus should be shown at all. The show_empty attribute
+ can be "true" or "false".
+ It may have an inline attribute that can be either "true" or "false".
+ If the inline attribute is "true" the menu that is referenced may be copied into the
+ current menu at the current point instead of being inserted as sub-menu of the current menu.
+ The optional inline_limit attribute defines the maximum number of entries that can be inlined.
+ If the sub-menu has more entries than inline_limit, the sub-menu will not be inlined.
+ If the inline_limit is 0 (zero) there is no limit.
+ The optional inline_header attribute defines whether an inlined menu should be preceded with
+ a header entry listing the caption of the sub-menu.
+ The inline_header attribute can be either "true" or "false".
+ The optional inline_alias attribute defines whether a single inlined entry should adopt the
+ caption of the inlined menu. In such case no additional header entry will be added regardless
+ of the value of the inline_header attribute.
+ The inline_alias attribute can be either "true" or "false".
+ Example: if a menu has a sub-menu titled "WordProcessor" with a single entry "OpenOffice 4.2",
+ and both inline="true" and inline_alias="true" are specified then this would result in the
+ "OpenOffice 4.2" entry being inlined in the current menu but the "OpenOffice 4.2" caption
+ of the entry would be replaced with "WordProcessor".
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>&lt;Separator&gt;</term>
+ <listitem>
+ <para>
+ This element may only appear as a child of a &lt;Layout&gt; or &lt;DefaultLayout&gt;
+ menu. It indicates a suggestion to draw a visual separator at this point in the menu.
+ &lt;Separator&gt; elements at the start of a menu, at the end of a menu or that directly
+ follow other &lt;Separator&gt; elements may be ignored.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>&lt;Merge type="menus"|"files"|"all"/&gt;</term>
+ <listitem>
+ <para>
+ This element may only appear as a child of a &lt;Layout&gt; or &lt;DefaultLayout&gt;
+ menu. It indicates the point where desktop entries and sub-menus that are not explicitly
+ mentioned within the &lt;Layout&gt; or &lt;DefaultLayout&gt; element are to be inserted.
+ It has a type attribute that indicates which elements should be inserted:
+ type="menus"
+ means that all sub-menus that are not explicitly mentioned should be inserted in
+ alphabetical order of their visual caption at this point.
+ type="files"
+ means that all desktop entries
+ contained in this menu that are not explicitly mentioned should be inserted in
+ alphabetical order of their visual caption at this point.
+ type="all" means that a mix of all sub-menus
+ and all desktop entries that are not explicitly mentioned should be inserted in
+ alphabetical order of their visual caption at this point.
+ Each &lt;Layout&gt; or &lt;DefaultLayout&gt; element shall have exactly one &lt;Merge type="all"&gt;
+ element or it shall have exactly one &lt;Merge type="files"&gt; and exactly one
+ &lt;Merge type="menus"&gt; element. An exception is made for a completely empty &lt;Layout&gt;
+ element which may be used to indicate that the default-layout should be used instead.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="merge-algorithm">
+ <title>Merging</title>
+ <para>
+ Sometimes two menu layouts need to be merged. This is done when folding in
+ legacy menu hierarchies (see <xref linkend="legacy-hierarchies"/>) and also
+ for files specified in &lt;MergeFile&gt; 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.
+ </para>
+ <para>
+ Merging involves a base &lt;Menu&gt; and a merged &lt;Menu&gt;. The base
+ is the "target" menu and the merged &lt;Menu&gt; is being added to it. The
+ result of the merge is termed the "combined menu."
+ </para>
+ <para>
+ As a preparatory step, the goal is to resolve all files into
+ XML elements. To do so, traverse the entire menu tree. For each
+ &lt;MergeFile&gt;, &lt;MergeDir&gt;, or &lt;LegacyDir&gt; element, replace
+ the &lt;MergeFile&gt;, &lt;MergeDir&gt;, or &lt;LegacyDir&gt; element with
+ the child elements of the root &lt;Menu&gt; of the file(s) being
+ merged. As a special exception, remove the &lt;Name&gt; element from the
+ root element of each file being merged. To generate a
+ &lt;Menu&gt; based on a &lt;LegacyDir&gt;, see
+ <xref linkend="legacy-hierarchies"/>.
+ </para>
+ <para>
+ Continue processing until no &lt;MergeFile&gt;, &lt;MergeDir&gt;, or
+ &lt;LegacyDir&gt; elements remain, taking care to avoid infinite loops
+ caused by files that reference one another.
+ </para>
+ <para>
+ Once all files have been loaded into a single tree, scan the tree
+ recursively performing these steps to remove duplicates:
+ <orderedlist>
+ <listitem>
+ <para>
+ Consolidate child menus. Each group of child &lt;Menu&gt;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 <emphasis>last</emphasis> menu with that name.
+ Delete all the newly empty &lt;Menu&gt; elements, keeping the
+ last one.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Expand &lt;DefaultAppDirs&gt; and &lt;DefaultDirectoryDirs&gt;
+ elements to &lt;AppDir&gt; and &lt;DirectoryDir&gt; elements.
+ Consolidate duplicate &lt;AppDir&gt;, &lt;DirectoryDir&gt;,
+ and &lt;Directory&gt; elements by keeping the last one.
+ For &lt;Directory&gt; 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.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Recurse into each child &lt;Menu&gt;, performing this list of
+ steps for each child in order.
+ </para>
+ </listitem>
+ </orderedlist>
+ </para>
+ <para>
+ After recursing once to remove duplicates, recurse a second time to
+ resolve &lt;Move&gt; elements for each menu starting with any child
+ menu before handling the more top level menus.
+ So the deepest menus have their &lt;Move&gt; operations performed first.
+ Within each &lt;Menu&gt;, execute &lt;Move&gt; operations in the order
+ that they appear. If the destination path does not exist, simply relocate
+ the origin &lt;Menu&gt; element, and change its &lt;Name&gt; field to
+ match the destination path. If the origin path does not exist, do
+ nothing. If both paths exist, take the origin &lt;Menu&gt; element,
+ delete its &lt;Name&gt; element, and prepend its remaining child elements
+ to the destination &lt;Menu&gt; element.
+ </para>
+ <para>
+ If any &lt;Move&gt; operations affect a menu, then re-run the
+ steps to resolve duplicates in case any duplicates have been
+ created.
+ </para>
+ <para>
+ Finally, for each &lt;Menu&gt; containing a &lt;Deleted&gt; element which
+ is not followed by a &lt;NotDeleted&gt; element, remove that menu and all
+ its child menus.
+ </para>
+
+ <para>
+ Merged menu elements are kept in order because &lt;Include&gt; and
+ &lt;Exclude&gt; elements later in the file override &lt;Include&gt; and
+ &lt;Exclude&gt; 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 &lt;MergeFile&gt;
+ that incorporates the system file.
+ </para>
+ <para>
+ 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.
+ </para>
+ <para>
+ 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
+ <filename><replaceable>datadir</replaceable>/applications/</filename> or it could
+ install desktop files in a <filename><replaceable>datadir</replaceable>/applications/gnome</filename>
+ subdirectory. When including legacy menu hierarchies the <literal>prefix</literal> argument
+ of the &lt;LegacyDir&gt; element can be used to specify a prefix.
+ </para>
+ </sect1>
+
+ <sect1 id="query-algorithm">
+ <title>Generating the menus</title>
+ <para>
+ After merging the menus, the result should be a single menu layout
+ description. For each &lt;Menu&gt;, 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 &lt;Include&gt; and &lt;Exclude&gt;
+ directives.
+ </para>
+ <para>
+ For each &lt;Menu&gt; element, build a pool of desktop entries by
+ collecting entries found in each &lt;AppDir&gt; 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) &lt;AppDir&gt; must be discarded. Next, add to the
+ pool the entries for any &lt;AppDir&gt;s specified by ancestor
+ &lt;Menu&gt; elements. If a parent menu has a duplicate entry (same
+ desktop-file id), the entry for the child menu has priority.
+ </para>
+ <para>
+ Next, walk through all &lt;Include&gt; and &lt;Exclude&gt; statements.
+ For each &lt;Include&gt;, 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 and mark it as having been allocated.
+ For each &lt;Exclude&gt;, match the rules against the currently-included
+ desktop entries. For each desktop entry that matches, remove it again
+ from the menu. Note that an entry that is included in a menu but excluded
+ again by a later &lt;Exclude&gt; is still considered allocated (for the
+ purposes of &lt;OnlyUnallocated&gt;) even though that entry no longer
+ appears in the menu.
+ </para>
+ <para>
+ Two passes are necessary, once for regular menus where any entry may
+ be matched, and once for &lt;OnlyUnallocated&gt; menus where only entries
+ which have not been marked as allocated may be matched.
+ </para>
+ <para>
+ The result is a tree of desktop entries, of course.
+ </para>
+ </sect1>
+
+ <sect1 id="legacy-hierarchies">
+ <title>Legacy Menu Hierarchies</title>
+ <para>
+ 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.
+ </para>
+ <para>
+ The general approach is: the legacy hierarchy is converted into a
+ &lt;Menu&gt;, and then this menu layout is merged with the menu that
+ specified &lt;LegacyDir&gt;.
+ </para>
+ <para>
+ Desktop entries in the legacy hierarchy should be added to the pool of
+ desktop entries as if the &lt;LegacyDir&gt; were an
+ &lt;AppDir&gt;. Directory entries in the legacy hierarchy should be added
+ to the pool of directory entries as if the &lt;LegacyDir&gt; were a
+ &lt;DirectoryDir&gt;. This can be trivially implemented by adding
+ appropriate &lt;AppDir&gt; and &lt;DirectoryDir&gt; statements to the root
+ legacy &lt;Menu&gt;. There is one slight complexity, namely the
+ "prefix" attribute of &lt;LegacyDir&gt;.
+ </para>
+ <para>
+ The menu layout corresponds conceptually to the following, though actually
+ generating the XML is not necessary:
+ <itemizedlist>
+ <listitem>
+ <para>
+ For each directory in the legacy hierarchy, a
+ &lt;Menu&gt; is created with the same &lt;Name&gt;
+ as the directory on disk.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ This menu then contains an &lt;Include&gt; element that includes
+ each desktop entry in the directory. That is, it should have a
+
+ &lt;Filename&gt;<replaceable>Foo/Bar/foo.desktop</replaceable>&lt;/Filename&gt;
+ for each desktop entry in the directory.
+ </para>
+ <para>
+ As a special exception, if a desktop entry in a directory contains
+ a <varname>Categories</varname> field, that desktop entry should
+ <emphasis>not</emphasis> be included in the legacy menu.
+ That is, no &lt;Include&gt; 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.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ If the legacy directory contains a ".directory" file, then
+ a &lt;Directory&gt; element should be generated that points to said
+ ".directory" file.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Legacy desktop entries should not be assigned any
+ <varname>Categories</varname> 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 &lt;LegacyDir&gt; and an &lt;AppDir&gt;, its desktop
+ entries should be labeled "Legacy" only if the &lt;LegacyDir&gt;
+ appears later in the file than the &lt;AppDir&gt;.)
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ For example, say we have the following legacy directory hierarchy:
+ <informalexample>
+ <programlisting>
+ /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
+ </programlisting>
+ </informalexample>
+ Conceptually that is converted to the following &lt;Menu&gt;:
+ <informalexample>
+ <programlisting>
+ &lt;!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu &dtd-version;//EN"
+ "http://www.freedesktop.org/standards/menu-spec/menu-&dtd-version;.dtd"&gt;
+
+ &lt;Menu&gt;
+ &lt;Name&gt;Applications&lt;/Name&gt;
+ &lt;AppDir&gt;/usr/share/applnk&lt;/AppDir&gt;
+ &lt;DirectoryDir&gt;/usr/share/applnk&lt;/DirectoryDir&gt;
+ &lt;Directory&gt;.directory&lt;/Directory&gt;
+ &lt;Include&gt;
+ &lt;Filename&gt;bar.desktop&lt;/Filename&gt;
+ &lt;/Include&gt;
+ &lt;Menu&gt;
+ &lt;Name&gt;System&lt;/Name&gt;
+ &lt;AppDir&gt;/usr/share/applnk/System&lt;/AppDir&gt;
+ &lt;DirectoryDir&gt;/usr/share/applnk/System&lt;/DirectoryDir&gt;
+ &lt;Directory&gt;.directory&lt;/Directory&gt;
+ &lt;Include&gt;
+ &lt;Filename&gt;foo.desktop&lt;/Filename&gt;
+ &lt;/Include&gt;
+ &lt;/Menu&gt;
+ &lt;/Menu&gt;
+ </programlisting>
+ </informalexample>
+ This &lt;Menu&gt; is then merged as if it were in a file
+ and loaded with &lt;MergeFile&gt;.
+ </para>
+ </sect1>
+
+ <sect1 id="example">
+ <title>Example Menu File</title>
+ <para>
+ <informalexample>
+ <programlisting>
+ &lt;!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu &dtd-version;//EN"
+ "http://www.freedesktop.org/standards/menu-spec/menu-&dtd-version;.dtd"&gt;
+
+ &lt;Menu&gt;
+ &lt;Name&gt;Applications&lt;/Name&gt;
+ &lt;Directory&gt;Applications.directory&lt;/Directory&gt;
+
+ &lt;-- Search the default locations --&gt;
+ &lt;DefaultAppDirs/&gt;
+ &lt;DefaultDirectoryDirs/&gt;
+
+ &lt;-- Merge third-party submenus --&gt;
+ &lt;MergeDir&gt;applications-merged&lt;/MergeDir&gt;
+
+ &lt;-- Merge legacy hierarchy --&gt;
+ &lt;LegacyDir&gt;/usr/share/applnk&lt;/LegacyDir&gt;
+
+ &lt;-- Define default layout --&gt;
+ &lt;DefaultLayout&gt;
+ &lt;Merge type="menus"/&gt;
+ &lt;Merge type="files"/&gt;
+ &lt;Separator/&gt;
+ &lt;Menuname&gt;More&lt;/Menuname&gt;
+ &lt;/DefaultLayout&gt;
+
+ &lt;-- some random moves, maybe to clean up legacy dirs,
+ maybe from menu editing --&gt;
+ &lt;Move&gt;
+ &lt;Old&gt;Foo&lt;/Old&gt;
+ &lt;New&gt;Bar&lt;/New&gt;
+ &lt;Old&gt;Foo2&lt;/Old&gt;
+ &lt;New&gt;Bar2&lt;/New&gt;
+ &lt;/Move&gt;
+
+ &lt;-- A preferences submenu, kept in a separate file
+ so it can also be used standalone --&gt;
+ &lt;Menu&gt;
+ &lt;Name&gt;Preferences&lt;/Name&gt;
+ &lt;Directory&gt;Preferences.directory&lt;/Directory&gt;
+ &lt;MergeFile&gt;preferences.menu&lt;/MergeFile&gt;
+ &lt;/Menu&gt;
+
+ &lt;-- An Office submenu, specified inline --&gt;
+ &lt;Menu&gt;
+ &lt;Name&gt;Office&lt;/Name&gt;
+ &lt;Directory&gt;Office.directory&lt;/Directory&gt;
+ &lt;Include&gt;
+ &lt;Category&gt;Office&lt;/Category&gt;
+ &lt;/Include&gt;
+ &lt;Exclude&gt;
+ &lt;Filename&gt;foo.desktop&lt;/Filename&gt;
+ &lt;/Exclude&gt;
+ &lt;/Menu&gt;
+
+ &lt;/Menu&gt;
+ </programlisting>
+ </informalexample>
+ </para>
+ </sect1>
+
+ <appendix id="category-registry">
+ <title>Registered Categories</title>
+ <para>
+ This section contains a number of well known categories and
+ suggestions on how to use them. The list of Main Categories consist
+ of those categories that every conforming desktop environment MUST
+ support. By including one of these categories in an application's
+ desktop entry file the application will be ensured that it will
+ show up in a section of the application menu dedicated to this
+ category. The list of Additional Categories provides categories
+ that can be used to provide more fine grained information about
+ the application.
+ </para>
+ <para>
+ Category-based menus based on the Main Categories listed in this
+ specification do not provide a complete ontology for all
+ available applications. Category-based menu implementations
+ SHOULD therefore provide a "catch-all" submenu for applications
+ that cannot be appropriately placed elsewhere.
+ </para>
+ <para>
+ The table below lists all Main Categories.
+ Note that category names are case-sensitive.
+ <informaltable>
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Main Category</entry>
+ <entry>Description</entry>
+ <entry>Notes</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>AudioVideo</entry>
+ <entry>Application for presenting, creating, or processing multimedia (audio/video)</entry>
+ </row><row>
+ <entry>Audio</entry>
+ <entry>An audio application</entry>
+ <entry>Desktop entry must include AudioVideo as well</entry>
+ </row><row>
+ <entry>Video</entry>
+ <entry>A video application</entry>
+ <entry>Desktop entry must include AudioVideo as well</entry>
+ </row><row>
+ <entry>Development</entry>
+ <entry>An application for development</entry>
+ </row><row>
+ <entry>Education</entry>
+ <entry>Educational software</entry>
+ </row><row>
+ <entry>Game</entry>
+ <entry>A game</entry>
+ </row><row>
+ <entry>Graphics</entry>
+ <entry>Application for viewing, creating, or processing graphics</entry>
+ </row><row>
+ <entry>Network</entry>
+ <entry>Network application such as a web browser</entry>
+ </row><row>
+ <entry>Office</entry>
+ <entry>An office type application</entry>
+ </row><row>
+ <entry>Settings</entry>
+ <entry>Settings applications</entry>
+ <entry>Entries may appear in a separate menu or as part of a
+ "Control Center"</entry>
+ </row><row>
+ <entry>System</entry>
+ <entry>System application, "System Tools" such as say a log viewer or network monitor</entry>
+ </row><row>
+ <entry>Utility</entry>
+ <entry>Small utility application, "Accessories"</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </para>
+ <para>
+ The table below describes Additional Categories. The Related
+ Categories column lists one or more categories that are suggested
+ to be used in conjunction with the Additional Category. If multiple
+ Main Categories are included in a single
+ desktop entry file, the entry may appear more than once in the menu.
+ If the Related Categories column is blank, the
+ Additional Category can be used with any Main Category.
+ <informaltable>
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Additional Category</entry>
+ <entry>Description</entry>
+ <entry>Related Categories</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>Building</entry>
+ <entry>A tool to build applications</entry>
+ <entry>Development</entry>
+
+ </row><row>
+ <entry>Debugger</entry>
+ <entry>A tool to debug applications</entry>
+ <entry>Development</entry>
+
+ </row><row>
+ <entry>IDE</entry>
+ <entry>IDE application</entry>
+ <entry>Development</entry>
+
+ </row><row>
+ <entry>GUIDesigner</entry>
+ <entry>A GUI designer application</entry>
+ <entry>Development</entry>
+
+ </row><row>
+ <entry>Profiling</entry>
+ <entry>A profiling tool</entry>
+ <entry>Development</entry>
+
+ </row><row>
+ <entry>RevisionControl</entry>
+ <entry>Applications like cvs or subversion</entry>
+ <entry>Development</entry>
+
+ </row><row>
+ <entry>Translation</entry>
+ <entry>A translation tool</entry>
+ <entry>Development</entry>
+
+ </row><row>
+ <entry>Calendar</entry>
+ <entry>Calendar application</entry>
+ <entry>Office</entry>
+
+ </row><row>
+ <entry>ContactManagement</entry>
+ <entry>E.g. an address book</entry>
+ <entry>Office</entry>
+
+ </row><row>
+ <entry>Database</entry>
+ <entry>Application to manage a database</entry>
+ <entry>Office or Development or AudioVideo</entry>
+
+ </row><row>
+ <entry>Dictionary</entry>
+ <entry>A dictionary</entry>
+ <entry>Office;TextTools</entry>
+
+ </row><row>
+ <entry>Chart</entry>
+ <entry>Chart application</entry>
+ <entry>Office</entry>
+
+ </row><row>
+ <entry>Email</entry>
+ <entry>Email application</entry>
+ <entry>Office;Network</entry>
+
+ </row><row>
+ <entry>Finance</entry>
+ <entry>Application to manage your finance</entry>
+ <entry>Office</entry>
+
+ </row><row>
+ <entry>FlowChart</entry>
+ <entry>A flowchart application</entry>
+ <entry>Office</entry>
+
+ </row><row>
+ <entry>PDA</entry>
+ <entry>Tool to manage your PDA</entry>
+ <entry>Office</entry>
+
+ </row><row>
+ <entry>ProjectManagement</entry>
+ <entry>Project management application</entry>
+ <entry>Office;Development</entry>
+
+ </row><row>
+ <entry>Presentation</entry>
+ <entry>Presentation software</entry>
+ <entry>Office</entry>
+
+ </row><row>
+ <entry>Spreadsheet</entry>
+ <entry>A spreadsheet</entry>
+ <entry>Office</entry>
+
+ </row><row>
+ <entry>WordProcessor</entry>
+ <entry>A word processor</entry>
+ <entry>Office</entry>
+
+ </row><row>
+ <entry>2DGraphics</entry>
+ <entry>2D based graphical application</entry>
+ <entry>Graphics</entry>
+
+ </row><row>
+ <entry>VectorGraphics</entry>
+ <entry>Application for viewing, creating, or processing vector graphics</entry>
+ <entry>Graphics;2DGraphics</entry>
+
+ </row><row>
+ <entry>RasterGraphics</entry>
+ <entry>Application for viewing, creating, or processing raster (bitmap) graphics</entry>
+ <entry>Graphics;2DGraphics</entry>
+
+ </row><row>
+ <entry>3DGraphics</entry>
+ <entry>Application for viewing, creating, or processing 3-D graphics</entry>
+ <entry>Graphics</entry>
+
+ </row><row>
+ <entry>Scanning</entry>
+ <entry>Tool to scan a file/text</entry>
+ <entry>Graphics</entry>
+
+ </row><row>
+ <entry>OCR</entry>
+ <entry>Optical character recognition application</entry>
+ <entry>Graphics;Scanning</entry>
+
+ </row><row>
+ <entry>Photography</entry>
+ <entry>Camera tools, etc.</entry>
+ <entry>Graphics or Office</entry>
+
+ </row><row>
+ <entry>Publishing</entry>
+ <entry>Desktop Publishing applications and Color Management tools</entry>
+ <entry>Graphics or Office</entry>
+
+ </row><row>
+ <entry>Viewer</entry>
+ <entry>Tool to view e.g. a graphic or pdf file</entry>
+ <entry>Graphics or Office</entry>
+
+ </row><row>
+ <entry>TextTools</entry>
+ <entry>A text tool utiliy</entry>
+ <entry>Utility</entry>
+
+ </row><row>
+ <entry>DesktopSettings</entry>
+ <entry>Configuration tool for the GUI</entry>
+ <entry>Settings</entry>
+
+ </row><row>
+ <entry>HardwareSettings</entry>
+ <entry>A tool to manage hardware components, like sound cards, video cards or printers</entry>
+ <entry>Settings</entry>
+
+ </row><row>
+ <entry>Printing</entry>
+ <entry>A tool to manage printers</entry>
+ <entry>HardwareSettings;Settings</entry>
+
+ </row><row>
+ <entry>PackageManager</entry>
+ <entry>A package manager application</entry>
+ <entry>Settings</entry>
+
+ </row><row>
+ <entry>Dialup</entry>
+ <entry>A dial-up program</entry>
+ <entry>Network</entry>
+
+ </row><row>
+ <entry>InstantMessaging</entry>
+ <entry>An instant messaging client</entry>
+ <entry>Network</entry>
+
+ </row><row>
+ <entry>Chat</entry>
+ <entry>A chat client</entry>
+ <entry>Network</entry>
+
+ </row><row>
+ <entry>IRCClient</entry>
+ <entry>An IRC client</entry>
+ <entry>Network</entry>
+
+ </row><row>
+ <entry>FileTransfer</entry>
+ <entry>Tools like FTP or P2P programs</entry>
+ <entry>Network</entry>
+
+ </row><row>
+ <entry>HamRadio</entry>
+ <entry>HAM radio software</entry>
+ <entry>Network or Audio</entry>
+
+ </row><row>
+ <entry>News</entry>
+ <entry>A news reader or a news ticker</entry>
+ <entry>Network</entry>
+
+ </row><row>
+ <entry>P2P</entry>
+ <entry>A P2P program</entry>
+ <entry>Network</entry>
+
+ </row><row>
+ <entry>RemoteAccess</entry>
+ <entry>A tool to remotely manage your PC</entry>
+ <entry>Network</entry>
+
+ </row><row>
+ <entry>Telephony</entry>
+ <entry>Telephony via PC</entry>
+ <entry>Network</entry>
+
+ </row><row>
+ <entry>TelephonyTools</entry>
+ <entry>Telephony tools, to dial a number, manage PBX, ...</entry>
+ <entry>Utility</entry>
+
+ </row><row>
+ <entry>VideoConference</entry>
+ <entry>Video Conference software</entry>
+ <entry>Network</entry>
+
+ </row><row>
+ <entry>WebBrowser</entry>
+ <entry>A web browser</entry>
+ <entry>Network</entry>
+
+ </row><row>
+ <entry>WebDevelopment</entry>
+ <entry>A tool for web developers</entry>
+ <entry>Network or Development</entry>
+
+ </row><row>
+ <entry>Midi</entry>
+ <entry>An app related to MIDI</entry>
+ <entry>AudioVideo;Audio</entry>
+
+ </row><row>
+ <entry>Mixer</entry>
+ <entry>Just a mixer</entry>
+ <entry>AudioVideo;Audio</entry>
+
+ </row><row>
+ <entry>Sequencer</entry>
+ <entry>A sequencer</entry>
+ <entry>AudioVideo;Audio</entry>
+
+ </row><row>
+ <entry>Tuner</entry>
+ <entry>A tuner</entry>
+ <entry>AudioVideo;Audio</entry>
+
+ </row><row>
+ <entry>TV</entry>
+ <entry>A TV application</entry>
+ <entry>AudioVideo;Video</entry>
+
+ </row><row>
+ <entry>AudioVideoEditing</entry>
+ <entry>Application to edit audio/video files</entry>
+ <entry>Audio or Video or AudioVideo</entry>
+
+ </row><row>
+ <entry>Player</entry>
+ <entry>Application to play audio/video files</entry>
+ <entry>Audio or Video or AudioVideo</entry>
+
+ </row><row>
+ <entry>Recorder</entry>
+ <entry>Application to record audio/video files</entry>
+ <entry>Audio or Video or AudioVideo</entry>
+
+ </row><row>
+ <entry>DiscBurning</entry>
+ <entry>Application to burn a disc</entry>
+ <entry>AudioVideo</entry>
+
+ </row><row>
+ <entry>ActionGame</entry>
+ <entry>An action game</entry>
+ <entry>Game</entry>
+
+ </row><row>
+ <entry>AdventureGame</entry>
+ <entry>Adventure style game</entry>
+ <entry>Game</entry>
+
+ </row><row>
+ <entry>ArcadeGame</entry>
+ <entry>Arcade style game</entry>
+ <entry>Game</entry>
+
+ </row><row>
+ <entry>BoardGame</entry>
+ <entry>A board game</entry>
+ <entry>Game</entry>
+
+ </row><row>
+ <entry>BlocksGame</entry>
+ <entry>Falling blocks game</entry>
+ <entry>Game</entry>
+
+ </row><row>
+ <entry>CardGame</entry>
+ <entry>A card game</entry>
+ <entry>Game</entry>
+
+ </row><row>
+ <entry>KidsGame</entry>
+ <entry>A game for kids</entry>
+ <entry>Game</entry>
+
+ </row><row>
+ <entry>LogicGame</entry>
+ <entry>Logic games like puzzles, etc</entry>
+ <entry>Game</entry>
+
+ </row><row>
+ <entry>RolePlaying</entry>
+ <entry>A role playing game</entry>
+ <entry>Game</entry>
+
+ </row><row>
+ <entry>Simulation</entry>
+ <entry>A simulation game</entry>
+ <entry>Game</entry>
+
+ </row><row>
+ <entry>SportsGame</entry>
+ <entry>A sports game</entry>
+ <entry>Game</entry>
+
+ </row><row>
+ <entry>StrategyGame</entry>
+ <entry>A strategy game</entry>
+ <entry>Game</entry>
+
+ </row><row>
+ <entry>Art</entry>
+ <entry>Software to teach arts</entry>
+ <entry>Education</entry>
+
+ </row><row>
+ <entry>Construction</entry>
+ <entry></entry>
+ <entry>Education</entry>
+
+ </row><row>
+ <entry>Music</entry>
+ <entry>Musical software</entry>
+ <entry>AudioVideo;Education</entry>
+
+ </row><row>
+ <entry>Languages</entry>
+ <entry>Software to learn foreign languages</entry>
+ <entry>Education</entry>
+
+ </row><row>
+ <entry>Science</entry>
+ <entry>Scientific software</entry>
+ <entry>Education</entry>
+
+ </row><row>
+ <entry>ArtificialIntelligence</entry>
+ <entry>Artificial Intelligence software</entry>
+ <entry>Education;Science</entry>
+
+ </row><row>
+ <entry>Astronomy</entry>
+ <entry>Astronomy software</entry>
+ <entry>Education;Science</entry>
+
+ </row><row>
+ <entry>Biology</entry>
+ <entry>Biology software</entry>
+ <entry>Education;Science</entry>
+
+ </row><row>
+ <entry>Chemistry</entry>
+ <entry>Chemistry software</entry>
+ <entry>Education;Science</entry>
+
+ </row><row>
+ <entry>ComputerScience</entry>
+ <entry>ComputerSience software</entry>
+ <entry>Education;Science</entry>
+
+ </row><row>
+ <entry>DataVisualization</entry>
+ <entry>Data visualization software</entry>
+ <entry>Education;Science</entry>
+
+ </row><row>
+ <entry>Economy</entry>
+ <entry>Economy software</entry>
+ <entry>Education</entry>
+
+ </row><row>
+ <entry>Electricity</entry>
+ <entry>Electricity software</entry>
+ <entry>Education;Science</entry>
+
+ </row><row>
+ <entry>Geography</entry>
+ <entry>Geography software</entry>
+ <entry>Education</entry>
+
+ </row><row>
+ <entry>Geology</entry>
+ <entry>Geology software</entry>
+ <entry>Education;Science</entry>
+
+ </row><row>
+ <entry>Geoscience</entry>
+ <entry>Geoscience software</entry>
+ <entry>Education;Science</entry>
+
+ </row><row>
+ <entry>History</entry>
+ <entry>History software</entry>
+ <entry>Education</entry>
+
+ </row><row>
+ <entry>ImageProcessing</entry>
+ <entry>Image Processing software</entry>
+ <entry>Education;Science</entry>
+
+ </row><row>
+ <entry>Literature</entry>
+ <entry>Literature software</entry>
+ <entry>Education</entry>
+
+ </row><row>
+ <entry>Math</entry>
+ <entry>Math software</entry>
+ <entry>Education;Science</entry>
+
+ </row><row>
+ <entry>NumericalAnalysis</entry>
+ <entry>Numerical analysis software</entry>
+ <entry>Education;Science;Math</entry>
+
+ </row><row>
+ <entry>MedicalSoftware</entry>
+ <entry>Medical software</entry>
+ <entry>Education;Science</entry>
+
+ </row><row>
+ <entry>Physics</entry>
+ <entry>Physics software</entry>
+ <entry>Education;Science</entry>
+
+ </row><row>
+ <entry>Robotics</entry>
+ <entry>Robotics software</entry>
+ <entry>Education;Science</entry>
+
+ </row><row>
+ <entry>Sports</entry>
+ <entry>Sports software</entry>
+ <entry>Education</entry>
+
+ </row><row>
+ <entry>ParallelComputing</entry>
+ <entry>Parallel computing software</entry>
+ <entry>Education;Science;ComputerScience</entry>
+
+ </row><row>
+ <entry>Amusement</entry>
+ <entry>A simple amusement</entry>
+ <entry></entry>
+
+
+ </row><row>
+ <entry>Archiving</entry>
+ <entry>A tool to archive/backup data</entry>
+ <entry>Utility</entry>
+
+ </row><row>
+ <entry>Compression</entry>
+ <entry>A tool to manage compressed data/archives</entry>
+ <entry>Utility;Archiving</entry>
+
+ </row><row>
+ <entry>Electronics</entry>
+ <entry>Electronics software, e.g. a circuit designer</entry>
+ <entry></entry>
+
+ </row><row>
+ <entry>Emulator</entry>
+ <entry>Emulator of another platform, such as a DOS emulator</entry>
+ <entry>System or Game</entry>
+
+ </row><row>
+ <entry>Engineering</entry>
+ <entry>Engineering software, e.g. CAD programs</entry>
+ <entry></entry>
+
+ </row><row>
+ <entry>FileTools</entry>
+ <entry>A file tool utility</entry>
+ <entry>Utility or System</entry>
+
+ </row><row>
+ <entry>FileManager</entry>
+ <entry>A file manager</entry>
+ <entry>System;FileTools</entry>
+
+ </row><row>
+ <entry>TerminalEmulator</entry>
+ <entry>A terminal emulator application</entry>
+ <entry>System</entry>
+
+ </row><row>
+ <entry>Filesystem</entry>
+ <entry>A file system tool</entry>
+ <entry>System</entry>
+
+ </row><row>
+ <entry>Monitor</entry>
+ <entry>Monitor application/applet that monitors some resource or activity</entry>
+ <entry>System</entry>
+
+ </row><row>
+ <entry>Security</entry>
+ <entry>A security tool</entry>
+ <entry>Settings or System</entry>
+
+ </row><row>
+ <entry>Accessibility</entry>
+ <entry>Accessibility</entry>
+ <entry>Settings or Utility</entry>
+
+ </row><row>
+ <entry>Calculator</entry>
+ <entry>A calculator</entry>
+ <entry>Utility</entry>
+
+ </row><row>
+ <entry>Clock</entry>
+ <entry>A clock application/applet</entry>
+ <entry>Utility</entry>
+
+ </row><row>
+ <entry>TextEditor</entry>
+ <entry>A text editor</entry>
+ <entry>Utility</entry>
+
+ </row><row>
+ <entry>Documentation</entry>
+ <entry>Help or documentation</entry>
+ <entry></entry>
+
+ </row><row>
+ <entry>Adult</entry>
+ <entry>Application handles adult or explicit material</entry>
+ <entry></entry>
+
+ </row><row>
+ <entry>Core</entry>
+ <entry>Important application, core to the desktop such as a file manager or a help browser</entry>
+ <entry></entry>
+
+ </row><row>
+ <entry>KDE</entry>
+ <entry>Application based on KDE libraries</entry>
+ <entry>QT</entry>
+
+ </row><row>
+ <entry>GNOME</entry>
+ <entry>Application based on GNOME libraries</entry>
+ <entry>GTK</entry>
+
+ </row><row>
+ <entry>GTK</entry>
+ <entry>Application based on GTK+ libraries</entry>
+ <entry></entry>
+
+ </row><row>
+ <entry>Qt</entry>
+ <entry>Application based on Qt libraries</entry>
+ <entry></entry>
+
+ </row><row>
+ <entry>Motif</entry>
+ <entry>Application based on Motif libraries</entry>
+ <entry></entry>
+
+ </row><row>
+ <entry>Java</entry>
+ <entry>Application based on Java GUI libraries, such as AWT or Swing</entry>
+ <entry></entry>
+
+ </row><row>
+ <entry>ConsoleOnly</entry>
+ <entry>Application that only works inside a terminal (text-based or command line application)</entry>
+ <entry></entry>
+
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ </para>
+ <para>
+ The table below describes Reserved Categories.
+ Reserved Categories have a specific desktop specific meaning
+ that has not been standardized (yet). Desktop entry files that use
+ a reserved category MUST also include an appropriate OnlyShowIn= entry
+ to restrict themselves to those environments that properly support the
+ reserved category as used.
+ <informaltable>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Reserved Category</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>Screensaver</entry>
+ <entry>A screen saver (launching this desktop entry should activate the screen saver)</entry>
+ </row><row>
+ <entry>TrayIcon</entry>
+ <entry>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)</entry>
+ </row><row>
+ <entry>Applet</entry>
+ <entry>An applet that will run inside a panel or another such application, likely desktop specific</entry>
+ </row><row>
+ <entry>Shell</entry>
+ <entry>A shell (an actual specific shell such as
+ <filename>bash</filename> or <filename>tcsh</filename>, not a TerminalEmulator)</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ </para>
+ </appendix>
+ <appendix id="onlyshowin-registry">
+ <title>Registered OnlyShowIn Environments</title>
+ <para>
+ Remember, these are case-sensitive. "KDE" not "kde" should be
+ used.
+ <informaltable>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>OnlyShowIn Value</entry>
+ <entry>Environment</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>GNOME</entry><entry>GNOME Desktop</entry>
+ </row><row>
+ <entry>KDE</entry><entry>KDE Desktop</entry>
+ </row><row>
+ <entry>LXDE</entry><entry>LXDE Desktop</entry>
+ </row><row>
+ <entry>MATE</entry><entry>MATÉ Desktop</entry>
+ </row><row>
+ <entry>Razor</entry><entry>Razor-qt Desktop</entry>
+ </row><row>
+ <entry>ROX</entry><entry>ROX Desktop</entry>
+ </row><row>
+ <entry>Unity</entry><entry>Unity Shell</entry>
+ </row><row>
+ <entry>XFCE</entry><entry>XFCE Desktop</entry>
+ </row><row>
+ <entry>Old</entry><entry>Legacy menu systems</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </para>
+ </appendix>
+ <appendix id="third-party-howto">
+ <title>Integrating your application in the menus</title>
+ <sect1 id="adding-items">
+ <title>Adding menu items</title>
+ <para>
+ The following steps describe how a third party application can add
+ menu items to the menu system:
+ <itemizedlist>
+ <listitem>
+ <para>
+ Install desktop entries to
+ <replaceable>datadir</replaceable>/applications/ for each menu
+ item. Please namespace the filename, as in "vendor-foo.desktop", or
+ use a subdirectory of
+ <replaceable>datadir</replaceable>/applications/ so you have
+ "vendor/foo.desktop." Please be sure all desktop entries are valid
+ (see the <ulink
+ url="http://www.freedesktop.org/software/desktop-file-utils/">
+ desktop-file-utils</ulink> package for a validation utility).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Install an XML menu file to <replaceable>sysconfdir</replaceable>/menus/applications-merged/ to add any submenus, if your desktop entries aren't already
+ included in some common categories.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Install any directory entries needed for your submenus to <replaceable>datadir</replaceable>/desktop-directories/, taking care to namespace and validate
+ the directory entries.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ </sect1>
+ <sect1 id="locations">
+ <title>Install Locations</title>
+ <para>
+ If an application is intended to be installed by root on a system wide
+ basis then /usr/share is recommended to be used as value for
+ <replaceable>datadir</replaceable> and /etc/xdg is recommended to be
+ used as value for <replaceable>sysconfdir</replaceable>.
+ In case the /usr/share hierarchy is not writable it is recommended to
+ use /usr/local/share as value for <replaceable>datadir</replaceable>
+ instead.
+ </para>
+ <para>
+ If an application is intended to be installed by an unprivileged user
+ for exclusive use by that user only then
+ <varname>$XDG_DATA_HOME</varname> should be used as value
+ for <replaceable>datadir</replaceable> and
+ <varname>$XDG_CONFIG_HOME</varname> should be used as value
+ for <replaceable>sysconfdir</replaceable>.
+ If <varname>$XDG_DATA_HOME</varname> is not set, the default value of
+ $HOME/.local/share should be used for it.
+ If <varname>$XDG_CONFIG_HOME</varname> is not set, the default value of
+ $HOME/.config should be used for it.
+ </para>
+ </sect1>
+ <sect1 id="menu-add-example">
+ <title>Example</title>
+ <para>
+ The company ShinyThings Inc. has developed an application named
+ <emphasis>WebMirror 1.0</emphasis> and would like to add its own
+ submenu to the system menus consisting of a <emphasis>WebMirror</emphasis>
+ menu item and a <emphasis>WebMirror Admin Tool</emphasis>
+ menu item. The company will use "shinythings" as its vendor id.
+ For the purpose of this example all menu items will be available
+ in two languages, English and Dutch.
+ The language code for Dutch is <emphasis>nl</emphasis>.
+ </para>
+ <para>
+ First the company needs to create two .desktop files that describe
+ the two menu items:
+ <informalexample>
+ <programlisting>
+ <replaceable>datadir</replaceable>/applications/shinythings-webmirror.desktop:
+
+ [Desktop Entry]
+ Encoding=UTF-8
+ Type=Application
+
+ Exec=webmirror
+ Icon=webmirror
+
+ Name=WebMirror
+ Name[nl]=WebSpiegel
+ </programlisting>
+ </informalexample>
+ and
+ <informalexample>
+ <programlisting>
+ <replaceable>datadir</replaceable>/applications/shinythings-webmirror-admin.desktop:
+
+ [Desktop Entry]
+ Encoding=UTF-8
+ Type=Application
+
+ Exec=webmirror-admintool
+ Icon=webmirror-admintool
+
+ Name=WebMirror Admin Tool
+ Name[nl]=WebSpiegel Administratie Tool
+ </programlisting>
+ </informalexample>
+ A .directory file needs to be installed to provide a title and icon
+ for the sub-menu itself:
+ <informalexample>
+ <programlisting>
+ <replaceable>datadir</replaceable>/desktop-directories/shinythings-webmirror.directory:
+
+ [Desktop Entry]
+ Encoding=UTF-8
+
+ Icon=webmirror
+
+ Name=WebMirror
+ Name[nl]=WebSpiegel
+ </programlisting>
+ </informalexample>
+ And finally, a .menu file needs to be provided that links it all
+ togther:
+ <informalexample>
+ <programlisting>
+ <replaceable>sysconfdir</replaceable>/menus/application-merged/shinythings-webmirror.menu:
+
+ &lt;!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu &dtd-version;//EN"
+ "http://www.freedesktop.org/standards/menu-spec/menu-&dtd-version;.dtd"&gt;
+ &lt;Menu&gt;
+ &lt;Name&gt;Applications&lt;/Name&gt;
+ &lt;Menu&gt;
+ &lt;Name&gt;WebMirror&lt;/Name&gt;
+ &lt;Directory&gt;shinythings-webmirror.directory&lt;/Directory&gt;
+ &lt;Include&gt;
+ &lt;Filename&gt;shinythings-webmirror.desktop&lt;/Filename&gt;
+ &lt;Filename&gt;shinythings-webmirror-admin.desktop&lt;/Filename&gt;
+ &lt;/Include&gt;
+ &lt;/Menu&gt;
+ </programlisting>
+ </informalexample>
+
+ </para>
+ </sect1>
+ <sect1 id="compatibility">
+ <title>Backward Compatibility</title>
+ <para>
+ For a limited time, installing a directory hierarchy to
+ the old GNOME/KDE specific locations such as /usr/share/applnk and
+ /usr/share/gnome/apps will continue to work as way to add your
+ application to the menu system as well. There are two ways to support
+ both the old and new menu systems at the same time:
+ <itemizedlist>
+ <listitem>
+ <para>
+ If you add a <varname>Categories</varname> 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 <varname>Categories</varname> 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.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ If you add the line <literal>OnlyShowIn=Old;</literal> to a desktop
+ entry, then old legacy implementations that ignore
+ <varname>OnlyShowIn</varname> will still show the desktop entry, but
+ implementations of this specification will not. Thus you can
+ add an "<literal>OnlyShowIn=Old;</literal>" entry to the legacy
+ hierarchy, and a new-style desktop entry to
+ <replaceable>datadir</replaceable>/applications/, and still get
+ only one entry in the menus.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ </sect1>
+ </appendix>
+ <appendix id="implementation-notes">
+ <title>Implementation notes</title>
+ <sect1 id="menu-editing">
+ <title>Menu editing</title>
+ <para>
+ To implement menu editing, the intent is that a per-user file is
+ created. The per-user file should specify a &lt;MergeFile&gt; with the
+ system wide file, so that system changes are inherited. When the user
+ deletes a menu item, you add
+ <literal>&lt;Exclude&gt;&lt;Filename&gt;foo.desktop&lt;/Filename&gt;&lt;/Exclude&gt;</literal>. If
+ the user adds a menu item, you use
+ <literal>&lt;Include&gt;&lt;Filename&gt;foo.desktop&lt;/Filename&gt;&lt;/Include&gt;</literal>.
+ </para>
+ <para>
+ If the user moves a folder you can use &lt;Move&gt; elements
+ to represent the move. &lt;Move&gt; elements used for menu-editing
+ should always be added to the most top-level menu to ensure that moves
+ are performed in the order in which they are specified; moves specified
+ in child menus are always performed before moves specified in a more
+ top level menu regardless of their location in the menu file.
+ </para>
+ <para>
+ To delete a folder, simply append the &lt;Deleted&gt; element.
+ </para>
+ <para>
+ When adding a new folder or moving an existing folder, menu editing
+ implementations are advised not to re-use the menu path of a previously
+ deleted folder.
+ </para>
+ <para>
+ Menu editors probably need to do some kind of consolidation/compression
+ to avoid an XML tree that grows infinitely over time.
+ </para>
+ </sect1>
+ </appendix>
+ <glossary><title>Glossary</title>
+ <para>
+ This glossary defines some of the terms used in this specification.
+ </para>
+
+ <glossentry id="term-desktop-entry"><glossterm>Desktop entry</glossterm>
+ <glossdef>
+ <para>
+ A desktop entry is a file with a name ending in the ".desktop"
+ extension which conforms to the <ulink
+ url="http://www.freedesktop.org/Standards/desktop-entry-spec">desktop
+ entry specification</ulink> with <literal>Type=Application</literal>.
+ 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."
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="term-desktop-file-id"><glossterm>Desktop-File Id</glossterm>
+ <glossdef>
+ <para>
+ The id to identify a desktop entry with.
+ For example, if <filename>/usr/share/applications</filename> is
+ specified as an &lt;AppDir&gt;, and <filename>/opt/ude</filename>
+ as &lt;LegacyDir prefix="foo-"&gt;
+ then
+ <filename>/usr/share/applications/foo/bar.desktop</filename>,
+ <filename>/usr/share/applications/foo-bar.desktop</filename>
+ and
+ <filename>/opt/ude/Settings/bar.desktop</filename> all have
+ the same desktop-file id <literal>foo-bar.desktop</literal>
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="term-directory-entry"><glossterm>Directory entry</glossterm>
+ <glossdef>
+ <para>
+ A directory entry is a file with a name ending in the ".directory"
+ extension which conforms to the <ulink
+ url="http://www.freedesktop.org/Standards/desktop-entry-spec">desktop
+ entry specification</ulink> with <literal>Type=Directory</literal>.
+ It provides a localized name and an icon for a submenu.
+ Directory entries are also known as ".directory files."
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="term-menu-path"><glossterm>Menu path</glossterm>
+ <glossdef>
+ <para>
+ 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 &lt;Name&gt; of each parent
+ of the menu, followed by the &lt;Name&gt; of the menu itself.
+ For example, "Foo/Bar/Baz" is a valid menu path.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="term-relative-path"><glossterm>Relative path</glossterm>
+ <glossdef>
+ <para>
+ The canonical path to a directory entry, relative to the
+ &lt;DirectoryDir&gt; containing the
+ entry. For example, if <filename>/usr/share/desktop-directories</filename> is
+ specified as an &lt;DirectoryDir&gt;, the relative path to
+ <filename>/usr/share/desktop-directories/foo/bar.directory</filename> is
+ <filename>foo/bar.directory</filename>.
+ </para>
+ </glossdef>
+ </glossentry>
+ </glossary>
+</article>
+