spacer

App Developer

spacer

Resources

Technologies

Platform

  • API
  • Documentation
  • Unity Desktop

Tools

  • Graphical designers
  • Graphical libraries
  • Graphical toolkits
  • IDEs
  • Packaging
  • Project hosting
  • Quickly
  • Revision control

Programming languages

  • C and C++
  • C#
  • Java
  • JavaScript
  • Python
  • QML
  • Vala

Technologies

  • Application indicators
  • Messaging menu
  • Notification
  • Online Accounts
  • Sound menu
  • Ubuntu developer stack
  • Unity launcher
  • Unity lenses and scopes
  • Web Apps

App developer cookbook

  • All recipes
  • Mobile
  • Multitouch
  • Social networking
  • Ubuntu One
  • Unity
  • Widgets

Get help

  • Community

Application indicators

Application indicators provide a simple and effective API to provide an application icon in the notification area in the top-right part of the screen, and provide simple, accessible, and complete access to key parts of your application. With bindings for C, Python, and Mono, you can integrate your app into the Unity desktop quickly and easily.

Features

  • Application indicators are more consistent – no more left and right-click inconsistency. Always left click to see the items.
  • Scrubbing – you can click once on an app indicator and scrub left and right through other indicators with your mouse.
  • More accessible – importantly, scrubbing also applies to the keyboard: this means you could bind a key to the indicator applet, hit that key and then use the arrow keys to navigate through all the indicators.
  • Themable panel icons – you can set a specific icon to be a panel icon for an indicator: this should make it easier for creating single colour panel icons for light and dark themes.
  • KDE/GNOME compatibility – KDE applications running in GNOME will have their application notification menus rendered with GTK widgets and vice-versa.

Porting Guide for Applications

The application indicators API is similar to the GtkStatusIcon API in some ways, but simpler and more opinionated in its design.

Indicators are grouped together by category, so it’s important for the application to accurately specify its category.

Possible categories for indicators include:

  • APP_INDICATOR_CATEGORY_APPLICATION_STATUS: used to tell the user the current state of the application and allow users to act on that.
  • APP_INDICATOR_CATEGORY_COMMUNICATIONS: might be used by applications such as IM clients to let the user know they have received new messages.
  • APP_INDICATOR_CATEGORY_SYSTEM_SERVICES: inform the user about system-related events. Maybe there are updates available?
  • APP_INDICATOR_CATEGORY_HARDWARE: used for hardware-related tasks, for example Bluetooth.
  • APP_INDICATOR_CATEGORY_OTHER: if the app doesn’t belong in one of the other categories but needs an indicator, it should use other.

The category is set when the indicator is created and isn’t changed.

Application indicators also fall into one of three states:

  • APP_INDICATOR_STATUS_PASSIVE: the indicator should be hidden from the user
  • APP_INDICATOR_STATUS_ACTIVE: the indicator should be shown normally
  • APP_INDICATOR_STATUS_ATTENTION: the application wants the user’s attention

The indicator status can be set using app_indicator_set_status().

The icons need to use icon names from themes, direct paths to icon files are not supported. For example, icon names used with gtk_status_icon_new_from_file() won’t work.

Typical usage (C version)

Indicators should typically be created using the helper function app_indicator_new(). This returns a pointer to a newly created AppIndicator object, which is may be unref’d normally when it is no longer needed. This function expects three parameters:

  AppIndicator* app_indicator_new (const gchar          *id,
                                   const gchar          *icon_name,
                                   AppIndicatorCategory  category);

The id parameter should be unique to your application. Because app indicators are cross-desktop, the icon_name parameter expects an icon name according to the usual icon naming spec. The category parameter is the indicator category as described above.

Once an indicator object is created, the application may decide to set an attention icon using app_indicator_set_attention_icon().

Lastly, the indicator should be given a GtkMenu object. This can be either created manually or using some other method such as GtkUIManager. Below is an example using GtkUIManager.

#include <libappindicator/app-indicator.h>

static void activate_action (GtkAction *action);

