Moving to Portland: Simplifying Linux Desktop Development

The Portland Project is a joint Open Source Development Labs and Freedesktop.org initiative to provide independent software developers with stable application programming interfaces that span the many flavors of desktop Linux and other free desktop platforms.

The Portland Project is a joint Open Source Development Labs and Freedesktop.org initiative to provide independent software developers with stable application programming interfaces that span the many flavors of desktop Linux and other free desktop platforms. The first Portland product is Xdg-utils, a set of free, open source tools that allow applications to easily integrate with any desktop environment.

Xdg-utils is aimed at software developers who want to provide packaged software directly to end-users. Until now, integrating such software with the many different Linux distributions and desktop environments was a considerable amount of work. Xdg-utils makes delivering software easier. Describe your application once and install anywhere.

Xdg-utils is a set of command-line tools to help integrate applications with a Linux desktop. About half of the tools in the Xdg-utils suite facilitate common tasks commonly performed during the installation of a desktop application. The other half of the suite better integrates the running application with the desktop environment at-large.

Four tools simplify installs and to make installs work across a gamut of desktop environments (such as KDE and GNOME).

  • xdg-desktop-menu installs desktop menu items.
  • xdg-desktop-icon installs icons to the desktop.
  • xdg-icon-resource can be used to install icon resources.
  • xdg-mime determines how to handle file types and is able to add descriptions for new file types.

To improve and unify runtime integration with the desktop environment, Xdg-utils includes three utilities.

  • xdg-open opens a file or URL in the user’s preferred application.
  • xdg-email sends email via the user’s preferred email composer.
  • xdg-screensaver controls the desktop’s screensaver.

A complete version of Xdg-utils, including documentation and a test suite, is available from the Portland Project Web site. A stripped-down version, consisting only of the tools and manual pages, is available here. The latter version, which is less than 100 KB in size, is useful if you want or need to include the tools along with your application. Xdg-utils is provided under the MIT license, which allows you to freely (in spirit and expense) include the code in or along with proprietary and commercial software.

The Tools in Practice

Let’s take a look how Xdg-utils is used in practice. Imagine that you work for the ACME Corporation, purveyors of rockets, catapults, and magnetic bird feed, and that the corporation is now offering a new application, the ACME PDF Document Viewer. To reduce the cost of development of the Viewer, ACME based its implementation on the well-known xpdf viewer. The Viewer is shipped as an RPM package, and is installed by default to /opt/ACME/xpdf. To encourage use, the installer places an entry in the appropriate desktop “Start” menu, and adds a context-menu item for PDF files.

To accomplish this task among many desktops, Xdg-utils separates task from mechanism. A neutral-format .desktop file describes what must be done. Tools specific to each desktop interpret the .desktop file and realize its requirements.

A .desktop file is a simple text file with groups of (key, value) pairs of the form Key=Value. A header — text contained in square brackets — marks the start of each group. All .desktop files must have a “Desktop Entry” group with a type of Application.

[Desktop Entry]
Type=Application

Additionally, the .desktop file contains the name of the application as it should appear to the end-user:

Name=ACME PDF Document Viewer

It’s also possible to provide the name of the application in a number of languages by providing multiple Name keys, each with a unique, two-character language code as a suffix. So, to add the name of the Viewer in Italian, ACME Visualizzatore documenti PDF, you’d write:

Name[it]=ACME Visualizzatore documenti PDF

The Exec key contains the most important information: the command-line needed to start the application. If the application can open documents, use the %f placeholder to indicate where the document file name should be inserted. Or if the application is able to handle URLs, %u can be used instead of C<%f>. Similarly, analogs %F and %U can be used if the application can open multiple files or URLs at once, respectively.

Since the ACME Viewer displays PDF documents, %f is appropriate for the Exec key.

Exec=/opt/ACME/xpdf/bin/xpdf -q %f

An application can be added to the “Start” menu using two different techniques: it can be placed topically according to keywords, or it can create an individual, application-specific sub-menu. For the former technique, you provide category keywords that describe the application, and the desktop environment chooses the sub-menu associated with similarly-tagged programs. The other technique allows you to create a new sub-menu exclusively for the application.

