kirigami-app-components

Software

We just had a release of a new library, and future framework: kirigami-app-componets, which is a new repository where a certain kind of Kirigami extensions will go.

This repository will contain modules that are intended to be building blocks for applications to integrate within the KDE Frameworks ecosystem.

Why start a new repository when kirigami-addons already exists?

We now had a standalone release of kirigami-app-components with a single module inside for testing purposes, but the target here is to move it to frameworks releases, with all the stability promises and quality constraints of Frameworks.

Kirigami-addons is a bit more experimental of nature and have modules which, while they are a good first approach at solving a particular problem, would definitely need some work and refactoring for us to be comfortable having them in Frameworks, while other kirigami-addons modules will be a more straightforward import into kirigami-app-components.

An example of a module that was very useful but needed some work in its architecture is the StatefulApplication module (import org.kde.kirigamiaddons.statefulapp). It provides a Kirigami ApplicationWindow subclass and a way to map QActions to Kirigami actions.

The central idea is having a series of actions that can have their keyboard shortcuts configured by the user (while also providing a component for such configuration UI).

A problematic aspect of StatefulApp is that it’s based too much on C++: in order to add actions, it is necessary for the app to create a subclass and add them as QActions, then the QML part has to connect the QActions and Kirigami.Action using the proper API.

This is OK for the parts of the app where the logic is completely on the C++ side, but when it is necessary to add a very simple action (closing a page, opening a search dialog, and so on), this brings far too much boilerplate.

org.kde.kirigami.actioncollection

ActionCollection is the module that we introduce with kirigami-app-components. It’s all about collections of actions that are defined declaratively via QML (with the option of creating collections on the C++ side as well) and that have shortcuts configurable by the user via the standard interface.

In order to define a new collection, we would write the following QML:

import org.kde.kirigami.actioncollection as AC
AC.ActionCollectionManager {
    id: manager
    pageRow: pageStack

    AC.ActionCollection {
        name: "org.kde.myapp.mainactions"
        text: i18n("Main Actions")
        AC.ActionData {
            name: "hello"
            text: i18n("Hello")
            icon.name: "document-send"
            defaultShortcut: "Ctrl+H"
        }
        AC.StandardActionData {
            standardAction: AC.StandardActionData.Copy
        }
        ...
    }
    AC.ActionCollection {
        name: "org.kde.myapp.photoactions
        text: i18n("Photo Actions")
        AC.ActionData {
            ...
        }
        ...
    }
}

The ActionCollectionManager will be a single instance for the whole application, and it is what takes care of instantiating the common actions (such as About Application, About KDE, Configure Shortcuts, and so on) and doing the plumbing with the configuration dialogs and so on.

ActionCollection is a set of actions semantically grouped together in the same category (if an application would have, for instance, actions that operate on photos and actions that operate on videos, those could be two different collections).

ActionData is the semantic representation of an action (internally it is a QAction, so it has all its properties) and will be defined only once for the whole application. Instances of Kirigami.Action will be attached to it (even more than one), and those will define the actual buttons and menu entries in the application.

A Kirigami.Action is attached to an ActionData via an attached property:

Kirigami.Action {
    // Here shows how important is that each ActionCollection has
    //  an app-global unique name and each action has a collecion-global
    // unique name as well
    AC.ActionCollection.name: "org.kde.myapp.mainactions"
    AC.ActionCollection.action: "hello"
    onTriggered: {
        // Logic here
    }
}

The Kirigami.Action instance will not have text, shortcut, or icon defined, because everything comes from the attached ActionData. Only the onTriggered logic will be defined there (as well as the logic for when the action is enabled or visible).

When an ActionCollectionManager is created, a collection named org.kde.globalactions will be automatically created as well, which also contains an action called "KeyBindings“. When triggered, this dialog will open:

This is the configuration UI where it is possible to configure all the application shortcuts.

Another action called “FindAction" is also available: when triggered, this other dialog will open instead:

This is the classical Ctrl+Alt+I dialog also present in QWidget applications, where it is possible to search and trigger all the application’s actions.

KeepSecret 1.1

Software

KeepSecret is our new password management application, based on SecretService, which works both with our old KWallet infrastructure as well as more modern services such as oo7, KeepassXC and many others.

