Integrating an Application into a Gnome Environment

From LSDevLinux
Jump to: navigation, search

Intro

After creating your application, there are 3 procedures involved in integrating it with the rest of the GNOME environment so that it runs like all other applications on your computer.

  1. The application must be able to run by typing its name in the command line, no matter where it is written. In this case, we want to be able to type "proggy" and have it run. Also, it is good to have extra features, such as being able to type "proggy document.prog" to open a specific document, or "proggy --help" to get help for proggy instead of running the program.
  2. The application should be available in the Applications menu in the appropriate sub-category, complete with icon and description. Also, when typing its name in the Run Application dialog, it should be a recognized program. In our case, we want the user to be able to click Applications -> Office -> Proggy.
  3. Finally, you want to associate all files that your program is able to open with the program itself. So, in our case, we would like double-clicking on any ".prog" file to open up proggy with that file.

Adding the command to the command line

The biggest hurdle with this procedure is that the program must be able to find all external files relative to the assembly, not to the directory in which the user types the command. For example, if the program uses a file called images/dog.png, and the program is called "proggy" running from /home/me/program/, then proggy must get the file /home/me/program/images/dog.png. However, if the program is not set up to do this properly, then the program will try and look in the directory in which the program was called. So for example, one might type this and get the following error:

/home/me $ cd somewhere/overtherainbow
/home/me/somewhere/overtherainbow $ proggy
Error: Cannot find "/home/me/somewhere/overtherainbow/images/dog.png"

If the particular language is C#, there would need to be code similar to the following:

string location = System.Reflection.Assembly.GetExecutingAssembly().CodeBase;

Which would set location to "file:///home/me/program/proggy.exe". Then removing the "file://" part and the "proggy.exe" part, one obtains the absolute directory. Appending "/images/dog.png" would return "/home/me/program/images/dog.png", which is what we are looking for.

After assuring that the program was ready to handle the right paths, we should write a script for the program. This script would go into a directory in the user's $PATH so that it could be run from anywhere. It looks something like this (saved as proggy in /usr/local/bin/):

#!/bin/bash
DIR=~/program
EXE="$DIR/proggy.exe"
help="--help"
for arg in "$@"; do
   case "x$arg" in
   	"x$help")
       HELP="$arg"
       ;;
   esac
done
if [ -n "$HELP" ]; then
     echo "** Help! **"
else
     mono $EXE "$@"
fi

Now, one should be able to type proggy anywhere, and the program will run. If one types proggy --help, it will not run the program, and instead print out helpful text. Finally, because of the "$@" after $EXE, it will pass all other arguments to the program itself, assuming there are any.

Although this example handles the "--help" argument, it is common practice to send the argument to the program itself, in this case "proggy.exe". Proggy would then be in charge of outputting some helpful text to the console, and then immediately quitting.

Adding an Entry to the Applications and Run menus.

In order to add the program to the menus, one must do a few things. First, create an icon for the application, and place it in the /usr/share/pixmaps directory. It can be of just about any file type (png, ico, xpm, svg), though SVG is recommended because it can scale to any size without loss of quality. So, let's say the icon file is proggy.svg.

Next, one must create a .desktop file, which looks something like this:

[Desktop Entry]
Version=1.0
Encoding=UTF-8
Name=Proggy
Comment=Do fun things with this program!
Exec=proggy %F
Icon=proggy
Terminal=false
Type=Application
Categories=GNOME;GTK;Office;Proggy
MimeType=application/x-proggy;

The first 3 lines are a given.

"Name" is the actual name of the program that will be displayed to the user.

"Comment" is what it describes as both the pop-up tooltip, and as a description in the run dialog.

"Exec" is what the program will execute when run. The "%F" means that it can take multiple files as arguments.

"Icon" is the name of the icon to use, which is put into the /usr/share/pixmaps directory. Notice there is no filetype specified.

"Terminal=false" because we don't need a terminal for this one.

"Type" needs to be "Application".

"Categories" tells it where it goes it the application menu. The entry begins with "GNOME;GTK;" and is followed by the sub-category we want it to be in (eg. "Office", "Games") and then the name of the menu entry, separated by semicolons.

"MimeType" says what kind of files this program is able to run. If you need to make a new file type, you can name this whatever you want. We recommend following the "application/x-<type>" convention.

Save the file as proggy.desktop and put it into /usr/share/applications.

And magically, everything should work!!!

Associating files with the program

Running the "file" program on a demo.prog file, would give you the following:

$ file demo.prog
demo.prog: XML

So, it sees the demo.prog file as an XML file, which it is. However, we don't want proggy to open every XML file there is, so we have to define it as a type. To do so, we create a file like so:

<?xml version="1.0"?>
<mime-info xmlns='http://www.freedesktop.org/standards/shared-mime-info'>
 <mime-type type="application/x-proggy">
   <comment>Proggy File</comment>
   <glob pattern="*.prog"/>    
 </mime-type>
</mime-info>

The first 2 and last 2 lines are a given.

<mime-type type="foo"> - Specifies the name for the new file type. This MUST be the same as the "MimeType" we specified in our .desktop file. In this case, we want it to be application/x-proggy, to follow convention.

<comment> - Tells us the user-displayed name of the filetype.

<glob pattern="foo"> This indicates the kind of files that this mime should be applied to.

In this case, we want all files that end with .prog, so we put *.prog (the * is a wildcard, meaning it could be anything .prog).

Save this file as foo.xml (ex. proggy.xml) and put it in /usr/share/mime/packages/.

Then, update the database with the following command:

$ sudo update-mime-database /usr/share/mime

To assure that it is working, create a file using the filetype (ex. "sum.prog") and check its filetype with the following:

$ xdg-mime query filetype sum.prog
application/x-proggy

Now we have a mimetype to work with, so we just have to register the right program to it. To do so, I type the following (replacing words where necessary):

$ sudo desktop-file-install --rebuild-mime-info-cache /usr/share/applications/proggy.desktop

This associates all application/x-proggy mimetyped files with proggy.desktop.

After that, double-clicking on .prog files opens up proggy.

Finally, we want an icon for those documents. To do so, create an icon, and call it foo-baz-bar.svg, where hyphens replace slashes in the filetype. So application/x-proggy would be saved as application-x-proggy.svg.

Then, place it in /usr/share/icons/gnome/scalable/mimetypes and /usr/share/icons/hicolor/scalable/mimetypes.

TADA!

Removing the program and associates

This is simply a matter of removing the files that we've added:

/usr/bin/proggy
/usr/share/applications/proggy.desktop
/usr/share/mime/packages/proggy.xml
/usr/share/icons/gnome/scalable/mimetypes/application-x-proggy.svg
/usr/share/icons/hicolor/scalable/mimetypes/application-x-proggy.svg

Then, run

$ sudo update-mime-database /usr/share/mime