Settings module development

Introduction

This tutorial teaches you how you can and create your own modules.

Plasma Settings is an app, much like Plasma Desktop’s System Settings that shows and loads configuration modules. These configuration modules are plugins providing a QML package and an optional C++-plugin which exports custom-written configuration objects as QObject to the declarative environment.

You can query available modules using the –list argument to plasma-settings:

$ plasma-settings --list
kcm_mobile_time ........... Timezone, Date Display
kcm_mobile_power .......... Lock, Sleep, Timeout
kcm_mobile_theme .......... Font and Theme
kcm_mobile_kaccounts ...... Add Your Online Accounts

You can load an individual module by supplying its plugin name as argument to active-settings:

plasma-settings -m kcm_mobile_time

will open the plasma-settings app and load the “Time and Date” module on startup.

Architecture

The Plasma Settings app consists of a number of parts, a Kirigami app that provides the chrome for plasma-settings, a set of Declarative components which encapsulate loading settings modules and a set of settings modules, which provide the UI and backend code for a specific settings domain (i.e. Time and Date, Theme settings, etc.).

Create a settings module

Module architecture

A settings module nowadays consists of a library and a QML ui.

The basic structure of a settings module is the following:

├── CMakeLists.txt
├── timesettings.{cpp,h}
├── timesettings.desktop
└── package
    ├── metadata.desktop
    └── contents/ui
        └── Time.qml

Step-by-step guide

This documentation uses examples from different existing config modules, so make sure to always change the names to what fits your module.

In its desktop file, a module has to specify some basic values to be recognized as a config module. Those have to be added in addition to the usual contents of a desktop file.

Type=Service
X-KDE-ServiceTypes=KCModule

Since every module has to provide a library, it must also be specified in the desktop file.

X-KDE-Library=kcm_mobile_time

If your module is only useful for e.g embedded devices, make sure to hide it on all unrelated platforms.

X-KDE-FormFactors=handset,tablet,mediacenter

To build and install your kcm, you will need to write a CMakeLists.txt file. The special features of a settings module can be best explained on this example:

set(accountsettings_SRCS # Specify source files for the library
    accounts.cpp
)

add_library(kcm_mobile_kaccounts MODULE ${accountsettings_SRCS})

target_link_libraries(kcm_mobile_kaccounts
    Qt5::Core
    KF5::CoreAddons
    KF5::I18n
    KF5::QuickAddons
)

kcoreaddons_desktop_to_json(kcm_mobile_kaccounts "accountssettings.desktop") # Convert our desktop file to json

install(TARGETS kcm_mobile_kaccounts DESTINATION ${KDE_INSTALL_PLUGINDIR}/kcms) # Install the library to the kcm location

install(FILES accountssettings.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR}) # Install the desktop file
kpackage_install_package(package kcm_mobile_kaccounts kcms) # Finally install our QML kpackage.

Make sure the names of the .desktop files in CMakeLists.txt are correct, since incorrect names lead to problems finding and loading your package, or even to conflicts between different modules. In case of doubt check active-settings –list for already installed modules.

The json file generated by cmake will be used as metadata for the library we yet have to create. It consists of a class inheriting from ConfigModule::ConfigModule(QObject *parent, const QVariantList &args).

In the cpp file after the includes add

K_PLUGIN_CLASS_WITH_JSON(AccountsSettings, "accountssettings.json")

Now that we have created the library, let’s have a closer look at the QML kpackage. Every package needs to contain a metadata.desktop file, which holds the plugin information, which script to load from the plugin initially, and a bunch of metadata, just like normal Plasma Packages. A simple metadata.desktop file will look like this:

[Desktop Entry]
Name=Web and Browser
Comment=Settings for history, caching, etc.
Encoding=UTF-8
Type=Service
Icon=preferences-system-network
X-KDE-ServiceTypes=Active/SettingsModule
X-KDE-PluginInfo-Author=Sebastian Kügler
X-KDE-PluginInfo-Email=sebas@kde.org
X-KDE-PluginInfo-Name=kcm_mobile_web
X-KDE-PluginInfo-Version=1.0
X-KDE-PluginInfo-Website=http://plasma-mobile.org
X-KDE-PluginInfo-Category=Online Services
X-KDE-PluginInfo-License=GPL
X-Plasma-MainScript=ui/Web.qml

It needs to be placed in ./package/metadata.desktop.

The interesting bits, specific to active-settings are the plugin name, the package name and the mainscript. The plugin name is used to find the package. Web.qml points to a normal Item in a file, normal rules apply here.

It’s recommended to use ScrollViewKCM or SimpleKCM as the root item of your QML file, so your kcm visually fits into the settings app.

The ConfigModule class that your library inherits from provides a multilevel page api that you can use to push and pop pages into and from the settings app.

ConfigModule::push() pushes a QML file into the page row, while ConfigModule::pop() removes the last page of the row. Please not that there is no such function as replace as known from Kirigami.