Running PlasmaShell with Vulkan

About QtQuick and RHI

QtQuick, in one word, is amazing.

QtQuick, in slightly more words, is a scene graph implementation. At a developer level we create abstract "Items" which might be some text or a rectangle etc or a picture. This in turn gets transformed into a tree of nodes with geometry, "materials" and transforms. In turn this gets translated into a big long stream of OpenGL instructions which we send to the graphic card.

Qt6 will see this officially change to sit on top of the "Render Hardware Interface" stack, that instead of always producing OpenGL, will support Vulkan, Metal and Direct3D natively. The super clever part about it is that custom shaders (low level fast drawing) are also abstracted; meaning we will write some GLSL and generate the relevant shader for each API without having to duplicate the work.

This blog series gives a lot more detail: https://www.qt.io/blog/qt-quick-on-vulkan-metal-direct3d.

Plasma code primarily interacts with Items and occasionally nodes, slightly above the level being abstracted.

Current State

Qt 5.15 ships with a tech preview of RHI and the Vulkan interface. I spent some time to set it up and explore what we need to do to get our side fully working. With some packages installed, a few plasma code fixes and some env vars set, I have a fully working Vulkan plasmashell.

Screenshot

Unsurprisingly it looks the same, so a screenshot is very unexciting. I enabled the Mesa overlay as some sort of proof.
The reason it shows 2fps is because plasmashell only updates when something has changed; in this case the textcursor blinking every 500ms.

Despite it being a preview it is in a damn good state! Things are usable, and really quite snappy, especially notification popups.

What needs work

Some things need work on our side, in particular:

  • All of our custom shaders need porting to the updated shader language.
  • Taskbar thumbnails use low level GL code that needs one extra layer of implementation.
  • Use of QtQuickWidget in systemsettings.

It means some elements are invisible or don't render with the full graphical effects, or in the last case, crash.

But in the whole scheme of things, everything is in a very encouraging state

What about KWin?

Whilst QtQuick is the cornerstone of plasmashell, systemsettings and so many applications, for historical reasons KWin made use of OpenGL before it was a mainstream part of Qt. Therefore this setup is mostly unrelated to KWin. Fortunately there's no reason these two have to be in sync.

Wrap up

This isn't usable for end users, and given it's only a tech preview upstream, this is not something we can ever expect to officially support within Plasma 5.

But we can start doing the prep work, also the current state is so promising I think we can deliver a native Vulkan experience to users on the first day of Plasma 6.

What we can learn from Plasma telemetry

Since Plasma 5.18, about 7 months ago, Plasma has shipped with a telemetry system. Opt in (i.e off by default) it requires users to go to choose if (and how much) data to send to us.
No private or identifying information is sent, and everything is stored inline with our privacy policy.

Currently we have hit just shy of 100,000 updates!

We have started off requesting very little information. Versions, GPU info and some basic screen information. However the library powering this is extremely powerful and capable of so much more that we can try and build on in the future to try and identify weak areas and areas we need to invest time and effort and also to identify features or platforms that maybe are under utilised and can be dropped.

I have recently been trying to improve on how we can extract and visaulise data from the data collected and draw some conclusions. I want to present some of the aggregated metrics.

What we can learn from Plasma statistics

Used Plasma Versions

To explain our numerical versioning additons.
.80 = git master before the next version, up until the beta
.90 = after the stable branch forks for release up until the next.0 release.

LTS

The biggest surprise is that LTS is currently only used by around 5% of people with 93% of reporting users on the lastest stable (5.19)

At the current rate it does make me question whether the LTS is worth it. Maybe LTS will only gain traction when the next LTS distro gets a release which could come later?

Obviously any decision will only be made as the result of a discussion with all stakeholders, but this is definitely raising questions.

Testing

Right now about 1.5% of people run master, I had expected those users to be the most into helping with the telemetry and skew this further.
The bigger surprise is the number of people running master seems to fluctuate. Weekly users can go between 30-60. I had expected this to be constant.

It is comforting to see that betas do get more users, going up to 2.5% of our reporting userbase.

Interesting observations

There is one person who is still activitly using Plasma 5.18 beta. Not 5.18, the beta for 5.18.. which was 8 months ago.
I have so many questions.

Screens

800x600 resolution setups are still a thing we need to support, even if they are just VMs they're still used. This is very relevant as we often get commits blindly setting a minimum size hint of a window to be bigger because it "looks nicer". I now know I do still need to ensure in review that we don't break these setups.

