High DPI Progress

High DPI Revisited

A few weeks ago I talked about high DPI in KDE applications

Abridged Recap

  • By settings QT_DEVICE_PIXEL_RATIO=2 Qt will scale all painting to draw things twice the size
  • By default this will just scale all our images so it slightly defeats the point of buying a fancy new high resolution screen
  • Qt can try and be clever and draw high resolution icons and other images
  • This is liable to break stuff, so requires each and every app to opt-in


On Monday this week I was loaned a high resolution laptop, and set about trying to make sure everything works perfectly within the KDE world.
We can now set this environment variable from a configuration file, and a user interface is in review to allow the user to manually set their scaling factor.

I then set about trying to enable high resolution image support in various applications and trying to fix all that is broken.

This task is two-fold. The first is fixing any bugs that result in simply enabling the high resolution icons. Second is making sure applications that provide their own images, do so in a way that still look spot on when used on a high resolution monitor.

Progress Screenshots

Here is my screenshot just after installing Kubuntu CI on a high resolution laptop (3800x1800).

We can correct some parts by just boosting the font size, but that doesn't solve the problems of small checkboxes, buttons and other hit areas. This isn't just a superficial problem and it becomes a major usability problem especially as these screens become more widespread.

This second screenshot shows the result with the device pixel ratio set and a weeks worth of fixing in a range of apps. (click for full size)

The most obvious thing is that the sizes are bigger, but more importantly this is happening whilst all icons and scrollbars remain crystal clear at the native resolution for that screen.

A zoomed in section looks like this:

Current Status

Every Qt5 app can double up with no work at all, but to look right requires some effort.

For some applications supporting high DPI has been easy. It is a single one line in KWrite, and suddenly all icons look spot on with no regressions. For applications such as Dolphin which do a lot more graphical tasks, this has not been so trivial. There are a lot of images involved, and a lot of complicated code around caching these which conflicts with the high resolution support without some further work.

I am tracking progress on a Kanboard page. Naturally I can't do every application, but I hope that by checking a few I can make sure all of our frameworks have full support making it easy for every other developer.

We also have a problem that Qt4 applications do not support device independent pixels. There are still many applications without a frameworks release even in the upcoming 15.04 applications release. Even in the next applications release in 15.08 August we are still unlikely to see a released PIM stack.
Is it a good idea to add an option into our UIs that improves some applications at the cost of consistency? It's not an easy answer.

Help fix up all of System Settings

System Settings is a strange part of Plasma; it composes of umpteen modules gradually written over the last 15 years by a lot of different people.

As each configuration module is generally small and self-contained it doesn't take a lot of continual maintenance so when a developer becomes inactive we tend not to notice.

Unfortunately over time we've seen the number of open tickets on system settings modules increase over time. They get left unsorted as it's "someone elses problem".

This leads to things falling between the cracks, particularly for finding the Plasma 5 / Frameworks regressions as we can't see the real issues through the noise of all the duplicates, outdated bugs and frankly bad ideas.

Whilst I'm doing Plasma this isn't a trend that is going to continue.

I've spent the last week of evenings triaging system settings tickets and fixing up some of the most important bugs.

I need some help on going through the remaining bugs, my personal target is to get the total number of open tickets down to 400 by the end of February.

If you want to help out join us in #kde-quality on Freenode and we can co-ordinate some triage and split out some of fixing, making Plasma a polished experience once again.

A list of bugs split by component can be found here.

How does systemd relate to Plasma?

In some of the comments about the latest Plasma release sometimes someone brings up the topic of systemd. This is normally met with the rebuttal "Why should a desktop environment care about what init sytstem is used?".

It's a very sensible question, but it's also one that's easily answered. I wanted to explain how different parts of systemd relate to Plasma.

The init system

We don't care. It doesn't affect us.

The init system is one part of systemd that doesn't affect us at all, and any other could be used.


Logind is a tiny daemon that keeps track of seats and sessions on your machine.

In principle it's very simple, every login (including autologin) goes via PAM (Pluggable Authentication Modules) modules; a special PAM module signals to a central daemon that a new session is started and tell it when it stops.