Version 1.1 has now been released.

This release Has been focused mainly on small usability papercuts and improved messaging to the user.

An important aspect of this release is that is the first one that’s available on flathub, so it’s very easy to install and test now, just hop on Discover to find it.

Kirigami forms and configurations

GraphicsSoftware

Recently a new submodule has landed in Kirigami: “Forms”.

Until this point, Kirigami had only offered the classic “FormLayout” component. which is used for configuration pages throughoug systemsettings, Plasma, and some apps. It’s the classical form used in desktop toolkits for decades:

This is a fairly clean layout which however is starting to slowly become outdated, as modern toolkits are starting to use a different layout nowdays, based on “cards”

Unfortunately FormLayout very bound to the classic layout, and it wasn’t really possible to adapt it to the new look in a compatible way which didn’t break existing applications in unexpected ways.

This is also the reason a new approach was done provided by kirigami addons: “FormCard”, which is used by a lot of applications; for instance here in NeoChat:

We wanted to have this new style of forms in the base Kirigami API, so after a review of the existing FormCard, we decided to make several changes, for two main reasons: First, FormCard is bound to the card style of form as much as FormLayout was bound to the classic flat style. Also, it tried to provide ready-made components for every kind of control; so it had its own TextField, its own RadioButton and so on — effectively becoming its own separate toolkit.

So we opted instead to go down the route of having a more generic API, so the Forms module includes containers that define a semantic structure of a form, which contains all the normal controls — such as textfields, checkboxes and radiobuttons.

This is a code example of the new API:

  import QtQuick.Controls as QQC
  import org.kde.kirigami as Kirigami

  Kirigami.Form {
    Kirigami.FormGroup {
        title: "Global Settings"
        Kirigami.FormEntry {
            contentItem: QQC.CheckBox {
                text: "Show Sidebar"
            }
        }
        Kirigami.FormEntry {
            contentItem: QQC.CheckBox {
                text: "Auto Save"
            }
        }
    }
    Kirigami.FormGroup {
        title: "Theme Options"
        Kirigami.FormEntry {
            title: "Colors:"
            contentItem: QQC.CheckBox {
                text: "Dark Theme"
            }
        }
        Kirigami.FormSeparator {}
        Kirigami.FormEntry {
            contentItem: QQC.CheckBox {
                text: "High Contrast"
            }
        }
        ...
    }
  }

which will look like this:

Or, in mobile mode:

Semantically, a Form will contain one or more FormGroup objects, each of which will contain one or more FormEntry objects. Then a FormEntry will contain the control which represents the configuration of the particular thing. It can be a single control (like a button or a checkbox) or it can be any layout with completely custom contents.

I already ported 4 modules of systemsettings to the new system: the landing page, the “workspace options” kcm, the mouse settings and the touchpad settings.

But wait… this page looks exactly the same as before; why?

A key was to do an API that was as much as separated from any appearance as possible, as we don’t know how UI design trends will evolve in the future. But this also allows us another thing: to have two separate implementations: the new one “card based” and a legacy one which looks exactly like the current FormLayout components. This is used only in systemsettings, so we can port all the kcms without introducing glaring visual inconsistencies, and when we are done, flick the switch and convert the look of everything all in one go.

Since most of KDE’s QML applications already use the existing card-style kirigamiaddons FormCard components, the new look will be used there.

And then in the future, when trends change again, we can re-style all the settings pages in one go.

A call to action

We ideally want the whole set of systemsettings kcms to be ported as soon as possible to the new system, so we can have soon a nice visual overhaul in the whole systemsettings.

In order for this to happen, we need the help of everyone, so… patches welcome 🙂

As an example, this is the merge request that ported the first four kcms.

When porting, it’s also possible to see how the kcm will look with the new system as well, to make sure it works well for when we flick the switch. If we run in a terminal:

KDE_KIRIGAMI_FORMS_STYLE=cards systemsettings

We get systemsettings using the new style for pages already ported:

Porting from FormLayout to the new Form/FormGroup/FormEntry system should be really straightforward; it should be possible to make good progress in little time.

With your help, soon KDE’s settings will benefit from greater consistency, a more modern style, and easier adaptation to future designs.