We also see that ultrawide monitors are surprisingly unpopular despite clearly being the best monitor setup possible.

Graphic drivers

The graph is pretty self-explanatory, Intel has the most, but the Nvidia proprietory driver comes in at ~1/4 of the total users.
It makes it an important target to support as best as we can even if it comes with its share of problems.

My personal setup doesn't match your conclusions!

The reason we want to use telemetrics is to drive decisions with real data.

As a user you are more than welcome to choose to opt into the statistics or not, we understand privacy is important which is why everything is opt-in only.
However, real decisions will ultimately be based on the data we have available, if you want your usecases to be noted, please do consider submitting to the telemetry to us.
To enable telemetry please go to "System Settings" and select the "User Feedback" tab.

Bringing modern process management to the desktop

A desktop environment's sole role is to connect users to their applications. This includes everything from launching apps to actually displaying apps but also managing them and making sure they run fairly. Everyone is familiar the concept of a "Task manager" (like ksysguard), but over time they haven't kept up with the way applications are being developed or the latest developments from Linux.

The problem

Managing running processes

There used to be a time where one PID == one "application". The kwrite process represents Kwrite, the firefox process represents Firefox, easy. but this has changed. To pick an extreme example:
Discord in a flatpak is 13 processes!

It basically renders our task manager's process view unusable. All the names are random gibberish, trying to kill the application or setting nice levels becomes a guessing game. Parent trees can help, but they only get you so far.

It's unusable for me, it's probably unusable for any user and gets in the way of feeling in control of your computer.

We need some metadata.

Fair resource distribution

As mentioned above discord in a flatpak is 13 processes. Krita is one process.

  • One will be straining the CPU because it is a highly sophisticated application doing highly complicated graphic operations
  • One will be straining the CPU because it's written in electron

To a kernel scheduler all it would see are 14 opaque processes. It has no knowledge that they are grouped as two different things. It won't be able to come up with something that's fair.

We need some metadata.

(caveat: Obviously most proceses are idling, and I've ignored threads for the purposes of making a point, don't write about it)

It's hard to map things

Currently the only metadata of the "application" is on a window. To show a user friendly name and icon in ksysguard (or any other system monitor) we have to fetch a list of all processes, fetch a list of all windows and perform a mashup. Coming up with arbitrary heuristics for handling parent PIDs which is unstable and messy.

To give some different real world examples:

  • In plasma's task manager we show an audio indicator next to the relevant window, we do this by matching PIDs of what's playing audio to the PID of a window. Easy for the simple case... however as soon as we go multi-process we have to track the parent PID, and each "fix" just alternates between one bug and another.
  • With PID namespaces apps can't correctly report client PIDs anymore.
  • We lose information on what "app" we've spawned. We have bug reports where people have two different taskmanager entries for "Firefox" and "Firefox (nightly)" however once the process is spawned that information is lost - the application reports itself as one consistent name and our taskbar gets confused.

We need some metadata.

Solution!

This is a solved problem!

A modern sysadmin doesn't deal in processes, but cgroups. The cgroup manager (which will be typically systemd) spawns each service as one cgroup. It uses cgroups to know what's running, the kernel can see what things belong together.

On the desktop flatpaks will spawn themselves in cgroups so that they can use the relevant namespace features.

You're probably already using cgroups. As part of a cross-desktop effort we want to bring cgroups to the entire desktop.

Example

Before and after of our system monitor

Ultimately the same data but way easier to read..

Slices

Another key part of cgroup usage is the concept of slices. Cgroups are based on a heirachical structure, with slices as logical places to split resource usage. We don't adjust resources globally, we adjust resources within our slice, which then provides information to the scheduler.

Conceptually you can imagine that we just adjust resources within our level of a tree. Then the kernel magically takes care of the rest.

More information can be found on slices in this excellent series World domination with cgroups.

Default slices

This means we can set up some predefined slices. Within the relevant user slice this will consist shared of

  • applications
  • the system (kwin/mutter, plasmashell)
  • background services (baloo, tracker)

Each of these slices can be given some default prioritisations and OOM settings out of the box.

Dynamic resource shifting

Now that we are using slices, and only adjusting our relative weight within the slice, we can shift resource priority to the application owning the focused window.