static GtkActionEntry entries[] = {
  { "FileMenu", NULL, "_File" },
  { "New",      "document-new", "_New", "<control>N",
    "Create a new file", G_CALLBACK (activate_action) },
  { "Open",     "document-open", "_Open", "<control>O",
    "Open a file", G_CALLBACK (activate_action) },
  { "Save",     "document-save", "_Save", "<control>S",
    "Save file", G_CALLBACK (activate_action) },
  { "Quit",     "application-exit", "_Quit", "<control>Q",
    "Exit the application", G_CALLBACK (gtk_main_quit) },
};
static guint n_entries = G_N_ELEMENTS (entries);

static const gchar *ui_info =
"<ui>"
"  <menubar name='MenuBar'>"
"    <menu action='FileMenu'>"
"      <menuitem action='New'/>"
"      <menuitem action='Open'/>"
"      <menuitem action='Save'/>"
"      <separator/>"
"      <menuitem action='Quit'/>"
"    </menu>"
"  </menubar>"
"  <popup name='IndicatorPopup'>"
"    <menuitem action='New' />"
"    <menuitem action='Open' />"
"    <menuitem action='Save' />"
"    <menuitem action='Quit' />"
"  </popup>"
"</ui>";

static void
activate_action (GtkAction *action)
{
        const gchar *name = gtk_action_get_name (action);
        GtkWidget *dialog;

        dialog = gtk_message_dialog_new (NULL,
                                         GTK_DIALOG_DESTROY_WITH_PARENT,
                                         GTK_MESSAGE_INFO,
                                         GTK_BUTTONS_CLOSE,
                                         "You activated action: \"%s\"",
                                         name);

        g_signal_connect (dialog, "response",
                          G_CALLBACK (gtk_widget_destroy), NULL);

        gtk_widget_show (dialog);
}

int main (int argc, char **argv)
{
  GtkWidget *window;
  GtkWidget *menubar;
  GtkWidget *table;
  GtkWidget *sw;
  GtkWidget *contents;
  GtkWidget *statusbar;
  GtkWidget *indicator_menu;
  GtkActionGroup *action_group;
  GtkUIManager *uim;
  AppIndicator *indicator;
  GError *error = NULL;

  gtk_init (&amp;argc, &amp;argv);

  /* main window */
  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_window_set_title (GTK_WINDOW (window), "Indicator Demo");
  gtk_window_set_icon_name (GTK_WINDOW (window), "indicator-messages-new");
  g_signal_connect (G_OBJECT (window),
                    "destroy",
                    G_CALLBACK (gtk_main_quit),
                    NULL);

  table = gtk_table_new (1, 5, FALSE);
  gtk_container_add (GTK_CONTAINER (window), table);

  /* Menus */
  action_group = gtk_action_group_new ("AppActions");
  gtk_action_group_add_actions (action_group,
                                entries, n_entries,
                                window);

  uim = gtk_ui_manager_new ();
  g_object_set_data_full (G_OBJECT (window),
                          "ui-manager", uim,
                          g_object_unref);
  gtk_ui_manager_insert_action_group (uim, action_group, 0);
  gtk_window_add_accel_group (GTK_WINDOW (window),
                              gtk_ui_manager_get_accel_group (uim));

  if (!gtk_ui_manager_add_ui_from_string (uim, ui_info, -1, &amp;error))
    {
      g_message ("Failed to build menus: %s\n", error->message);
      g_error_free (error);
      error = NULL;
    }

  menubar = gtk_ui_manager_get_widget (uim, "/ui/MenuBar");
  gtk_widget_show (menubar);
  gtk_table_attach (GTK_TABLE (table),
                    menubar,
                    0, 1,                    0, 1,
                    GTK_EXPAND | GTK_FILL,   0,
                    0,                       0);

  /* Document */
  sw = gtk_scrolled_window_new (NULL, NULL);

  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
                                  GTK_POLICY_AUTOMATIC,
                                  GTK_POLICY_AUTOMATIC);

  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw),
                                       GTK_SHADOW_IN);

  gtk_table_attach (GTK_TABLE (table),
                    sw,
                    /* X direction */       /* Y direction */
                    0, 1,                   3, 4,
                    GTK_EXPAND | GTK_FILL,  GTK_EXPAND | GTK_FILL,
                    0,                      0);

  gtk_window_set_default_size (GTK_WINDOW (window),
                               200, 200);

  contents = gtk_text_view_new ();
  gtk_widget_grab_focus (contents);

  gtk_container_add (GTK_CONTAINER (sw),
                     contents);

  /* Create statusbar */
  statusbar = gtk_statusbar_new ();
  gtk_table_attach (GTK_TABLE (table),
                    statusbar,
                    /* X direction */       /* Y direction */
                    0, 1,                   4, 5,
                    GTK_EXPAND | GTK_FILL,  0,
                    0,                      0);

  /* Show the window */
  gtk_widget_show_all (window);

  /* Indicator */
  indicator = app_indicator_new ("example-simple-client",
                                 "indicator-messages",
                                 APP_INDICATOR_CATEGORY_APPLICATION_STATUS);

  indicator_menu = gtk_ui_manager_get_widget (uim, "/ui/IndicatorPopup");

  app_indicator_set_status (indicator, APP_INDICATOR_STATUS_ACTIVE);
  app_indicator_set_attention_icon (indicator, "indicator-messages-new");

  app_indicator_set_menu (indicator, GTK_MENU (indicator_menu));

  gtk_main ();

  return 0;
}

