Server-Side decorations coming to KWin/Wayland

As a kind of Christmas present to our Wayland users I’m happy to announce that over the last two weeks I worked on adding support for server-side decorations.

The main motivations for working on it was the fact that I want to switch to Wayland as primary driver for my system and the nested KWin running on top of another Wayland server, which I need for development, doesn’t have any decorations. Of course I could have implemented client-side decorations for it. But as my readers might know, I consider client-side decorations as an inferior solution. And KWin of course has support for server-side decorations anyway for X11 and thus it’s less work to go for server-side decoration than to go for client-side.

The second reason is that Qt’s default client-side decorations are comparable ugly and lack important features like a difference between active and inactive windows which makes using a Wayland session really hard.

In this case a possibility could have been to develop a plugin so that KDecoration based themes could be used for client-side decoration. But to get it really useable this would have required a complex protocol to get in on par with what KWin internally has.

So here’s the solution:

Server Side decoration support in KWin/Wayland
Server Side decoration support in KWin/Wayland

A core element is a protocol to negotiate whether a window should have server-, client-side or no decoration which got added to KWayland. KWin got an implementation for that both as server and client. I plan to submit the protocol for inclusion in Wayland next year. I do think that this can be a general solution: KWin won’t stay the only Wayland compositor preferring to not have client-side decorations. If we think about tiling and use cases like phones we see that client-side cannot be the ultimate solution. Thus I think it’s a useful extension. Of course it doesn’t forbid client-side decoration, that’s still possible with the protocol. So GTK+ applications build upon client-side decoration are still able to use it, but of course I highly recommend to use server-side decorations on a system that prefers server-side decorations (the protocol is also able to tell that).

The last part to get this working got implemented in our Qt Platform Theme plugin for Plasma. This plugin will move from frameworksintegration to Plasma with 5.6, so we can easily extend it and depend on KWayland. The plugin checks whether the server supports the protocol and if it does it disables Qt’s client side decorations. For each new created Wayland window it tells KWin to either use server-side decoration or no decoration (popup windows). As all of that is implemented in our platform theme plugin it means that it doesn’t affect other Wayland compositors. There the plugin does not get loaded and Qt’s client-side decorations will be used. So no fear: this won’t affect GNOME Shell at all. As the plugin is currently in the process of being moved, it’s only in a scratch repository and won’t make it to main this year. Our code deserves a Christmas break as well 🙂

Happy holidays and a successful Wayland year 2016!

Looking at the memory improvements of KDecoration2

This week I finally moved kdecoration2 to the kde/workspace project structure and merged in the required backend code in kwin. This means the upcoming 5.2 release will ship with the new Breeze window decoration by default.

Thanks to the usage of the new library we get a nice performance boost in KWin. Some of this I already explained in my blog post announcing KDecoration2. The huge advantage here is that we do no longer use a QWindow as a backend and only require to hold an image the same size as the decoration. But there are more nice improvements around it. When I started designing KDecoration2 one of my aims was to focus it more on the use cases of a composited setup and design the API in such a way that a default decoration could be more efficient. Our previous default decoration Oxygen was rather heavy and KWin was not able to provide features to Oxygen which would make it more efficient. From a memory point of view the main issue with Oxygen were the shadows. With the old decoration API the shadows were part of the decoration. So the renderer got one big image for the shadow and the decoration part. But the shadow is the same for all inactive windows and could be defined by a much smaller image (lots of information is redundant). For KDecoration2 I looked at our existing shadow sharing mechanismn on X11 level and adopted a similar API which allows to provide a compressed shadow to the compositor. That way the shadow is no longer part of the window decoration and does not need to be part of the OpenGL texture. Of course this comes at the cost of needing more rendering calls (I deliberately moved the Time-memory-tradeoff towards better memory usage).

The real improvement comes when the decoration plugin can share the shadow between the decorations. This is being done for Breeze: there is never more than one shadow being created. In Breeze the shadow always has a size of 60×60 pixels, so we save 3600 pixels per decorated window. This is in addition to the saved memory for the compressed shadow instead of having the shadow as part of the window.

Today I went a step further and also modified the code in our OpenGL compositor to share the textures being created for the decoration shadow. So if two decorations have the same shadow, they will also use the same texture. This does not only save us some texture memory, but also means less pixel transfers from CPU to GPU. So a rather nice improvement. For our default decoration Breeze this means that only one shadow is created in the decoration plugin and also only one OpenGL texture needs to be created.

Unfortunately not all decoration plugins can benefit from this change. Also with KDecoration2 the problems outlined for Aurorae still exist and the change in the shadow mechanismn doesn’t improve the situation. The hope to improve this is in Qt 5.4 which gives us new useful features like QQuickRenderControl which allows us to integrate the OpenGL context used for QtQuick with our compositor’s OpenGL context. The hope is that we can render the QtQuick based decoration into an FBO and share the texture with our compositor, so that we can just bypass the normal decoration rendering process which is too costly in the case of Aurorae. I already switched the normal rendering to QQuickRenderControl if kwin is compiled with Qt 5.4 and the result is looking rather promising. Still the memory usage and performance of Aurorae will never be as good as the memory usage and performance of a native decoration. This has never been the aim of Aurorae.