This only has any effect if your system is running at full steam from mulitple sources at once, but it can provide a slicker response at no drawback.

Why slice, doesn't nice suffice?

Nice is a single value, global across the entire system. Because of this user processes can only be lowered, but never raised to avoid messing with the system. With slices we're only adjusting relative weight compared to services within our slice. So it's safe to give the user full control within their slice. Any adjustments to an application, won't impact system services or other users.

It also doesn't conflict with nice values set by the application explicitly. If we set kdevelop to have greater CPU weight, clang won't suddenly take over the whole computer when compiling.

Fixing things is just the tip of the iceberg

CGroup extra features

CGroup's come with a lot of new features that aren't available on a per-process level.

We can:

  • Set limits so that a CPU can't use more than N%
  • We can gracefully close processes on logout
  • We can disable networking
  • We can set memory limits
  • We can prevent forkbombs
  • We can provide hints to the OOM killer not just with a weight but with expected ranges that should be considered normal
  • We can freeze groups of processes (which will be useful for Plasma mobile)
    ...

All of this is easy to add for a user / system administrator. Using drop in's one can just add a .service file [example file link] to ~/.config/systemd/user.control/app-firefox@.service and manipulate any of these.

[caveat, some of those features works for applications created as new transient services, not the lite version using scopes that's currently merged in KDE/Gnome - maybe worth mentioning]

Steps taken so far

Plasma 5.19 and recent Gnome now spawn applications into respective cgroups, but we're not yet surfacing the results that we can get from this.

For the KDE devs providing the metadata is easy.

If spawning a new application from an existing application be sure to use either ApplicationLauncherJob or CommandLauncherJob and set the respective service. Everything else is then handled automagically. You should be using these classes anyway for spawning new services.

For users, you can spawn an application with either kstart5 --application foo.desktop"

That change to the launching is relatively tiny, but getting to this point in Plasma wasn't easy - there were a lot of edge cases that messed up the grouping correctly.

  • kinit, our zygote process really meddled with keeping things grouped correctly
  • drkonqi, our crash handler and application restarter
  • dbus activation has no knowledge of the associated .desktop file if an application is DBus activated (such as spectacle our screenshot tool)
  • and many many more papercuts throughout of different launches

Also to fully capitalise on slices we need to move all our background processes into managed services and slices. This is worthy of another (equally lengthy) blog post.

How you can help?

It's been a battle to find these edge cases.
Whilst running your system, please run systemd-cgls and point out any applications (not background services yet) that are not in their appropriate cgroup.

What if I don't have an appropriate cgroup controller?

(e.g BSD users)

As we're just adding metadata, everything used now will continue to work exactly as it does now. All existing tools work exactly the same. Within our task manager we still will keep a process view (it's still useful regardless) and we won't put in any code that relies on the cgroup metadata present. We'll keep the existing heuristics for matching windows with external events, cgroup metadata would just be a strongly influence factor in that. Things won't get worse, but we won't be able to capitalise on the new features discussed here,

Plasma 6 porting work we need help doing now!

"6.0" is a word that brings a lot of excitement but also a lot of aprehension and for good reason. The reason our .0 releases sometimes struggle to match the quality isn't due to changes in the underlying libraries changing but how much we have to port away from the things that we've deprecated internally and have put off porting to.

Too many changes in one release becomes overwhelming and bugs creep in without time to get address them.

We want to be proactive in avoiding that.

At a recent Plasma sprint, we went through some of our bigger targets that we want to finish completely porting away from in time for the 6.0 release that we can actively start doing within the 5.x series where we can do things more gradually and inrecementally.

I've listed two big topics below.

DataEngines

History

DataEngines were a piece of tech from the KDE4 era. Effectively the idea was to provide an abstract mechanism to expose arbitrary data or plugins to a scriptable format usable by various language bindings. A valid task at the time, but Qt5 provided a much more efficent mechanism to do this capitalising on the metaobject system and models

DataEngines mostly form a now unnecessary layer of indirection that makes QML code hard to parse and suboptimal to run. They also are Plasma specific, which doesn't help other QML consumers of the same data.

We kept with them for Plasma 5 as there's some valid, perfectly working code exposed through them, and have been slowly porting away.

Task

The task isn't to port all existing DataEngines. Some already have replacements under different names, some aren't widely used.

We want to find all existing applets that use DataEngines and make sure there are modern new QML bindings we can port the repsective applets to.