Python version

PyGI
#!/usr/bin/env python
#
# Copyright 2009-2012 Canonical Ltd.
#
# Authors: Neil Jagdish Patel <neil.patel@canonical.com>
#          Jono Bacon <jono@ubuntu.com>
#          David Planella <david.planella@ubuntu.com>
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of either or both of the following licenses:
#
# 1) the GNU Lesser General Public License version 3, as published by the
# Free Software Foundation; and/or
# 2) the GNU Lesser General Public License version 2.1, as published by
# the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranties of
# MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
# PURPOSE.  See the applicable version of the GNU Lesser General Public
# License for more details.
#
# You should have received a copy of both the GNU Lesser General Public
# License version 3 and version 2.1 along with this program.  If not, see
# <www.gnu.org/licenses/>
#

from gi.repository import Gtk
from gi.repository import AppIndicator3 as appindicator

def menuitem_response(w, buf):
  print buf

if __name__ == "__main__":
  ind = appindicator.Indicator.new (
                        "example-simple-client",
                        "indicator-messages",
                        appindicator.IndicatorCategory.APPLICATION_STATUS)
  ind.set_status (appindicator.IndicatorStatus.ACTIVE)
  ind.set_attention_icon ("indicator-messages-new")

  # create a menu
  menu = Gtk.Menu()

  # create some
  for i in range(3):
    buf = "Test-undermenu - %d" % i

    menu_items = Gtk.MenuItem(buf)

    menu.append(menu_items)

    # this is where you would connect your menu item up with a function:

    # menu_items.connect("activate", menuitem_response, buf)

    # show the items
    menu_items.show()

  ind.set_menu(menu)

  Gtk.main()</pre>
PyGTK
#!/usr/bin/env python
#
# Copyright 2009 Canonical Ltd.
#
# Authors: Neil Jagdish Patel <neil.patel@canonical.com>
#          Jono Bacon <jono@ubuntu.com>
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of either or both of the following licenses:
#
# 1) the GNU Lesser General Public License version 3, as published by the
# Free Software Foundation; and/or
# 2) the GNU Lesser General Public License version 2.1, as published by
# the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranties of
# MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
# PURPOSE.  See the applicable version of the GNU Lesser General Public
# License for more details.
#
# You should have received a copy of both the GNU Lesser General Public
# License version 3 and version 2.1 along with this program.  If not, see
# <www.gnu.org/licenses>
#

import gobject
import gtk
import appindicator

def menuitem_response(w, buf):
  print buf

if __name__ == "__main__":
  ind = appindicator.Indicator ("example-simple-client",
                              "indicator-messages",
                              appindicator.CATEGORY_APPLICATION_STATUS)
  ind.set_status (appindicator.STATUS_ACTIVE)
  ind.set_attention_icon ("indicator-messages-new")

  # create a menu
  menu = gtk.Menu()

  # create some
  for i in range(3):
    buf = "Test-undermenu - %d" % i

    menu_items = gtk.MenuItem(buf)

    menu.append(menu_items)

    # this is where you would connect your menu item up with a function:

    # menu_items.connect("activate", menuitem_response, buf)

    # show the items
    menu_items.show()

  ind.set_menu(menu)

  gtk.main()