To continue this example, let’s use category keywords. To ensure that the application shows up in the menu at all, you must specify at least one of the main category keywords. Table One lists the available choices.

Since this is a PDF viewer, the top-level Graphics category is apropos. In addition to a primary keyword, you can also provide additional category keywords to further describe the application. Here, let’s use Motif, VectorGraphics, and Viewer. The result is the following line:

Categories=Motif;Graphics;VectorGraphics;Viewer;

Another important attribute is StartupNotify. If your application doesn’t support startup notifications, set the attribute to false.

StartupNotify=false

The xdg-desktop man page contains a brief overview of the .desktop file format. The full specification for the format can be found here.

TABLE ONE: The main categories for desktop applications

Main Category Description Notes
AudioVideo A multimedia (audio/video) application
Audio An audio application Desktop entry must include AudioVideo as well
Video A video application Desktop entry must include AudioVideo as well
Development An application for software development
Education Educational software
Game A game
Graphics Display graphics
Network A network application such as a Web browser
Office An office suite application
Settings Settings applications Entries may appear in a separate menu or as part of a “Control Center”
System System application System tools, such as say a log viewer or network monitor
Utility Small utility application Accessories

Once the .desktop file is complete, name it uniquely so it doesn’t interfere with applications from other vendors. For example, you might Preface the filename with ACME-. The newly-minted ACME-xpdf.desktop file now looks like *Listing One.

LISTING ONE: Specifying a menu entry for the abstracted Linux desktop

[Desktop Entry]
Type=Application
Name=ACME PDF Document Viewer
Name[de]=ACME PDF Dokumentenbetrachter
Name[es]=ACME Visor de documentos PDF
Name[fr]=ACME Visionneur de documents PDF
Name[it]=ACME Visualizzatore documenti PDF
Name[ru]=ACME ________ PDF __________
Exec=/opt/ACME/xpdf/bin/xpdf -q %f
Categories=Motif;Graphics;VectorGraphics;Viewer;

During the RPM install, ACME-xpdf.desktop is copied to the /opt/ACME/xpdf/desktop/ directory. Now, all that’s left to do is run xdg-desktop-menu in the “post-installation” hook of the RPM. xdg-desktop-menu registers the .desktop file with the menu system. Here’s the snippet from the RPM specification for the ACME Viewer, xpdf.spec.

%post
xdg-desktop-menu install /opt/ACME/xpdf/desktop/ACME-xpdf.desktop

The preceding steps places the ACME Viewer in the proper menu on systems that already have xdg-utils installed. On older systems, you must include xdg-utils along with the application. Again, using RPM, a copy of xdg-desktop-menu is installed to /opt/ACME/xpdf/desktop/scripts/xdg-desktop-menu — if the distribution doesn’t already provide the software. To prefer a version that’s already installed, add the “ACME” xdg-desktop-menu as the last entry in the PATH. The xpdf.spec should look like this:

%post
PATH=$PATH:/opt/ACME/xpdf/desktop/scripts
xdg-desktop-menu install /opt/ACME/xpdf/desktop/ACME-xpdf.desktop

With this slight addition, a new menu entry is handily created on both old and new systems. The final result is shown in Figure One.

FIGURE ONE: The desktop’s “Graphics” submenu extended with the new ACME Viewer

Figure One

Icons, Icons!

To make the ACME Viewer stand out a little more, let’s add an icon to the menu entry. To do that, you must specify the name of an icon resource in the ACME-xpdf.desktop file and install the icon resource, typically in the form of one or more PNG files of varying sizes. (Because a heavily-scaled icon doesn’t always look nice, it’s a good idea to provide icon resources in a few different sizes.) For a menu entry, it’s helpful to provide PNG images in 22×22, 32×32, and 64×64 formats (as measured in pixels).

The PNG files are added to the RPM package as /opt/ACME/xpdf/desktop/ACME-xpdf-22.png, É/ACME-xpdf-32.png, and É/ACME-xpdf-64.png, respectively, and the ACME-xpdf.desktop and xpdf.spec files are extended to register the icons post-install.