A list of tasks can be found:
https://phabricator.kde.org/T13315

System settings modules

History

Systemsettings is powered by a multitude of KDE Configuration Modules (KCMs) each one is a standalone plugin. There are nearly 100 modules, and with dated code stretching back over 20 years.

KDE, plasma especially is on the turning point between two toolkits. Some things are written in QWidgets and other things use the newer QtQuick. We try and hide this from the user; everything should of course look seamless. Implementation details shouldn't affect the UI.

We've been slowly porting our system settings modules, and whilst some were rocky at first, the later results are looking really nice and really polished, able to make use of emerging new patterns in our Kirigami toolkit.

Mixing two toolkits in the same process leads to a lot of complications that leak into the UI as well as overhead. We want to make it an objective to see if we can port everything to lead to an overall simpler stack.

Task

The overall task is to find KCMs that haven't been ported yet and make the appropriate changes.

However, this isn't just a goal of blindly porting.

We want to take a step back, really polishing the UX, tidying the code to have a good logic vs UI split and revsit some modules that haven't been touched in a long time, putting effort into our underlying frameworks to make sure we have everything ready on the QtQuick side to do so.

A list of KCMs and their porting status can be found:
https://phabricator.kde.org/tag/plasma_kcm_redesign/

Getting involved

The best way to get involved is to comment on the relevant phabricator ticket. Or swing by #plasma on IRC and let people know what you want to work on and we'll help you get started.
Some of the systemsettings modules have mockups from the VDG and we want to keep them in the loop.

Running kwin wayland on Nvidia

Note: If you are visiting from the future please refer to the wiki here which will be more up-to-date than this blog post.


I recently switched to running wayland fulltime on all my machines, including my Nvidia box. It was good that I did as it seems Qt regressed, fortunately I was able to fix it just in time for the final Qt LTS.

I've also updated the wiki with the steps needed to run nvidia wayland whilst I had the information fresh.

Steps

Pre-requisites

You need a very up-to-date Qt. Make sure you have >= Qt5.15.0 or 4bd13402f0293e85b8dfdf92254e250ac28094c7 cherry-picked.

Mode setting

Check our driver is running in modesettings mode

cat /sys/module/nvidia_drm/parameters/modeset

It should print "Y"

If not, modify your kernel command line and add the line nvidia-drm.modeset=1. Search for "kernel parameters" in your distribution's documentation. Though https://wiki.archlinux.org/index.php/Kernel_parameters is typically a good guide for any distro.

Tell kwin to run with EGLStreams.

You should set the environment variable "KWIN_DRM_USE_EGL_STREAMS=1"

The easiest place is to add a file /etc/profile.d/kwin.sh with the line
export KWIN_DRM_USE_EGL_STREAMS=1

Verify this is working with the command line tool env after rebooting.

Login

Select "Plasma (wayland)" from your login manager
Enjoy your beautiful super-fast accelerated wayland desktop!

That's a lot of steps!

Obviously this number of manual steps is unnacceptable and I hope to reduce this over the next Plasma cycle.

With the user telemetry we get from Plasma users, we know a sizable amount of X11 users run the proprietory nvidia wayland driver. Ultimately user experience comes first above all else, so it is important.

Clearing up some facts on Nvidia and wayland

I read a lot of misinformation that on the wayland nvidia situation on the social medias. I'll try and clarfify some bits.

  • You cannot say "Nvidia doesn't support wayland". This doesn't make any sense. There's no relevant part of wayland for it to support or not support.

  • You can say "Nvidia doesn't support GBM" . A system for passing buffers (window contents) between places. Despite the name "Generic" Buffer Manager, GBM is very closely tied to Mesa. Mesa is the base of effectively all the open source Linux drivers.


  • You cannot say "Nvidia doesn't follow /the/ standard". There are a few. EGLStreams actually is a fully defined open standard defined in Khronos, which is as much of a core extension as possible. It's used by multiple vendors, albeit mostly horrible Mali chips

  • You can say it would be better if there was just one magic implementation that compositors and toolkits had to support. Maybe Vulkan (or more specifically WSI) will fix it 🙂


  • You cannot say that the experience of using wayland apps is worse on wayland. Practically it's just as fast, accelerated with all the shiny effects.

  • You can say that the experience of using GL X11 apps on wayland is worse. As XWayland doesn't have EGLStream support data gets copied the slow way. If you're playing an X game or doing some Blender work this is noticable.


  • You cannot say that KDE devs won't fix it. As this post starts with me literally fixing a toolkit when it came up!

  • You can say that Nvidia wayland experience has fewer testers. Though like all things wayland this is something you can help with! Get involved, file bugs, come join us on #kwin on Freenode. Start your kwin wayland hacking journey!