C# Example
using Gtk;
using AppIndicator;

public class IndicatorExample
{
        public static void Main ()
        {
                Application.Init ();

                Window win = new Window ("Test");
                win.Resize (200, 200);

                Label label = new Label ();
                label.Text = "Hello, world!";

                win.Add (label);

                ApplicationIndicator indicator = new ApplicationIndicator ("my-id",
                                                                           "my-name",
                                                                           Category.ApplicationStatus);

                indicator.Status = Status.Attention;

                /*
                Menu menu = new Menu ();
                menu.Append (new MenuItem ("Foo"));
                menu.Append (new MenuItem ("Bar"));

                indicator.Menu = menu;
                */

                win.ShowAll ();

                Application.Run ();
        }
}
Vala Example
/*
 * Copyright 2011 Canonical Ltd.
 *
 * This program is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 3, as published
 * by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranties of
 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
 * PURPOSE.  See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program.  If not, see <www.gnu.org/licenses/>.
 *
 * Authors:
 *   Marco Trevisan (Treviño) <3v1n0@ubuntu.com>
 *
 * Compile with:
 *   valac --pkg gtk+-3.0 --pkg appindicator3-0.1 indicator.vala
 */

using Gtk;
using AppIndicator;

public class IndicatorExample {
        public static int main(string[] args) {
                Gtk.init(ref args);

                var win = new Window();
                win.title = "Indicator Test";
                win.resize(200, 200);
                win.destroy.connect(Gtk.main_quit);

                var label = new Label("Hello, world!");
                win.add(label);

                var indicator = new Indicator(win.title, "indicator-messages",
                                              IndicatorCategory.APPLICATION_STATUS);

                indicator.set_status(IndicatorStatus.ACTIVE);
                indicator.set_attention_icon("indicator-messages-new");

                var menu = new Gtk.Menu();

                var item = new Gtk.MenuItem.with_label("Foo");
                item.activate.connect(() => {
                        indicator.set_status(IndicatorStatus.ATTENTION);
                });
                item.show();
                menu.append(item);

                item = new Gtk.MenuItem.with_label("Bar");
                item.show();
                item.activate.connect(() => {
                        indicator.set_status(IndicatorStatus.ATTENTION);
                });
                menu.append(item);

                indicator.set_menu(menu);

                win.show_all();

                Gtk.main();
                return 0;
        }
}
Haskell example
-- Either install the Haskell bindings through cabal (cabal install happindicator) or clone the git repository
-- at https://github.com/A1kmm/happindicator and install from there.

import Graphics.UI.AppIndicator
import Graphics.UI.Gtk
import Control.Monad

main = do
  initGUI
  appInd <- appIndicatorNew "appIndicatorDemo" "appointment-soon" AppIndicatorCategoryApplicationStatus
  appIndicatorSetStatus appInd AppIndicatorStatusActive
  set appInd [ appIndicatorAttentionIconName := Just "folder",
               appIndicatorIconDesc := Just "Demo - non-attention",
               appIndicatorAttentionIconDesc := Just "Demo - attention",
               appIndicatorLabel := Just "1" ]
  indMenu <- menuNew
  forM_ ["Hello", "World", "I'm a MenuItem"] $ \itemName -> do
    item <- menuItemNewWithLabel itemName
    menuShellAppend indMenu item
    item `on` menuItemActivate $ do
      appIndicatorSetStatus appInd AppIndicatorStatusAttention
    widgetShow item
  widgetShow indMenu
  appIndicatorSetMenu appInd indMenu
  mainGUI

We need your help!

Submit a tutorial

With your help, we can make this site grow to meet each developer's needs. Contribute by sharing your programming knowledge!

gipoco.com is neither affiliated with the authors of this page nor responsible for its contents. This is a safe-cache copy of the original web site.