Home Forums Wiki Doc Install Extras Screenshots Source Code Projects Blog Users Groups Register
Glx-Dock / Cairo-Dock Wiki Control_your_dock_with_DBus
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

fr Français

ru Russian

Support Us

Flattr this

Cairo-Dockon

Control_your_dock_with_DBus

The DBus API is a powerful way to write an applet in any language, or simply to control your dock from a script or a terminal.
To propose an applet to the community, the easiest way is to create your personal branch on Launchpad, and upload your sources there.
Alternatively you can upload a tarball on a hosting site, but using BZR on Launchpad is really simple and convenient; for more information, please see this link : Help us with BZR


Control your dock with DBus

The purpose of this tutorial
Dbus is an Inter Process Communication program, that is to say, it lets you send and receive messages to any application that is connected to DBus.
Cairo-Dock comes with a powerful DBus interface. Here we'll fully describe it and provide many useful exemples to show how you can control your dock from a script or a terminal, and even write a complete applet.

First Step
This tutorial is made for Cairo-Dock 2.1.3 or later. If your version is older, it is strongly recommended to upgrade, because the dock improves itself at each new version.
To get the latest version, use our repository, or grab the packages on LaunchPad, or install from the sources. This is fully explained on our wiki (http://wiki.glx-dock.org).
Be sure to install the plug-ins too.

You need to activate the "DBus" plug-in in the config panel of the dock. In the config panel of the plug-in, be sure that all the operations are allowed, for the examples.

The interface :
  • Several programs are connected to the bus; to talk to one program in particular, you have to specify the name of its service on the bus. For Cairo-Dock, the name is :
    org.cairodock.CairoDock
  • Each program loads some remote objects on the bus, that other applis can grab and use to communicate with the program. These remote objects are stored at a given path. Cairo-Dock stores 1 main object at the path
    /org/cairodock/CairoDock
  • Each object has one or several interface(s). An interface is a collection of methods (messages you can send to the program) and signals (messages the program will send you). The main object has a unique interface, named
    org.cairodock.CairoDock

Note : Actually Cairo-Dock provides other objects, associated with remote applets. We'll see that in the last part of this tutorial.

  • We'll give our exemples in bash, so that you can try them by simply copy-paste the commands inside a terminal.
  • The command to send a message on the bus is :
    dbus-send
    .
  • To talk to Cairo-Dock, we use the following command :
    dbus-send --session --dest=org.cairodock.CairoDock /org/cairodock/CairoDock org.cairodock.CairoDock.xxx type1:arg1 type2:arg2 ...
    where xxx is the name of the message to send, followed by the arguments : type is the type of an argument (string, int32, boolean, etc), and arg is the argument ("some text", 123, true, etc).


Act on the dock :

Reboot
It will completely reload the current theme, as if you had quitted and restarted the dock.
dbus-send --session --dest=org.cairodock.CairoDock /org/cairodock/CairoDock org.cairodock.CairoDock.Reboot


Quit
It will quit the dock, as if you killed it but in a more proper way.
dbus-send --session --dest=org.cairodock.CairoDock /org/cairodock/CairoDock org.cairodock.CairoDock.Quit


ReloadModule
It will reload a given module, as if you entered its config panel and applied.
You can use it after making some modification in its conf file, for instance.
Thus, you may make some modification to the Dustbin's conf file (using sed), and then apply the modifications with the following command :
dbus-send --session --dest=org.cairodock.CairoDock /org/cairodock/CairoDock org.cairodock.CairoDock.ReloadModule string:dustbin


ShowDock
It will show or hide the dock, depending on the argument you specify (if you have several docks, it will show/hide all of them).
For instance, you may quick-hide the dock with the following command :
dbus-send --session --dest=org.cairodock.CairoDock /org/cairodock/CairoDock org.cairodock.CairoDock.ShowDock boolean:false


ShowDesklet
It will toggle the visibility of the desklets, like a "show-desktop" would do, but only for the desklets' windows.
The argument lets you specify if you also want to show the desklets placed on the Compiz Widget Layer.
dbus-send --session --dest=org.cairodock.CairoDock /org/cairodock/CairoDock org.cairodock.CairoDock.ShowDesklet boolean:true


LoadLauncherFromFile
It will load a desktop file, creating a new launcher into the dock.
It takes the path to the desktop file as parameter.
The following command creates a Nautilus launcher (the path may vary depending on your distribution, and if Nautilus is installed or not).
dbus-send --session --dest=org.cairodock.CairoDock /org/cairodock/CairoDock org.cairodock.CairoDock.LoadLauncherFromFile string:/usr/share/applications/nautilus.desktop

The icon will appear into the dock, but only until the dock restarts (and will not be editable); if you want to make it permanent, you have to copy before the desktop file into the launcher directory of the dock :
cp /usr/share/applications/nautilus.desktop ~/.config/cairo-dock/current_theme/launchers


CreateLauncherFromScratch
It will create a temporary launcher from scratch : you specify the image, name, and command of the launcher, plus the name of the dock where it should be placed (or "none" to place it inside the main dock).
If you want to make it permanent, you have to create a .desktop file, filled with the vales you want, and copy it into ~/.config/cairo-dock/current_theme/launchers.
The following command creates a launcher named "my launcher", with the icon "/path/to/image", and the command "xterm -e 'echo pouet'", and place it inside the main dock.
dbus-send --session --dest=org.cairodock.CairoDock /org/cairodock/CairoDock org.cairodock.CairoDock.CreateLauncherFromScratch string:"/path/to/image" string:"my launcher" string:"xterm -e 'echo pouet'" string:none


Act on the icons
Icons are refered by their name and/or their command, or by the module's name in the case of an applet.
Each of the following methods takes 3 strings as their last arguments, which are {icons's name; icon's command; module's name} (in this order).
This should allow you to point the icon you want. Let the other strings to "none" or "any".
For exemple, to find the firefox launcher, you can use the strings {"any"; "firefox"; "none"} to say : the icon with the command "firefox", with any label, and no module.
To find the Dustbin applet, you can use the strings {"any"; "none"; "dustbin"} to say : the icon with any label, no command, and the module "dustbin".
The case is not taken into account.
You can specify only the beginnig of the command, the dock will search any icon whose command starts with the given string (like a "grep command*")
For instance, if you want to point to the Amarok launcher, you should use the string "amarok", the dock will find the launchers with the command "amarok" and "amarokapp" (both are valid command to launch amarok).

SetQuickInfo
Sets the quick-info on a given icon (this is a small text displayed on the icon).
The following command write "123" on the dustbin applet, overwriting the number of files in the Trash if it was displayed.
dbus-send --session --dest=org.cairodock.CairoDock /org/cairodock/CairoDock org.cairodock.CairoDock.SetQuickInfo string:123 string:none string:none string:dustbin


SetLabel
Sets the label of an icon (its name), overwriting the previous one.
The following command sets the name "Fabounet" on the gnome-terminal launcher.
dbus-send --session --dest=org.cairodock.CairoDock /org/cairodock/CairoDock org.cairodock.CairoDock.SetLabel string:"Fabounet" string:any string:gnome-terminal string:none


SetIcon
Sets the image of an 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.
The following command sets the image of Firefox on the Nautilus launcher.
dbus-send --session --dest=org.cairodock.CairoDock /org/cairodock/CairoDock org.cairodock.CairoDock.SetIcon string:firefox-3.0 string:none string:nautilus string:none


SetEmblem
Sets an emblem on an 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 an integer :
0 = UPPER_LEFT, 1 = LOWER_RIGHT, 2 = LOWER_LEFT, 3 = UPPER_RIGHT, 4 = MIDDLE
The following command draws an arrow in the lower left corner of the Nautilus launcher.
dbus-send --session --dest=org.cairodock.CairoDock /org/cairodock/CairoDock org.cairodock.CairoDock.SetEmblem string:/usr/share/icons/gnome/32x32/actions/gtk-go-down.png int32:3 string:none string:nautilus string:none


Animate
Animates an icon, with a given animation and for a given number of rounds.
The following command launches the default animation on the firefox launcher for 2 rounds.
dbus-send --session --dest=org.cairodock.CairoDock /org/cairodock/CairoDock org.cairodock.CairoDock.Animate string:default int32:2 string:any string:firefox string:none

The following command will make the Clock applet burn for 1 or 2 minutes, or until you fly over it with the mouse.
dbus-send --session --dest=org.cairodock.CairoDock /org/cairodock/CairoDock org.cairodock.CairoDock.Animate string:fire int32:60 string:none string:none string:clock


ShowDialog
Pops up a dialog bubble with a message on a given icon and for a given duration (in seconds). If the icon is not found, it displays the message as a general message. The dialog can be closed by clicking on it.
The following command will pop up a dialog saying "Cairo-Dock is great !" for 5 seconds, which is perfectly true
dbus-send --session --dest=org.cairodock.CairoDock /org/cairodock/CairoDock org.cairodock.CairoDock.ShowDialog string:"Cairo-Dock is great \!" int32:5 string:none string:none string:none


Write a DBus applet
There is a second interface, named
org.cairodock.CairoDock.applet

It contains methods and signals to interact on a distant applet (that is to say, an applet that has been loaded from outside of the dock).
This allows to write complete applets that are loaded into the dock from another process.

To make the applet auto-activated by the dock, you need to place it in ~/.config/cairo-dock/third-party.
Then when your applet is launched by the dock, you will :
  • grab the remote object associated on the bus => this will let us use the DBus interface.
  • connect to the signals to listen for events on the applet (clic, reload, etc), and use methods to act on it (change its image, animate the icon, etc)
  • do your stuff

Make your applet auto-loaded
This is done very simply through a file named auto-load.conf, placed within the applet's folder.
The file contains the following keys :
  • author : your name
  • description : a short description of the applet and how to use it.
  • category : the category of the applet (2 = accessory, 3 = Desktop, 4 = Controler)
  • version : Version of the applet; change it everytime you change something in the config file. Don't forget to update the version both in this file and in the config file.

There are also few rules to respect; let's say we are makking an applet called "demo".
  • All the files must be contained in a folder, named like the applet. Here, the folder containing all the files is named "demo".
  • The folder itself must be placed either in /usr/share/cairo-dock/plug-ins/Dbus/third-party, or in ~/.config/cairo-dock/third-party. So here, you'll place all your files in ~/.config/cairo-dock/third-party/demo.
  • The folder must contain the following files :
      • the script of the applet, named as the applet; here the script is called "demo", whatever language it uses
      • the default config file, named like the applet with the ".conf" suffix, so here it will be "demo.conf"
      • a default icon, named "icon" without the suffix (the dock can guess the format of the image)
      • a preview of the applet, an image named "preview" without the suffix, like the icon (this one is optionnal)
      • the auto-load.conf.

The .conf file should be filled with some default parameters so that the applet is usable immediately. It should contain at least the groups "Icon" and "Desklet", as any other applet (you can just copy the logout.conf from the Logout applet to start with).

Grab the object
Before our script is launched by the dock, Cairo-Dock creates a remote object on the bus. It represents the applet and its icon. It is stored at
/org/cairodock/CairoDock/name-of-the-applet

So in our exemple, the path is : /org/cairodock/CairoDock/demo.
This object has a unique interface, named
org.cairodock.CairoDock.applet

So in bash, we can access this interface with the following command :
dbus-send --session --dest=org.cairodock.CairoDock /org/cairodock/CairoDock/demo org.cairodock.CairoDock.applet.xxx type1:arg1 type2:arg2 ...
where xxx is the name of the message to send, followed by the arguments : type is the type of an argument (string, int32, boolean, etc), and arg is the argument ("some text", 123, true, etc).

Ok we have a new applet inside the dock, and its corresponding remote object on the bus; now let's see how to act on it.

Act on the applet
The followinf methods are provided by the interface to act on the applet; they look like the ones to act on any icon, but they target the icon of your applet only.

SetQuickInfo
Sets the quick-info on our icon (this is a small text displayed on the icon).
dbus-send --session --dest=org.cairodock.CairoDock /org/cairodock/CairoDock/demo org.cairodock.CairoDock.applet.SetQuickInfo string:123


SetLabel
Sets the label of our icon (its name), overwriting the previous one.
dbus-send --session --dest=org.cairodock.CairoDock /org/cairodock/CairoDock/demo org.cairodock.CairoDock.applet.SetLabel string:"Fabounet"


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.
dbus-send --session --dest=org.cairodock.CairoDock /org/cairodock/CairoDock/demo org.cairodock.CairoDock.applet.SetIcon string:firefox-3.0


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 an integer :
0 = UPPER_LEFT, 1 = LOWER_RIGHT, 2 = LOWER_LEFT, 3 = UPPER_RIGHT, 4 = MIDDLE
dbus-send --session --dest=org.cairodock.CairoDock /org/cairodock/CairoDock/demo org.cairodock.CairoDock.applet.SetEmblem string:/usr/share/icons/gnome/32x32/actions/gtk-go-down.png int32:3


Animate
Animates our icon, with a given animation and for a given number of rounds.
dbus-send --session --dest=org.cairodock.CairoDock /org/cairodock/CairoDock/demo org.cairodock.CairoDock.applet.Animate string:default int32:2

dbus-send --session --dest=org.cairodock.CairoDock /org/cairodock/CairoDock/demo org.cairodock.CairoDock.applet.Animate string:fire int32:60


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.
dbus-send --session --dest=org.cairodock.CairoDock /org/cairodock/CairoDock/demo org.cairodock.CairoDock.applet.DemandsAttention boolean:True string:"bounce"

dbus-send --session --dest=org.cairodock.CairoDock /org/cairodock/CairoDock/demo org.cairodock.CairoDock.applet.DemandsAttention boolean:False string:""


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.
dbus-send --session --dest=org.cairodock.CairoDock /org/cairodock/CairoDock/demo org.cairodock.CairoDock.applet.ShowDialog string:"Cairo-Dock is great \!" int32:5


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.
dbus-send --session --dest=org.cairodock.CairoDock /org/cairodock/CairoDock/demo org.cairodock.CairoDock.applet.PopupDialog dict:string:variant:"message","Hello world!","time-length",5 dict:string:variant:"widget-type","none"

The following example pops up a dialog to select a password of 30 characters max.
dbus-send --session --dest=org.cairodock.CairoDock /org/cairodock/CairoDock/demo org.cairodock.CairoDock.applet.PopupDialog
dict:string:variant:"message","Enter your password:","buttons","ok;cancel","icon","gtk-stock-edit"
dict:string:variant:"widget-type","text-entry","visible",false,"nb-chars",30

The following example pops up a dialog to select a temperature in Celsius.
dbus-send --session --dest=org.cairodock.CairoDock /org/cairodock/CairoDock/demo org.cairodock.CairoDock.applet.PopupDialog
dict:string:variant:"message","Select the temperature:","buttons","ok;cancel","icon","/path/to/thermometer.png"
dict:string:variant:"widget-type","scale","min-value",-20,"max-value",50,"nb-digit",1,"min-label","cold","max-label","hot","initial-value",15


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.
dbus-send --session --dest=org.cairodock.CairoDock /org/cairodock/CairoDock/demo org.cairodock.CairoDock.applet.AddDataRenderer string:gauge int32:2 string:"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.
dbus-send --session --dest=org.cairodock.CairoDock /org/cairodock/CairoDock/demo org.cairodock.CairoDock.applet.RenderValues array:double:.7,.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 connect to the on_change_focus signal if you need to track the active state of the application.
dbus-send --session --dest=org.cairodock.CairoDock /org/cairodock/CairoDock/demo org.cairodock.CairoDock.applet.ControlAppli string:pidgin


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.
Connect to the signal on_shortkey to be notified when the shortkey is pressed.
dbus-send --session --dest=org.cairodock.CairoDock /org/cairodock/CairoDock/demo org.cairodock.CairoDock.applet.BindShortkey array:string:"<Control>F8","<Control><Shift>Z"


PopulateMenu
Add entries to the menu that is popped up on a right-click on the applet's icon (so you can only use this method after you received a on_build_menu signal).
It takes a NULL-terminated array of strings as parameter. Each string of the array will be displayed as an entry in the menu.
When the user choose one of these entries, you will get a "on_menu_select" signal with the number of the selected entry.
dbus-send --session --dest=org.cairodock.CairoDock /org/cairodock/CairoDock/demo org.cairodock.CairoDock.applet.PopulateMenu array:string:"a choice","another choice"


AddMenuItems
An enhanced version of PopulateMenu. 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 after you received a on_build_menu signal).
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 callback when it is selected by the user (in the case of a sub-menu, it is used to reference this menu; in case of a separator, the id is useless).
  • 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 choose 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.
items = [ {
    "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
} ]
icon.AddMenuItems(items)


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 (0 : dock, 1 : desklet)
orientation : orientation of the container on the screen (0 : bottom, 1 : top, 2 : right, 3 : left). A desklet has always an orientation of 0.
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.
dbus-send --session --dest=org.cairodock.CairoDock /org/cairodock/CairoDock/demo org.cairodock.CairoDock.applet.Get string:"width"


GetAll
Get all the available properties in a dictionnary.
dbus-send --session --dest=org.cairodock.CairoDock /org/cairodock/CairoDock/demo org.cairodock.CairoDock.applet.GetAll


Great, we can make our applet live inside the dock !
Now what we want to do is to be notified when the user clicks on the icon or such things. We'll have to connect to some signals; then each time the corresponding event occurs, the signal will be broadcasted to us, possibly with some parameters.

Signals
The DBus interface contains some signals, that is to say Cairo-Dock will emit a signal when some event occurs inside the dock.
You can register to these actions, and thus be notified of the events.
You can then react to these events, as if you were inside the dock.

on_click
Signal received when the user clicks on the icon.
We receive : an integer that says if some special key were activated (Ctrl, Shift or Super).

on_middle_click
Signal received when the user middle-clicks on the icon.
No argument.

on_scroll
Signal received when the user scrolls on the icon.
We receive : a boolean that is true if the user scrolled up, and false if the user scrolled bottom.

on_build_menu
Signal received when the user right-clicks on the icon.
No argument.
You can populate the menu thanks to the PopulateMenu method :
dbus-send --session --dest=org.cairodock.CairoDock /org/cairodock/CairoDock/demo org.cairodock.CairoDock.applet.PopulateMenu array:string:"choice 0","choice 1"


on_drop_data
Signal received when the user drops something on the icon.
We receive : the received text or url.

on_change_focus
Signal received when the window controlled by your applet has become the current active window or not. You can only receive this signal if you used the ControlAppli method beforehand to control an application.
We receive : a boolean that is True is the window has just become active, and False if it has just become inactive (lost the focus).

on_menu_select
Signal received when the user chooses an entry in the menu. The entries are the one you added in the meun with the PopulateMenu method.
We receive : the number of the selected entry, from 0.

on_answer_dialog
Signal received when the user answers to a dialog raised beforehand by the applet.
We receive : the number of the button that was clicked (starting from 0), and the content of the dialog, which is a variant (a boolean, an int, a double, or a string).
The user can also press the Enter and Escape keys; the Enter key will give a clicked_button of -1, the Escape will give -2.
The variant contains the interaction widget's content. For a text-entry, it will be the string entered by the user, for a scale it will be the selected value, for a list it will be the number of the selected row, or (if the list is editable), the content of the text-entry.

on_shortkey
Signal received when the user pressed one of the shortkeys that have been bound to the applet.
We receive : the shortkey that has been pressed.

on_reload_module
Signal received when the module is reloaded.
We receive : a boolean that is true if the config has changed and false if it was just a reload because of a resize.

on_stop_module
Signal received when the module is stopped (because the dock is closed or because the user has deactivated the module).
No argument.

Sub-dock
Is is possible to have a sub-dock with sub-icons inside (or sub-icons inside the desklet if the user has choosed to detach the applet). For this purpose, Cairo-Dock creates a second object, so that you can interact on the sub-icons, in the same way as you do on the main icon. As it would be tough to maintain an up-to-date list of remote objects for all the sub-icons, only 1 object is created to manage all the sub-icons. To distinguish sub-icons between each other, you'll give an ID to each of them when you load them; this ID will be used in all the methods and signals concerning the sub-icons.

Note : The default view for sub-docks is used. For desklet, the 3D Caroussel is used.
The object is stored at
/org/cairodock/CairoDock/name-of-the-applet/subicons

So in our exemple, the path is : /org/cairodock/CairoDock/demo/subicons.
It has a unique interface, named
org.cairodock.CairoDock.subapplet


AddSubIcons
This will load one or several sub-icons. It takes a NULL-terminated array of strings as parameter.
The array contains 3xN strings, and will be read by triplets : {name, icon, ID}, where name is the name the sub-icon will have, icon is an image to set on the icon, and ID is an unique ID that will identify the sub-icon amongst the others.
dbus-send --session --dest=org.cairodock.CairoDock /org/cairodock/CairoDock/demo/sub_icons org.cairodock.CairoDock.subapplet.AddSubIcons array:string:"first icon","firefox","id1","second icon","nautilus","id2"


RemoveSubIcon
This allow you to remove one or all the sub-icons you have previously loaded.
It takes the ID of the icon you want to remove, or NULL or "any" to remove them all.
dbus-send --session --dest=org.cairodock.CairoDock /org/cairodock/CairoDock/demo/sub_icons org.cairodock.CairoDock.subapplet.RemoveSubIcon string:"id2"


Methods and signals on the sub-icons
The methods and signals available on the sub-icons are esesntially the same as for the main icon. The only difference is that they will all take the icon ID as the last parameter.
You have the following methods : SetQuickInfo, SetLabel, SetIcon, Animate, ShowDialog
and the following signals : on_click_sub_icon, on_middle_click_sub_icon, on_scroll_sub_icon, on_build_menu_sub_icon, on_menu_select_sub_icon, on_drop_data_sub_icon
The PouplateMenu method is independant of the clicked icon (from the point of view of the dock), and therefore is not duplicated here; use the interface on the applet object to populate the menu when you receive a "on_menu_select_sub_icon" signal.
dbus-send --session --dest=org.cairodock.CairoDock /org/cairodock/CairoDock/demo/sub_icons org.cairodock.CairoDock.subapplet.SetLabel string:"new_label" string:"id1"


Conclusion :
The remote control interface of Cairo-Dock allows you to interact on the dock, modify the icons, and even write new applets without needing to dig into the C API of the dock. You can use it anywhere, inside a program, a script, or even a terminal, and with the language of your choice.

I hope this little guide was helpful. If you have any comment/suggestion, feel free to write me at fabounet (at) users [dot] berlios -dot- de, or pay us a visit at http://glx-dock.org !

Fabounet.


External applet
Demos
You can find two demos in the source code (cairo-dock-plug-ins/Dbus/demo) but we also regroup all stable external applets here

How to start it automatically?
Simply move your folder to ~/.config/cairo-dock/third-party/. This folder (e.g. MY_APPLET) have to contain your script (named 'MY_APPLET' without any extension), an image named 'icon' and a .conf file (e.g. MY_APPLET.conf). You can also put there all the other files that your applet will need.

How to share it with the community?
We try to regroup all external applets on BZR. It's really easy to upload your applet on a personal branch linked to the cairo-dock-plug-ins-extras part of Cairo-Dock project. Take a look at this link: Help us with BZR

Tips :
If you want to launch a dbus command with a cron, add "DISPLAY=:0" before your command. For example :
* * * * * DISPLAY=:0 /usr/bin/dbus-send --session --dest=org.cairodock.CairoDock /org/cairodock/CairoDock org.cairodock.CairoDock.Animate string:default int32:2 string:any string:firefox string:none


A complete exemple :
The following exemple is an applet called "demo_python".
Here is the content of the "demo_python" file :
#!/usr/bin/python
### 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), "demo_python.conf" (the default config file), "auto-load.conf" (the file describing our applet), "icon" (the default icon of the applet) and "preview" (a preview of this applet)

### 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 sys
import os.path
import ConfigParser
import random
import gobject
import glib
import dbus
from dbus.mainloop.glib import DBusGMainLoop

##################################
### get our applet on the bus ###
##################################
applet_name = os.path.basename(os.path.abspath(".")) # the name of the applet must the same as the folder.
applet_path = "/org/cairodock/CairoDock/"+applet_name # path where our object is stored on the bus.
DBusGMainLoop(set_as_default=True)
bus = dbus.SessionBus()
try:
    applet_object = bus.get_object("org.cairodock.CairoDock", applet_path)
except dbus.DBusException:
    print ">>> module '"+applet_name+"' can't be found on the bus, exit."
    sys.exit(2)
myIcon = dbus.Interface(applet_object, "org.cairodock.CairoDock.applet") # this object represents our applet and also our icon. It can be either in a dock or in a desklet, we don't have to care.

### we'll have a sub-dock, so we also get the sub-icons object ###
sub_icons_object = bus.get_object("org.cairodock.CairoDock", applet_path+"/sub_icons")
mySubIcons = dbus.Interface(sub_icons_object, "org.cairodock.CairoDock.subapplet") # this object represents the list of icons contained in our sub-dock, or in our desklet. We'll add them one by one later, giving them a unique ID, which will be used to identify each of them.

##################################
### callbacks on the main icon ###
##################################
def action_on_click(iState):
    print ">>> clic !"
    set_counter(random.randint(0,myApplet.config['iMaxValue']))

def action_on_middle_click():
    print ">>> middle clic !"
    myIcon.PopupDialog({"message":"Set the value you want"}, {"widget-type":"scale", "max-value":myApplet.config['iMaxValue'], "initial-value":myApplet.count})

def action_on_build_menu():
    print ">>> build menu !"
    myIcon.PopulateMenu(["set min value", "set medium value", "set max value"])
    
def action_on_menu_select(iNumEntry):
    print ">>> choice",iNumEntry,"has been selected !"
    if iNumEntry == 0:
        myApplet.set_counter(0)
    elif iNumEntry == 1:
        myApplet.set_counter(myApplet.config['iMaxValue']/2)
    elif iNumEntry == 2:
        myApplet.set_counter(myApplet.config['iMaxValue'])

def action_on_scroll(bScrollUp):
    print ">>> scroll !"
    if bScrollUp:
        count = min(myApplet.config['iMaxValue'], myApplet.count+1)
    else:
        count = max(0, myApplet.count-1)
    myApplet.set_counter(count)

def action_on_drop_data(cReceivedData):
    print ">>> received",cReceivedData
    myApplet.icon.SetLabel(cReceivedData)

def action_on_answer_dialog(button,answer):
    print ">>> answer :",answer,buttons
    if button == 0 or button == -1:
        myApplet.set_counter(int (answer))

##################################
### callbacks on the sub-icons ###
##################################
def on_click_sub_icon(iState, cIconID):
    print "clic on the sub-icon '"+cIconID+"' !"

###############################
### callbacks on the applet ###
###############################
def action_on_stop():
    print ">>> our module is stopped"
    loop.quit()

def action_on_reload(bConfigHasChanged):
    print ">>> our module is reloaded"
    if bConfigHasChanged:
        print ">>> and our config has changed"
        myApplet.get_config()
        myApplet.icon.AddDataRenderer("gauge", 1, myApplet.config['cTheme'])
        myApplet.icon.RenderValues([float(myApplet.count)/myApplet.config['iMaxValue']])
        myApplet.sub_icons.RemoveSubIcon("any")
        myApplet.sub_icons.AddSubIcons(["icon 1", "firefox-3.0", "id1", "icon 2", "natilus", "id2", "icon 3", "thunderbird", "id3"])

##########################
### connect to signals ###
##########################
myIcon.connect_to_signal("on_click", action_on_click) # when the user left-clicks on our icon.
myIcon.connect_to_signal("on_middle_click", action_on_middle_click) # when the user middle-clicks on our icon.
myIcon.connect_to_signal("on_build_menu", action_on_build_menu) # when the user right-clicks on our applet (which builds the menu)
myIcon.connect_to_signal("on_menu_select", action_on_menu_select) # when the user selects an entry of this menu.
myIcon.connect_to_signal("on_scroll", action_on_scroll) # when the user scroll up or down on our icon.
myIcon.connect_to_signal("on_drop_data", action_on_drop_data) # when the user drops something on our icon.
#myIcon.connect_to_signal("on_init_module", action_on_init)
myIcon.connect_to_signal("on_answer_dialog", action_on_answer_dialog) # when the user answer a question.
myIcon.connect_to_signal("on_stop_module", action_on_stop) # when the user deactivate our applet (or the DBus plug-in, or when the Cairo-Dock is stopped).
myIcon.connect_to_signal("on_reload_module", action_on_reload) # when the user changes something in our config, or when the desklet is resized (with no change in the config).
mySubIcons.connect_to_signal("on_click_sub_icon", on_click_sub_icon) # when the user left-clicks on a sub-icon.

class Applet:
    def __init__(self,icon,sub_icons):
        self.icon = icon
        self.sub_icons = sub_icons
        self.config = {}
        self.conf_file = os.path.expanduser("~/.config/cairo-dock/current_theme/plug-ins/"+applet_name+"/"+applet_name+".conf") # path to the conf file of our applet.
        self.count = 0
    
    def get_config(self):
        keyfile = ConfigParser.RawConfigParser()
        keyfile.read(self.conf_file)
        self.config['cTheme']         = keyfile.get('Configuration', 'theme')
        self.config['iMaxValue']     = keyfile.getint('Configuration', 'max value')
        self.config['yesno']         = keyfile.getboolean('Configuration', 'yesno')
    
    def load(self):
        self.icon.ShowDialog("I'm connected to Cairo-Dock !", 4) # show a dialog with this message for 4 seconds.
        self.icon.SetQuickInfo(format(self.count, "d")) # write the counter value on the icon.
        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.icon.RenderValues([float(self.count)/self.config['iMaxValue']]) # draw the gauge with an initial value.
        mySubIcons.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")
    
    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"))

############
### main ###
############
if __name__ == '__main__':
    myApplet = Applet(myIcon, mySubIcons)
    myApplet.get_config()
    myApplet.load()
    loop = gobject.MainLoop()
    loop.run()
    print ">>> bye"
    sys.exit(0)


Here is the content of the "auto-load.conf" file :

[Register]
# Author of the applet
author = Fabounet

# A short description of the applet and how to use it.
description = This is a distant applet\nIt simulates a counter:\n Scroll up/down to increase/decrease the counter,\n Click/middle-click to increase/decrease the counter by 10\n Drop some text to set it as the label.

# Category of the applet : 2 = accessory, 3 = Desktop, 4 = Controler
category = 2

# Version of the applet; change it everytime you change something in the config file. Don't forget to update the version both in this file and in the config file.
version = 0.0.2


And here is the content of the "demo_python.conf" file :
#!en;0.0.2

#[gtk-about]
[Icon]
#j+[0;128] Desired icon size for this applet
#{Set to 0 to use the default applet size}
icon size = 0;0

#s Name of the icon as it will appear in its label in the dock :
name = Dbus Applet

#S+ Image's filename :
#{Let empty to use the default one.}
icon =

#d Name of the dock it belongs to:
dock name =

order=

#[gtk-convert]
[Desklet]

#j+[48;512] Desklet's dimension (width x height) :
#{Depending on your WindowManager, you can resize it with ALT + middle_click or ALT + left_click for exemple.}
size = 164;96

#i[-2048;2048] Desklet's position (x ; y) :
#{Depending on your WindowManager, you can move it with ALT + left_click}
x position=0
#i[-2048;2048] ...
y position=0

#b Is detached from the dock ?
initially detached=false
#l[Normal;Keep above;Keep below;On Widget Layer;Reserve space] Accessibility :
#{for CompizFusion's "widget layer", set behaviour in Compiz to: (class=Cairo-dock & type=utility)}
accessibility=0
#b Should be visible on all desktops ?
sticky=true

#b Lock position ?
#{If locked, the desklet can't be moved by simply dragging it with the left mouse button. Of course you can still move it with ALT + left_click.}
locked = false

#I[-180;180] Rotation :
#{in degrees.}
rotation = 0

use size=

#F[Decorations;gtk-orientation-portrait]
frame_deco=

#o+ Choose a decoration theme for this desklet :
#{Choose the 'personnal' one to define your own decorations below.}
decorations = default

#v
sep_deco =

#S+ Background image :
#{It's an image that will be displayed below the drawings, like a frame for exemple. Let empty to not use any.}
bg desklet =
#e+[0;1] Background tansparency :
bg alpha = 1
#i+[0;256] Left offset :
#{in pixels. Use this to adjust the left position of the drawings.}
left offset = 0
#i+[0;256] Top offset :
#{in pixels. Use this to adjust the top position of the drawings.}
top offset = 0
#i+[0;256] Right offset :
#{in pixels. Use this to adjust the right position of the drawings.}
right offset = 0
#i+[0;256] Bottom offset :
#{in pixels. Use this to adjust the bottom position of the drawings.}
bottom offset = 0
#S+ Foreground image :
#{It's an image that will be displayed above the drawings, like a reflect for exemple. Let empty to not use any.}
fg desklet =
#e+[0;1] Foreground tansparency :
fg alpha = 1

#[gtk-preferences]
[Configuration]

#h+[/usr/share/cairo-dock/gauges;gauges;gauges] Choose one of the available themes :/
theme = Turbo-night

#i[10;100] Max value :
max value = 100

#b Yes / No ?
yesno = false


These 3 files (along with an icon) are to be placed in a folder ~/.config/cairo-dock/third-party/demo_python.
Then to activate it, simply restart the DBus plug-in of the dock.


Glx-Dock / Cairo-Dock Wiki Control_your_dock_with_DBus 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.