Improving Plasma’s Rendering (Part 1/2)

Background:

Many parts of Plasma are powered by QtQuick, an easy to use API to render shapes/text/buttons etc.
QtQuick contains a rendering engine powered by OpenGL making full use of the graphics card keeping our drawing super fast, super lightweight and in general amazing...when things work.

Handling Nvidia context loss events

When the proprietary nvidia driver comes out of suspend, or from a different terminal the pictures that it had stored get corrupted. This leads to returning to an image like this. Worst as we show stray video memory it even leak data on the lock screen.

When this occurs it might look something like this:
Like something from the Tate Modern...a horrible mess.

With various text or icons getting distorted seemingly at random.

Fortunately NVidia do have an API to emit a signal when this happens, allowing us to at least do something about it.

This handling to be done inside every single OpenGL powered application, which with the increasing popularity of QtQuick is a lot of places.

The new state

After over a year of gradual changes all of Plasma now handles this event and recovers gracefully. Some of these changes are in Qt5.13, but some more have only just landed in Qt 5.14 literally this evening.

Some notes for other devs

A QtQuick application

Due to some complications, handling this feature has to be opt-in. Triggering the notification leads to some behavioural changes. These behavioural changes if you're not prepared for will freeze or crash your application.

To opt-in one must explicitly set the surfaceFormat used for the backing store to have:
QSurfaceFormat::setOption(QSurfaceFormat::ResetNotification)

Within KDE code this can be done automagically with the helper function
KQuickAddons::QtQuickSettings::init() early in your main method.
This sets up the default surface format as well as several other QtQuick configurable settings.

Everything else is now all handled within Qt, if we detect an event the scene graph is invalidated cleaned and recreated.

However, if you create custom QQuickItem's using the QSG classes, you must be really really sure to handle resources correctly.

As a general rule all GL calls should be tied to the lifespan of QSGNodes and not of the QQuickItem itself. Otherwise items should connect to the window's sceneGraphInvalidated signals.

Using QtOpenGL outside QtQuick

To detect a context loss, check for myQOpenGLContext->isValid() if a makeCurrent fails.

In the event of a context loss one must discard all known textures, shaders, programs, vertex buffers, everything known to GL and recreate the context.

One especially quirky aspect of this flag is that in the event of a context loss glGetError will not clear itself, but continue to report a context loss error. Code trying to reset all gl errors will get stuck in a loop. This was the biggest battle in the seemingly never-ending series of patches upstream and why it has to be opt-in.

In the case of a shared context a reset notification is sent to all contexts who should recreate independently.

You can read more about the underlying GL spec.

Changes to KSMServer

Reason for the blog

I'm changing KDE startup/shutdown a lot, whilst I aim to keep everything working exactly as before, please test this part thoroughly and report if you see any issues in the 5.15 cycle.

What is ksmserver?

In theory ksmserver is an X session manager.
An X session manager is responsible for saving/restoring your session when you log out and in
(and subsessions if you use activities) as well as prompting all your applications if it's safe to log out.

Currently this is one of the most important processes of the plasma session. Killing this process will immediately end the session.

As it runs all session it's a bit of a dumping ground for:
- handling all autostart (including plasmashell etc)
- running shutdown scripts
- screensaver
- some global shortcuts about session management
- spawning the logout prompts
- invoking the actual shutdown

Why change it?

As ksmserver handles startup our wayland session depends on X (or rather Xwayland), this is slower as we have to spawn it on startup, as well as being problematic for alternative devices where Xwayland may not be a useful option.

Also if we come up with a new session manager protocol that works well with wayland, we will need to replace just the session manager part.

