background: #eeeeee; border: solid 1px #aaaaaa; padding: 0.5em; } .programlisting { background: #eeeeff; border: solid 1px #aaaaff; padding: 0.5em; } .variablelist { padding: 4px; margin-left: 3em; } .navigation { background: #ffeeee; border: solid 1px #ffaaaa; margin-top: 0.5em; margin-bottom: 0.5em; } .navigation a { color: #770000; } .navigation a:visited { color: #550000; } .navigation .title { font-size: 200%; }

Porting Applets from the GNOME 1.x interfaces

Table of Contents
Applet Activation
Activation files
Context Menu

In GNOME 1.x the applet interface lived in a header called applet-widget.h. The interface was based on GOAD, the GNOME 1.x object activation framework. A new interface was designed for GNOME 2.x using the power of bonobo UI embedding and the new object activation framework, bonobo-activation. The interface is intended to be easy to use, cruft free, but semantically similar to the old API in order to make porting relatively painless.


Applet Activation

The first thing to change when porting to the new API is the header. Include panel-applet.h instead of applet-widget.h.

Next you need to change how the applet is activated. Browsing through old applet's code, its obvious that this was done in various ways in the past. The best advice is to hunt out the calls to applet_widget_init, applet_widget_new and applet_widget_add. applet_widget_new and applet_widget_add are now effectively merged into one call panel_applet_new, to which the top-level widget of the applet should be passed. applet_widget_init is not neccessary anymore. So the new code should look something like this

#include <panel-applet.h>

static BonoboObject *
blah_applet_new ()
{
        PanelApplet *applet;

	/*
	 * The old code setting up the applet widgetry
	 * goes here. So effectively delete calls to
	 * applet_widget_init and applet_widget_new
	 * and the replace applet_widget_add with a call
	 * to panel_applet_new.
	 */

        applet = panel_applet_new (label);

        return BONOBO_OBJECT (panel_applet_get_control (applet));
}

static BonoboObject *
blah_applet_factory (BonoboGenericFactory *this,
		     const gchar          *iid,
		     gpointer              data)
{
        BonoboObject *applet = NULL;

        if (!strcmp (iid, "OAFIID:BlahApplet"))
                applet = blah_applet_new ();

        return applet;
}


PANEL_APPLET_BONOBO_FACTORY ("OAFIID:BlahApplet_Factory",
                             "Blah",
                             "0",
                             blah_applet_factory,
                             NULL)
      

You should use PANEL_APPLET_BONOBO_FACTORY or PANEL_APPLET_BONOBO_SHLIB_FACTORY depending on whether you want the applet to be out of process or in process.


Activation files

The next thing to do may be to port from a .gnorba file to a bonobo-activation .server file. You no longer need a .desktop file for applets. A .gnorba looks something like this :

[blah]
type=exe
repo_id=IDL:GNOME/Applet:1.0
description=Blah
location_info=blah-de-blah
	

Your .server file should look like this :

<oaf_info>

<oaf_server iid="OAFIID:BlahApplet"
            type="exe"
            location="blah-de-blah-2">

        <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="Blah Factory"/>
        <oaf_attribute name="description" type="string" value="Blah De Blah"/>

</oaf_server>

<oaf_server iid="OAFIID:BlahApplet"
            type="factory"
            location="OAFIID:BlahApplet_Factory">

        <oaf_attribute name="repo_ids" type="stringv">
                <item value="IDL:GNOME/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="Blah Applet"/>
        <oaf_attribute name="description" type="string" value="Blah De Blah"/>
        <oaf_attribute name="panel:category" type="string" value="Amusements"/>
        <oaf_attribute name="panel:icon" type="string" value="blah-de-blah.png"/>

</oaf_server>

</oaf_info>
	

A lot of this should be copied and pasted. The most important bits are setting "panel:category" and "panel:icon". The "panel:category" attribute sets what directory the applet should go in the "Add Applet" menu. The "panel:icon" attribute specfies the icon that should be displayed in the "Add Applet" menu.


Context Menu

Most applets also place extra menu items into it context menu. It might be a good idea to port this next. In GNOME 1.x this was done using the applet_widget_register_stock_callback API call. In GNOME 2.x 3 things must be done

The xml description should look something like this :

static const char fish_menu_xml [] =
        "<popup name=\"button3\">\n"
        "   <menuitem name=\"Properties Item\" verb=\"BlahProperties\" _label=\"Properties ...\"\n"
        "             pixtype=\"stock\" pixname=\"gtk-properties\"/>\n"
        "   <menuitem name=\"Help Item\" verb=\"BlahHelp\" _label=\"Help\"\n"
        "             pixtype=\"stock\" pixname=\"gtk-help\"/>\n"
        "   <menuitem name=\"About Item\" verb=\"BlahAbout\" _label=\"About ...\"\n"
        "             pixtype=\"stock\" pixname=\"gnome-stock-about\"/>\n"
        "</popup>\n";
	

This could also be in a seperate .xml file and loaded with panel_applet_setup_menu_from_file. The description of the verbs should look something like :

static const BonoboUIVerb fish_menu_verbs [] = {
        BONOBO_UI_VERB ("BlahProperties", display_properties_dialog),
        BONOBO_UI_VERB ("BlahHelp",       display_help_dialog),
        BONOBO_UI_VERB ("BlahAbout",      display_about_dialog),

        BONOBO_UI_VERB_END
};
	

This is just a list of callbacks invoked when the menu items are clicked. There are other macros you may use other than BONOBO_UI_VERB - see bonobo-ui-component.h.

To actually register the menu you just do something like :

	panel_applet_setup_menu (PANEL_APPLET (blah->applet),
                                 blah_menu_xml,
                                 blah_menu_verbs,
                                 blah);
	

The last argument is the user_data argument passed back to the callbacks.