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)
Information : The version displayed on this page is not the latest available.
History View code

Glx-Dock / Cairo-Dock

Home

History

Language

en English

es Español

Support Us

Flattr this

Cairo-Dockon

Documentation

Do you want to create your own applet? Add a new feature to the current code ? Or just control your dock through DBus?


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

Writing or improving an applet
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:
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".

Write simply 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 support DBus (Java, Perl, etc).
A concrete exemple in Python is available in the end of this page.

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):

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

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

SetIcon
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.:
self.icon.SetIcon("gimp")
self.icon.SetIcon("gtk-go-up")
self.icon.SetIcon("/path/to/image")

SetEmblem
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:
UPPER_LEFT, LOWER_RIGHT, LOWER_LEFT, UPPER_RIGHT, MIDDLE E.g.:
self.icon.SetEmblem("./emblem-charged.png", UPPER_RIGHT)

Animate
Animates our icon, with a given animation and for a given number of rounds. E.g.:
self.icon.Animate("default",2)
self.icon.Animate("fire",30)

DemandsAttention
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.:
self.icon.DemandsAttention(True,"bounce")
self.icon.DemandsAttention(False,"")

ShowDialog
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)

PopupDialog
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. E.g.:
self.icon.PopupDialog( {"message" : "Hello World!",
"time-length" : 5},
{} )

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


AddDataRenderer
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.:
self.icon.AddDataRenderer("gauge",2,"Turbo-night-fuel")

RenderValues
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])

ControlAppli
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.:
self.icon.ControlAppli("pidgin")

ShowAppli
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.
E.g.:
self.icon.ShowAppli(True) # bring to front the window controlled by the icon

BindShortkey
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.:
self.icon.BindShortkey(["<Control>F8","<Control><Shift>Z"])

AddMenuItems
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. E.g.:
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
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")

GetAll
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).

A concrete example in Python
#!/usr/bin/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
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# 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
        CDApplet.__init__(self)
    
    ##### private methods #####
    
    def set_counter(self,count):
        self.count = count
        percent = float(self.count)/self.config['iMaxValue']
        self.icon.RenderValues([percent])
        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.icon.RenderValues([float(self.count)/self.config['iMaxValue']])
        self.sub_icons.RemoveSubIcon("any")
        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"
        self.set_counter(random.randint(0,self.config['iMaxValue']))
    
    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
            } ]
        self.icon.AddMenuItems(items)
        
    def on_menu_select(self,iNumEntry):
        print "*** choice",iNumEntry,"has been selected !"
        if iNumEntry == 1:
            self.set_counter(0)
        elif iNumEntry == 2:
            self.set_counter(self.config['iMaxValue']/2)
        elif iNumEntry == 3:
            self.set_counter(self.config['iMaxValue'])
    
    def on_scroll(self,bScrollUp):
        print "*** scroll !"
        if bScrollUp:
            count = min(self.config['iMaxValue'], self.count+1)
        else:
            count = max(0, self.count-1)
        self.set_counter(count)
    
    def on_drop_data(self,cReceivedData):
        print "*** received",cReceivedData
        self.icon.SetLabel(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__':
    Applet().run()


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.