KWallet, SecretService, oo7: the story so far

Software

Continuing previous efforts to update the “secure passwords” story of the Plasma desktop, I’ve done some integration work between Plasma and oo7.

Oo7 is a relatively recent SecretService provider written in Rust; it’s very nice, lightweight and cross-desktop. Very interesting for us supporting it as a first class citizen.

We want in the end to replace completely the old KWallet system with something based on SecretService, have all our applications migrated transparently with user data as well, if possible with a cross-desktop backend implementation.

We also want it to be as transparent as possible for the end user, not having any complicated first time setup, or dialogs that ask for a manual unlock when not needed. For the user, the whole system should be just invisible, except when looking up their passwords or when client applications add passwords to it themselves.

As a first thing several months ago we did a transparent translation layer for the KWallet DBus interface, so now the “KWallet” service became just a translation layer between the kwallet api and the secretservice one.

The old kwalletd service instead became “ksecretd” now providing only the SecretService interface, and that’s what we use by default now. however, it can be configured to use a different provider, so it can already be used with gnome-keyring or KeepassXC if the user wishes. In that case the user data will be migrated the first time.

Also I’ve written a new application called KeepSecret. It is centered around SecretService, with a much more modern UI compared to KWalletManager and works also much better on mobile, so we can have also a modern password manager on Plasma Mobile.

KeepSecret running with the oo7 backend, with a native password dialog

The last thing that we did so far is integration with a new SecretService provider on the block: oo7.

If oo7 is Just another SecretSerive provider, Won’t it “just work” in Plasma? Not quite, but that’s actually a good thing. Oo7 wants to properly integrate with the environment it runs in, so we need to build that integration.

When you use KWallet, KeepassXC, or gnome-keyring directly, they create their own password dialogs using their own toolkits and styles, therefore potentially looking a bit alien when run in a different environment than the one it it was designed for.

This is not ideal for evaluating options for a possible future replacement of KWallet (which piece by piece we are working towards), as we want the UI part completely integrated with the Plasma desktop.

Instead, oo7 is built on the assumption that the environment it runs on will provide its own dialogs, a bit like the portal system for services like screen sharing and file picking.
This requires active integration both on the Plasma part and the oo7 part, but on the other hand it will look native on Plasma, Gnome, and any other platform that implements the integration hooks. And that’s with the added benefit of sharing the password storage if someone every now and then goes desktop environment hopping.

On the Plasma side we decided to employ a very small daemon which is launched only on demand with dbus activation. It will create the needed system dialogs, pass the user input back to oo7 and then quit when not needed anymore, so it won’t constantly use up system resources.

This is already available in Plasma 6.6: the code for it is here. It’s designed first for oo7, but it can be used by any daemon which wishes to provide native password dialogs, so we might start to use it also from other components in the future, either other SecretService providers or completely different things which have similar needs like Polkit.

On the oo7 part, Harald implemented the integration with its dbus interface, so with oo7 from main branch (or its next release) it can be used in place of KWallet (with all old applications still using the KWallet API using its backend as well), with all data migrated to it, and it will show native UI for its password dialogs… all the pieces of the puzzle slowly falling together 🙂

Needless to say this is still at an experimental stage, but it’s an important milestone in getting more independent from the aging KWallet infrastructure.

Pixel perfection

GraphicsSoftware

Sometimes an application can look kinda wrong due to very small details, few pixels can make or ruin the first impact. And since today a lot of monitors, especially laptop ones have to use fractional scaling, making things look sharp and pixel perfect is even harder.

Here is System Settings, on a screen scaled at 175%:

Here is zoomed, you can see some separators being one pixel, some other being two, usually blurred, making them appear of significantly different colors:

It was something that always annoyed me, so this is how System Settings will look with the next Kirigami that will come with the next Frameworks release in the beginning of November:

Here zoomed:

Separators are now 2 perfectly sharp pixels everywhere on 175%, giving the app a much cleaner look.

This will apply to every application which uses the Separator QML component. There are of course a lot of similar details fixes to do (and yes, I can see several ones still in the above screenshot), but sometimes small polishes can look like a big improvement 🙂

KWallet to SecretService, a client application: name wanted

Software