Add this line to the .desktop file:

Icon=ACME-xpdf

Next, add instructions to xpdf.spec to register the PNGs as the resources for the icon. The specifics are shown in Listing Two.

LISTING TWO: Additions to an RPM package to register icons

%post
PATH=$PATH:/opt/ACME/xpdf/desktop/scripts
xdg-desktop-menu install /opt/ACME/xpdf/desktop/ACME-xpdf.desktop
xdg-icon-resource install --size 22 /opt/ACME/xpdf/desktop/ACME-xpdf-22.png ACME-xpdf
xdg-icon-resource install --size 32 /opt/ACME/xpdf/desktop/ACME-xpdf-32.png ACME-xpdf
xdg-icon-resource install --size 64 /opt/ACME/xpdf/desktop/ACME-xpdf-64.png ACME-xpdf

At this point, installation is complete — but to keep things nice and tidy, you also must make sure to unregister the resources during uninstallation. You can do that in a “pre-uninstallation” hook in xpdf.spec.

%preun
PATH=$PATH:/opt/ACME/xpdf/desktop/scripts
xdg-icon-resource uninstall --size 22 ACME-xpdf
xdg-icon-resource uninstall --size 32 ACME-xpdf
xdg-icon-resource uninstall --size 64 ACME-xpdf
xdg-desktop-menu uninstall /opt/ACME/xpdf/desktop/ACME-xpdf.desktop

(Don’t use the “post-uninstallation” hook of RPM for this, because at that point, xdg-utils has been deleted.)

Extending the Context Menu

Since the ACME PDF Viewer’s main purpose in life is to show PDF files, it’d be nice if PDF files would offer the option to view the file in the ACME PDF Viewer. To do this, you must define what “PDF files” exactly are, and tell the system that the application is able to handle these files.

The Linux desktop identifies files based on MIME type. For the purpose of this example, let’s define a MIME type for PDF files. (In the case of PDF files, this is normally not necessary, since Linux desktop systems already know about the file type.) To define a new file type, create an XML file similar to Listing Three.

LISTING THREE: How to define a MIME type for the Linux desktop

ACME-xpdf.xml:
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info"&gt;
  &lt;mime-type type="application/pdf"&gt;
    &lt;comment&gt;PDF document&lt;/comment&gt;
    &lt;comment xml:lang="de"&gt;PDF-Dokument&lt;/comment&gt;
    &lt;comment xml:lang="es"&gt;Documento PDF&lt;/comment&gt;
    &lt;comment xml:lang="fr"&gt;document PDF&lt;/comment&gt;
    &lt;comment xml:lang="it"&gt;Documento PDF&lt;/comment&gt;
    &lt;comment xml:lang="ru"&gt;________ PDF&lt;/comment&gt;
    &lt;glob pattern="*.pdf"/&gt;
  &lt;/mime-type&gt;
&lt;/mime-info&gt;

The XML file, call it ACME-xpdf.xml, tells the system that files with a .pdf extension are MIME type application/pdf. The file also provides a human-readable description of the file type in several languages. An overview of the format is explained in the xdg-mime man page. A full specification of the format can be found here.

Next, register the ACME-xpdf.xml file with the system in the RPM post-install hook:

xdg-menu install /opt/ACME/xpdf/desktop/ACME-xpdf.xml

And, of course, don’t forget to un-register the MIME type in the RPM “pre-uninstall” hook in xpdf.spec:

xdg-menu uninstall /opt/ACME/xpdf/desktop/ACME-xpdf.xml

The final version of xpdf.spec is shown in Listing Four.

LISTING FOUR: The RPM description file combining Xdg-utils and RPM

Summary:    PDF viewer
Name:       ACME-xpdf
Version:    3.00
Release:    1
License:    GPL
Group:      Applications/Publishing
Source: ACME-xpdf-3.00.tar.gz
BuildRoot:  /var/tmp/%{name}-buildroot

%description
ACME-xpdf allows you to view PDF files.

%prep
%setup -q

%build
./configure --prefix=$RPM_BUILD_ROOT/opt/ACME/xpdf --with-freetype2-includes=/usr/include/freetype2/
make