Window decoration themes in KDecoration2

Most of the window decorations available for KWin are not native decorations but themes for a native theme engine, such as deKorator, Smaragd, QtCurve or my own Aurorae. Themes are much easier to design and to distribute than a native decoration which has to be implemented in C++ and be distributed by the Linux distribution. Thus themes are an important part of the decoration system.

But we did a very bad job of integrating the themes into our configuration system. The configuration system only knows about native decorations and doesn’t know that the native decoration is in fact a theme engine. This makes selecting a theme difficult, because a user has to first select the theme engine and then configure this to select the theme. Downloading new themes through GHNS is also difficult as again it requires to go through the configuration of the theme engine. We can do better.

With Aurorae I tried to address some of the problems by extending the configuration system to know about Aurorae, to be able to find the themes and render previews for it. This only worked because Aurorae and the configuration module are in the same source tree and could share code. Nevertheless it needed to have multiple code paths in the configuration module to load the native themes, Aurorae’s SVG themes, Aurorae’s QML themes and to render the three different kind of themes.

The solution works for one theme engine, but others are still not supported. Which is something I find very sad as it turns the theme engines to second class citizens and also looks bad as my theme engine has full support while others don’t, while doing as a good or even a better job at themeing than Aurorae.

When I started to think about KDecoration2 and started to draft the API design I wanted to make sure that theme engines become a first class citizen in KWin. Last week I started to port the Aurorae theme engine to KDecoration2 and added the missing pieces to make KDecoration2 fully theme aware. The configuration of the selected theme is moved into the framework and the selected theme is passed to the native plugin when a Decoration gets created.

As a result of this work the command line options for kdecoration-viewer changed to:

kdecorationviewer [plugin] [theme]

which allows us to load for example the plugin for Aurorae with one of the SVG based themes:

To announce support that the decoration plugin is a theme engine, the decoration plugin has to put some information into the JSON meta data:

"org.kde.kdecoration2": {
        "themes": true,
        "defaultTheme": "kwin4_decoration_qml_plastik",
        "themeListKeyword": "themes"
    }

If the value for themes is present and true the framework will pass theme information to the Decoration. The framework looks in its configuration for the theme to be used, if there is none it falls back to the defaultTheme from the JSON meta data. The configured theme is passed to the Deocration when being created through KPluginFactory::create which takes a QVariantList as argument. As first element the framework passes in a QVariantMap with a key/value pair of “theme” as key and the configured theme as the value.

The last value of the meta data above is themeListKeyword which is used by the configuration module to locate all themes and provide them. I have not yet finalized the mechanismn so this is still experimental code. The keyword is used to create a different Object through the KPluginFactory. Right now this is a QObject with a QVariantMap property called “themes”. Each key is the user visible name and the value is the internal plugin name. That’s enough information for the configuration module to create a dedicated instance for each of the themes, create a preview for it and properly load/store the information. It allows us to have a configuration module which currently looks like this:

This new configuration module does not have any Aurorae specific code any more. It just knows about plugins and themes and can display them all. As one can see in this screenshot the KCM does not need to know whether it’s a QML based theme (e.g. Plastik) or a SVG based theme (all the others). Which is a nice improvement to the situation before.

The mechanismn for locating the themes will probably change and be moved to KDecoration2 directly. It needs some more tweaks to expose GHNS information and support looking for new themes and deleting existing themes. So there is still a little bit of work to be done. But overall the state is now looking really good and I will soon start the review process for the new API so that KDecoration2 will land in Plasma 5.2. Of course that will be faster if we get more help to finalize the last missing pieces.

A KDecoration2 update

Before heading into the weekend I thought about writing a small update about the KDecoration2 status. Since my last blog post I started integrating KDecoration2 into KWin. This was partially easier and partially more difficult than anticipated. Especially ripping out the old decoration code is rather complex. There are quite some design differences which make the transition complex and especially values inside KWin core are using enums defined in the decoration API – e.g. the maximized state is kept as a KDecorationDefines::MaximizedMode. This will need further work to move the enums and so at the moment the old decoration library is still compiled although the library is no longer in use.

Ah that means there is code? Yes, today I pushed the branch as “graesslin/kdecoration2” into kde:kwin git repository. To give it a proper try you also need the kde:kdecoration (master branch) and kde:breeze also on “graesslin/kdecoration2” branch. The new decoration API is working quite well and I’m rather satisfied. The memory usage of KWin dropped significantly. In a previous report I mentioned that KWin needs around 200 MB, right now my KWin only needs around 40 MB, the number of open windows is a little bit smaller, but still it shows in the right direction. And that’s without any optimisations. There is still some optimization potential in Breeze (check out our todos, all purple tasks are in Breeze) and in KWin (red tasks). Also a nice improvement is that the window decoration no longer flickers when resizing the window. This is a rather big annoyance of KWin 5.0. I expected that the new API would fix this issue, but seeing it confirmed is really nice 🙂

