Session Saving

The panel is session manager aware but the applets don't have to be, they can depend on the panel to save their information in a proper place. Basically session saving has two parts, loading the info, and saving the info. Loading is pretty simple, after you do applet_widget_new, you can get the correct paths to load your properties from the widget's structure. For example:

Example 7. Getting Private Data

gnome_config_push_prefix(APPLET_WIDGET(applet)->privcfgpath);
hello = gnome_config_get_bool("section/hello=true");
gnome_config_pop_prefix();
	    
will do the trick.

For saving it's a little bit more complicated but not by much, let's make our original example save a global variable hello.

Example 8. Saving Private HelloWorld

#include <config.h>
#include <applet-widget.h>

/* useless variable that we want to save the state of*/
gint hello = TRUE;

/* sesion save signal handler*/
static gint
applet_save_session(GtkWidget *w,
                    const char *privcfgpath,
                    const char *globcfgpath)
{
        gnome_config_push_prefix(privcfgpath);
        gnome_config_set_string("section/hello",hello);
        gnome_config_pop_prefix();

        gnome_config_sync();
        /* you need to use the drop_all here since we're all writing to
           one file, without it, things might not work too well */
        gnome_config_drop_all();

        /* make sure you return FALSE, otherwise your applet might not
           work compeltely, there are very few circumstances where you
           want to return TRUE. This behaves similiar to GTK events, in
           that if you return FALSE it means that you haven't done
           everything yourself, meaning you want the panel to save your
           other state such as the panel you are on, position,
           parameter, etc ... */
        return FALSE;
}


int
main(int argc, char **argv)
{
        GtkWidget *applet;
        GtkWidget *label;

        /* Initialize the i18n stuff */
        bindtextdomain (PACKAGE, GNOMELOCALEDIR);
        textdomain (PACKAGE);

        /* intialize, this will basically set up the applet, corba and
           call gnome_init */
        applet_widget_init("hello_applet", NULL, argc, argv, NULL, 0, NULL);

        /* create a new applet_widget */
        applet = applet_widget_new("hello_applet");
        /* in the rare case that the communication with the panel
           failed, error out */
        if (!applet)
                g_error("Can't create applet!\n");

        /* read the contents of the stored value of hello from the
           config file */
        gnome_config_push_prefix(APPLET_WIDGET(applet)->privcfgpath);
        hello = gnome_config_get_bool("section/hello=true");
        gnome_config_pop_prefix();

        /* create the widget we are going to put on the applet */
        label = gtk_label_new(_("Hello There!"));
        gtk_widget_show(label);

        /* bind the session save signal */
        gtk_signal_connect(GTK_OBJECT(applet),"save_session",
                           GTK_SIGNAL_FUNC(applet_save_session),
                           NULL);

        /* add the widget to the applet-widget, and thereby actually
           putting it "onto" the panel */
        applet_widget_add (APPLET_WIDGET (applet), label);
        gtk_widget_show (applet);

        /* special corba main loop */
        applet_widget_gtk_main ();

        return 0;
}
	    

That's basically it. Make sure you return FALSE from the save_session handler, else the panel will not remember your applet next time. Also note the presence of gnome_config_drop_all, that needs to be done, especially for multi applets (discussed below), or your info might get lost.

If you need to store information global to all applets you can use the globcfgpath counterpart of privcfgpath, which gives you a path to a file which is the same for all applets.

IMPORTANT! Make sure you only use two levels of config path below privcfgpath/globcfgpath. Which means you only tack on "section/key". Also don't just use "key". You need to tack on both the section and the key, no more, no less.

Example 9. Retrieving Global Data

gnome_config_push_prefix(APPLET_WIDGET(applet)->globcfgpath);
hello = gnome_config_get_bool("all_hello_applets/hello=true");
gnome_config_pop_prefix();
	    
Similarly for the save_session.

Note: When you update your configuration in some properties dialog, or however lse, you should call applet_widget_sync_config (AppletWidget *applet), it will tell the panel to send a session save signal to the applet with the correct paths etc. This is not 100% neccessary, but makes it nice so that configuration is not lost during crashes (when the panel couldn't do it's complete save during shutdown) [ed: you should still do this, even though the panel doesn't crash anymore]