Home Forums Wiki Doc Install Extras Screenshots Source Code Projects Blog Users Groups Register
Glx-Dock / Cairo-Dock Wiki Documentation
The latest stable release is the *3.4.0* : How to install it here.
Note: We just switched from BZR to Git on Github! (only to host the code and your future pull requests)
History View code

Glx-Dock / Cairo-Dock




en English

es Español

Support Us

Flattr this



This is the applet interface of Cairo-Dock. It provides an easy way to write applets in any languages.
Note: There is another interface to control the dock itself, with wrappers in many languages; see this page.

This page describes how to write an applet for Cairo-Dock. However, you may also be interesting in the following ressources:

There are 2 ways to write an applet for Cairo-Dock, depending on what kind of applet you want:
  • An applet that does fancy things, like some new 3D animations or OpenGL effects, or just that draws its icon dynamically, like a Clock.
    • In this case, go for the C API and let your hacker heart express itself !
  • An applet that just displays some values/text, responds to basic actions like click or scroll, adds entries in the menu and can pop-up dialogs, all in a convenient way.
    • In this case, pick up your favorite langage (yes, literally!), write few lines, and be happy with a functionnal applet !

Write a full-featured applet in C
Cairo-Dock is very modular: it comes with a core library (itself separated in several components) called libgldi (GL Desktop Interface). It exposes a clear and powerful API, that you can use to write any kind of applet.
Most of the time however, writing an applet in C is very straightforward, since a lot of convenient macros are provided.

To start:
Grab the sources, go into the plug-ins folder, and run the script generate-new-applet.sh; answer the few questions, install the applet, restart your dock, and voila! a new applet is available in the config window of Cairo-Dock.

To continue:
The best is to look at the code of some simple applets like Logout or ShowDesktop.
If you want to write a plug-in that extends the possibilities of the dock (not an applet which has an icon inside the dock), take a look at Icon-effects for instance.
The complete API is described at http://doc.glx-dock.org, or you can generate it by going into cairo-dock-core/doc and running generate-doc.sh.

Writing easily an applet in your favorite language
Whatever language you choose, the way is the same: write a class that inherits from the CDApplet class, and then override the methods you need.
Currently supported languages are Python, Ruby, Mono, Vala, and Bash. You can easily write an interface for any language that supports DBus (Java, Perl, etc).
A concrete exemple in Python is available at the end of this page. For other examples, please have a look to our demo applets (python/bash/ruby/mono/vala) : Bazaar Viewer

Overriding the methods you need
The methods available are:

Applet definition
  • begin : do here what you need to do when your applet is started
  • end: if you have anything to do when your applet is terminated
  • reload: reload your applet with the new config parameters
  • get_config: get your config parameters from the config keyfile.

Actions from the user
  • on_click: action to do when the user clicks on the icon
  • on_middle_click: same with middle-click
  • on_scroll: same with scroll up/down
  • on_build_menu: same with right-click (which opens the menu)
  • on_menu_select: action to do when the user selects one of the entries you added beforehand in the menu
  • on_drop_data: action to do when the user drops some data on the icon
  • on_answer_dialog: action to do when the user answers a dialog you raised beforehand
  • on_shortkey: action to do when the user triggers a shortkey you registered beforehand
  • on_change_focus: action to do when the user give or remove the focus on the window controlled by the applet

Acting on the icon
The CDApplet class holds the main icon of your applet (icon), and the sub-icons (the icons in the sub-dock, optional) (sub_icons). You can act on the icon and the sub-icons with several methods (examples are given in Python, you can easily adapt):

Sets the quick-info on our icon (this is a small text displayed on the icon).E.g.:

Sets the label of our icon (its name), overwriting the previous one. E.g.:

Sets the image of our icon, overwriting the previous one.
You can refer to the image by either its name if it's an image from a icon theme, or by a path. E.g.:

