Le applet per il pannello di gnome sono delle piccole applicazioni che girano nel pannello di gnome, ad esempio, il task manager e l’orologio visibili di default sul pannello.
Per pannello di gnome si intende l’applicazione gnome-panel che fa parte della sessione di fallback di gnome 3. Infatti la sessione normale usa gnome-shell e gnome-panel non è presente.
Prima di tutto servono le librerie quindi diamo un:
yum install gnome-panel-devel
e per lo sviluppo di un’applet ora avremo l’header panel-applet.h in /usr/include/gnome-panel*
Se utilizzate DevHelp a me ha automaticamente installato anche la guida
Panel Applet Library Reference Manual, quindi pare che venga installata assieme alla libreria.
Ora che abbiamo la libreria ci servono 3 file per creare la nostra applet:
Un file .panel-applet da copiare in /usr/share/gnome-panel/4.0/applets //4.0 è la versione e potrebbe cambiare nel tempo
Un file .service da copiare in /usr/share/dbus-1/services
Il codice in C della nostra applet
Il file .panel-applet contiene informazioni sull’applet e sull’applet factory.
L’applet factory viene descritta nella guida come l’oggetto che crea l’applet quando il pannello richiede di creare una nuova applet. La sua implementazione è nascosta e per utilizzarla ci serviremo solo di una macro nel codice sorgente.
Il file .service
La comunicazione tra il pannello e l’applet è fatta attraverso D-Bus un servizio di sistema che permette lo scambio di messaggi tra applicazioni (IPC).
Quindi il servizio dbus deve essere in esecuzione perche l’applet funzioni:
nel mio caso il comando
systemctl list-units | grep dbus
ritorna
dbus.service loaded active running D-Bus System Message Bus
dbus.socket loaded active running D-Bus System Message Bus Socket
Personalmente ho creato come prova un’applet che misura l’utilizzo di cpu memoria e swap
IL FILE /usr/share/gnome-panel/4.0/applets/sysmon.panel-applet:
[Applet Factory]
Id=SysMonFactory
InProcess=false
Location=/home/zizzu/Documents/Programmazione/applet
Name=SysMon Applet Factory
Description=Factory for the sysmon applet
[SysMonApplet]
Name=Sysmon
Description=Show resources usage
Icon=hello-world-icon
IL FILE /usr/share/dbus-1/services/org.gnome.panel.applet.SysMon.service:
[D-BUS Service]
Name=org.gnome.panel.applet.SysMonFactory
Exec=/home/zizzu/Documents/Programmazione/applet
Tutto qui, cambiate i valori per rispecchiare la vosta applet
E ora il codice sorgente da compilare passando pkg-config --cflags --libs libgtop-2.0 libpanelapplet-4.0
a gcc:
#include <gtk/gtk.h>
#include <panel-applet.h>
#include <glibtop/cpu.h>
#include <glibtop/mem.h>
#include <glibtop/swap.h>
static unsigned short int get_mem_usage()
{
glibtop_mem mem;
glibtop_get_mem(&mem);
return mem.used * 100 / mem.total;
}
static unsigned short int get_swap_usage()
{
glibtop_swap swap;
glibtop_get_swap(&swap);
return swap.used * 100 / swap.total;
}
static unsigned short int get_cpu_usage(glibtop_cpu c1, glibtop_cpu c2)
{
double percent;
unsigned long long total;
total = (c2.user - c1.user) + (c2.nice - c1.nice) + \
(c2.sys - c1.sys) + (c2.iowait - c1.iowait) + (c2.irq - c1.irq) + \
(c2.softirq - c1.softirq);
percent = total;
total += (c2.idle - c1.idle);
percent /= total;
percent *= 100;
return percent;
}
static gboolean routine(GtkLabel *label)
{
gchar *str = NULL;
glibtop_cpu cpu1,cpu2;
unsigned short int cpu,mem,swap;
glibtop_get_cpu(&cpu1);
g_usleep(G_USEC_PER_SEC);
glibtop_get_cpu(&cpu2);
cpu = get_cpu_usage(cpu1,cpu2);
mem = get_mem_usage();
swap = get_swap_usage();
str = g_strdup_printf("CPU: %u%% Memory: %u%% Swap: %u%%", cpu,mem,swap);
gtk_label_set_text(label,str);
g_free(str);
return TRUE;
}
//Avvia gnome-system-monitor facendo doppio click sull'applet
gboolean start_system_monitor(GtkWidget *widget,GdkEventButton *event,gpointer user_data)
{
GAppInfo *appinfo;
GdkScreen *screen;
GdkDisplay *display;
GdkAppLaunchContext *context;
GError *error;
if (event->type == GDK_2BUTTON_PRESS)
{
screen = gdk_screen_get_default();
display = gdk_display_get_default();
context = gdk_display_get_app_launch_context(display);
gdk_app_launch_context_set_screen (context, screen);
gdk_app_launch_context_set_timestamp (context,gtk_get_current_event_time ());
appinfo = g_app_info_create_from_commandline ("/home/franzizzu/LPM/main",NULL, \
G_APP_INFO_CREATE_NONE,&error);
g_app_info_launch (appinfo, NULL, G_APP_LAUNCH_CONTEXT (context), &error);
g_object_unref (context);
g_object_unref (appinfo);
}
return FALSE;
}
static gboolean sysmon_applet_start(PanelApplet *applet)
{
GtkWidget *label,*hbox,*eventbox;
label = gtk_label_new(NULL);
eventbox = gtk_event_box_new();
hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL,0);
gtk_event_box_set_visible_window(GTK_EVENT_BOX(eventbox),FALSE);
gtk_container_add (GTK_CONTAINER (eventbox), label);
gtk_container_add (GTK_CONTAINER (hbox), eventbox);
gtk_container_add (GTK_CONTAINER (applet), hbox);
g_signal_connect (G_OBJECT(eventbox),"button-press-event",G_CALLBACK(start_system_monitor),(gpointer)applet);
panel_applet_set_background_widget(applet,label);
panel_applet_set_flags(applet, PANEL_APPLET_EXPAND_MINOR);
g_timeout_add_seconds(2,(GSourceFunc)routine,(gpointer)label);
gtk_widget_show_all(GTK_WIDGET(applet));
return TRUE;
}
//Funzione richiamata dall'applet factory
static gboolean sysmon_factory_callback(PanelApplet *applet,const gchar *iid,gpointer data)
{
gboolean retval = FALSE;
glibtop_init();
if (g_strcmp0 (iid, "SysMonApplet") == 0)
retval = sysmon_applet_start (applet);
return retval;
}
PANEL_APPLET_OUT_PROCESS_FACTORY ("SysMonFactory",PANEL_TYPE_APPLET,sysmon_factory_callback,NULL);
Quando aggiungiamo l’applet al pannello l’applet factory specificata come OUT_PROCESS, cioe l’applet gira come applicazione al di fuori del pannello ed è visibile nella lista dei processi, richiama sysmon_factory_callback che esegue un controllo di routine e richiama sysmon_applet_start, dove abbiamo un riferimento alla nostra applet come argomento e che possiamo utilizzare come una “main window”, nel mio caso ho aggiunto una label dove, tramite la libreria libgtop riporto ogni due secondi l’utilizzo delle risorse di sistema.
Notare che i valori passati devono rispecchiare quelli nei files.
Per maggiori informazioni fare riferimento a:
http://developer.gnome.org/panel-applet/stable/
Se trovate qualche errore scrivete pure perche l’ho fatta in poco tempo e senza approfondire e programmo per svago non sono un professionista ciao! ^^