This blog series has the most detail on session tracking and why logind solves problems better.

We need knowledge of all active sessions from within Plasma to be able to offer session switching inside the UI and to warn the user if they attempt to shutdown whilst other sessions are still active.

This class kdisplaymanager in plasma-workspace shows our abstraction layer growing since 2004; it currently has Logind support but as we have been adding to a constantly broken abstraction layer it's used very badly. It has tracking code for over 5 different systems (KDM, old GDM, new GDM (which is now old), consolekit, org.freedesktop.DisplayManager, and now logind) and is probably one of the ugliest pieces of code in Plasma.

Logind does seem to solve these problems better, particularly with regards to multi-seat and the other features it provides.

We need to tidy this area, having an abstraction layer only leaves us with a lowest common denominator, and it isn't pretty.

When people reference standards, someone will cite XKCD, I think more of it like this:

Device Management

Logind allows the session leader to open input devices which are otherwise only available to root.
This allows kwin to monitor key and mouse events whilst blocking other applications from sniffing your keystrokes.

Martin Graesslin's blog explains this in more detail.

Inhibitor Locks

One other feature logind provides that we are making use of is inhibition locks.

Upower will notify us when the system is about to be suspended. Which sounds ideal, we should be able to react to that and perform pre-suspend tasks. Unfortunately it's not very useful as the system is shutdown before it finishes.

When logind is asked to suspend, it will inform all applications which have requested a delay. It will then wait for up to 30s for all apps to respond that they have finished their pre suspend tasks.

This allows us to make sure the lock screen is completely up and running before we suspend the system; so you don't have that jarring and insecure moment where you open your laptop and it is still showing the original contents before the lock screen finally loads.

We even use this feature from Telepathy, the instant messaging system. In order to save bandwidth most IM protocols aren't constantly sending data The problem is when we disconnect it will take a long time for the server to notice and update your status. We have an inhibition delay that gives us a very small window to shout to all the servers "we're going offline now".

Timedated and Friends

Systemd also comes with a set of utilities for performing some system administration utilities, such as changing the hostname, timezone, locale and such.

What makes these interesting is that the components are split into two parts; a small command line client but more importantly a defined DBus interface to a small DBus activated daemon that uses polkit for authorisation and does the actual changes.

This approach is similar to what we do in our date and time config module; we have our GUI and we also have a small helper app that's DBus activated and runs as root which we are shipping ourselves. Our helper app then runs one of 6 different ntp programs; almost all of which are now outdated.

We don't want to be writing code that runs as root and as a user you really don't want us to be doing so.

By using a defined DBus interface we are able to share this code between desktops and share safe audited code for all root access.

Naturally this not only applies for timedated, but also hostnamed, machined and whatever else might come in the future.

Change Monitoring

In addition timedated, the systemd interface for changing the time, emits signals whenever it changes the timezone.

Currently in order to achieve the same effect we have a constantly running daemon that monitors /etc/localtime for file changes and then emits DBus signals for all the other apps.

If we could rely on everyone setting the timezone through timedated we can remove this watch which will free some resources for everyone.

What else could we make use of?

There are a few other places where embracing systemd adds functionality or makes code simpler; our system guard can show which seat and which container an application is running on. I already wrote a patch for this, but got bored #ifdef-ing everything.

Using a common storage for log files means ksystemlog could be restored to a working product again.

User Units

Last but not least we have user units.

Currently init is handled by a rather cumbersome shell script. It's as simple as starting the KDE services in order in a list.

User Units allow Plasma services to use the same features as available to system daemons.

Most obviously we get the faster bootup as we are able to parallelise component startup, but there are more benefits.

Systemd provides services to restart crashing applications with finer control, a watchdog can detect a hung application or if a process gets out of control using too much resources and restart it automatically. Logging will also be greatly improved; faster to run and easier to supply developers with relevant information instead of a giant .xsession-errors file.

A trial has been started here providing user units; which when ready will work their way into the main plasma-workspace.

Longer term, we can investigate replacing parts of kded, the KDE daemon with systemd directly, providing a single common way to manage all services.


