Tuesday, January 6, 2009

Freedesktop (Gnome, KDE, etc) menu specs and layouts

Ok, so, more explanations later, but when I used to work at Google, I found keeping some notes on a blog really helpful for me when I was working on a project... so one of my current projects is to build a simple point and click launcher for ubuntu applications similar to the old "Launcher" application on Classic Mac OS, but with the ability to show a description for each program, and the ability to display multiple languages simultaneously.

I want to use python / pygtk to accomplish this and want it to require as little maintenance for new programs as possible. Looking at existing menus in Ubuntu (and any distrobution that follows the freedesktop.org specs), all the information we need is already in the existing menu system, but its not straightforward as to where to access the underlying info. After some digging, I found it, so I'm laying it down here for anyone else who wants to solve a similar problem.

I'll take a minute to explain *why* I want to build an app like this because inevitably if anyone is reading this, someone is thinking, "what's wrong with just using the menu system?" I volunteer at a community center on the southside of chicago, and a large part of the demographic we serve are adults who've never touched a computer before, many of whom speak only spanish, and some who have literacy problems. We also have a large youth population who are largely bilingual and a smaller core of volunteers and staff who are either bilingual, english or spanish speakers. To those of us who've been using computers for a long time, a menu system seems very natural, but in our computer classes we often have to teach people how to use a mouse, what a folder is, etc. So, if someone wants to use a computer but cannot attend one of our classes, its very intimidating for them. Having a simple launcher that can display application names with descriptions in multiple languages (in our case, english and spanish, but keeping it fairly easy to allow for any language that the system supports) is the goal, and all the information is here already.

So, the freedesktop.org manu spec is located here: http://standards.freedesktop.org/menu-spec/latest/ this has most of the info we need but is a little verbose. Here's the quick and dirty:

Top level menu definitions are defined here:
$XDG_CONFIG_DIRS
/menus/${XDG_MENU_PREFIX}applications.menu


Where $XDG_CONFIG_DIRS and ${XDG_MENU_PREFIX} are environment variables. On ubuntu, the xdg config dir is /etc/xdg/

So if i look in /etc/xdg/menus on my ubuntu machine, I see:
applications.menu gnome-screensavers.menu settings.menu
applications-merged kde-applications.menu
gnomecc.menu preferences.menu


All we're worried about for now is applications.menu. For the unified menu system on ubuntu, most window managers use this as their main top level menu. This file defines the categories displayed, etc. It's an XML file and if you look at it, its fairly straight forward. We're not going to use it much at the moment, but we'll want to remember it later when we get to traversing the menus with python.

Individual applications are defined in $XDG_DATA_DIRS/applications. On ubuntu, $XDG_DATA_DIRS defaults to:
/usr/local/share/:/usr/share/:/usr/share/gdm/

The majority of our apps in the main applications menu appear to be in /usr/share/applications... you'll see files for each app that's something like firefox.desktop... lets look at that for an example:

