Archive

Posts Tagged ‘gnome’

Gnome panel applet : Part 1

July 20th, 2009 Danny 6 comments

I was looking at my black gnome panel bar, and taking a look at all those little gadgets hooked on it! And i was wondering, could i make one too? So i looked it up, did some searches, encountered some headaches but well thanks to  a good tutorial i made it. So i thought i could try to pass to you this knowledge i gathered.

Generally, developing a widget / applet for a panel of  the Gnome graphical display manager is a mostly easy process. Such a widget, consists of two elements. It’s .server XML file, where many information about the widget are described. And the actual source code of the widget.

The source code is written in C / C++ or other languages by using the appropriate language bindings.
So, lets see how the “Hello World!” of a Gnome panel widget is like :)

I Will be using C++ ( its just C, but i use C++ in case i want to use string streams or the new operator, just a habbit, stick with C if you prefer. ) for the examples.
First of all, the .server file :

[ helloworld.server ]

[xml]<oaf_info>
<oaf_server iid="OAFIID:HelloWorld_Factory" type="exe"
location="/usr/lib/gnome-panel/helloworld">

<oaf_attribute name="repo_ids" type="stringv">
<item value="IDL:Bonobo/GenericFactory:1.0"/>
<item value="IDL:Bonobo/Unknown:1.0"/>
</oaf_attribute>
<oaf_attribute name="name" type="string" value="Hello World Factory"/>
<oaf_attribute name="description" type="string" value="its my own factory!"/>
</oaf_server>

<oaf_server iid="OAFIID:HelloWorld" type="factory"
location="OAFIID:HelloWorld_Factory">

<oaf_attribute name="repo_ids" type="stringv">
<item value="IDL:GNOME/Vertigo/PanelAppletShell:1.0"/>
<item value="IDL:Bonobo/Control:1.0"/>
<item value="IDL:Bonobo/Unknown:1.0"/>
</oaf_attribute>
<oaf_attribute name="name" type="string" value="Hello World!!"/>
<oaf_attribute name="description" type="string" value="Thats my description!!"/>
<oaf_attribute name="panel:category" type="string" value="Amusements"/>
<oaf_attribute name="panel:icon" type="string" value="myicon.png"/>
</oaf_server>
</oaf_info>
[/xml]

Most of the .server XML code is the same for all apps. Notable lines are :

[xml light="true" wraplines="true"]<oaf_server iid="OAFIID:HelloWorld_Factory" type="exe" location="/usr/lib/gnome-panel/helloworld">[/xml]

Means that the unique IID of our applet will be “HelloWorld_Factory”, the name of the executable file will be named helloworld and located in folder “/usr/lib/gnome-panel”.

[xml light="true" wraplines="true"]<oaf_attribute name="name" type="string" value="Hello World!!"/>
<oaf_attribute name="description" type="string" value="Thats my description!!"/>[/xml]

“Hello World!” will be the name of the applet in the “Add to Panel…” menu and “Just a description…” will be the description of the applet displayed below its name. ( yeah you guessed right :) )

[xml light="true" wraplines="true"]<oaf_attribute name="panel:icon" type="string" value="myicon.png"/>[/xml]

This line specifies that the icon displayed for our applet in the “Add to panel…” menu will be named “myicon.png”. Note that it must be placed inside “/usr/share/pixmaps” directory.

The .server file has to be placed in the folder “/usr/lib/bonobo/servers/” so that Gnome will know which applications to “query” when you want to add a new applet on your panel. Now that we built the “describer” .server file, lets go onto the actual code of the applet :

[ helloworld.cpp ]

[c]
#include <string.h>
#include <panel-applet.h>
#include <gtk/gtklabel.h>

static gboolean
helloworld_applet_create (PanelApplet *applet,
const gchar *iid,
gpointer data)
{
GtkWidget *label;

if (strcmp (iid, "OAFIID:HelloWorld") != 0)
return FALSE;

label = gtk_label_new ("Hello World!!");
gtk_container_add (GTK_CONTAINER (applet), label);
gtk_widget_show_all (GTK_WIDGET (applet));
return TRUE;
}

PANEL_APPLET_BONOBO_FACTORY ("OAFIID:HelloWorld_Factory",
PANEL_TYPE_APPLET,
"The Hello World Applet",
"0",
helloworld_applet_create,
NULL);
[/c]

I am using GTK+ because its a bit more simple to me, but you can use gtkmm without any problem also.
As you can see, we include headers <panel-applet.h> which provides essential functions for the applet creation, and <gtk/gtklabel.h> , since our “Hello World!” example is just a label sitting on our Gnome Panel!

Lets take a look at the bottom first, where we call PANEL_APPLET_BONOBO_FACTORY() routine which takes as parameters :

  1. the OAFIID of the applet ( remember we typed it at the .server file )
  2. PANEL_TYPE_APPLET, which describes that our program will be a panel applet.
  3. The name which bonobo server will respond with when it gets queried for applets.
  4. The version of our creation.
  5. A callback function which will be called when the applet is added on the panel. ( helloworld_applet_create() in this example. )
  6. Data that we want to pass as arguments to the callback function, but we don’t need any, so we specify NULL.

Now consider the callback function helloworld_applet_create() like the constructor of our applet, our initiator. First of all, we define our variables ( GtkWidget *label ). It is important to check if bonobo called the right applet, by checking if the unique IID is the same with the one we specified in our .server file. After this point its just GTK+ programming, we just say label to show the appropriate text ( label = gtk_label_new (“Hello World”) ).

The space we are given in the panel ( PanelApplet *applet ) is like a GTK+ container, so we need to contain the label inside it by calling the gtk_container_add() function. In the end we show the applet and all its children ( the label in this case ) by calling gtk_widget_show_all().

Compiling

In order to compile our source file [ helloworld.cpp ] we need to tell g++ where to find the header files for the applets and the GTK+ library. Hopefully the program dpk-config can give us those directories or g++ include flags to be precise by using the command

[sourcecode language="plain" light="true"]pkg-config –cflags –libs libpanelapplet-2.0[/sourcecode]

So to combine this with the compilation, type

[sourcecode language="plain" light="true"]g++ $(pkg-config –cflags –libs libpanelapplet-2.0) -o helloworld helloworld.cpp[/sourcecode]

in your terminal.

By using $(pkg-config ….) we tell to the terminal to first execute the command included in the parentheses and include its output in the execution of the g++ command. Hopefully you have the package libpanelapplet-2.0-dev or the appropriate package required for your linux distribution installed.

Now you need to place the executable in “/usr/lib/gnome-panel/” directory and the helloworld.server file inside “/usr/lib/bonobo/servers/” if you haven’t already done it.
Right click on your Gnome Panel and select “Add to panel…”, choose “Hello World!” and voila!! A useless label sitting on your panel!

Result

Result

For any questions, post a comment, check links inside the post for more information on specific subjects.

Dont forget to follow wedevblog on twitter!

Incoming Part : 2, moving the “Hello World!” to the next step!

  • Share/Bookmark
Categories: dev Tags: , , , ,