Hopefully it clears up what we mean when we talk about systemd and desktop environments, and where we could use different parts of systemd.

It should be apparent that as developers there are parts we want to embrace as it. In many cases it allows us to throw away large amounts of code whilst at the same time providing a better user experience. Adding it as an optional extra defeats the main benefit.

As maintainers we have a duty to balance what will provide the best experience for the majority of our Plasma users without leaving anyone with a broken system. Projects like this bring the interfaces we need to BSD and as it gets more stable we should be able to start distributing features.

Plasmoid Tutorial 1

With Plasma 5.2 out I wanted to update the tutorials on how to write a Plasmoid. Going through all of the steps from hello world, to using Plasma Components to configuration through to differing form factors.

It made sense to publish them as blog posts before I copy them to the wiki.

Behold, the first rather wordy blog post in a series of 7.


With Plasma5 we have embraced QML as our technology of choice. It is the only method of writing the UI for plasmoids.

Whilst Plasma4 offered a range of language, QML is the only way of interacting with QtQuick, the technology that powers the Plasma Shell. By using this we we get to provide a better developer experience as there is a wealth of existing QML resources. Some of the best links are:

  • http://doc.qt.io/qt-5/qml-tutorial1.html
  • http://qmlbook.org/

Before you get started with writing plasmoids, it is recommended to read through the basics of these and have a bit of playing to get used to the language.

Writing plasmoids is effectively the same as writing any other QtQuick QML, with a few extensions:

  • We have a specific folder structure with metadata for our plasmashell to be able to load the files.
  • We provide a massive collection of libraries that extend the QtQuick library both with functionality and widgets that blend in with the Plasma theme.
  • Special API exists to interact with the shell, allowing you to save configurations or set default sizes.

In this series of tutorials we'll go through the steps of writing a real plasmoid from scratch, using some of the plasma libraries.

By the end we should have a completely working, deployable RSS reader.

Hello world

Initial Folder Structure

Plasmoids follow the simple KPackage structure. In the top-most folder there should be a file titled metadata.desktop and a single folder called "contents".

Inside the contents folder we place all our QML, assets and other additional files. We split the contents into subdirectories: config, data and ui to make things easier.

In our tutorial we will be making an RSS reader so everything is named appropriately to that.

The basic directory structure should be as follows:



[Desktop Entry]
Name=RSS Plasmoid
Comment=Shows RSS Feeds
X-KDE-PluginInfo-Author=David Edmundson

Most of the fields here should be fairly self explanatory.
If in doubt, copy this and change the relevant fields.


import QtQuick 2.0

