KService: provide solution to migrate away from KServiceTypeTrader/KMimeTypeTrader for loading plugins and parts
Open, Needs TriagePublic

Description

Look for applications that still use KService/KPluginInfo/KServiceTypeTrader/KMimeTypeTrader (i.e. desktop files in ksycoca) for plugins.

Any use for application listing is fine and can be ported to KApplicationTrader - D25698.
Loading plugins for an application can be done with KPluginLoader/KPluginMetaData (kcoreaddons).
Loading KParts can be done with KParts::PartLoader.

mart created this task.Nov 23 2019, 4:49 PM
dfaure added a subscriber: dfaure.Nov 23 2019, 5:00 PM

This means: searching for KMimeTypeTrader, KServiceTypeTrader (and KPluginInfo, more generally).

Powerdevil uses KServiceTypeTrader for loading the actions

The worst offender seems to be thumbnailer loading. This should be easy to port

A few places actually make use of KPluginTrader's trading capabilities:

  • plasma-framework's PluginLoader in loadPackage (already deprecated) and in listDataEngineInfo to filter on X-KDE-ParentApp. Needs checking what happens to DataEngines in KF6
  • KWin KCMs to match effect config modules to the corresponding effect modules. Could probably be solved differently
  • Plasma widget explorer, but I don't understand what it does

KRunner uses KServiceTypeTrader to load plugins. This is non-trivial to port because of the DBus runners

A few places actually make use of KPluginTrader's trading capabilities

Unlike KMimeTypeTrader and KServiceTypeTrader (which are based on desktop files and can be used for both apps (good) and plugins (bad)),
KPluginTrader as a class is actually fine, there's no reason to port away from it. The only thing that needs to happen to KPluginTrader and its users is to port from KPluginInfo to KPluginMetaData (that's T12194).

Looking at the code in KPluginTrader and KPluginInfo, it looks like earlier developers touching this code meant for both of them to be deprecated and for KPluginLoader::findPlugins (or instanciatePlugins) to be used instead. Those are 100% clean (based on KPluginMetaData i.e. JSON). They just don't offer a "trader language", instead the caller can pass a std::function to do the filtering in C++. Maybe all I need to do (for the KParts use case) is add a method KPluginMetaData::supportMimeType() in order to encapsulate mimetype inheritance (and iterating over the list of supported mimetypes).

Then the plan becomes to deprecate KPluginTrader [kservice] as well, in favour of KPluginLoader [kcoreaddons, i.e. better for dependencies, too].

dfaure added a comment.EditedDec 21 2019, 12:08 AM

KPluginMetaData::supportsMimeType added in D26137

dfaure added a comment.EditedJan 1 2020, 6:58 PM

OK I found one problem with this approach:

auto supportsMime = [&](const KPluginMetaData &md) { qDebug() << md.fileName(); return md.supportsMimeType(mimeType); };
const QList<QObject *> plugins = KPluginLoader::instantiatePlugins(QStringLiteral("kf5/parts"), supportsMime, this);

It loads *all* plugins that support the given mimetype, not just one.
We could add a method that stops at the first one, but what this is missing is how to choose which one, i.e. sorting on InitialPreference (as we did with desktop files) and also letting the user define the preferred part for a given mimetype (I need to research this further, I think that's something currently stored in ksycoca based on a kde-specific section in mimeapps.list).

Confirmed. keditfiletype5 ('s second tab) updates mimeapps.list, ksycoca reads that (code in internal class KMimeAssociations) and stores a sorted list of offers for each mimetype [all servicetypes mixed up, it seems, I wonder if we have ordering bugs due to that]. KMimeTypeTrader gets those and filters for the requested servicetype.

Options:

  1. we keep desktop files and KMimeTypeTrader for this
  2. we keep desktop files and provide a new trader for KParts specifically (to kill the "servicetype" concept)
  3. we implement sorting on top of the KPluginLoader query, at runtime (no cache anymore), the reasoning being that nobody will ever have more than 4-5 parts for a given mimetype. Can't be done in KPluginLoader (kcoreaddons, no kconfig), so this would go somewhere in kservice.
dfaure renamed this task from KService: Look application that still use KService for plugins to KService: provide solution to migrate away from KServiceTypeTrader/KMimeTypeTrader for loading plugins and parts.Jan 2 2020, 8:34 AM
dfaure updated the task description. (Show Details)

My current thinking is to go with option 3, with high-level API in KParts itself, to encapsulate underlying discovery and loading mechanisms completely.

Current patch: http://www.davidfaure.fr/2020/kparts_partloader_unfinished.diff
Missing the parsing of mimeapps.list, but otherwise ready.

dfaure updated the task description. (Show Details)Mar 21 2020, 6:17 PM
alex added a subscriber: alex.Jan 9 2021, 12:24 PM

KRunner uses KServiceTypeTrader to load plugins. This is non-trivial to port because of the DBus runners

It is ported and the old methods are deprecated

Thanks Alex, you rock.

ervin moved this task from In Progress to Done on the KF6 board.Mar 27 2021, 2:08 PM