Contributing is more than just code

When thinking about how to contribute to KDE, many people probably still think that you have to write actual code. While it’s true that C++ and QML is at the heart of our applications, it’s just one puzzle piece of many that make up a successful product. Besides donating money to KDE or developers like me individually, there’s much more you can do to support us: promo work, drawing icons, brainstorming ideas, writing documentation, triaging bug reports or writing new ones, or in this case sending the relevant piece of hardware to a developer. Every single contribution counts!

Dolphin Places sidebar listing various drives, among them a "CD-ROM" in the "Removable Devices" section
It’s been at least ten years since I last used an optical drive

A key ingredient to KDE’s cross-platform story is Solid, our device integration framework. It lets applications enumerate devices, such as hard drive partitions, USB thumb drives, but also batteries and peripherals, in a platform-independent way. When it comes to hardware, sometimes emulating its behavior is tough and even a virtual machine might not behave exactly the same as the real thing. Here’s the story of how the donation of a portable DVD drive let me unlock a massive performance boost.

On Linux, to enumerate storage devices it talks to UDisks2 on DBus. You can actually view all the information yourself by using qdbusviewer or d-feet and navigate to the org.freedesktop.UDisks2 service on the System Bus. The Places panel found in applications like Dolphin but also the Device Notifier applet in System Tray query Solid for interesting storage devices to display to the user.

On a typical system, there’s plenty of mount points (particularly Snap is notorious for creating lots of loop devices) which we don’t want to show. Nevertheless, we have to fetch them all to decide whether they’re interesting to us. For example, usually only storage devices explicitly listed in fstab, mounted from /media (your typical USB stick drive), or originating in the user’s home directory (an ISO image in your Downloads folder) are displayed.

Currently, owing to Solid’s modular nature and the fact that a lot of its original code was written in KDE 4 times where many API conveniences in DBus and UDisks didn’t exist yet, Solid uses the DBus Introspectable interface to enumerate all devices. This gives us an XML description of the available interfaces and object paths on the service. As you can imagine, receiving and processing that data string can be quite expensive. Furthermore, for every device that was enumerated, a Solid Device instance is created which then fetches all properties from all interfaces on the relevant object, which again can be slow. The DBus interfaces an object implements in UDisks gives us a good idea of what type of storage we’re dealing with, for example org.freedesktop.UDisks.Loop contains properties regarding loop devices, such as the original path of the image file that has been mounted, which in turn is also a org.freedesktop.UDisks.Block device, and so on.

qdbusviewer viewing the org.freedesktop.UDisks2 service on the System Bus with block_device/nvme0n1p1/ expanded and property "MountPoints" displayed as raw value. Reads 47, 98, 111, 111, 116, 47, 101, 102, 105 (/boot/efi)
Retrieving a mount point via DBus, eventually you realize that “47” is forward slash.

There must be a better way to do this, right? There is! It’s called org.freedesktop.DBus.ObjectManager. It lets you fetch all objects and their properties in a single call. This would allow Solid to query everything at once on startup and then only fetch individual properties when they get invalidated or a new device is plugged in at runtime.

Both encrypted drives and optical media are somewhat special in that they’re a drive (or container) containing the actual media or partition. While a USB stick just disappears entirely as you unplug it, a DVD drive will only have its media ejected. It means we need to monitor the drive and check its media availability and then announce the disc inside of it. However, when I asked fellow KDE developers to test my changes, the patch-set worked fine with the CD-ROM drive emulated in a virtual machine but failed miserably with a legit drive. The situation with Audio CDs was even worse since they don’t have a regular file system associated with. And guess what: there’s also CDs that contian both audio and data.

I asked around on KDE’s Matrix channels whether someone might have a spare USB CD-ROM drive and is willing to help. The other day MartinR approached me in the KDE neon channel and said he had a spare one he could mail somewhere. When it arrived a week later, I immediately tried it out (it’s been some time since I’ve seen a device with a USB Y cable) and it indeed let me iron out a bunch of remaining issues with the original patch-set. There’s other examples, too, where having the actual hardware is key. For instance, in order to properly develop HDR support in KWin, the developers need to have an actual screen capable of displaying it.

An AMOLED screen running Plasma 6 in HDR mode with the then-current Plasma 5.27 wallpaper (a pale blue painted mountain scenery) and a panel on the left side
KWin Wayland running in HDR mode on a portable OLED screen, courtesy of Xaver (the picture of course doesn’t do it justice)

The change isn’t actually merged yet as I am in the process of writing a fake UDisks2 service for Solid. This would let us run a bunch of automated tests, particularly for the weird cases, and ensure that my refactor doesn’t cause any regressions. Solid has unit tests for its general working but not specifically to the way it interacts with UDisks2. A bug in Solid that renders your data inaccessible (sorry about that encrypted drives bug the other week) or causes the shell or some KDE background service to crash upon plugging in a device would be a disaster.

Having said all of that, let me thank you again very much, without your generous donation I would not have been able to realize this project. On my laptop, the time it took to initialize a KFilePlacesModel went down from 55–60 ms to just under 20 ms. The number of DBus calls it places to the UDisks2 service went down from around 60 “get all properties”, 45 “introspect”, and 15 “get this particular property” calls to a single “get all managed objects” call, and one “introspect” call I have yet to hunt down. I’m sure our users will very much appreciate a faster starting Dolphin and snappier file dialog! Also many thanks to Fabian Vogt and notably Jan R. for continued advice and testing.

If you have a KDE development setup (and if you don’t, go set one up), please test this Solid patch, and let me know if it causes any trouble for you!

2 thoughts on “Contributing is more than just code”

  1. Maybe a silly question, but would the same situation apply to USB floppy drives (or even a real floppy drive on a desktop machine)?

    1. I am not sure. I know that USB floppy drives behave wildly different from actual built-in floppy controllers.

      That being said, KFloppy has been discontinued recently and I don’t think anyone will really care about a floppy drive nowadays.

      I did fix a Solid bug regarding floppies in 2017 though. :D

Leave a Reply

Your email address will not be published. Required fields are marked *