That moment when the application “just works” after all your unit tests pass…
A really nice experience after working on these low-level bits was firing up the kscreen systemsettings module configured to use my wayland test server. I hadn’t done so in a while, so I didn’t expect much at all. The whole thing just worked right out of the box, however. Every single change I’ve tried had exactly the expected effect.
This screenshot shows Plasma’s screen configuration settings (“kscreen”). The settings module uses the new kwayland backend to communicate with a wayland server (which you can see “running” on the left hand side). That means that another big chunk of getting Plasma Wayland-ready for multi-display use-cases is falling nicely into place.
I’m working on this part of the stack using test-driven development methods, so I write unit tests for every bit of functionality, and then implement and polish the library parts. Something is done when all units tests pass reliably, when others have reviewed the code, when everything works in on the application side, and when I am happy with it.
The unit tests stay in place and are from then on compiled and run through our continuous integration system automatically on every code change. This system yells at us as soon as any of the unit tests breaks or shows problems, so we can fix it right away.
Interestingly, we run the unit tests live against a real wayland server. This test server is implemented using the KWayland library. The server runs headless, so it doesn’t do any rendering of windows, and it just implements the bits interesting for screen management. It’s sort of a mini kwin_wayland, the real kwin will use this exact same library on the server side, so our tests are not entirely synthetical. This wasn’t really possible for X11-based systems, because you can’t just fire up an X server that supports XRandR in automated tests — the machine running the test may not allow you to use its graphics card, if it even has one. It’s very easy to do, however, when using wayland.
Our autotests fire up a wayland server from one of many example configurations. We have a whole set of example configurations that we run tests against, and it’s easy to add more that we want to make sure work correctly. (I’m also thinking about user support, where we can ask to send us a problematic configuration written out to a json file, that we can then add to our unit tests, fix, and ensure that it never breaks again.
The wayland test server is only about 500 lines of relatively simple code, but it provides full functionality for setting up screens using the wayland protocol.
The real kwin_wayland will use the exact same library, on the server as we do in our tests, but instead of using “virtual screens”, it does actually interact with the hardware, for example through libdrm on more sensible system or through libhybris on ones less so.
Kwin takes a more central role in our wayland story, as we move initial mode-setting there, it just makes to have it do run-time mode setting as well.
The next steps are to hook the server side of the protocol up in kwin_wayland’s hardware backends.
In the back of my head are a few new features, which so far had a lower priority — first the core feature set needed to be made stable. There are three things which I’d like to see us doing:
- per-display scaling — This is an interesting one. I’d love to be able to specify a floating point scaling factor. Wayland’s wl_output interface, which represents the application clients, only provides int-precision. I think that sucks since there is a lot of hardware around where a scaling factor of 1 is to small, and 2 is too high. That’s pretty much everything between 140 and 190 DPI according to my eyesight, your mileage may vary here. I’m wondering if I should go ahead and add the necessary API’s at least on our end of the stack to allow better than integer precision.
Also, of course we want the scaling be controlled per display (and not globally for all displays, as it is on X11), but that’s in fact already solved by just using wayland semantics — it needs to be fixed on the rendering side now.
- pre-apply checks — at least the drm backend will allow us to ask it if it will be able to apply a new configuration to the hardware. I’d love to hook that up to the UI, so we can do things like enable or disable the apply button, and warn the user of something that the hardware is not going to like doing.
The low-level bits have arrived with the new drm infrastructure in the kernel, so we can hook it up in the libraries and the user interface.
- configuration profiles — it would make sense to allow the user to save configurations for different situations and pick between them. It would be quite easy to allow the user to switch between setups not just through the systemsettings ui, but also for example when connecting or disabling a screen. I an imagine that this could be presented very nicely, and in tune with graphical effects that get their timing juuuuust right when switching between graphics setups. Let’s see how glitch-free we can make it.