In this article, I explain changes to the plugin loading mechanism in KDE Frameworks 5. The article is intended for a technical audience with some affinity to KDE development.
Over the past weeks, I’ve spent some time reworking the plugin system in KDE Frameworks 5. The original issue I started with is that we are shifting from a plugin system that is mostly KDE specific to making more use of Qt’s native plugin system. Qt’s plugin system has changed in a few ways that caused many of our more complex plugins to not work anymore. On the other side, moving closer to Qt’s plugins makes our code easier to use from a wider range of applications and reduces dependencies for those that just want to do plugin loading (or extending their app with plugins). A mostly complete, and I must say spiffy, solution is now in place, so here’s a good opportunity to tell a little about the technical background of this, what the implications for application developers are, and how you can use a few new features in your plugins.
Bye bye, K_EXPORT_PLUGIN
In the KDE Platform 4, the K_EXPORT_PLUGIN macro did two things. It provided an entry point (qt_plugin_instance()) function which loads the plugin. With Qt5, the need for the entry point is gone, since plugins are now QObject based, so the methods defined in Q_INTERFACE can be relied on as entry points. K_EXPORT_PLUGIN also provided PLUGIN_VERIFICATION_DATA, which can be used to coarsely identify if a plugin was built against the right version. In most cases, this wasn’t very useful, as it would only catch a relatively small class of errors. The plugin verification data is missing in the new implementation so far, but we plan to get it back in another form: being able to specify the version in the plugin, and checking against that. This part is not yet there, but it’s also not a problem for now, as it’s not required and won’t produce fatal errors.
The heavy lifting is done by this macro, which is often used together with K_EXPORT_PLUGIN: You create a factory class using this macro, and then, in the old world, you’d use K_EXPORT_PLUGIN to create the necessary entry points. Since we’re already defining the plugin factory instance using Q_DECLARE_INTERFACE, Qt is happy about that, and the stuff in K_EXPORT_PLUGIN becomes useless. Basically, we’ve moved the interesting bits from K_EXPORT_PLUGIN to K_PLUGIN_FACTORY. For porting that means, in the vast majority of cases, you can just remove K_EXPORT_PLUGIN from your code, and be done. (If you don’t remove it, it’ll warn during build, but will still work, so it’s source-compatible. Mostly, in some cases, .moc can’t pick up the macro, in this case, either move it into the .h file, or include the corresponding .moc file in your .cpp code.)
K_PLUGIN_FACTORY, or rather its base class, KPluginFactory is pretty neat. It’s mostly assembled by macros and templates, which makes it a bit hard to read and understand, but once you realize what kind of effort is saved for you by that, you’ll happily go for it (you don’t have to care about its internals as it is well encapsulated, of course). The really interesting piece is this:
T *create(const QString &keyword, QObject *parent = 0, const QVariantList &args = QVariantList());
This is a method available in the factory (generated by K_PLUGIN_FACTORY) that is the base of your plugin, basically what you get from QPluginLoader::instance() from your plugin once you’ve loaded the .so file. You basically call (roughly)
MyFancyObject* obj = pluginLoader->instance()->create<MyFancyObject*>(this);
to load your code into the app hosting the plugin. (Of course, MyFancyObject can be either the class actually defined in the plugin, or, more commonly, the baseclass of it (you don’t want to include your plugin’s header in the app, as that defeats the point of the plugin in the first place). You only do the above if you go through QPluginLoader directly, KService and Plasma::PluginLoader can do most of this work for you (also, here the API didn’t change, so no worries).
K_PLUGIN_FACTORY_WITH_JSON or where is the metadata?
Qt5′s new plugin system allows you to bake metadata into the plugin binary itself. They’re specified as an extra argument to the Q_PLUGIN_METADATA macro, and basically point to a json file containing whatever info you want in the plugin. The metadata is compiled into the ELF section of the plugin, can be found very fast, and the plugin itself doesn’t need to be dlopened in order to read it. With Qt’s previous plugin system, the plugin shared object files would have to be loaded, which significantly impacts performance.
This mechanism is very useful for something we’ve been doing in KDE for a long time, namely the data included in the .desktop files. Those are being installed separately, into a services install dir, indexed by ksycoca for faster access and searching. These .desktop files (which really are the plugin’s metadata contain all the usual stuff, name, icon, author, etc., but also the plugin name, dependencies, and most importantly, the ServiceType (e.g. Plasma/DataEngine). KService uses them to find a plugin (often by service type) and load it from the plugin name.
Having the metadata baked into the plugin allows us to not use KServiceTypeTrader (which handles the searching through the sycoca cache) but to ask QPluginLoader directly. Right now, we’re still using sycoca for the lookup, but this mechanism allows us to move away from it in the future.
Something we do use the metadata for already, at least in Plasma::DataEngine is the creation of a KPluginInfo object. (This object basically exposes the metadata, and can be instantiated from a .desktop file. With the above changes, I also added a constructor to KPluginInfo that instantiates a KPluginInfo object from the json metadata baked into the plugin. This is one nail in the coffin of KServiceTypeTrader (and in extension KSyCoCa), but obviously not its death blow.
K_PLUGIN_FACTORY_WITH_JSON simply takes an extra argument, the metadata file, and bakes that into the plugin (by inserting it, internally, into the Q_PLUGIN_METADATA macro which is included in the KPluginFactory implementation.
In order to ease the transition from .desktop files to baked-in metadata, we introduced a cmake macro to help you with that. It’s pretty simple, you just write (in your CMakeLists.txt):
and during build time, a file called mypluginmetadata.json will be generated. You can include this file using the K_PLUGIN_FACTORY_WITH_JSON macro in your code, and the metadata will be baked in. When the plugin is loaded, your ctor will have a QVariantList as argument, which you can just pass to KPluginInfo, and get a valid plugininfo object back. If you’re interested what the .json file looks like, either peak into your build directory, or use the command
$ desktoptojson -i mydesktopfile.desktop
to generate a json file. (You usually want to run this at build time, and not put it in your repo, since otherwise, changes to the .desktop file, for example translations, will not be picked up.)
Changes are largely source-compatible (K_EXPORT_PLUGIN can just go away, you might have to include the .moc file explicitely)
You can optionally use JSON metadata in your plugin to create KPluginInfo objects
If you want to create a plugin, do the following:
In your CMakeLists.txt file, convert your old .desktop file at build-time using kservice_desktop_to_json() and use the resulting file (replace .desktop with .json) in the following step
In your plugin .cpp file, add a K_PLUGIN_FACTORY macro, this does Q_DECLARE_INTERFACE and Q_PLUGIN_METADATA for you. Optionally pass a .json file
Use QPluginLoader, KServiceTypeTrader or Plasma::PluginLoader to load your plugin.
Personal thanks go out to kdelibs hacker extraordinaire David Faure, who has been patiently guiding me through making these changes to our plugin system.
Update by David Faure
One thing it doesn’t detail (because you didn’t directly work on that) is differences in where plugins get installed (the install dir changed), and how they are found ($QT_PLUGIN_PATH).
One of the porting ideas is: if you don’t need the trader to find your plugins, don’t use it anymore. E.g. if you can put all your plugins into a subdirectory of the plugin path, and you don’t need any filtering (you just want to load them all), iterate over that, no servicetype and no trader needed. We still have to solve the use case of filtering/querying though, ideally in Qt (so that the json metadata can actually be useful).
One of the things that we have been discussing at length in the past few months is the graphics stack in Kubuntu, and how we’re working towards having Plasma Workspaces 2 running on top of Kubuntu-next and Kubuntu-next-next(-next). In this article, I will explain the strategy we have laid out for a smooth transition.
2013: 4.11 atop XOrg
For Kubuntu-next (13.10), the answer is pretty easy: We’ll be relying on plain old Xorg. End of story. Alternatives do not provide us any benefits, so instead of jumping onto an unproven and at the time of writing buggy new technology stack, 13.10 will present you a stable and proven solution as to the display server, and on top of that provide a KDE SC 4.11 with all the performance improvements that we have worked on in the past months. They will, on many systems be quite impressive. The port to XCB provides a whole slew of advantages, and we have reduced memory consumption significantly in many components, Kontact for example.
Later this year, we’ll make the first test packages of Plasma Workspaces 2 available, which is the upcoming version of Plasma, based on Qt5 and an entirely hardware-accelerated graphics stack. Do not expect them to be much useful at that point, however, as Plasma 2 (and the underlying Frameworks 5) is still a fast-moving target. The packages are mainly useful to catch integration problems early on, such as co-installability of KDE SC 4 and Frameworks 5 packages. Later on be able to run a KDE SC 4 application atop a Plasma Workspaces 2 — mixing and matching whatever is stable and mature enough for you. This eases the transition for our users and makes it a lot easier for us to dogfood ported apps.
2014: Offering Wayland
Fast-forward to 2014. The stable release of 14.04 will be relatively boring (a.k.a. stable :D). Regarding Plasma, it will be based on 4.11 with all the bugfixes we have accumulated until then. Maybe not the most exciting release, but stability and continuity aren’t the worst thing in the world. Also, as 4.11 will get extended support from the upstream Plasma team, this offers quite a nice choice for those that don’t want to upgrade too often.
At the same time, the brave among us will be able to test early versions of Plasma Workspaces 2, which are being constantly updated through Project Neon, a sort of rolling testing releases.
In the first half of 2014, we will start the transition process to the Wayland display server, not for 4.11, mind you, but on top of KDE Frameworks 5 and Plasma Workspaces 2. Project Neon, by that time will get support for Wayland, which likely means that we are going to package a Wayland-based graphicsstack, and maintain that. Not exactly what we’d like to do, but a little more integration work is, in my opinion preferable to rely on a technology which doesn’t provide a stable protocol and is focused solely on another desktop shell. The risk of breakage is not something we want to put our users up with. Us committing to making Wayland available will probably yield a few happy faces in other desktops’ camps as well. So let’s collaborate on that.
Summer 2014 will then (hopefully!) see the first stable version of Plasma Workspaces 2, running natively on a Wayland stack. The time until the 14.10 release will be spent further polishing the living bejesus out of that, so as many of our users as possible will be able to use Plasma Workspaces 2 on top of a fully accelerated graphics stack productively.
Kernel hacker Sarah Sharp has stood up against the way of communication common on the Linux Kernel Mailing List. I have quite a few thoughts about this, and I thought I’d share them here. Quoting Sarah:
I’m standing up against verbal abuse on LKML. I will happily stand alone, however you can also support this cause. Please speak up, either here on Google+ by resharing this post, or commenting on this post with words of support. If you dare, you can also reply to my lkml email.
Thanks for posting this, Sarah. You’re bringing up an important topic here, which is avoided all too often.
Sarah is completely right, and entitled to demand an abuse-free working environment. Thank you for making this explicit, and standing up against those that think it’s not necessary. You’re speaking for a silent crowd, that is now not so silent anymore.
If people really think they can only be productive when using abusive language, they need a reality check and grow up, especially if these people are highly regarded personalities such as Linus Torvalds. What they do is settings a bad example at best, and being actively harmful and divisive at worst.
I wouldn’t care much if that this abusive behavior were happening in their private living room, but in a public place that is not acceptable. It harms our whole community. It cultivates a macho culture of fat white men, while what we really need is diversity.
Within KDE, we have created a culture of friendliness and mutual respect. We have codified this in a code of conduct, and it has grown into the baseline for making work and leisure in the community more fun and less stressful. It also allows us to grow beyond an in-bred bunch of geeks, and become a diverse team, with the skills needed to not just create Free Software, but to contribute to Free Culture (which I think Free software is part of).
Food for thought: If we want Asian hardware manufacturers to work with us on, e.g. drivers for their hardware, and do it upstream, it simply won’t happen in a rude atmosphere that is entirely incompatible with Asian culture (where critique has to be much more subtile). Of course it’s a general problem with cultural diversity.
One thing that strikes me here during Akademy is the sense of community convergence one gets.
While other Free software projects drift apart, splitting up in multiple forks that stop talking to each other, differentiate based on the wrong reasons, what we see here during Akademy is projects growing closer to each other. This is a good development, so let’s look at it a bit more detailed.
KDE is continually evolving, becoming more diverse by the day. As an organisation, we realised that, and many see KDE as an umbrella organisation for Free software, rather than a “project doing a desktop environment”. When we published the KDE Manifesto, we set the tone for this to happen, and now we see it unfold. The KDE manifesto defines KDE as a community of like-minded Free software people. One of the most important adjectives to describe KDE is inclusive, that means that we define ourselves in terms of commonalities, rather than trying to differentiate ourselves from our peers.
Also, as an organisation that is in the business for 17 years, we have gathered a large body of expertise, best practises, knowledge how to run a community. We have also proven to be a sustainable and stable organisation.
At Akademy, the KDE community is joined by a wide variety of people not directly involved with KDE. We have VLC here, Razor Qt, Mer and of course our long-time friends from Qt present. This, on the one hand provides excellent opportunities for cross-pollination and solving common problems (or even just sharing pain!), on the other hand it makes us think if we’re at the right level of collaboration right now. Is there more to share among these distinct organisation, does it make sense to merge some of them and share the overhead?
This surely is food for thought, and I expect this class of discussions to last until long after Akademy, but it is very refreshing to see. It also increases the value of all our communities. Synergy through convergence.
It’s also an excellent way to make new friends, and look outside our own frame of reference.
This year’s general assembly of KDE e.V. during Akademy will be my last one as a member of the KDE e.V.‘s Board of Directors. I had been elected during Akademy 2006 in Dublin, and since then served the KDE community by working on organisational bits necessary to support a Free Software project. We’ve seen times where our environment wildly changed, times of growth, consolidation, growing pains. Looking back fills me with satisfaction how we have developed KDE e.V. as an organisation. I think KDE e.V. is exemplary in many ways for other Free Software, and Free Culture projects. One of the cornerstones here is continuity, we simply had the time to learn a lot, to define and implement necessary processes around administration, fund-raising, legal questions, conference organisation and many more. As it stands today, KDE e.V. is an organisation that provides the continuity necessary for a community to think ahead, and the necessary infrastructure to foster and support those next steps. KDE e.V. is also an organisation that constantly evolves, reacting, but also foreseeing and preparing for the next steps. We have a well-functioning team in place to guide this, and I’m confident that the current and coming board members will keep developing KDE e.V. as an organisation towards its goal of supporting KDE.
Earlier this year, I had also resigned from my role as one of KDE’s release managers. When I joined the release time, around KDE 3.5 (our software compilation was still called KDE back then), our release process was becoming dysfunctional. In KDE 3 times, coolo (to some known as Stephan Kulow) was the release dude, and it was all in his hands. He did a great job, but, just like in many other areas of KDE, embodied a single point of failure. Not that he, or others we relied on, ever failed, but it’s usually more a matter of statistics than personal skills, attitude and motivation. For critical tasks (and actually releasing all the work of such a community for others to use is a pretty critical one!), you want a team in place that can fall back on each other, both to spread workload and risks. Afin, KDE needed release managers, and after a detour through a more official body (the KDE e.V.-elected Technical Working Group, for those who remember this episode), it became clear that only a self-motivated group of people that want to get the job done will work. In hindsight, this sounds completely natural and closely aligned to KDE’s way of achieving things, but I think this way had to be walked, we have learned from it, and in the end, there’s a competent team in place which can deliver our software in time and quality. As being on the release team is work, and at times quite a lot, I wanted to get rid of this eventually. I managed to pull out, I think without leaving too much of a hole. A few releases have been done without me actively particating. Probably, most people won’t even have noticed. Perfect.
So am I on the way out? Most certainly not! I’ve been consistently shifting from organisational tasks to more technically oriented work, which to me personally, is a good development. I simply get more kicks out of writing code than reading emails. In that regard, I think I’m in good company.
On a professional level, I’ve been working for Blue Systems on Plasma’s upcoming version for a while now. I’m spending most of my time on Plasma and our Frameworks 5 effort, and enjoy that a lot. It gives me both the time to intimately understand more parts of our codebase, and much opportunity to learn new things and improve and develop existing skills. The work happens entirely within KDE infrastructure and community, and I’ve got a bunch of great colleagues who are equally eager to take big steps, technologically with our codebase. My role has now shifted a bit to also include team coordination tasks, which is an interesting exercise. On the one hand, a geographically spread team is harder to keep track of, but this is offset by the great motivation, skills and attitude of my colleagues (within both Blue Systems and KDE).
Luckily, my life’s not all KDE and the serious business of software development. In May, Kim and me travelled to Indonesia. We spent a few nights in the jungle of Borneo, took a walk with Orang Utans. We planted trees, and slept the nights on the deck of our boat acompanied by jungle noises and clear skies. On Java, we visited the Borobodur, a giant buddhistic temple, one of the 7 wonders of the world, we learnt about the roots (literally and figuratively) of many conveniences such as coffee, rice, tobacco and latex. We climbed up a Volcano. From Java, we set off to Bali, travelled along its North coast and then spent some time on Gili Trawangan, which is part of a group of sandy, tropical islands just off the coast of Lombok. The time in Bali and on the Gilis did my scuba diving skills really well. The area is excellent for diving with warm waters and amazing marine life. My finning technique has improved vastly and I’ve got dehydration under control much better now. During our dives we spotted lots of coral, soft and hard, vast amounts of colourful reef fish, turtles, reef sharks, morays, sea snakes. The abundance of colour and life was enchanting, though fragile.
With all that said, some of you will meet me later this week in Bilbao for Akademy. I will arrive on Wednesday already, going to see Depeche Mode and The Editors at BKK festival. If you want to talk Frameworks5, Plasma2 or anything else which lies in my line of interest: Talk to me.
We (the KDE Plasma Team) are sitting at the SUSE office in Nürnberg, Germany right now, kicking off the already 6th edition of Tokamak, which is the name for (most of) our Plasma meetings. A Tokamak is a container for Plasma, which uses magnetic force to keep the Plasma in one (very hot) place. For the Plasma team, it provides a high-bandwidth setting where we can discuss, design, review and hack on the technology behind the Plasma workspaces. This meeting’s topic is Plasma2, the evolution of Plasma into the Qt5 and Wayland world.
First, we agreed on a bottom line: “Plasma 2 will be at least as good as the current Plasma, and probably better in many aspects.” This means that we’ll have to invest considerable effort and time into stabilization. At this point, where we are probably still a year or so away from a Plasma2-based release, making it part of our planning now will allow us to focus on the things that we think, matter. Among that is making sure the transition to KDE Frameworks 5, Plasma 2 and Wayland will be as seamless as possible, and perceived as an upgrade to our users.
But why are we doing this? Why are we putting so much work into it, what’s the benefit for the user?
Why switch graphics stacks?
In the past years, the landscape of graphics under Linux has changed quite a bit. Many things, like memory management of the graphics stack, rendering of primitives, font rendering, and a few other things involved in the process of “getting pixels onto your screen” have changed, and they’ve changed for the better. With a stack based on Wayland (and in extension Qt5), we are able to utilise modern graphics hardware better, to reduce maintainance effort and hopefully grow the community around the graphics stack, and not at least, to make sure that every frame that ends up on the screen is perfect. In the X11 world, we can’t really control it, since we have no idea when something is painted, in which way it is, where it’s painted, and when the pixels end up on the screen. With Wayland, this process of event processing, rendering and blitting is structured and guaranteed to happen in a certain order. In the end, this transition will enable us to put 60 perfect frames every second on the screen. The new architecture also allows us to split the rendering into its own thread, so data processing or event handling in the application doesn’t end up delaying rendering. 60 frames per second will make the UI feel smooth as buttery silk, leading to less strain on the eyes and a nicer user experience.
While moving its codebase to Qt5, the KDE Development Platform is undergoing a number of changes that lead to a more modular codebase (called KDE Framework 5) on top of a hardware-accelerated graphics stack. In this post, you’ll learn a bit about the status of Frameworks 5 and porting especially Plasma — that will be known as Plasma Workspaces 2, paying credit to its more convergent architecture.
Let’s start with something visual, before we get to the nitty-gritty:
Video showing a basic port of a Plasma Desktop Containment to Plasma 2
A whole bunch of libraries can now be built, installed and packaged separately. Those include (in tier1) Solid, Threadweaver, kdecore, karchive, kwindowsystem, and more, and in tier2 kauth and kconfig. Plasma has already moved into its own repository, and can of course also be built separately.
Kevin has been plugging away at removing problematic interdependencies between those libs, and recently could ditch (i.e. move to kde4support) a few classes that make it easier to just use Qt machinery (QApplication & friends) to bring up “KDE applications”. KAction has gone, KAboutData, so KDE Applications are now less “special” in the Qt world — a good thing for portability.
Splitting and untangling kdeui from kdelibs proves to be a bit more work- intensive than initially hoped. Fracture lines are becoming visible. The problem here is that this task is holding up the parallelization of development, so this has a high priority right now.
We’re also using a continuous integration system now to keep us on our toes with respect to “buildability” (which can be a bit daunting with so heavily shifting ground in kdelibs, this will calm down at some point though).
Video showing a Plasma 2 OpenGL shader demo widget
Plasma & KWin
Good progress, especially in the last month, in three areas:
API reviews: we’ve been doing weekly sessions for libplasma2 API reviews, where we’re going through the entire API and think about improvements for the Plasma 2, post-graphicsview world. As a result, libplasma2 has shrunk to about 1/3 in (compiled) size in its current state. We don’t expect it to grow much, since, in the scenegraph world, it plays another role than previously (although developers used to QML won’t really notice). (Join in the Hangout, if you like, we usually start on Monday morning around 10.00 UTC, just pop up in the #plasma channel and ask Marco to invite you). Our mutual status updates and Cool New Development is recorded and made available on Youtube for interested people, Last Monday’s session can be found here, but today we skipped it — you get this more detailed blog post in return. :)
Imports: Basically our QML runtime, it consists of Plasma Components, extras, bindings for things like dialog, framesvg and dataengines, drag and drop, krunner models, and a bunch of other stuff. I’m working on this right now, and have about 95% of the imports originating from kde-runtime working in Plasma2. We’ll be able to offer almost the same API to Plasma2 QML users, as in Plasma1, so porting of your QML code will be very easy.
Shell: In Plasma2, instead of having specific plasma-desktop, plasma-netbook, plasma-device shells, we will use one “generic” shell that loads containments (which then load applets), wallpaper, toolbox, etc. The shell can dynamically replace these components (change wallpaper, for example).
A few things are new here: in Plasma2, plasmoids provide their config ui via QML files, that are part of the package. That solves the problem that we could not really influence the behaviour of the configuration UIs from QML in Plasma1. It will also allow to transparantly switch between instant apply and “OK/Apply/Cancel” buttons, depending on what fits the usecase. Marco is on this.
Martin has been pushing the removal of the direct X dependency further through porting to XCB. He’s also recently started on a Qt5 port. One problem with KWin is that Martin needs a bunch of changes to have QtQuick and KWin run in the same process, that means making sure that KWin and Plasma (or QtQuick2 really) properly share and interact in the same OpenGL context. There’s a chicken-and-egg situation for kwin, since it needs to load for example window decorations and task switchers (both from QML) to be useful, but it can’t right now. The X11-based windecos won’t make it into Plasma2, so we’d rather avoid porting them just for the time being. Martin is on that though, and he earns our gratitude for going through this painful period in the porting procedure.
One of the perks of doing the release notes for the upcoming KDE SC 4.10 is that you get to try a lot of new applications. One of the highlights of tonight’s webmonkeying certainly is KTouch. It’s actually been around for a while, now Sebastian Gottfried has taken it under his wings and modernized the user interface. KTouch welcomes the user and takes it through the lessons, I’ve got to say that it’s all works rather spiffy, easy to understand and quite fun to use.
The user interface is done in QML, it uses Plasma’s QML Components, transitions and subtle animations. The application also nicely presents statistics about your performance and progress, it guides, but doesn’t restrict the user. Well done. :)
The new version of KTouch will be available with the KDE Applications 4.10, to be released on February 6th.
As many other components of the Plasma Workspaces, Plasma Desktop’s default Containment is being ported to QML. A technology preview of the containment is being demoed and can be tested by a wider audience now. While the port is mainly replicating the current desktop containment in QML, its interaction scheme to position and manipulate widgets on the desktop has been improved.
First of all, a note: The code presented in this article is not part of the upcoming Plasma Desktop 4.10. It can easily be installed on top of it, it might see inclusion in the summer 2013 release, however
In our Roadmap, you learn that KDE is currently porting many aspects of its workspaces to QML, with the goal to create a more modern user experience on top of state-of-the-art technologies such as Qt5, OpenGL scenegraph and Wayland. The move to QML is a gradual process, made possible by the componentized architecture of Plasma. Widgets and other components that make up the workspace are replaced with QML ports one by one. The premise is to not introduce regressions by shipping each component “when it’s ready”. Ultimately, we need a complete set of QML components to run the whole desktop (and at some point also apps) directly on top of the graphics hardware, leading to higher graphics performance and more available resources on the CPU.
One of the important pieces is the Desktop containment. This is the component in Plasma that is responsible for managing and laying out widgets on the desktop and creating the toolbox (which makes some “workspace actions” available to the user. In general, a “Containment” is an area on the screen (a panel, the desktop background, the dashboard, …), and it takes care of managing widgets, their position and sizing within. It also offers access to action specific to widgets, or the containment or workspace.
The currently shipped (also in 4.10) default Desktop containment is written in C++, using QGraphicsWidgets and offers free placing of widgets on the desktop, with a bit of edge and overlap detection and repositioning poured in.
Most of the new containment is exactly the same as in the current default — this is done by design, we do not want to introduce radical changes to the workspace (and the users’ workflows), but rather improve gradually and in an iterative process. There are two areas (which in fact are closely related) where we did change a few things: positioning/sizing and visual cleanliness. These are expressed in two changes: integration of applet handle and positioning aids.
In order to reduce visual clutter, we integrated the applet handle into the applet’s background frame. Previously, it would be its own frame, and shift out as separate element from under the widget. Merging handle and background frame reduces the number of distinct elements on the screen and allows less intrusive transitions when the widget handle becomes visible.
The second important change is that we now provide helpers when the user moves and resizes a widget. When moving, we show a halo at the position the applet will snap to when dragged. This makes widget placement more predictable and allows the user to get it right in one go. We also align the widgets to an invisible grid, so applets automatically end up being aligned pixel-perfectly with each other, which leads to a more ergonomic workflow, cleaner appearance of the workspace, and again to less visual clutter.
Platform improvements: Bindings and Toolbox
An important aspect of the work on the QML containment, was to improve the bindings which load declarative code (QML) into Plasma shells, these improvements are included in Plasma 4.10, due to be released in early february. This includes the necessary platform features to allow running fully-featured QML containments, something which we have done in Plasma Active for a while, but within a more confined context.
As a result of this work, Plasma can now also load toolboxes written in QML. The Plasma Toolbox is the little widget with the Plasma icon you can see on top of many containments, and which gives access to actions such as add widgets, settings, shortcuts, etc.. The toolbox used with the containment shown is a 1:1 port of its counterpart in the current default (C++) toolbox. The name of the toolbox package is currently hard-coded in the bindings (it loads it from the org.kde.toolbox package and silently falls back to the C++ implementation if that isn’t found — a 4.10 feature), but it also opens up this part of the workspace to QtQuick goodness. The toolbox is basically a translucent layer on top of the desktop, so much freedom is given to other implementations).
A template and a bridge
The code is not only there to replace the current containment, it also serves as a template for new developments. With the new containment bindings in place, it is now very easy to create your own containment, modify someone else’s and publish them to share them. The containment shown is just one example for what we can do with the QML integration features in Plasma. As Plasmoid packages are architecture independent, this of course works across devices and different workspaces.
The work that is upcoming in Plasma Desktop is further bridging the gap between Plasma’s interfaces for different devices and formfactors. Some of its code has been introduced in Plasma Active, and is now available in a more generic fashion also for Plasma Desktop (and Netbook). This brings us closer to one of our goals, having only one shell that dynamically loads a suitable interface (Containment, Widgets) for a given formfactor, use case, output device, etc.
Give it a spin
If you’re interested and would like to try it (we appreciate feedback, it’s especially valuable in this phase!), there are two ways to get this containment. The minimal requirement for it is Plasma 4.10-beta1.
If you’re using git, you will find the code in the branch called “plasma/sebas/desktop-qml”, just check it out and build it, install it, run kbuildsycoca4, and you’re done.
If you are using the packages, you can easily install the following two Plasmoid packages to your system:
If your system is using a version prior to KDE SC 4.10-beta1, the packages will install, but not work.
The following commands install the necessary Plasma packages into your home KDE install directory.
# create the package directory and go there
mkdir -p `kde4-config --prefix`/share/apps/plasma/packages/org.kde.toolbox
cd `kde4-config --prefix`/share/apps/plasma/packages/org.kde.toolbox
# unpack the plasmoid package
# check if it's installed correctly,
# this should list metadata.desktop and contents/
ls -la `kde4-config --prefix`/share/apps/plasma/packages/org.kde.toolbox
[Edit: changes --localprefix to --prefix, as we've found a bug in --localprefix code.]
Then install the desktop containment package (If you’re updating the containment at a later stage, use plasmapkg -u.):
plasmapkg -i desktop-git28012013.plasmoid
You can now choose the new containment from Layout dropdown in the Desktop Settings, pick “Default Desktop (QML)” there.
I would like to thank Blue Systems for supporting my work on the above topics.
KDE’s Next Generation user interfaces will run on top of Qt5, on Linux, they will run atop Wayland or Xorg as display server. The user interfaces move away from widget-based X11 rendering to OpenGL. Monolithic libraries are being split up, interdependencies removed and portability and dependencies cut by stronger modularization.
For users, this means higher quality graphics, more organic user interfaces and availability of applications on a wider range of devices.
Developers will find an extensive archive of high-quality, libraries and solutions on top of Qt. Complex problems and a high-level of integration between apps and the workspace allow easy creation of portable, high-quality applications.
The projects to achieve this goal are KDE Frameworks 5 and Plasma 2. In this article, you’ll learn about the reasons for this migration and the status of the individual steps to be taken.
As this article is going to be a bit long, due to its level of detail, you can just skip to the end of every subsection to get the executive summary. Also, I would like to thank Blue Systems for their sponsoring of a lot of the work that is going into the future of KDE’s products, among which, mine.
Status Frameworks 5
Development of KDE’s Frameworks5, which focuses on modularization of APIs currently contained in kdelibs and kde-runtime, loosening its internal structure and making it possible to only use specific parts by splitting it into individual libraries and solutions.
The entire work to be done for Frameworks 5.0 is split into 7 topics. Three of these “Epics” are done:
Initial communication and documentation (Kevin Ottens),
Merging of code into Qt 5.0 (David Faure)
Reduction of duplication with Qt by removing classes and using their Qt alternatives (Stephen Kelly)
Four Epics are currently work in progress, three of them are monstrous:
Build system (Alex Neundorf, Stephen Kelly)
CMake (upstreaming some stuff, modularization, porting)
Modularization of CMake KDE settings (work in progress)
Modularization of macros
Review and inventarize Find* CMake modules
kdelibs cleanups (David Faure)
This is a large Epic, containing many bite-sized tasks. Roughly 50% of them are done, 37 tasks remain open and 7 are being worked on, an extensive list is on the wiki.
Qt 5.1 merging (David Faure)
This is the list of things that we haven’t been able to merge upstream into Qt 5.0, so we hope we can upstream as much as possible into Qt 5.1. This can potentially cause timing problems, if we can’t get all the necessary things we need into Qt 5.1. 9 tasks are work in progress by David Faure, Thiago Maciera, Richard Moore and others. 52 tasks are on the todo list, most of them currently unclaimed.
Splitting kdelibs (blocked) (Kevin Ottens)
Another large Epic, in bigger chunks, meaning going through all libraries one by one, porting their build system to the changes in Frameworks5, cut out certain library dependencies and changing the translation system. 13 tasks are done, 12 work in progress and 8 on the todo list, not all of them assigned.
An extensive list of libraries and their status can be found on the wiki.
Frameworks 5 currently compiles on top of Qt 5.0 and basic system services run (kdeinit5), although not all of its dependencies have been ported to Qt 5. Work on Frameworks5 is ongoing, so it is currently quite a moving target, and will remain so for a while.
Plasma and KWin Direction
An architecture based on Qt5 and Wayland makes it possible to use a more modern graphics stack, which means moving from X11-based rendering to OpenGL graphics rendering. QtQuick2 (which is the QtQuick shipped with Qt5) makes it possible to offer a very nice and extensible development API, while using the full power of the graphics hardware to produce excellent visual possibilites. Plasma offers development APIs that make it easy to create well-integrated applications as well as workspaces that are flexible, extensible and fully featured on top of QtQuick, and in the future QtQuick2.
As KDE moves forward towards Frameworks5, Plasma is taking the opportunity of the source and binary compatibility break of Qt5 to do necessary updates to its architecture. The goal is to have a leaner Plasma Development API and depdendency chain and achieve a better user- and developer experience by moving the UI fully to Plasma Quick, which is QtQuick plus a number of integration components for theming, compositor interaction, internationalization, data access and sharing, configuration, hardware, etc..
This constitutes a major refactoring of the Plasma libraries and components. First, their UI needs to be done in QML. This effort of porting workspace components to QML is already well underway. Second, the Plasma library and runtime components need to be ported from the QGraphicsView-based canvas to QML. This means cutting out dependencies on classes such as QGraphicsItem and QGraphicsWidget to their equivalent in QML. In the case of painting and layouting code, it means porting this code to QML.
Plasma Components (containing a basic QtQuick widget set)
QtExtras (containing components missing in Qt, such as MouseEventListener)
PlasmaExtras (containing additional UI widgets for better integration, such as animations, text layout helpers, Share-like-connect integration, etc.)
Making scriptengines (such as the Python scriptengine) only export QObject-deriven classes to the QML runtime (needs investigation right now)
Port of widgets away from QGraphics*, also necessary for some QML code
Plans for KWin Plasma Compositor
Plasma Compositor refers, in a Wayland world, to the compositor used for Plasma workspaces, which is essentially KWin in disguise as Wayland compositor.
In KWin, we benefit from an ongoing effort to modularize and clean it up architecturally. For most of its UI, KWin already supports QML (Window decorations, tabswitcher, etc.). Some mechanisms which currenty work through XAtoms will need to be ported, the API impact of that will likely be quite limited for application developers.
The strategy for KWin is to port KWin to Qt 5, then make it possible to run KWin outside of an X server on top of KMS, using the graphics hardware more directly. The next step is to use KWin as compositor for Wayland display servers. The dependency of X11 can be removed once it is not needed anymore to provide compatibility with X11 applications, or can possibly be made optional.
Milestones for KWin (Martin Graesslin) (updated with further clarifications, thanks Martin):
KWin on Qt5 (work in progress, planned for 4.11): KWin will not depend on Qt 5 as of 4.11. The idea is to have KWin in a state that we could compile KWin with Qt 5/KF 5. But as it is unlikely that KF 5 will be allowed dependency for 4.11, we will not see a KWin on top of Qt 5 even if we achieve that goal. It’s a weak goal as we cannot release on it anyway.
on top of KMS (planned for 4.11): KWin in 4.11 will still run on top of the X-Server. This is mostly about adding a proof-of-concept. Whether that will be merged into 4.11 and compilation enabled will be seen once the code has been written. So in this case it will at most be an additional very hidden (env variable) mode for testing.
KWin as Wayland compositor (planned for 4.12): Again only as addition. As of 4.12 we will still be targetting X-Server as default. If we succeed we might add an option. But this pretty much depends on the state of Qt 5/KF 5 and QtCompositor. If any of those dependencies is not ready to depend on, the code might exist, but will not be released.
no X11 dependency (planned for the distant future): There are no plans to drop X11 support. But we want to have the possibility to build a KWin without X for new targets like Plasma Active. For the desktop there are no such plans.
Once we have a working libplasma2 and a useful set of QML Plasmoids, we can think of running an entire workspace in QML and on top of QtQuick2, either on top of X11, or with KWin’s plans in mind, on Wayland.
Porting status of important widgets to QML / Plasma Quick needed for the workspace:
Taskbar (close to first review, target: 4.11) (Eike Hein)
Folderview (work in progress) (Ignat Semenov)
Desktop containment (second revision close to review, target: 4.11) (Sebastian Kügler)
Calendar (work in progress, target: 4.11) (Davide Bettio, Sebastian Kügler)
Kickoff (about to be merged into master, target: 4.11)
KRunner (work in progress, target: 4.11) Aaron Seigo, Aleix Pol
Done: System tray, pager, notifications, device notifier, battery, lock/logout, weather, Wallpaper, Containment support
others from kdeplasma-addons
and more (see wiki)
KDE’s Framework 5 project is well underway. It will allow us to move to a more modern graphics rendering engine, make our development platform more portable, and make it easier to reuse solutions KDE has built. The work does not happen by itself, however, yet it is time-critical. With Qt5.0 being released, 3rd parties are porting their code already. These people will only consider using KDE’s technologies if they are actually available — and that means we need a Frameworks 5 release.
So is this going to be KDE 5? The answer to this question is still “No!”, for a number of reasons:
Frameworks 5, apps and the Plasma workspaces are not one singular entity. These parts are only released together (which might change in the future), and cobbling them up under one name really is really not helpful. (3rd party developers will think we’re only targeting Plasma workspaces, Plasma users will think you’ll only be able to run “KDE apps”, potential users of applications will assume that you can only use them inside Plasma workspaces — all of them untrue, all of them taken right out of my daily experience)
Within the Plasma team, we tend to use the abbreviation PW2 to refer to the next generation of Plasma workspaces. It stands for Plasma Workspaces 2, and it will probably be named differently in the future.
So, now you’re fully up to date on the status, isn’t it time to get cracking?