Last but not least the restart of KWin got faster which is a nice improvement for KWin developers, for users it’s not that important. The reason for this is that when we enabled/disabled compositing we recreated the window decorations. So when restarting KWin we first created all windows with their decoration before enabling compositing to just destroy them and create them again (yes it would have been possible to improve it, but it doesn’t hit users). Now with the new API there is no need to recreate the decoration. Only a Renderer is exchanged, but the rendering is delayed till it’s needed.

This screen shot does not only show the new Breeze decoration, but also some new features: when quick tiling a window the borders cornering the screen edges are removed. Also in the preview application one can see that the decoration scales which is nice for high-dpi screens. The decoration API follows the approach Plasma is using.

I have been running a KWin with the new decoration API since Monday, which means we are close to start the review process. But there’s of course still work to be done and I’d appreciate any help. The window tab API is not yet implemented, the configuration module needs adjustments to load and render the new deco and most important we have to port the existing decorations like Oxygen, Aurorae, deKorator and QtCurve. For the last three I want to improve the theme experience by allowing the plugin to say that it supports themes directly in the JSON meta data and point to where to find them. So the configuration module can just show all of them. The trick will be to pass the to be used theme to the factory method (we have a nice QVariantList there which can be used). Also the meta data will make it possible to point to GHNS configuration files so that we can not only download Aurorae themes from the configuration module, but also other themes.

KDecoration2 – The road ahead

Yesterday I blogged about why Breeze is not the default window decoration in KWin 5.0. The blog post touched a little bit the problems with our decoration API. In short: it’s QWidget based and that doesn’t fit our needs any more. It uses a QWidget as an X11 window. At the same time KWin intercepts the rendering and also input handling, redirects it and forwards it. So why use a QWidget at all? Also using a QWidget is quite a memory waste in the Qt5 world. The QWindow behind the QWidget uses a QXcbShmImage with the same size as the window. As explained in yesterdays blog post the window has the size of the managed window plus the decoration. So for a maximized window we hold an image of the size of the complete window while we just need the titlebar strip. We can do better 🙂

Our decoration API is also showing it’s age. It’s cumbersome to use, too difficult to use. In fact there is a KDecoration and a KCommonDecoration – the latter trying to make KDecoration easier to use by for example providing buttons. The API got extended several times to support more features which are all optional. The API is difficult to use from KWin side as it’s not stateful and quite often needs to call into the decoration API calling virtual methods the decoration API provider needs to implement. Last but not least it’s difficult to test new decorations as we don’t have a dedicated viewer application to test the interaction and painting. You have to kind of use KWin as the development host. Not the best solution.

The idea for a new API had been in the room for a long time. I opened a bug report for it more than two years ago. Last week I finally started with the implementation and tackled three things at the same time:

  • New decoration API
  • Viewer application
  • Breeze decoration

In the current state it looks like this:

The outer decoration is the existing Aurorae theme. It looks already quite good, but there is of course still lots of work to do. The API is not yet feature complete, it needs implementation in KWin and Breeze needs a pixel perfectionist to get it right (which I am not). And that’s where you can help! Thanks to our sysadmins we have a new todo board and I requested a project for KDecoration2 and prefilled it with very easy tasks. This is a wonderful opportunity to work on easy and new code and helping both KWin and the Visual Design Group achieving an important new step. Without your help we won’t have this in 5.1 and it would be so important for both KWin and the overall design of the Plasma desktop. So please grab the code and start hacking. Grabbing the code, where? The new decoration API can be found in the git repository kde:kdecoration, the viewer application in git repository kde:kdecoration-viewer and the new Breeze window decoration in git repository kde:breeze in branch “graesslin/kdecoration2”.

So what makes KDecoration2 better? Obviously it’s no longer QWidget or QWindow based. Instead it’s a pure QObject based API. It provides a paint method a plugin needs to implement which gets a QPainter passed into. This allows KWin to control the rendering and to render to the best suited backend for the current compositor (e.g. just a QImage or a Shm shared pixmap). Also the input handling will be controlled from the backend side by sending appropriate events to the decoration. The API takes care of all of the handling – activating the buttons forwarding title bar presses, etc. This alone makes the API hopefully much easier to use from plugin side. It also provides the base implementation for all the required buttons, so that the decoration only needs to provide the painting of the buttons. Simplified the API looks like the following:

There’s an additional singleton DecorationSettings which provides common settings for the decoration. Also there’s an additional second private API which must be implemented by a backend. This will allow us to use KDecoration2 in multiple places. I want to see it uses in KWin, but in future I’d also like to provide our decorations for QtWayland. For this I hope that KDecoration plugins can also be a solution.