Sets an emblem on our icon. The emblem is drawn directly on the icon, so if you want to remove it, you have to use SetIcon with the original image.
The image is given by its path, and the position of the emblem is fixed by one of the following integer:
self.icon.SetEmblem("./emblem-charged.png", CDApplet.UPPER_RIGHT)

To erase the emblem you have to reset the icon, using SetIcon method with the default "icon" parameter.
Animates our icon, with a given animation and for a given number of rounds. E.g.:

Like the Animate method, but will animate the icon endlessly, and the icon will be visible even if the dock is hidden. If the animation is an empty string, or "default", the animation used when an application demands the attention will be used. The first argument is True to start demanding the attention, and False to stop it. E.g.:

Pops up a simple dialog bubble on our icon, with a given message and for a given duration (in seconds). The dialog can be closed by clicking on it. E.g.:
self.icon.ShowDialog("Cairo-Dock is great!",4)

Pops up a dialog bubble on our icon (since 2.2.0). The dialog can contain a message, an icon, some buttons, and a widget the user can act on.
To get the answer, you need to connect to the "on_answer_dialog" signal.
The dialog has several attributes, and the interaction widget too. Each of these are optionnal.
dialog attributes:
  • message (string) : the message of the dialog (empty by default)
  • icon (string) : an icon to be displayed next to the message (same icon as the applet by default)
  • time-length (int) : time length of the dialog, in second (unlimited duration by default)
  • force-above (bool): true to force the dialog above (use it with parcimony, false by default)
  • use-markup (bool) : true to use markups (HTML)
  • buttons (string) : images of the buttons, separated by comma ";". Adding buttons will trigger an on_answer_dialog signal when the user press one of them. "ok" and "cancel" are used as keywords for the default "ok" and "cancel" buttons defined by the dock.
widget attributes:
  • type (string) : type of the widget (can be "text-entry", "scale", "list")
text-entry attributes:
  • multi-lines (bool) : true to have a multi-lines text-entry, ie a text-view (false by default)
  • editable (bool) : whether the user can modify the text or not (true by default)
  • visible (bool) : whether the text will be visible or not (useful to type passwords) (true by default)
  • nb-chars (int) : maximum number of chars (the current number of chars will be displayed next to the entry) (infinite by default)
  • initial-value (string): text initially contained in the entry (empty by default)
scale attributes:
  • min-value (double) : lower value (0 by default)
  • max-value (double) : upper value (100 by default)
  • nb-digit (int) : number of digits after the dot (2 by default)
  • initial-value (double): value initially set to the scale (0 by default)
  • min-label (string) : label displayed on the left of the scale (empty by default)
  • max-label (string) : label displayed on the right of the scale (empty by default)
list attributes:
  • editable (bool) : true if a non-existing choice can be entered by the user (in this case, the content of the widget will be the selected text, and not the number of the selected line) (false by default)
  • values (string) : a list of values, separated by comma ";", used to fill the combo list.
  • initial-value (string or int, depending on the "editable" attribute) :
    • The initial selection (the number of line or the initial text depending on
    • The "editable" attribute) (0 or empty by default)
The following example pops up a simple message for 5 seconds:
self.icon.PopupDialog( {"message" : "Hello World!",
"time-length" : 5},
{} )

The following example pops up a dialog to select a password of 30 characters max:
self.icon.PopupDialog( {"message" : "Enter your password:",
"buttons" : "ok;cancel",
"icon" : "gtk-stock-edit"},
{"widget-type" : "text-entry",
"visible" : false,
"nb-chars" : 30} )

This method lets you add a data renderer, that is to say a gauge, graph, etc.
You define the data renderer with a type ("gauge", "graph"), the number of values to render, and a theme. E.g.:

Renders some values on your icon. You must have added a data renderer before with the previous method.
The number of values you send to the dock is the one you defined with the previous method. Values are given between 0 and 1. E.g.:
self.icon.RenderValues([0.7, 0.2])

