Until the 2.1.0 release of Cairo-Dock you can create your applet in another language than C.
Have a look to this section Control your dock with DBus
Cairo-dock put at your disposal a framework dedicated to quickly writing standardized applets.
Let's see how to do.
First we can generate a fonctionnal applet with the script generate-new-applet.sh, located in the "plug-ins" folder of the sources.
Run it, answer the few questions, and after all is finished go to your new applet's folder and type sudo make install. You're done ! If you restart the dock, you will see your new applet in the config panel. You can even activate it, it will appear in the main dock.
Now all we have to do is to complete the code.
Before we go further, let us look at the structure of your applet (let's say that its name is "truc") :
Source Tree structureThe source tree structure is basic and can be copied from any existing applet:
truc ---> configure.ac, Makefile.am
+--> src -> applet-init.c/h, applet-config.c/h, applet-notifications.c/h, *.c/h
+--> data -> truc.conf.in, preview, readme.in, *
+--> po -> Makefile.in.in, LINGUAS, POTFILES.in, *.po
The files names are not imposed, but respecting these conventions will make it possible to immediately find your way around for any applets even the one you don't know about.
Sources FolderIn ./src, we have :
- applet-init.c : contains the functions to initialize, stop and reload the applet.
- applet-config.c : contains the functions to load the config, reset it, and reset the datas.
- applet-notifications.c : contains the functions which are called when the applet is notified by Cairo-Dock that something interesting has happened (a click, a drop, etc)
- *.c : the others can contain everything you need (connection to a server, functions of drawings, calculations, etc...) Separating your functions into different files by familly is a good habit.
Data FolderIn --./data-- we find :
- preview : a picture (png or jpg) giving a preview of the applet, around 200x200 pixels. It will be displayed in the config panel of Cairo-Dock.
- readme.in : a file giving the author of the applet (you; -)), and a short summary of this one (the text will also be displayed in the config panel of Cairo-Dock).
- truc.conf.in : the config file of the applet, which contains all the parameters that the user can change. We'll see later how to use it.
- icon.png : an icon used to represent your applet in the config panel. It is common to also use it as a default icon in the dock.
Translation FolderIn ./po we have :
- Makefile.in.in : no need to care this one.
- LINGUAS : the list of the available languages.
- POTFILES.in : the files list where one finds messages to be translated.
- *.po : files containing the translations of each message.
Installation Tree structureThe installation tree structure is very simple :
- the contents of the folder "data" will be copied in /usr/share/cairo-dock/plug-ins/truc
- the plug-in itself will be in /usr/lib/cairo-dock/libcd-truc.so
- the translation files will go in /usr/share/locale/$lang/LC_MESSAGES/cd-truc.mo, where $lang = fr, jp, ...
Compilation filesDon't forget to define the dependencies with other libs in configure.ac if needed, along with the version number of your applet. Also, report the files you need to install in the Makefile.am files.
Well, now start the serious things !
Using the applet framework
The variablesAn applet is a CairoDockModuleInstance structure. You can acces to yours through the myApplet variable.
An applet has an Icon, yours is myIcon.
The icon is located inside a CairoContainer, yours is myContainer.
This container can be either a CairoDock (yours is myDock) or a CairoDesklet (yours is myDesklet). In the first case myDock == myContainer and myDesklet == NULL, and vide versa, so they are just here for convenience.
The applet has some parameters, taken from the config file, grouped into an AppletConfig structure. Yours is myConfig.
The applet has some datas it loads at run-time, grouped into an AppletData structure. Yours is myData.
Last, an icon has an associated cairo_t drawing context, yours is myDrawContext. Note that if the applet is in Desklet mode, the context is only available after you set the desklet's renderer, that you should therefore do at first.
Single and multi-instanceIn Cairo-Dock, applets can be launched several times or just 1 time. For exemple you can have many instances of Clock, each one giving the time of a different country.
If you want to make your applet multi-instanciable, just add the following line to the src/Makefile.am :
In the case of a single-instance applet, myApplet is available everywhere, as a global variable. In the case of a multi-instance applet, it is only available at init and reload, and it's up to you to pass it to all of your functions as an input parameter (you can't make it a global variable).
The notificationsIn Cairo-Dock, applets can interact with the dock through notifications. When something happens (the user clicks somewhere, drop a data in the dock, etc), the dock will send a notifications of the event. Everybody that has registerd to this notification will receive it.
When you register to a notification, you give a function (a callback) that will be called when the notification occurs.
Some macros exists for the most usual notifications (right/left/middle/double clicks in particular). Be careful to respect the format of the callback if you don't use the macros, they are all described in cairo-dock-notifications.h.
Init, stop and reload your appletCairo-Dock will allocate an icon and a container for your applet, and then will let you initialize it.
So in your init function, you already have all the variables available, including myConfig.
All yo have to do here is to start your applet (launch a timer, register to notifications, etc).
When your applet is stopped (because the user removed it), you have to free all the ressources you have allocated, so that your applet will give back all the memory it used, and of course put an end to any existing timer or notification.
Freeing the datas is done in the reset_data function, that will be called for you by the dock, so put there all the code that will free the parameters of myData. The rest goes in the stop function.
The reload occurs in 2 situations :
- when your desklet is resized by the user or when some change is made in the dock's config
- when the user makes some change in the applet's config or detached/ratached the applet.
The macros CD_APPLET_MY_CONFIG_HAS_CHANGED tells you which case it is. In the second case, myConfig has already been reloaded, so you never need to worry about.
The macrosThe macros aim to make your code smaller, and more robust. They shadow the complexity of some functions, and prevent API breaks, so you should always use a macro when one is available.
They are all defined in cairo-dock-applet-facility.h, and documented (for a better readability, you can generate an html document from it with doxygen).
The configWhen you edit the configuration of the dock or an applet, the panel is dynamically built from the config file. A conf file is a key file, grouped by group.
Each key will generate a widget (a spinbutton, a text entry, etc)
Each key has a comment (starting with a '#'), this comment will be displayed next to the widget.
To know what kind of widget it is, the first letter of the comment indicates that. To have the complete list, look into src/cairo-dock-gui-factory.c, or if you prefer an exemple, look into data/cairo-dock.conf.in.
This system allows you to not care at all about the config panel : no need to build it, no need to get the values modified by the user !