diff options
Diffstat (limited to 'menu/menu-spec.xml')
-rw-r--r-- | menu/menu-spec.xml | 2383 |
1 files changed, 2383 insertions, 0 deletions
diff --git a/menu/menu-spec.xml b/menu/menu-spec.xml new file mode 100644 index 0000000..28c0097 --- /dev/null +++ b/menu/menu-spec.xml @@ -0,0 +1,2383 @@ +<!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 + <DefaultMergeDirs> element. By convention, third parties + may add new <Menu> 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 <DefaultMergeDirs> 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 <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. + </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 <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. + </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 & 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> + <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu &dtd-version;//EN" + "http://www.freedesktop.org/standards/menu-spec/menu-&dtd-version;.dtd"> + </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><Menu></term> + <listitem> + <para> + The root element is <Menu>. Each <Menu> element may + contain any number of nested <Menu> elements, indicating submenus. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><AppDir></term> + <listitem> + <para> + 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. + </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 <AppDir> + <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 <AppDir> + <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> + <AppDir> 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 <AppDir> is not an absolute + path, it should be located relative to the location of the menu + file being parsed. + </para> + <para> + Duplicate <AppDir> 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 + <AppDir> elements with respect to <Include> and + <Exclude> elements is not relevant, also to facilitate + merging. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><DefaultAppDirs></term> + <listitem> + <para> + 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 + (<replaceable>datadir</replaceable>/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. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><DirectoryDir></term> + <listitem> + <para> + 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. + </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 <DirectoryDir> elements (that specify the same + directory) are handled as with duplicate <AppDir> + elements (the last duplicate is used). + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><DefaultDirectoryDirs></term> + <listitem> + <para> + 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 + (<replaceable>datadir</replaceable>/desktop-directories/ etc.). The default + locations that are earlier in the search path go later in the + <Menu> so that they have priority. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><Name></term> + <listitem> + <para> + 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 <xref linkend="term-menu-path"/>. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><Directory></term> + <listitem> + <para> + Each <Menu> element has any number of <Directory> + elements. The content of the <Directory> element + is the relative path of a directory entry containing meta information + 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. + </para> + <para> + 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. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><OnlyUnallocated> and <NotOnlyUnallocated></term> + <listitem> + <para> + 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>. + </para> + <para> + 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 as allocated according + to whether it was matched by an <Include> rule 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 marked as allocated during the first pass. + See <xref linkend="query-algorithm"/>. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><Deleted> and <NotDeleted></term> + <listitem> + <para> + 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. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><Include></term> + <listitem> + <para> + 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. + </para> + <para> + <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 <xref linkend="merge-algorithm"/>. + See <xref linkend="query-algorithm"/> for full details on + how to process <Include> and <Exclude> elements. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><Exclude></term> + <listitem> + <para> + 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.) + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><Filename></term> + <listitem> + <para> + 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 <xref linkend="term-desktop-file-id"/>. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><Category></term> + <listitem> + <para> + The <Category> 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><All></term> + <listitem> + <para> + The <All> element is a matching rule that matches + all desktop entries. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><And></term> + <listitem> + <para> + 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. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><Or></term> + <listitem> + <para> + 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. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><Not></term> + <listitem> + <para> + 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 + <emphasis>not</emphasis> match the desktop entry. That is, + matching rules below <Not> have a logical OR relationship. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><MergeFile [type="path"|"parent"] ></term> + <listitem> + <para> + 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. <xref linkend="merge-algorithm"/> + 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. + </para> + <para> + If the type attribute is missing or set to "path" then the + contents of the <MergeFile> 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 <MergeFile> element. + </para> + <para> + Duplicate <MergeFile> elements (that specify the same + file) are handled as with duplicate <AppDir> + elements (the last duplicate is used). + </para> + <para> + If the type attribute is set to "parent" and the file that + contains this <MergeFile> 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 <MergeFile> + 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 <MergeFile> 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 + <MergeFile type="parent">/opt/kde3/etc/xdg/menus/applications.menu</MergeFile> + 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 + <MergeFile type="parent">/opt/kde3/etc/xdg/menus/applications.menu</MergeFile> + then the file /etc/xdg/menus/applications.menu should be merged + if it exists. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><MergeDir></term> + <listitem> + <para> + 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. + </para> + <para> + Duplicate <MergeDir> elements (that specify the same + directory) are handled as with duplicate <AppDir> + elements (the last duplicate is used). + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><DefaultMergeDirs></term> + <listitem> + <para> + 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. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><LegacyDir></term> + <listitem> + <para> + 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 <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 <LegacyDir> is not an absolute path, + it should be located relative to the location of the menu file + being parsed. + </para> + <para> + Duplicate <LegacyDir> elements (that specify the same + directory) are handled as with duplicate <AppDir> + elements (the last duplicate is used). + </para> + <para> + The <LegacyDir> element may have one attribute, + <literal>prefix</literal>. Normally, given a <LegacyDir> + <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><KDELegacyDirs></term> + <listitem> + <para> + 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 <filename>kde-config --path apps</filename> + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><Move></term> + <listitem> + <para> + 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 <xref + linkend="merge-algorithm"/> for details). + </para> + <para> + <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. + </para> + <para> + <Move> is also useful for implementing menu + editing, see <xref linkend="menu-editing"/>. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><Old></term> + <listitem> + <para> + 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 + <xref linkend="term-menu-path"/>). + Paths are interpreted relative to the menu containing + the <Move> element. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><New></term> + <listitem> + <para> + 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. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><Layout></term> + <listitem> + <para> + The <Layout> element is an optional part of this specification. + Implementations that do not support the <Layout> element should + preserve any <Layout> elements and their contents as far as + possible. + Each <Menu> may optionally contain a <Layout> 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 <Layout> element or if it contains + an empty <Layout> element then the default layout should be used. + The <Layout> element may contain <Filename>, <Menuname>, + <Separator> and <Merge> elements. The <Layout> 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 <Include> and <Exclude> elements should + be ignored. References to sub-menus that are not directly contained in this + menu as defined by the <Menu> elements should be ignored. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><DefaultLayout [show_empty="false"] [inline="false"] [inline_limit="4"] [inline_header="true"] [inline_alias="false"]></term> + <listitem> + <para> + The <DefaultLayout> element is an optional part of this specification. + Implementations that do not support the <DefaultLayout> element should + preserve any <DefaultLayout> elements and their contents as far as + possible. + Each <Menu> may optionally contain a <DefaultLayout> element + which defines the default-layout for the current menu and all its sub-menus. + If a menu has a <DefaultLayout> element then this will override + any default-layout specified by a parent menu. + The default-layout defines the suggested layout if a <Menu> element + does either not have <Layout> element or if it has an empty <Layout> element. + For explanations of the various attributes see the <Menuname> element. + If no default-layout has been specified then the layout as specified by the following + elements should be assumed: + <DefaultLayout show_empty="false" inline="false" inline_limit="4" inline_header="true" inline_alias="false"><Merge type="menus"/><Merge type="files"/></DefaultLayout> + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><Menuname [show_empty="..."] [inline="..."] [inline_limit="..."] [inline_header="..."] [inline_alias="..."]></term> + <listitem> + <para> + This element may only appear as a child of a <Layout> or <DefaultLayout> + menu. Its contents references an immediate sub-menu of the current menu as defined + with the <Menu> 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><Separator></term> + <listitem> + <para> + This element may only appear as a child of a <Layout> or <DefaultLayout> + menu. It indicates a suggestion to draw a visual separator at this point in the menu. + <Separator> elements at the start of a menu, at the end of a menu or that directly + follow other <Separator> elements may be ignored. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><Merge type="menus"|"files"|"all"/></term> + <listitem> + <para> + This element may only appear as a child of a <Layout> or <DefaultLayout> + menu. It indicates the point where desktop entries and sub-menus that are not explicitly + mentioned within the <Layout> or <DefaultLayout> 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 <Layout> or <DefaultLayout> element shall have exactly one <Merge type="all"> + element or it shall have exactly one <Merge type="files"> and exactly one + <Merge type="menus"> element. An exception is made for a completely empty <Layout> + 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 <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. + </para> + <para> + 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." + </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 + <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 + <xref linkend="legacy-hierarchies"/>. + </para> + <para> + Continue processing until no <MergeFile>, <MergeDir>, or + <LegacyDir> 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 <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 <emphasis>last</emphasis> menu with that name. + Delete all the newly empty <Menu> elements, keeping the + last one. + </para> + </listitem> + <listitem> + <para> + 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. + </para> + </listitem> + <listitem> + <para> + Recurse into each child <Menu>, 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 <Move> elements for each menu starting with any child + menu before handling the more top level menus. + So the deepest menus have their <Move> operations performed first. + Within each <Menu>, 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. + </para> + <para> + If any <Move> operations affect a menu, then re-run the + steps to resolve duplicates in case any duplicates have been + created. + </para> + <para> + Finally, for each <Menu> containing a <Deleted> element which + is not followed by a <NotDeleted> element, remove that menu and all + its child menus. + </para> + + <para> + 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. + </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 <LegacyDir> 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 <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. + </para> + <para> + 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. + </para> + <para> + 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 and mark it as having been allocated. + For each <Exclude>, 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 <Exclude> is still considered allocated (for the + purposes of <OnlyUnallocated>) 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 <OnlyUnallocated> 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 + <Menu>, and then this menu layout is merged with the menu that + specified <LegacyDir>. + </para> + <para> + 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>. + </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 + <Menu> is created with the same <Name> + as the directory on disk. + </para> + </listitem> + <listitem> + <para> + This menu then contains an <Include> element that includes + each desktop entry in the directory. That is, it should have a + + <Filename><replaceable>Foo/Bar/foo.desktop</replaceable></Filename> + 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 <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. + </para> + </listitem> + <listitem> + <para> + If the legacy directory contains a ".directory" file, then + a <Directory> 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 <LegacyDir> and an <AppDir>, its desktop + entries should be labeled "Legacy" only if the <LegacyDir> + appears later in the file than the <AppDir>.) + </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 <Menu>: + <informalexample> + <programlisting> + <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu &dtd-version;//EN" + "http://www.freedesktop.org/standards/menu-spec/menu-&dtd-version;.dtd"> + + <Menu> + <Name>Applications</Name> + <AppDir>/usr/share/applnk</AppDir> + <DirectoryDir>/usr/share/applnk</DirectoryDir> + <Directory>.directory</Directory> + <Include> + <Filename>bar.desktop</Filename> + </Include> + <Menu> + <Name>System</Name> + <AppDir>/usr/share/applnk/System</AppDir> + <DirectoryDir>/usr/share/applnk/System</DirectoryDir> + <Directory>.directory</Directory> + <Include> + <Filename>foo.desktop</Filename> + </Include> + </Menu> + </Menu> + </programlisting> + </informalexample> + This <Menu> is then merged as if it were in a file + and loaded with <MergeFile>. + </para> + </sect1> + + <sect1 id="example"> + <title>Example Menu File</title> + <para> + <informalexample> + <programlisting> + <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu &dtd-version;//EN" + "http://www.freedesktop.org/standards/menu-spec/menu-&dtd-version;.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> + + <-- Define default layout --> + <DefaultLayout> + <Merge type="menus"/> + <Merge type="files"/> + <Separator/> + <Menuname>More</Menuname> + </DefaultLayout> + + <-- some random moves, maybe to clean up legacy dirs, + maybe from menu editing --> + <Move> + <Old>Foo</Old> + <New>Bar</New> + <Old>Foo2</Old> + <New>Bar2</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> + </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. Additional Categories should always be used in + combination with one of the Main Categories. + </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. Note that at + least one Main Category must be included in the desktop entry's list + of categories. 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>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: + + <!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu &dtd-version;//EN" + "http://www.freedesktop.org/standards/menu-spec/menu-&dtd-version;.dtd"> + <Menu> + <Name>Applications</Name> + <Menu> + <Name>WebMirror</Name> + <Directory>shinythings-webmirror.directory</Directory> + <Include> + <Filename>shinythings-webmirror.desktop</Filename> + <Filename>shinythings-webmirror-admin.desktop</Filename> + </Include> + </Menu> + </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 <MergeFile> with the + system wide file, so that system changes are inherited. When the user + deletes a menu item, you add + <literal><Exclude><Filename>foo.desktop</Filename></Exclude></literal>. If + the user adds a menu item, you use + <literal><Include><Filename>foo.desktop</Filename></Include></literal>. + </para> + <para> + If the user moves a folder you can use <Move> elements + to represent the move. <Move> 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 <Deleted> 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 <AppDir>, and <filename>/opt/ude</filename> + as <LegacyDir prefix="foo-"> + 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 <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. + </para> + </glossdef> + </glossentry> + + <glossentry id="term-relative-path"><glossterm>Relative path</glossterm> + <glossdef> + <para> + The canonical path to a directory entry, relative to the + <DirectoryDir> containing the + entry. For example, if <filename>/usr/share/desktop-directories</filename> is + specified as an <DirectoryDir>, the relative path to + <filename>/usr/share/desktop-directories/foo/bar.directory</filename> is + <filename>foo/bar.directory</filename>. + </para> + </glossdef> + </glossentry> + </glossary> +</article> + |