%install
make install

%clean
rm -rf $RPM_BUILD_ROOT

%files
%defattr(-,root,root)

/opt/ACME/xpdf/bin/xpdf
/opt/ACME/xpdf/etc/xpdfrc

/opt/ACME/xpdf/desktop/scripts/xdg-mime
/opt/ACME/xpdf/desktop/scripts/xdg-desktop-menu
/opt/ACME/xpdf/desktop/scripts/xdg-icon-resource
/opt/ACME/xpdf/desktop/ACME-xpdf.xml
/opt/ACME/xpdf/desktop/ACME-xpdf.desktop
/opt/ACME/xpdf/desktop/ACME-xpdf-22.png
/opt/ACME/xpdf/desktop/ACME-xpdf-32.png
/opt/ACME/xpdf/desktop/ACME-xpdf-64.png

%post
PATH=$PATH:/opt/ACME/xpdf/desktop/scripts
xdg-mime install /opt/ACME/xpdf/desktop/ACME-xpdf.xml
xdg-desktop-menu install /opt/ACME/xpdf/desktop/ACME-xpdf.desktop
xdg-icon-resource install --size 22 /opt/ACME/xpdf/desktop/ACME-xpdf-22.png ACME-xpdf
xdg-icon-resource install --size 32 /opt/ACME/xpdf/desktop/ACME-xpdf-32.png ACME-xpdf
xdg-icon-resource install --size 64 /opt/ACME/xpdf/desktop/ACME-xpdf-64.png ACME-xpdf

%preun
PATH=$PATH:/opt/ACME/xpdf/desktop/scripts
xdg-icon-resource uninstall --size 22 ACME-xpdf
xdg-icon-resource uninstall --size 32 ACME-xpdf
xdg-icon-resource uninstall --size 64 ACME-xpdf
xdg-desktop-menu uninstall /opt/ACME/xpdf/desktop/ACME-xpdf.desktop
xdg-mime uninstall /opt/ACME/xpdf/desktop/ACME-xpdf.xml

Finally, tell the system that Viewer supports application/pdf. Add the following line to the ACME-xpdf.desktop file:

MimeType=application/pdf;

Make sure to use the right capitalization, otherwise it won’t work. Listing Five shows the entire xpdf.desktop file. Figure Two shows the context menu in place.

FIGURE TWO: The context menu for PDF files now includes the Viewer
Figure Two

LISTING FIVE: The complete *.desktop file for the sample Viewer*

ACME-xpdf.desktop:
[Desktop Entry]
Type=Application
Name=ACME PDF Document Viewer
Name[de]=ACME PDF Dokumentenbetrachter
Name[es]=ACME Visor de documentos PDF
Name[fr]=ACME Visionneur de documents PDF
Name[it]=ACME Visualizzatore documenti PDF
Name[ru]=ACME ________ PDF __________
Exec=/opt/ACME/xpdf/bin/xpdf -q %f
Icon=ACME-xpdf
Categories=Motif;Graphics;VectorGraphics;Viewer;
MimeType=application/pdf;
StartupNotify=false

Connecting to the Browser

The last step is to integrate the ACME PDF Viewer with the user’s web browser. This step is simple, as the xpdfrc configuration file for the application already has an entry to configure just that. Simply write the entry use xdg-open by default, as shown in Listing Six.

LISTING SIX: Run the *Viewer when the browser downloads a PDF file*

# Set the command used to run a web browser when a URL hyperlink is
# clicked.
urlCommand      "PATH=$PATH:/opt/ACME/xpdf/desktop/scripts xdg-open '%s'"

Again, adding your own version of xdg-open to the end of $PATH gives precedence to a version already installed on the system. Hence, the Viewer application will benefit from system upgrades and potential service packs by the distribution’s vendor.

You can provide feedback on the Portland project through the freedesktop.org bug reporting system, or via the Portland mailing list. Please use the mailing list for any questions.

Fatal error: Call to undefined function aa_author_bios() in /opt/apache/dms/b2b/linux-mag.com/site/www/htdocs/wp-content/themes/linuxmag/single.php on line 62