Equally we have attempts to replace startup with for example, systemd units (and yes, there'd be a fallback) where we still want a working session manager.

In addition, some of the code isn't in the best state. It dates back to the 90s, without really having an active maintainer. There's been some significant changes to the way linux desktops work since that time. There's a lot to be cleaned up.

The plan

The golden rule is to refactor not rewrite. There have been numerous attempts at redoing startup, all good tech demos, but none are usable for production as they don't pay attention to matching with the current state and intricate startup hooks, something we need when we're talking about enterprise deployment who will have customisations.

The end goal is for KSMServer to be just an xsessionmanager. Allowing wayland-compatiable competitors to come alongside or potentially replace it down the line.

Startup and Shutdown will become multiple independent binaries (unix philosophy style) allowing them to be individually replaced all tied together with DBus activation. They will also be refactored to be considerably more readable.

Current state

There's been an internal refactor, which has been merged in master, the next step is to split into different processes once we've had feedback on the current work.

My month in KWin/Wayland

June has been a busy month in KWin, with me working on fixing remaining Wayland functionality and upcoming legend Vlad Zagorodniy working on polishing and cleaning up all the effects.

In this blog I'll talk about the more interesting bits of kwin work that I did during June.

Fractional Scaling

A requested feature is to allow fractional scaling for QHD monitors which are roughly 1.5 times the resolution of standard monitors, but not the full 4k.

The wayland scale system is based around integers, but because the scaling is based around a normalised co-ordinate system, the compositor can show a display at a scale of 1.5 whilst clients are rendering for a 2x display with no changes in the client.

Patchset consists of XdgOutput support in both kwin and Qt so that windows that position themselves (such as xwayland clients, or plasmashell) can know the correct logical size of the screen and then relevant changes in kwin/kscreen to implement the extra fractional part.

Unfortunately as this requires a change in Qt to function properly. this won't be available in our UI until Plasma depends on the Qt version that contains this support, probably around March 2019. Stupid desktop Linux.

Cursor Scaling

On the topic of scaling, I merged support for making sure that the cursor is the physical size the user selected regardless of the resolution of the monitor it happens to be on or the scale of the client that supplied it. Particularly useful for a multi-monitor setup where blindly using a pixel size doesn't cut it.

XdgWmBase

The protocol for clients to register toplevels and popups to the window manager has gone through multiple stages, wl_shell, XDGShellV5, XdgShellV6 now settling on the finally stable protocol, Xdg WM Base. Having this finally stable is a hugely signifiant point in the road to wayland.

Previously we were lagging behind other desktops in shell protocol support, but KWin 5.14 will have support for XDG WM Base ahead of the toolkit support coming in Qt 5.12 / next GTK.

GTK decorations

GTK gained server side decoration support in 3.22, however, the implementation needed some work. It correctly removed it's own decorations under KWin but failed to inform KWin, which didn't want to add a "second" titlebar, leaving it in an even worse state than before.

I submitted a patch for GTK rectifiying all the issues and that was all merged pretty swiftly.

It's a window looking normal, I don't know why I added a screenshot. Just imagine it looking worse before then feel excited about this.

Misc

KWin also gained support to show different mouse cursors for resizing the left edge of a window or the right edge of a window. Useful for telling which window will be resized in the case of touching windows.

Plasma Startup

Startup is one of the rougher aspects of the Plasma experience and therefore something we've put some time into fixing

Why is startup slow?

The primary reason for Plasma startup being slow is simply that it does a lot of things, including:

  • Session restore
  • Config migration
  • Setting keyboard layouts
  • Most esoterically, making sure your colour scheme gets synced to the xrdb database, so that loading xfig or dia or any other pre-Qt/GTK1 application still has the correct colours in your Plasma session

Too many to list. This means it's easily a whole second or more before we even start loading plasmashell, one of the more time consuming parts of startup.
This slow load gets exaggerated by us not removing the splash screen till everything is actually properly loaded.

However, it's still an area we can improve.

About startup

Startup consists of mulitple components invoked at 3 different levels.

  • Kcminit
    Config modules (kcms) typically update a system when the user applies the settings, however as we need to restore settings there is an optional hook called on startup for various modules.
  • KDE Daemons (kded)
    Evolving from the more static nature above may services require running in the background waiting for external events. Some modules are loaded on demand, others are loaded explicitly during startup.
  • Autostarted applications
    Meaning launcing core applications such as plasmashell/krunner as well as other applications a user might have selected; such as nextcloud or kgpg
  • User shell scripts
    For anything else

These effectively all have their loading invoked at 3 different levels; as defined in the relevant kcminit/kded/autostart .desktop files. Note these may be shipped as core plasma, but can also include completely 3rd party items.

  • Before plasmashell and other core autostart services
  • Before user applications are restored / autoloaded
  • After everything is restored and

A slightly more detailed version can be seen here.

Profiling

The most important part of any speed work is correctly analysing it.
systemd-bootchart is nearly perfect for this job, but it's filled with a lot of system noise.

I've made a fork of systemd-bootchart that only tracks processes owned by that user on github.
To use put the following line into:
/etc/X11/Xsession.d/00-bootchart

/usr/lib/systemd/systemd-bootchart -o /tmp -r &

To profile wayland sessions, mod the SDDM config wayland SessionCommand option.

After 20 seconds an SVG will be placed in /tmp.

An example

Below shows the boot process of my personal machine. The important part to track is when ksplashqml gets destroyed, that signifies that boot is complete. In my case this happens after 4.5 seconds.



Just some of the many fixes

There have been and continue to be lots of tiny changes around the code. Mostly using the awesome tool hotspot here are just a few of the more significant and interesting ones.

A mysterious gap of nothingness

This stupid bug was caused by ksmserver blocking whilst it completed launching phase 1 of kded daemons before it continued onto loading the next section.
Problem is plasmashell and other GUI apps loaded in phase0 first task is to register with the X session manager, ksmserver. End result is we lockup in X code till
ksmserver is done. Solved by a logic rewrite.

Multiple starts of the same daemon

This is the result of the following code in a bunch of processes all started at once.

if (! serviceExistsOnDBus) {
startExecutable(...)
}

Whilst the daemon did handle this case correctly and the false starts aborted, it's still a lot of time spend linking a process we don't want.
Solution in this case was to port to DBus activation which is designed for this exact case.

Shortcuts writing on load

When profiling kglobalaccel5 we found it spent a lot of time writing entries on boot, which is a clear sign of something being wrong. The cause was quite complex. Powerdevil would report that the user visible name of the executable (kded) was "Powerdevil". KScreen would load and report that the username of the executable (also kded) was "kded" this would cause the shortcut daemon to think locales had changed and forcibly reload and save everything.

Summary

Startup is an area that is being improved and we have tonnes of ideas left of things to do, but because it's dealing with unpredictable 3rd parties it's an area which requires 90% reading and 10% coding.

If you do have an excessively long boot time, please do try creating a boot chart as above, it will really help start to narrow down where we have problem. I hope to see some detailed reports on bugzilla soon.

Cross-process Runners

KRunner, the framework, is the backend behind the 'krunner' UI, as well as being used for search operations within the Plasma shell. Backends (or 'runners') are written as plugins, which can come from a range of sources and loaded by both the plasmashell and krunner process.

This works fine for simple tasks like calculators, dictionaries and listing applications. However, if we want to search through data that's available in an already running application, this approach isn't ideal.

What's changing

In addition to the current plugin structure, runners can have their results fetched from another process via DBus.

To work, apps supply a .desktop file with the DBus service name of a search provider. The apps then implements a couple of DBus methods to return a list of matches for a given search query, and another method called when a match is invoked. Depending on the situation, you might want to make this DBus-activatable, or just silently do nothing if the service is not running.

Example of a query being performed:


Results are presented identically.

Benefits:

Reduce code re-implementations

The original motivation for writing this was plasma-browser-integration writing a runner. Kai ended up writing both a DBus API on the client, and a runner to read from it. A common standard cuts that in half for any future apps wanting runners.

Memory saving

Instead of data being in 3 places: the app with the data, plasma shell and krunner, data is only stored in one place and then fetched by the two UIs.

Robustness

Plasma shell is a very core process. We want that to stay alive even if the included plugins fail. One of our more problematic runners was moved out of process to solve this in Plasma/5.11

Portability

By not being linked inside the same binary, we solve a lot of portability issues.

* I can make runners in python (example) or potentially any other language with no extra dependencies

* We'll be able to handle the ineviatible Qt6 changeover in a few years without runners having to all be ported at the same time.

This was a big problem for KTp, which had the main USP of having tight Plasma integration. We caused a big problem for ourselves resulting in a rushed port.

* It's a step towards next gen where more apps and services are sandboxed.

Conclusion

Hopefully this will improve Plasma and make it easier to write runners.

I hope to see runner support to kde-connect and search active konversation tabs. Personally, I'm already using the python support for custom code to talk to my home-automation server which had a python lib.

If this has inspired you to write a runner and documentation is unclear, ping me (d_ed) on #plasma.