Makes your applet control the window of an external application, instead of the Taskbar (Logout, MusicPlayer and System-Monitor use this feature).
The parameter is the class of the application you wish to control (which is most of the time the name of the appli, but not always; use "xprop | grep CLASS" to find it), or "none" to stop controlling any appli. You can then override the on_change_focus method if you need to track the active state of the application. E.g.:

Makes the application controlled by the icon (see ControlAppli) to get/lost focus depending on the parameter passed to the method. The parameters are True, and False to get, and lost focus respectively.
self.icon.ShowAppli(True) # bring to front the window controlled by the icon

Bind keyboard shortcuts to your applet (since 2.2.0). You can bind several shortkey at once, since the method takes an array as input.
Override the method on_shortkey to be notified when the shortkey is pressed. E.g.:

It allows you to add any kind of entries to the menu that is popped up on a right-click (so you can only use this method in the on_build_menu method).
It takes a an array of dicts as parameter. Each dict represents 1 menu-item.
The dict contains the properties of the menu-item in the form of variants :
  • type (integer) : 0 <-> normal entry, 1 <-> sub-menu, 2 <-> separator, 3 <-> check-box, 4 <-> grouped radio-box. By default it is 0.
  • label (string) : the text displayed in the menu-item.
  • icon (string) : a GTK stock icon, or the path to an image. (optionnal)
  • id (integer) : the ID of the menu-item, that will be passed to the on_menu_select method when it is selected by the user.
  • menu (integer) : the ID of a menu where the menu-item will be placed : 0 <-> the main menu, -1 <-> the default sub-menu (it is automatically built and contains at least the applet's handbook), another integer <-> the ID of a previously added sub-menu. By default it is -1.
  • state (boolean) : the state of the entry in the case of a check-box or a radio-button. By default it is False.
  • tooltip (string): a tooltip (message that will appear when you let the mouse over the item). (optionnal)
When the user chooses one of these entries, you will get a "on_menu_select" signal with the ID of the selected entry.
The following exemple in Python will insert a normal entry in the main menu, followed by a separator and a sub-menu, in which there will be a check-box and an entry, and will insert a group of 3 radio-buttons in the default sub-menu, the 2nd button being active.
self.icon.AddMenuItems( {"widget-type" : 0,
"label": "this is an entry of the main menu",
"icon" : "gtk-add",
"menu" : 0,
"id" : 1,
"tooltip" : "this is the tooltip that will appear when you hover this entry"},
{"widget-type" : 2,
"menu" : 0},
{"widget-type" : 1,
"label": "this is a sub-menu",
"icon" : "/path/to/image",
"menu" : 0,
"id" : 2},
{"widget-type" : 3,
"label": "this entry can be true or false",
"icon" : "/path/to/another/image",
"menu" : 1,
"state": True,
"id" : 101},
{"widget-type" : 0,
"label": "bla bla bla",
"menu" : 1,
"id" : 102},
{"widget-type" : 4,
"label": "you can choose this entry",
"menu" : -1,
"group": 201,
"id" : 201},
{"widget-type" : 4,
"label": "or this one",
"menu" : -1,
"group": 201,
"state": True,
"id" : 202},
{"widget-type" : 4,
"label": "or even this one",
"menu" : -1,
"group": 201,
"id" : 203} )

Get a property of the icon of your applet. Current available properties are :
  • x : x position of the icon's center on the screen (starting from 0 on the left)
  • y : y position of the icon's center on the screen (starting from 0 at the top of the screen)
  • width : width of the icon, in pixels (this is the maximum width, when the icon is zoomed)
  • height : height of the icon, in pixels (this is the maximum height, when the icon is zoomed)
  • container : type of container of the applet (DOCK, DESKLET)
  • orientation : orientation of the container on the screen (BOTTOM, TOP, RIGHT, LEFT). A desklet has always an orientation of BOTTOM.
  • Xid : ID of the application's window which is controlled by the applet, or 0 if none (this parameter can only be non nul if you used the method ControlAppli beforehand).
  • has_focus : whether the application's window which is controlled by the applet is the current active window (it has the focus) or not. E.g.:
    w = self.icon.Get(width")
Get all the available properties in a dictionnary. E.g.:
props = self.icon.GetAll()

Methods that act on the sub-icons are the same, except that they take as their first argument the ID of the icon (a unique string that you have assigned to each icon when using the AddSubIcons method).
self.sub_icons.SetQuickInfo("abc", "id1")

A concrete example in Python

# This is a part of the external demo applet for Cairo-Dock
# Copyright : (C) 2010-2011 by Fabounet
# E-mail : fabounet@glx-dock.org
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# GNU General Public License for more details.
# http://www.gnu.org/licenses/licenses.html#GPL

# The name of this applet is "demo_python"; it is placed in a folder named "demo_python", with a file named "auto-load.conf" which describes it.
# Copy this folder into ~/.config/cairo-dock/third-party to let the dock register it automatically.
# In the folder we have :
# - "demo_python" : the executable script, without extension
# - "demo_python.conf" : the default config file
# - "auto-load.conf" : the file describing our applet
# - "icon" : the default icon of the applet (optionnal)
# - "preview" : a preview of this applet (optionnal)

### This very simple applet features a counter from 0 to iMaxValue It displays the counter on the icon with a gauge and a quick info.
### Scroll on the icon increase or decrease the counter.
### The menu offers the possibility to set some default value.
### Left-click on the icon will set a random value.
### Middle-click on the icon will raise a dialog asking you to set the value you want.
### If you drop some text on the icon, it will be used as the icon's label.

### dependancies ###
import random
from CDApplet import CDApplet

### Applet class ###
class Applet(CDApplet):
    def __init__(self):
        # define internal variables
        self.count = 0
        # call high-level init
    ##### private methods #####
    def set_counter(self,count):
        self.count = count
        percent = float(self.count)/self.config['iMaxValue']
        self.icon.SetQuickInfo(format(self.count, "d"))
    ##### applet definition #####
    def get_config(self,keyfile):
        print "*** get config"
        self.config['cTheme']         = keyfile.get('Configuration', 'theme')
        self.config['iMaxValue']     = keyfile.getint('Configuration', 'max value')
        self.config['yesno']         = keyfile.getboolean('Configuration', 'yesno')
    def end(self):
        print "*** end of demo_python"
    def begin(self):
        print "*** begin"
        self.icon.ShowDialog("I'm connected to Cairo-Dock !", 4) # show a dialog with this message for 4 seconds.
        self.icon.AddDataRenderer("gauge", 1, self.config['cTheme']) # set a gauge with the theme read in config to display the value of the counter.
        self.set_counter(0) # set the initial value of our counter.
        self.sub_icons.AddSubIcons(["icon 1", "firefox-3.0", "id1", "icon 2", "trash", "id2", "icon 3", "thunderbird", "id3", "icon 4", "nautilus", "id4"]) # add 4 icons in our sub-dock. The tab contains triplets of {label, image, ID}.
        self.sub_icons.RemoveSubIcon("id2") # remove the 2nd icon of our sub-dock.
        self.sub_icons.SetQuickInfo("1", "id1") # write the ID on each icon of the sub-dock.
        self.sub_icons.SetQuickInfo("3", "id3")
        self.sub_icons.SetQuickInfo("4", "id4")
        self.icon.BindShortkey(["<Control>F9"]) # bind to ctrl+F9
    def reload(self):
        print "*** reload"
        self.icon.AddDataRenderer("gauge", 1, self.config['cTheme'])
        self.sub_icons.AddSubIcons(["icon 1", "firefox-3.0", "id1", "icon 2", "natilus", "id2", "icon 3", "thunderbird", "id3"])
    ##### callbacks #####
    def on_click(self,iState):
        print "*** click"
    def on_middle_click(self):
        print "*** middle click"
        dialog_attributes = {
            "icon" : "stock_properties",
            "message" : "Set the value you want",
            "buttons" : "ok;cancel"}
        widget_attributes = {
            "widget-type" : "scale",
            "max-value" : self.config['iMaxValue'],
            "message" : "Set the value you want"}
        self.icon.PopupDialog(dialog_attributes, widget_attributes)
    def on_build_menu(self):
        print "*** build menu"
        items = [ {
                "label": "set min value",
                "icon" : "gtk-zoom-out",
                "id" : 1
            }, {
                "label": "set medium value",
                "icon" : "gtk-zoom-fit",
                "id" : 2
            }, {
                "label": "set max value",
                "icon" : "gtk-zoom-in",
                "id" : 3
            } ]
    def on_menu_select(self,iNumEntry):
        print "*** choice",iNumEntry,"has been selected !"
        if iNumEntry == 1:
        elif iNumEntry == 2:
        elif iNumEntry == 3:
    def on_scroll(self,bScrollUp):
        print "*** scroll !"
        if bScrollUp:
            count = min(self.config['iMaxValue'], self.count+1)
            count = max(0, self.count-1)
    def on_drop_data(self,cReceivedData):
        print "*** received",cReceivedData
    def on_answer_dialog(self,button, answer):
        print "*** answer dialog :",button, answer
        self.set_counter(int (answer))
    def on_shortkey(self,key):
        print "*** shortkey :",key
### main ###
if __name__ == '__main__':

Editing the Applet's Configuration Window

The configuration window of an applet is reached with a right-click on the applet icon and selecting "configure this applet" or from the main configuration panel, by clicking on the button corresponding to the applet.
The content of the configuration window of the applet is loaded from the .conf file in the ~/.config/cairo-dock/current_theme/plugins/applet-name folder, where "applet-name" is the name of the applet. The .conf file is named after the applet, using the same spelling (case sensitive). The .conf file in the above mentioned folder is the user configuration file (hereafter named as such), which will change as the user makes his/her modifications. The original configuration file (hereafter named as such) file is found at ~/.config/cairo-dock/third-party/applet-name, where "applet-name" is the name of the applet.
If there is no user configuration file, or if this file's version number is inferior to the original configuration file's, a copy of the latter is used to create the former. In order for the user configuration file to update to the original, the original configuration file's version must be increased.
The configuration file's version number should be identical to the applet's version number. Prefer the classic format x.y.z. Change it each time you modify the .conf file.

Editing the Configuration File
The configuration file of an applet is a classical group/key file:
  • Lines starting with a # are comments.
  • Groups (or sections) are between brackets, eg. [section-name].
  • Keys are of the form key-name=value

A configuration file is filled with four types of data: comments, sections, widget descriptors and key=value pairs. Each occupies one line of the configuration file.
  • Comments are preceded by #, the first line of the configuration file is commented and stands for the version number of the configuration file.
  • Sections are describing and organising the content of the configuration file and configuration window. Sections are written between brackets eg. [section], where section is the section name. The sections [Icon] and [Desklet] should be there by default, usually these two sections are left untouched. Typically you use a third section [Configuration] followed by the data you require. Depending on the applet you are making, you may need other sections, which you can name as you wish. Each new section in the configuration file will appear as a new tab in the configuration window.
  • Widget descriptors are preceded by #. The information following # will change the type, icon and labels of the widget displayed in the configuration window. A list of these descriptors is available here below.
  • Key-Value pairs are identified by the = sign following the key name. The key is the variable name you need to retrieve for your code and the value is the value of that variable. The key name need not be the same as the variable in your code, but it is a good practice to call them the same, for better reading. The key can have no value, the equal sign is then followed by nothing (or a return sign depending on your perspective). To add a value to a key in the original configuration file will make it the default value. If you use a drop-down (aka. combo) list as a widget, make sure the default value is the first of the list or it may become confusing when opening the configuration window.

Reading from the Configuration File
The applet inherits a method from the CDApplet() class called get_config(self,keyfile). "keyfile" is a variable Cairo-Dock will recognise as the user configuration file object, hence there is no need to specify the path to it.
The configuration file object "keyfile" has several methods to fetch and load data to the applet:

  • keyfile.getstring(section, key)
  • keyfile.getint(section, key)
  • keyfile.getboolean(section, key)

In the above methods, section is a section name of the configuration file, which the method will recognize because it is written in brackets ([section]) and key is a key of the configuration file, the value of which you want to retrieve and which the method will recognise be cause it is followed by an equal sign (key=value).
NOTE TO REVIEWER: is there any other keyfile getter method?

Writing to the Configuration File
NOTE TO REVIEWER: is there any keyfile setter method to write to the configuration file?

List and Syntax of Widget Descriptors
NB: This list may not be exhaustive, but it strives to. Pleas add any if missing.

Tabs are automatically created for each new section in the configuration file.

Tab Icons
Tab icons, may precede the section name. The icon can be one of the Gtk Stock Icons (need documentation for Gtk Stock Icons) or an absolute path to another icon.

Frames can be used to group a certain type of data. The widget descriptor contains the label and optional icon. The icon again may be from Gtk Stock or absolute. Its widget descriptor needs to be followed by a key identifying the frame name variable. The variable will not appear on the configuration screen.

Combo/Drop-down Lists (integer)
Lists provide multiple choices for a user to choose from. The first item of this list should be the default value unless you have good reasons to do otherwise. Lists return integers as values to the key that follow them.
#l[option0;option1;option2] label-content

Combo/Drop-down Lists (strings)
Idem, but the list returns strings rather than integers:
#L[optionA;optionB;optionC] label-content
**Combo/Drop-down List for Animations**
Preformated list for choosing between existing animations. If no selection is made, the default animation will be used.
[code]#a Choose animation:

l+ list
NOTE TO REVIEWER: found that one in clock applet but not sure what difference it makes with other lists.
Check Buttons
Check button return a boolean as the value of the key that follows it.
#b label-content

Tool Tips
Tooltips appear when hovering a widget with the mouse pointer. They follow on the next line the widget they should support:

Horizontal Scale (int)
A horizontal scale returns an integer between the minimum and maximum integer defined by its descriptor.
#I[min-int;max-int] label-content

Horizontal Scale (float)
NOTE TO REVIEWER: please confirm.
A horizontal scale returns a float between the minimum and maximum integer defined by its descriptor.
#e+[min-float;max-float] label-content

Search Field
A search field is a text-input field and a search button. NOTE TO REVIEWER: I am not exactly sure of the usage of this widget.
#s label-content

Expanders are expandable/retractable frames. They save a lot of space on the window, so don't hesitate to use theme. Their descriptor can include an icon. Just like frame they must be followed by an empty key as their variable.
#X [label-content; icon-name]

Theme Chooser
Provides a list of themes from a folder, a description and a preview of the theme if any. NOTE TO REVIEWER: I am not exactly sure of the usage of this widget.

Colour Chooser
Color chooser returns a RGB value NOTE TO REVIEWER: please confirm. for the selected colour.
#C+ label

Font Chooser
Font chooser returns a font name and size in a single string.
#P+ label
key=font-name font-size

File Chooser (with button)
The file chooser has an input field for the path to file name and a button to browse and search the file instead.
#S+ label

Text Input
An input field for the user to fill.
#s label

Spin Box
A spin box returns an integer.
#i[min-int;max-int] label

descriptors starting with "#_" or "Add and Remove" descriptors
NOTE TO REVIEWER: I didn't figure out how these works yet eg. Clock applet or Mail applet.
more widgets?
Please append if necessary.

Glx-Dock / Cairo-Dock Wiki Documentation Top

Online users :

Powered by ElementSpeak © 2007 Adrien Pilleboue, 2009-2013 Matthieu Baerts.
Dock based on CSS Dock Menu (Ndesign) with jQuery. Icons by zgegball
Cairo-Dock is a free software under GNU-GPL3 licence. First stable version created by Fabounet.
Many thanks to TuxFamily for the web Hosting and Mav for the domain name.