Settings module (KCM) development
Settings in Plasma are provided by KDE Configuration Modules (KCM). These can be loaded by multiple wrapper applications
systemsettings5 on the desktop,
plasma-settings on mobile or
kcmshell5 for standalone config windows.
The source code for the different modules is split across different locations, such as plasma-workspace or plasma-desktop.
You can query the available KCMs using
kcmshell5 --list. To load an individual module in a standalone window pass its
name to the wrapper application, e.g.
plasma-settings -m kcm_kaccounts, or
KCMs consist of a KPackage holding the QML UI and a C++ library holding the logic. Some legacy KCMs are based on QtWidgets,
however this is not recommended for new KCMs and it's not possible to load these in
plasma-settings. In Plasma, new KCMs should be built using QML and
As an example, we are going to create a time settings module that allows us to configure the time in our system. The basic structure of this hypothetical time settings module is the following:
├── CMakeLists.txt ├── timesettings.cpp ├── timesettings.h ├── kcm_time.json └── package └── contents/ui └── main.qml
This CMake file contains a few packages of note:
provides various classes that allow us to work with
Config includes the
classes. You are likely to have seen most of the other packages elsewhere in this documentation; if not, you can read this page which goes through a similar CMakeLists file line by line.
What's different here is that we are using C++ code as a plugin for our QML code. This is why we don't have a
main.cpp: we only need the class that will provide the backend functionality for our KCM.
kcoreaddons_add_plugin creates such a plugin and installs it to the right location.
Here we are defining the class we will be using for our KCM. KQuickAddons::ConfigModule serves as the base class for all QML-based KCMs. The KQuickAddons::ManagedConfigModule inherits KQuickAddons::ConfigModule and adds the KConfigXT integration. You can read the linked API documentation to get a full description, and the KConfigXT page goes into more detail about how KConfigXT works.
Here is where we would put any backend code that changes things behind the scenes. We can expose functions in here to our QML so that elements of our UI can be used to trigger backend functionality. This C++ code is then installed in our system on compilation in a KCM plugin directory, where upon execution the KCM can access and use it.
In this C++ file we define the constructor for the class in the previous file. We include some basic metadata about this KCM and we provide the buttons that we will want included in our window.
.json file provides metadata about our KCM. These entries specify the following:
Namedefines the name of the KCM which is shown in the settings app.
Descriptionis a short, one sentence description of the module.
FormFactorsdefines on which kinds of devices this KCM should be shown.
X-KDE-System-Settings-Parent-Categorydefines the category systemsettings5 is showing the module in.
X-KDE-Keywordsdefines Keywords used for searching modules.
As you can see, this is a very basic KCM QML file. We have used a SimpleKCM component as the root component, and we have just included a label inside here.
More complex layouts will require using a different root component. Each has its own use:
- Use ScrollViewKCM for content that is vertically scrollable, such as ListView.
- Use GridViewKCM for arranging selectable items in a grid.
- Use SimpleKCM otherwise.
KCMs can consist of multiple pages that are dynamically opened and closed. To push another page to the page-stack, we can use:
AnotherPage.qml should have one of the aforementioned KCM component types as the root element.
To pop a page (remove the last page on the page-stack) you can just use:
All we need to do now is compile and run our KCM.
In this case, we are installing our KCM to
~/kde/usr, a non-standard location, so that we don't risk messing up anything on our local environment.
// Configure our project in an out-of-tree build/ folder cmake -B build/ -DCMAKE_INSTALL_PREFIX=~/kde/usr // Compile the project inside the build/ folder cmake --build build/ // Install the files compiled in build/ into the ~/kde/usr prefix cmake --install build/
Now that our KCM is installed, we can run it (that is, so long as we have executed
source prefix.sh, which includes our non-standard
~/kde/usr/ location in our current environment).
source build/prefix.sh kcmshell5 kcm_time