Hello World Example

In this section we will write a simple example applet. This simple applet will have no functionality and only displays a label with "Hello World" on the panel. For this simple applet only following three parts are needed:

  • PANEL_APPLET_OUT_PROCESS_FACTORY() : this creates an applet factory named HelloWorldFactory, and each time our applet is added to a GNOME Panel, this applet factory will create an applet instance, and calls hello_world_factory_callback() with a PanelApplet object already created.

  • hello_world_factory_callback(): this checks if the request to create an applet instance is for an applet type supported by our applet factory. Here we can see that we only support the HelloWorldApplet applet type. This function returns TRUE on success and FALSE on failures.

    If you return FALSE here, GNOME Panel will show a dialog and notify the user that the applet loading failed.

  • hello_world_applet_start(): this is where we actually setup the PanelApplet widget for the work the applet should do. This can include adding widgets to the applet, connecting to signals, loading settings via GSettings, etc.

    The PanelApplet is a subclass of GtkBin container, to add more than one widget to it you will need to use another GtkContainer implementation such as GtkBox or GtkGrid.

An example is worth a million words, so here is the code for our Hello World applet.

Example 1. Hello World applet

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <gtk/gtk.h>
#include <panel-applet.h>

static void
hello_world_applet_start (PanelApplet *applet)
{
    GtkWidget *label;

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

static gboolean
hello_world_factory_callback (PanelApplet  *applet,
                              const gchar  *iid,
                              gpointer      data)
{
    if (g_strcmp0 (iid, "HelloWorldApplet") != 0)
         return FALSE;

    hello_world_applet_start (applet);

    return TRUE;
}

PANEL_APPLET_OUT_PROCESS_FACTORY ("HelloWorldFactory",
                                  PANEL_TYPE_APPLET,
                                  hello_world_factory_callback,
                                  NULL)


While the previous example is simple, it can be useful to directly subclass the PanelApplet type. This makes it easy to have a per-applet instance private structure, among other benefits. Most of the code below is related to the GObject system and needed to subclass the Panel Applet. The only noteworthy difference is that the PANEL_APPLET_OUT_PROCESS_FACTORY macro now takes our subclassed type (e.g. HELLO_WORLD_TYPE_APPLET) as its second parameter, instead of PANEL_TYPE_APPLET.

Example 2. Hello World applet, with a PanelApplet subclass

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include <gtk/gtk.h>
#include <panel-applet.h>

#define HELLO_WORLD_TYPE_APPLET (hello_world_applet_get_type ())

typedef struct _HelloWorldApplet        HelloWorldApplet;
typedef struct _HelloWorldAppletClass   HelloWorldAppletClass;
typedef struct _HelloWorldAppletPrivate HelloWorldAppletPrivate;

struct _HelloWorldApplet {
    PanelApplet parent_object;

    /*< private >*/
    HelloWorldAppletPrivate *priv;
};

struct _HelloWorldAppletClass {
    PanelAppletClass parent_class;
};

struct _HelloWorldAppletPrivate
{
    GtkWidget *label;
};

static GType hello_world_applet_get_type (void) G_GNUC_CONST;

G_DEFINE_TYPE (HelloWorldApplet, hello_world_applet, PANEL_TYPE_APPLET);

static void
hello_world_applet_init (HelloWorldApplet *applet)
{
    applet->priv = G_TYPE_INSTANCE_GET_PRIVATE (applet, HELLO_WORLD_TYPE_APPLET,
                                                HelloWorldAppletPrivate);

    applet->priv->label = gtk_label_new ("Hello World");
    gtk_container_add (GTK_CONTAINER (applet), applet->priv->label);
    gtk_widget_show (applet->priv->label);
}

static void
hello_world_applet_class_init (HelloWorldAppletClass *klass)
{
  g_type_class_add_private (class, sizeof (HelloWorldAppletPrivate));
}

static
hello_world_applet_start (HelloWorldApplet *applet)
{
    gtk_widget_show (GTK_WIDGET (applet));
}

static gboolean
hello_world_factory_callback (HelloWorldApplet *applet,
                              const gchar      *iid,
                              gpointer          data)
{
    if (g_strcmp0 (iid, "HelloWorldApplet") != 0)
         return FALSE;

    hello_world_applet_start (applet);

    return TRUE;
}

PANEL_APPLET_OUT_PROCESS_FACTORY ("HelloWorldFactory",
                                  HELLO_WORLD_TYPE_APPLET,
                                  hello_world_factory_callback,
                                  NULL)