Click here to Skip to main content
13,299,727 members (64,278 online)
Click here to Skip to main content
Add your own
alternative version

Stats

27.7K views
10 bookmarked
Posted 20 Jun 2008

Minimize to tray with GTK

, 20 Jun 2008
Rate this:
Please Sign up or sign in to vote.
How to place an icon in tray and interact with it.

Introduction

This article explains the use of the GtkStatusIcon widget which is used to place an icon in system tray. A tooltip and a pop-up menu can be added to this icon for interaction. This icon can be made to blink.

How to place a icon in System tray

The following functions can be used to create a new status icon:

GtkStatusIcon* gtk_status_icon_new ();

GtkStatusIcon* gtk_status_icon_new_from_pixbuf    (GdkPixbuf *pixbuf);

GtkStatusIcon* gtk_status_icon_new_from_file      (const gchar *filename);

GtkStatusIcon* gtk_status_icon_new_from_stock     (const gchar *stock_id);

GtkStatusIcon* gtk_status_icon_new_from_icon_name (const gchar *icon_name);

To set a tooltip text use the following function:

void gtk_status_icon_set_tooltip (GtkStatusIcon *icon, const gchar *tooltip_text);

To blink the icon use the following function:

void gtk_status_icon_set_blinking (GtkStatusIcon *icon, gboolean blinking);

The tray icon emits "activate" signal when user activates the tray icon and emits "popup-menu" signal when the user has indicated that a menu should be shown.

Sample program

The follwing program creates a trayicon and hides application window when minimize button is pressed. The application window becomes visible with pop-up menu associated with the tray icon. These signals can be handled to interact with the icon.

//trayicon.c
#include <span class="code-keyword"><gtk/gtk.h></span>

static void trayView(GtkMenuItem *item, gpointer user_data);
static void trayExit(GtkMenuItem *item, gpointer user_data);
static void trayIconActivated(GObject *trayIcon, gpointer data);
static void trayIconPopup(GtkStatusIcon *status_icon, guint button, guint32 activate_time, gpointer popUpMenu);
static void destroy (GtkWidget*, gpointer);
static gboolean delete_event (GtkWidget*, GdkEvent*, gpointer);
static gboolean window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer user_data);

int main(int argc, char *argv[])
{
    gtk_init (&argc, &argv);
    
    GtkWidget *window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title (GTK_WINDOW (window), "GtkStatusIcon Example");
    gtk_widget_set_size_request (window, 200, -1);
    
    //set try icon file
    GtkStatusIcon *trayIcon  = gtk_status_icon_new_from_file ("/root/Desktop/icon.png");
    //set popup menu for tray icon
    GtkWidget *menu, *menuItemView, *menuItemExit;
    menu = gtk_menu_new();
    menuItemView = gtk_menu_item_new_with_label ("View");
    menuItemExit = gtk_menu_item_new_with_label ("Exit");
    g_signal_connect (G_OBJECT (menuItemView), "activate", G_CALLBACK (trayView), window);
    g_signal_connect (G_OBJECT (menuItemExit), "activate", G_CALLBACK (trayExit), NULL);
    gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuItemView);
    gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuItemExit);
    gtk_widget_show_all (menu);
    //set tooltip
    gtk_status_icon_set_tooltip (trayIcon, "MsgWatcherGTK");
    //connect handlers for mouse events
    g_signal_connect(GTK_STATUS_ICON (trayIcon), "activate", GTK_SIGNAL_FUNC (trayIconActivated), window);
    g_signal_connect(GTK_STATUS_ICON (trayIcon), "popup-menu", GTK_SIGNAL_FUNC (trayIconPopup), menu);
    gtk_status_icon_set_visible(trayIcon, FALSE); //set icon initially invisible
    
    
    GtkWidget *menuBar, *menuItemTopLvl, *mainMenu, *mainMenuItemExit;
    menuBar = gtk_menu_bar_new ();
    menuItemTopLvl = gtk_menu_item_new_with_label ("Menu");
    gtk_menu_shell_append (GTK_MENU_SHELL (menuBar), menuItemTopLvl);
    
    mainMenu = gtk_menu_new ();
    gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuItemTopLvl), mainMenu);
    mainMenuItemExit = gtk_menu_item_new_with_label ("Quit");
    g_signal_connect (G_OBJECT (mainMenuItemExit), "activate", G_CALLBACK (trayExit), NULL);
    gtk_menu_shell_append (GTK_MENU_SHELL (mainMenu), mainMenuItemExit);
    
    g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (destroy), NULL);
    g_signal_connect (G_OBJECT (window), "delete_event", G_CALLBACK (delete_event), trayIcon);
    g_signal_connect (G_OBJECT (window), "window-state-event", G_CALLBACK (window_state_event), trayIcon);
    gtk_container_add (GTK_CONTAINER (window), menuBar);
    gtk_widget_show_all (window);
    gtk_main ();
    return 0;
}

static void trayView(GtkMenuItem *item, gpointer window) 
{
    gtk_widget_show(GTK_WIDGET(window));
    gtk_window_deiconify(GTK_WINDOW(window));    
}

static void trayExit(GtkMenuItem *item, gpointer user_data) 
{
    printf("exit");
    gtk_main_quit();
}

static void trayIconActivated(GObject *trayIcon, gpointer window)
{
    gtk_widget_show(GTK_WIDGET(window));
    gtk_window_deiconify(GTK_WINDOW(window));
}

static void trayIconPopup(GtkStatusIcon *status_icon, guint button, guint32 activate_time, gpointer popUpMenu)
{
    gtk_menu_popup(GTK_MENU(popUpMenu), NULL, NULL, gtk_status_icon_position_menu, status_icon, button, activate_time);
}

static void destroy (GtkWidget *window, gpointer data)
{
  gtk_main_quit ();
}

static gboolean delete_event (GtkWidget *window, GdkEvent *event, gpointer data)
{
    return FALSE;
}

static gboolean window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer trayIcon)
{
    if(event->changed_mask == GDK_WINDOW_STATE_ICONIFIED && (event->new_window_state == GDK_WINDOW_STATE_ICONIFIED || event->new_window_state == (GDK_WINDOW_STATE_ICONIFIED | GDK_WINDOW_STATE_MAXIMIZED)))
    {
        gtk_widget_hide (GTK_WIDGET(widget));
        gtk_status_icon_set_visible(GTK_STATUS_ICON(trayIcon), TRUE);
    }
    else if(event->changed_mask == GDK_WINDOW_STATE_WITHDRAWN && (event->new_window_state == GDK_WINDOW_STATE_ICONIFIED || event->new_window_state == (GDK_WINDOW_STATE_ICONIFIED | GDK_WINDOW_STATE_MAXIMIZED)))
    {
        gtk_status_icon_set_visible(GTK_STATUS_ICON(trayIcon), FALSE);
    }
    return TRUE;
}

The above code can be build with the following command:

gcc trayicon.c -o trayicon `pkg-config --cflags --libs gtk+-2.0`.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Ranjeetsih
Software Developer (Junior)
India India
ranjeet sih, working as a programmer since 2007

You may also be interested in...

Comments and Discussions

 
Questionwhat's GTK? Pin
zhfaddr@gmail.com15-Sep-10 5:24
memberzhfaddr@gmail.com15-Sep-10 5:24 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.171207.1 | Last Updated 20 Jun 2008
Article Copyright 2008 by Ranjeetsih
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid