Thursday, August 02, 2007

GTK system tray icon example

It's hard to find an example of system tray icon example. In the past, we should use libegg, but this library is deprecated. The current option, when using GTK, is the Status Icon. GTK implements freedesktop's System Tray specification and works on any desktop environment that is compliant (like KDE or GNOME).

I created a very simple example to help other people to solve this problem more quickly in the future:

#include 

void tray_icon_on_click(GtkStatusIcon *status_icon,
gpointer user_data)
{
printf("Clicked on tray icon\n");
}

void tray_icon_on_menu(GtkStatusIcon *status_icon, guint button,
guint activate_time, gpointer user_data)
{
printf("Popup menu\n");
}

static GtkStatusIcon *create_tray_icon() {
GtkStatusIcon *tray_icon;

tray_icon = gtk_status_icon_new();
g_signal_connect(G_OBJECT(tray_icon), "activate",
G_CALLBACK(tray_icon_on_click), NULL);
g_signal_connect(G_OBJECT(tray_icon),
"popup-menu",
G_CALLBACK(tray_icon_on_menu), NULL);
gtk_status_icon_set_from_icon_name(tray_icon,
GTK_STOCK_MEDIA_STOP);
gtk_status_icon_set_tooltip(tray_icon,
"Example Tray Icon");
gtk_status_icon_set_visible(tray_icon, TRUE);

return tray_icon;
}

int main(int argc, char **argv) {
GtkStatusIcon *tray_icon;

gtk_init(&argc, &argv);
tray_icon = create_tray_icon();
gtk_main();

return 0;
}


Don't forget to compile with GTK libraries.

There are some other aspects when implementing a tray icon and you want to minimize to tray, such as:

- Hide/Show window to avoid minimizing it to the task bar (yes, use gtk_widget_hide() and gtk_widget_show()) when the user clicks on the system tray icon
- Listen to the "window-state-event" (GObject's signal) to detect when minimizing and, instead of doing that, hide the window (ie, "minimize to the tray").

Finally, in case you experienced something interesting concerning system tray icons, please share with us.

10 comments:

Andrew said...

Just one correction - after gtk_widget_show() you should call gtk_window_present() to set focus on main window
:)

Ferran Garriga said...

Thanks for your post !!!

Anonymous said...

Thank you for your code! This is excellent stuff!!!

Cagnulein said...

Great Post!
How can i change the picture icon without reloading a new icon?
Thanks

kuratkull said...

What official docs failed to show me, you did in a short(but very useful) example :)
Thank you!

Ofer Koren said...

Great post
Thanks

sabine said...

great example but why the tray icon does not show with Mac OS?

Anonymous said...

Thanks a million!

knightmanish said...

Nicely explained.
Thumbs up!!

Thiago said...

Compiling this example could be like this:

gcc main.c -o tray-icon `pkg-config --cflags --libs gtk+-2.0`