Item {
    Text {
        anchors.centerIn: parent
        text: "Hello World!";

Providing you have followed the recommended reading this should be fairly self-explanatory, we have a text item in the middle of the plasmoid which will say "Hello World".

Over the next few tutorials this will get somewhat larger, we will also see some of the problems with this example; here translations aren't implemented and the text won't match the Plasma theme colour.


From the directory above run

plasmapkg2 --install myrssplasmoid

It should now be visible in the plasmashell in the "Add widgets" option along with every other plasmoid.

We can then it to our desktop or panel like any other installed plasmoid.


Next tutorial, we will cover getting data from external sources.

Plasma – Calling Qt 5.4 Testers

Plasma 5 pushes QtQuick to the limits. It sounds like a cheesy marketing line, but it's true. Unfortunately this isn't a good thing. Although Plasma 5.1 is somewhat stable we have had some crashers, and whilst we've worked hard to fix the ones that are ours a sizeable number of these were caused by problems deep inside Qt.

Fortunately Qt 5.4 has just been released. It contains countless bug fixes that really improve the situation; several of which were even written by me and the rest of the Plasma crew.

We need people with Qt 5.4 (hey all you Arch people) to help go through all open crash reports and test if they still happen since upgrading.

I don't like closing bugs wtih a vague "it seems to work for me" without getting at least a second opinion, I may be overlook something and it's not fair on the original reporter.

I've added a quick link to the high priority candidates

And feel free to help go through the rest of our list

So far everything is looking very positive towards having a completely rock solid Plasma 5.2 in January; lets make it happen.

HighDPI in KDE Applications

Recently I was asked about the state of High DPI in KDE Applications, by someone with a fancy screen.

In Plasma we have our own solution for solving the HighDPI problem, as we were working with new code where we provide the styling, this is all fairly straightforward. However, this doesn't work for applications which have a lot of existing code we need to bring this feature to.

This upcoming release of Qt (5.4) brings us everything we need to support High DPI in our applications. It's not going to be useful for end users just now, but this is a time where we need each and every developer to start getting interested and making sure their applications are ready.

Support requires at least one line of change in every application.

High DPI in Qt

Normally my application, will look something like this. On my screen this is fine,if you see this on a high DPI screen everything will be tiny.

If we change the DPI used in the fonts we, naturally, get bigger fonts. More usable, but all of the other controls are still hilariously small as they haven't changed. This is our current state.

Device Independent Pixels

Qt borrowed a concept used in Android and iOS of separating the pixel sizes we use in the code, to the actual pixel density on the screen.

From a programming perspective we keep coding like everything is in 96dpi like a normal desktop display, but underneath all co-ordinates and graphics will be doubled or quadrupled to scale up to the device resolution.

This API at a Qt level works per screen; with every screen having it's own independent scaling factor. However, in the X backend for Qt 5.4 it's loaded from an environment variable that applies to all screens. Not ideal, but better than nothing.

This gives a result, that is now usable, but very blocky and pixelated.
(you may need to click the image to really see this)

This blockiness problem is also solved. Whenever we create a pixmap we can make sure we provide graphics that have a higher size in device pixels than their size in user space.

To quote the QPixmap documentation, "For example, painting on a 200x200 image if with a ratio of 2.0 will result in effective (device-independent) painting bounds of 100x100.".

With "pixel" now meaning one of two things can get confusing very quickly.

As you might imagine, all of this wizardry under the scenes means it's moderated likely to break at least some applications. As Qt follows the rule of never breaking existing application it requires each and every application to opt in.

I added a command line flag --highdpi to oxygen-demo, the application in the screenshots, to enable the scaling support and test both side-by-side which finally leaves us with:

There were no additional changes to oxygen demo to make this work yet we see we're using high resolution pixmaps on the icons and on the clear buttons in the text field.

How to make sure your app works with Qt's high DPI

1) Port to Qt5
If you're putting it off porting because you're scared of regressions. The reality is over time you will have more bugs from not porting. Without Qt5 we don't get /any/ scaling. Not even the blocky version.

2) Opt in to the high DPI pixmap support

app.setAttribute(Qt::AA_UseHighDpiPixmaps, true);

to your main function

3) Port code
If you don't do any low level work with unusual QPainter painting, provide any of your own pixmaps or load textures in QQuickItems, everything will just work.

Most likely your app will have something broken. Useful links are here and here.

4) Test
I only have a poor person's screen, but it's still easy(ish) to test:

  • Change the DPI under system settings -> font -> force font DPI to 192
  • Set the environment variable QT_DEVICE_PIXEL_RATIO=2

On a normal screen everything will appear massive, but hopefully also super smooth.

My thoughts on the GNOME trademark dispute

Unless you've been living under a rock today you would have seen that Groupon™ have been trying to use a trademark that belongs to GNOME™. Today GNOME™ started raising money to fight a legal battle.

I know there have been ongoing private discussions for months, and even though I have no idea what was said I do have full faith that if it got to the point of GNOME threatening to take legal action, it's because they felt they needed to.

It seems to have worked.

Communities Unified

What I loved to see most about this was I opened my G+/Facebook/Twitter feeds to see all of my KDE colleagues resharing this piece and donating money. Even /r/linux on Reddit, normally a somewhat feisty community, was filled with comments like "I don't use Gnome, but I'm going to support them".

Working together, supporting each other is what us open source communities should be about.

We're Not Easily Pushed Over

I don't think there was any attempt or conspiracy to try and destroy Gnome, but I do think there must have been some decision maker thinking "it's only a small charity software project, they're not going to bother fighting back, we can walk over them".

We, collectively, showed them wrong and I like to think the next company won't think the same thing.

Money Well Spent?