[Desktop Entry]
Version=1.0
Name=Firefox Web Browser
Name[ca]=Navegador web Firefox
Name[cs]=Firefox Webový prohlížeč
Name[es]=Navegador web Firefox
Name[fa]=ﻡﺭﻭﺭگﺭ ﺍیﻦﺗﺮﻨﺗی Firefox
Name[fi]=Firefox-selain
Name[fr]=Navigateur Web Firefox
Name[hu]=Firefox webböngésző
Name[it]=Firefox Browser Web
Name[ja]=Firefox ウェブ・ブラウザ
Name[ko]=Firefox 웹 브라우저
Name[nb]=Firefox Nettleser
Name[nl]=Firefox webbrowser
Name[nn]=Firefox Nettlesar
Name[no]=Firefox Nettleser
Name[pl]=Przeglądarka WWW Firefox
Name[pt]=Firefox Navegador Web
Name[pt_BR]=Navegador Web Firefox
Name[sk]=Internetový prehliadač Firefox
Name[sv]=Webbläsaren Firefox
Comment=Browse the World Wide Web
Comment[ca]=Navegueu per el web
Comment[cs]=Prohlížení stránek World Wide Webu
Comment[de]=Im Internet surfen
Comment[es]=Navegue por la web
Comment[fa]=ﺺﻔﺣﺎﺗ ﺶﺑکﻩ ﺞﻫﺎﻧی ﺍیﻦﺗﺮﻨﺗ ﺭﺍ ﻡﺭﻭﺭ ﻦﻣﺍییﺩ
Comment[fi]=Selaa Internetin WWW-sivuja
Comment[fr]=Navigue sur Internet
Comment[hu]=A világháló böngészése
Comment[it]=Esplora il web
Comment[ja]=ウェブを閲覧します
Comment[ko]=웹을 돌아 다닙니다
Comment[nb]=Surf på nettet
Comment[nl]=Verken het internet
Comment[nn]=Surf på nettet
Comment[no]=Surf på nettet
Comment[pl]=Przeglądanie stron WWW
Comment[pt]=Navegue na Internet
Comment[pt_BR]=Navegue na Internet
Comment[sk]=Prehliadanie internetu
Comment[sv]=Surfa på webben
GenericName=Web Browser
GenericName[ca]=Navegador web
GenericName[cs]=Webový prohlížeč
GenericName[es]=Navegador web
GenericName[fa]=ﻡﺭﻭﺭگﺭ ﺍیﻦﺗﺮﻨﺗی
Comment[fi]=Selaa Internetin WWW-sivuja
Comment[fr]=Navigue sur Internet
Comment[hu]=A világháló böngészése
Comment[it]=Esplora il web
Comment[ja]=ウェブを閲覧します
Comment[ko]=웹을 돌아 다닙니다
Comment[nb]=Surf på nettet
Comment[nl]=Verken het internet
Comment[nn]=Surf på nettet
Comment[no]=Surf på nettet
Comment[pl]=Przeglądanie stron WWW
Comment[pt]=Navegue na Internet
Comment[pt_BR]=Navegue na Internet
Comment[sk]=Prehliadanie internetu
Comment[sv]=Surfa på webben
GenericName=Web Browser
GenericName[ca]=Navegador web
GenericName[cs]=Webový prohlížeč
GenericName[es]=Navegador web
GenericName[fa]=ﻡﺭﻭﺭگﺭ ﺍیﻦﺗﺮﻨﺗی
GenericName[fi]=WWW-selain
GenericName[fr]=Navigateur Web
GenericName[hu]=Webböngésző
GenericName[it]=Browser Web
GenericName[ja]=ウェブ・ブラウザ
GenericName[ko]=웹 브라우저
GenericName[nb]=Nettleser
GenericName[nl]=Webbrowser
GenericName[nn]=Nettlesar
GenericName[no]=Nettleser
GenericName[pl]=Przeglądarka WWW
GenericName[pt]=Navegador Web
GenericName[pt_BR]=Navegador Web
GenericName[sk]=Internetový prehliadač
GenericName[sv]=Webbläsare
Exec=firefox %u
Terminal=false
X-MultipleArgs=false
Type=Application
Icon=firefox-3.0
Categories=Application;Network;
MimeType=text/html;text/xml;application/xhtml+xml;application/xml;application/vnd.mozilla.xul+xml;application/rss+xml;application/rdf+xml;image/gif;image/jpeg;image/png;
StartupWMClass=Firefox
StartupNotify=true


Alright, so here we have everything we need for our app... we have the application name and a generic name in multiple languages, the info about the icon and the executeable, and a description or "Comment" in multiple languages that should be descriptive enough for most users. We also have the "Categories" section that shows us what submenu its part of (because we likely don't want to show all applications in our launcher, but may want to limit by submenu, or possibly have tabs for different categories).

Next up: we'll talk about how to traverse this info in python using python-gmenu and figure out how to use multiple languages simultaneously.