Implementing a new window decoration for KWin is not the easiest thing to do. While the API has hardly changed since early 3.x releases it is not very Qt like and requires a strong understanding of how the window decoration in KWin works. To design a window decoration you basically have three options which come with KWin:
- Subclass KDecoration
- Subclass KCommonDecoration
- Design an Aurorae theme
KDecoration gives a developer the most powerful options. The developer can design the decoration in whatever way he likes. But it also means that the developer has to take care about everything himself. E.g. properly laying out the buttons, handling mouse events on the decoration, ensuring the right resize handles are shown, etc. etc.
An easier way is to implement KCommonDecoration which already implements the common aspects of a decoration. For example a normal decoration has some buttons on the left and some buttons on the right side. The main task of a developer is to define how large various parts of the decoration should be, e.g. the margin between the left buttons and the caption. This of course limits the possibilities with the decoration.
The third option is to design an Aurorae theme which means just creating a few SVG elements. This is of course for designers the best option, but again very limiting. If a feature is not provided by the theme engine it cannot be represented. In the same way there are third party deKorator themes available.
The C++ based decoration APIs seem to be too difficult to be used. If we look at kde-look we see that there are just 14 native decorations available and some of them are forks or old versions of decorations available in KWin directly. But there are already 79 Aurorae themes available and more than 150 deKorator themes.
What seems to be a real issue concerning 3rd party usage can be validated if we just look into the KWin source base. In 4.9 we ship four window decorations: the Aurorae theme engine, Oxygen, Plastik, b2 and Laptop. Together they are 10 kSLOC of C++ code and 1 kSLOC QML code (Aurorae). Before Aurorae got ported to QML the size of the decorations was 13 kSLOC. Overall that is about 10 per cent of the KWin source base, which is rather large.
When I ported Aurorae to QML one of the nice results was that I had to add a QProperty based API to communicate with QML in the first place. If this were the actual API writing a window decoration would be probably much easier. As a first step in that direction I started adding generic QML support to Aurorae.
Following the general direction of all scriptable elements in KWin I decided to go for the well known Plasma Package structure, and added support to Aurorae to use a QML file from a package instead of the own QML file. The patch for this had been in my workspace for quite some time but I did not have any code to actually test whether it works.
So yesterday I started to re-implement one of our C++ based decorations in QML. I decided for Plastik as the decoration is in fact broken and had been scheduled for removal. We have not yet removed it as we acknowledge the user’s wish to have the KDE 3 look still around. But we are unhappy with having a decoration which is broken and unmaintained. So having a QML replacement would be something rather nice.
After one and a half days of work I’m proud to say that writing decorations in QML is possible. The changes to the configuration module and Aurorae itself are already under code review, the new Plastik still needs some love. But the decoration is already completely useable as can be seen in this screen shot:
In the current state the decoration consists of 370 lines of QML code and I expect to need an additional 100 lines to finish the buttons (they are already functional, that is the close button closes the window) and add some of the configuration options. The same API in C++ consists of 1500 lines of code. So we do not only get fewer lines of code but also a more readable and easier to maintain codebase. For something like a window decoration a declarative approach is much better suited than the imperative C++ way of painting elements.
Overall the new QML API will provide the same powerful features as the KDecoration API, but also provides convenience functionality as KCommonDecoration, e.g. a button group taking care of laying out the decoration buttons. To make development of QML based decorations quite simple support is currently being added to Plasmate as part of the Google Summer of Code project. So you will be able to design and also test the decoration directly from inside Plasmate. This is also quite some improvement as with C++ the only way to test a decoration is to use it in KWin, which can be quite nasty during development.
The API will need some more love till I’m quite confident to provide it’s usage but there is enough time till 4.10 🙂 So I hope that we can provide a better decoration experience in 4.10. I have a few ideas concerning the usage of QML based decorations in KWin and are looking forward to experiment with them.