As i wrote in the previous post, now the KWallet service has been splitted in a compatibility layer that exposes the old KWallet api, but actually consumes the Secret Service API, provided by default by the old KWallet daemon converted in a secretservice-only provider.

Another pain point is the application used to look inside the wallets, KWalletmanager, which only speaks the KWallet api and looks a bit dated nowdays:

I am working on a new application which goal is strictly to be a client for Secret Service. It can access passwords of any Secret Service provider (being KWallet, Gnome-keyring, KeepassXC, oo7 or whatever else) and should hopefully look a bit more modern and simple, while still being powerful:

Both as a desktop application or a mobile one:

For items imported from KWallet supports editing the values of type “Map” as well:

As well as visualizing “binary” entries (here super censored for obvious reasons 😉

The application can be tested at https://invent.kde.org/mart/kwallets

But has a fundamental problem, for which i need help… Right now is just called “KWallets” which can be kinda confusing with old KWallet and KWalletManager, so it probably needs a new name, any opinion is welcome 😄.

Towards a transition from KWallet to Secret Service

Software

Historically passwords and credentials in all of our apps and services (such as kio and our Network Manager plasmoid), are stored and managed by our KWallet subsystem and API. In a similar way, GNOME had gnome-keyring, and other similar systems were available. A major problem was the mutually incompatible interface between them, making impossible to have a single place where all the passwords go.

For this reason, a standard DBus interface called Secret Service has been developed, and systems like KWallet, gnome-keyring and KeepassXC have adopted the interface as well.

In the future, we want to eventually port our applications to use the Secret Service API directly, preferably via the QtKeychain library (some applications already do), which will use Secret Service natively on Linux. And as a bonus the Windows/Android native systems on those platforms will work too.

This will make our applications work much better, be more integrated in other desktops or platforms, and be less dependent on the KWallet framework which has big legacy code parts at this point.

Right now, KWallet has the option to bring up a Secret Service compatible interface, and this is a valuable first step, but there are still some potential problems in the migration path:

  • Applications using Secret Service will store their secret data in different places when running in different environment, including our own that have been migrated. If you login into a different session ,every app will have forgotten its credentials.
  • It’s possible to use a different Secret Service provider also in a Plasma session, for instance enabling it in KeepassXC. At that point some apps will save into it, while other ones will keep using KWallet with a different storage backend.
  • Applications ported from KWallet to SecretService will lose their credentials, unless some clunky porting code is written for each application.

A KWallet compatibility layer

Enter the recent refactor that happened in KWallet: it has now been split into 2 different system services now: one that exposes only the Secret Service API, and one that exposes only the KWallet API.

The service exposing the KWallet API has been written from scratch and is now just a thin wrapper around the Secret Service API, translating the KWallet DBus calls to Secret Service ones. The old KWallet service is now a pure Secret Service provider that just happens to use the old KWallet backend, exposing to Secret Service all the entries that had already been stored in the past.

This decouples our KWallet compatibility layer for existing or old applications (not only KDE applications, also third party ones like Chromium use it) with our actual secret storage and SecretService implementation, allowing a separate development roadmap, and even potential future transition to a different backend in a completely transparent way to the user.

You can see this decoupling in the same spirit as the recent KWin Wayland/X11 split: being able to develop the new technology without risking breaking compatibility of the legacy system.

What it means for users and developers

For the immediate future, not much really changes: users will still have all their secrets accessible, and every app they use that was using KWallet will keep working without forgetting anything.

In the same way, for developers, the whole KWallet C++ API keeps working exactly as it was (even though we’re discouraging its use in new projects). Also, the KWallet-to-Secret-Service API proxy layer will save data inside Secret Service with the same schema used by QtKeychain, keeping the data accessible if the application gets ported from using the KWallet C++ API to QtKeychain.

An experimental feature

Disclaimer: The following description is of an experimental feature behind a hidden configuration key: it will take a bit before it’s deemed ready for prime time.

One advantage of having 2 independent services to handle the KWallet API and the Secret Service one is that now it’s possible to chose different backends as well, such as KeepassXC, gnome-keyring or oo7.

Setting the following in kwalletrc:

[Migration]
MigrateTo3rdParty=true
[KSecretD]
Enabled=false

With this, the old KWallet backend (now a service called ksecretd) won’t be started anymore, and instead any Secret Service provider that is running or has been configured to be DBus-activatable will be used. The first time this happens, a data migration procedure will be executed, writing the data in KWallet into the new service, keeping all the user-saved secrets accessible.

New Plasma Edit Mode in 6.1

GraphicsSoftware

In Plasma, when the user wants to do some significant layout change in the desktop, such as adding, moving or removing panels or add and manage desktop widgets, will go in the so called “edit mode”, by a context menu entry when driven by mouse, or by long-press in the desktop when driven by touchscreen.

Let me introduce you the improved edit mode workflow Plasma 6.1 will have:

An “edit mode” is necessary because since is an operation potentially destructive, we really want to avoid the user to for instance remove their own taskbar or some similar operation by mistake, during day to day use.

“Modes” in UI are a delicate thing: they have advantage as well many possible problems, which come in when it’s not immediately clear in which mode the user is in, and can try to use the UI as it was “in the other mode” (see https://www.nngroup.com/articles/modes/ as a quick introduction on advantages and disadvantages of modes).

This was a bit of a problem of the edit mode in plasma, as the edit mode was not clearly visually separated with the normal UI workflow of the day to day plasma usage.

Another problem present was that the action buttons of the edit mode toolbar were often hidden away by either the panel configuration window or the add widgets sidebar.

This new mode zooms out the desktop with the same visual effect of the window overview effect (yay for consistency), to well differentiate between normal and edit mode. Using the same zoom effect it puts the whole desktop “out of the way” when either the add widget sidebar of the panel configuration window appear, making sure the whole desktop area is always reachable, applets can be dropped anywhere in the desktop and the edit mode toolbar is always completely accessible.

Akademy 2023, Plasma 6 and Plasmoids

Software

During this week Akademy 2023 is going on in Thessaloniki, Greece. It’s always awesome, to see many old friends and getting together with that amazing hacker community which is KDE.

There, me and Niccolò gave a talk about what;s happening in Plasma 6 and what will change, Noccolò on more visual things, about some changes we are cooking on the UI and on the visual themes. Here you can find a recording of the talk (alongside all the others of the day)

I talked more about the work I’ve bein doing in the Plasma shell during the last couple of months: code rafactors and how the API for writing plasmoids will change.

There were many things we were not quite happy about and now with the major release is the occasion for streamlining many things.

Now, It’s very important those changes are are well communicated, and easy to do for developes, because there are *a lot* of 3rd party plasmoids on the KDE store, which people are using and enjoying.

Let’s go trough the most important changes:

Dataengines

Dataengines were an API designed in early KDE 4 times, especially one of for our first offereings of Plasmoid API which was the pure JavaScript API, which existed long before the QML existed.

But now in a QML world, their API doesn’t really fit, instead is a much better fit having a QML extension which offers classes with all the needed properties, data models and signals that provide access to the needed data, such as tasks, notifications etc.

Dataengines are now deprecated and moved into a separed library, called “plasma5support” which will be still available for the time being, but consider porting away from it as we plan to eventually drop it.

Base Plasmoid API

The way plasmoids are declared in QML changed a bit: we used to have a magical “plasmoid” context property available from anywhere. This was an instance of a QQuickItem which was both the item where all the plasmoid contents were *and* a wrapper for some of the api for the central plasmoid object: the C++ class Plasma::Applet.

Now the access to plasmoid is an attahced property, the (uppercase) “Plasmoid”, which is directly the access to the instance of the central Plasma::Applet, without an in-between wrapper anymore.

The central QQuickItem is now called “PlasmoidItem”, and must be the root item of the plasmoid, just alike ApplicationWindow is for applications.

PlasmoidItem will have the purely graphical properties, such as the “compactRepresentation” or “fullRepresentation”

Here is a very minimal example of a plasmoid main file under plasma6:

import org.kde.plasma.plasmoid 2.0
PlasmoidItem {
    Plasmoid.title: i18n("hello")
    fullRepresentation: Item {....}
}

Actions

Plasmoids can export actions to their right mouse button menu, such as “mute” for the mixer plasmoid and so on.

In Plasma 5 we had an imperative API to add those actions, which was again coming from that old pure JS API, which really looked a bit out of tune in QML. In Plasma 6 the API has been replaced with a completely declarative API, in this form:

PlasmoidItem {
    Plasmoid.contextualActions: [
        PlasmaCore.Action {
            text: i18n("Foo")
            icon.name: "back"
            onTriggered: {...}
        },
        PlasmaCore.Action {
             ...
        }
    ]
}

PlasmaCore.Action is actually a binding to QAction (not the internal QML action type), so that it can be shared between C++ and QML easily

SVG theming

Plasma Themes don’t really have changed for now (and you can expect any old theme from the store to keep working), but the C++ and QML API for them has been moved to a standalone framework called KSvg. Plasma Svgs have quite some interesting features over the pure QtSvg API, such as disk caching of the rendered images, stylesheet recoloring to system colors and the 9 patch rectangular stretched images of FrameSvg.

Some applications were interested in using that, but couldn’t due to the long dependency chain of plasma-framework, so now they can be used as a much more manageable compact framework, offering both the usual C++, QPainter based api and QML bindings.

import org.kde.ksvg 1.0 as KSvg
FrameSvg {
    imagePath: "widgets/background"
}

Kirigami all the way down

Designing Kirigami in the beginning we lifted two concept from the Plasma API (which again we couldn’t use directly due to the dependency chain) Theme and Units

Theme gives access to the named system colors, and Units to standard spacing and animation durations.

Over the years the Kirigami version got way more advanced then the Plasma version, and having this code duplication didn’t make much more sense, to in Plasma6 whenever referring to a named color or an unit, the Kirigami version should be used, as the Plasma version is going away.

import org.kde.kirigami 2.20 as Kirigami
RowLayout {
    spacing: Kirigami.Units.smallSpacing
    Rectangle {
        color: Kirigami.Theme.backgroundColor
        bordere.color: Kirigami.Theme.textColor
    }
}

Plasma Sprint 2023

BlaBlaSoftware

IT feels like a billion years before the last plasma sprint, which was in 2019 in Valencia, before the pandemic, but finally this year we are back on track, and was great to see again many old friends as well as seeing many new faces for which it was the first sprint.

We were gracefully hosted by Tuxedo Computers in Augsburgh, makers of very nice laptops that come with Linux and KDE Plasma, as well as being KDE patrons.

First of all, everybody got up to speed with a full git build of a Plasma 6 session, so that everybody could participate in development and discussions from the same level.

There were many discussions about Plasma 6, about what we want to do in Plasma and in Kirigami, how we want to change the look and defaults for the new major release. Most of the user-facing changes have been wonderfully described by Nate.

On my part, I worked on mainly 2 things, that were fairly not “glamorous” but quite important never the less (and mildly painful to do) : a refactor of the plasmoid loading code and splitting all the Svg themes code to a new framework with far less dependencies, ideally usable by any application.

Plasma API

I spent most of my hacking time at the sprint on a refactor of the plasmoid loading code, which won’t be really “seen” by the user, but will make the infrastructure much more robust and the API cleaner.

The person which must pay attention to it is the plasmoid author, which will need to adapt the plasmoid code in a few places.

Most notable is that, just like when you are writing a QML application you have to use the ApplicationWindow root QML Item, for a plasmoid you now have to use a PlasmoidItem root object, so something like

Item {
    Plasmoid.compactRepresentation: Label {text: Plasmoid.title}
    Plasmoid.fullRepresentation: Item {...}
}

becomes:

PlasmoidItem {
    compactRepresentation: Label {text: Plasmoid.title}
    fullRepresentation: Item {...}
}

A full porting guide is in progress.

KSvg

Using the Plasma Svg code to support stylesheet recoloring, on disk image cache to speed up loading, and the 9-patches FrameSvg is something the several applications would be interested to, and some actually are already doing, but since plasma-framework has a lot of dependencies, for some applications that is a blocker. All the svg code has now been broken out into a new framework called KSvg, which is still work in progress, but in the end will support all existing plasma themes with no change, and if an application wishes to use it, the svg sets will be loaded from the app own data folder (or anywhere else the application configures it to) instead of the share/plasma/desktoptheme folder, where plasmashell looks for them (so they can also use a complete different theme structure and don’t have to provide the same elements)