To everyone in engineering, the idea of having to spend money on legal mumbo jumbo is, at best, thoroughly depressing.

However, I saw a number of people making the rather silly comment "this is money that they should spend on developing instead". This was a fundraiser, which means it's "new" money that GNOME™ wouldn't have had otherwise.

Case in point; KDE™ and GNOME™ both have constant drives for developer funds which don't recieve anywhere near the level of interest this got.

If you feel that's where money should be spent, please please donate there and put your money where your mouth is.

My new library: Qlogind

What is it?

A high level wrapper round logind.

We are starting to use logind in numerous places; I need it in SDDM to track sessions. we have code in ksmserver to track Lock/Unlock signals, as well as in the kworkspace library to list sessions. It's coming into KWin for device hardware access as well as being used in solid.

The need for a library

Often we can simply automatically generate bindings at compile time using qdbusxml2cpp that turns DBus interface annotation into working code.

Unfortunately that doesn't work here for a few reasons.

qdbusxml2cpp and QDBusAbstractInterface are both really outdated; and don't know how to handle org.freedesktop.DBus.Properties.PropertiesChanged. Logind uses this method as the only way to notify of any changes, and in fact even introduced their own new type of changed signal annotation without these change signals it becomes near impossible to use.

To solve this, and a few other minor issues this repository contains a fork of qdbusxml2xpp and QDBusAbstractInterface with property caching and no blocking methods anywhere.

Ideally I want to push my changes upstream, but I always like to prototype code before committing to new API especially with Qt. Also we're going to need these changes before Qt5.5.

There are some other usages for a library, there are some changes needed to make to the annotation to make it compile (logind has a property called "class", funnily enough the c++ compiler does not like this) as well as code to demarshall complex types.

From personal experience having a good wrapper library can make a lot of development easier as we can write a higher level API on top to ease fetching multiple queries asynchronously.


I've tried to make the code as easy to use in an asynchronous way, without the user having to write chains of lambdas.


    PendingSession* ps = Session::sessionFromPid(QCoreApplication::applicationPid());
    QObject::connect(ps, &PendingSession::finished, [=](){
        SessionPtr session = ps->interface();
        if (session->active()) {
            qDebug() << "Session " << session->id(); << "is active";

This code internally both a call to Login1.Manager to find the session path for a PID then requesting Properties.GetAll on the Session object in one handy KJob like API.

Where is the code

Code is availabe at git://anongit.kde.org/scratch/davidedmundson/qlogind.git

Current State

It's not quite finished, I only started this 2 working days ago. It needs namespacing, d-pointers and unit tests.

I wanted to write a blog post to get the people who might need to use this to have a look and give some feedback if there's anything missing.

Display Managers In Plasma 5

The last blog posts about KDM/LightDM/SDDM/WhateverDM left things a bit on an exciting cliffhanger so I've been asked a few times what the current state is.

The short summary is we recommend SDDM as the display manager for Plasma 5.


KDM was dropped from Plasma 5. KDM includes code from XDM dating back to 1988! It had served it's job well. However, we're now at a point where we need the backend to be Wayland ready and we want to use more modern QML in the front end. When you have to replace both the back and front ends, it's a sign to just start from scratch.

There was some work done 2 years ago into sharing code with LightDM. In the meantime a separate project was started, SDDM which is (yet another) display manager.

Although personally I was very happy with what we had with LightDM it definitely doesn't make sense to split resources, so we focussed everything on SDDM and I have been helping work on that transferring knowledge from my old project.

Plasma Integration

SDDM is itself in Github and usage is shared with other desktop enviroments, in particular Maui. This makes it harder to add Plasma integration in the code itself, but we've managed nonetheless.

The visual design group made some mockups of a new display manager, which became the basis for the implementation of our login screen.

This is shipped with plasma-workspace. It is up to distributions to update /etc/sddm.conf to update the default theme on installation as it's not something we can do from our code.

In addition we also provide a configuration module that fits into SystemSettings. This is now back in the KDE repositories and will be included in Plasma 5.2.

Naturally Plasma can still work with any display manager as half of the point of having a display manager is to allow choosing which session to launch.