KSettings::Dialog: add support for KPluginInfos without a KService
ClosedPublic

Authored by dfaure on Apr 11 2020, 11:16 PM.

Details

Summary

KPluginInfo evolved into an abstraction over old-style plugins
(KService i.e. desktop files) and new-style plugins with JSON
(KPluginMetaData/KPluginLoader).

When porting kontact to new-style plugins, I hit the issue that
KSettings::Dialog has a code path that creates a 'fake' KCM module
just to get a checkable item in the config dialog. That fake module
was using the plugininfo's KService, which was null, into the KCModuleInfo.

So I added support for metadata-based plugins to KCModuleInfo.
But rather than using KPluginMetaData and then turning KCModuleInfo into
yet another abstraction over old and new, I just used KPluginInfo in
there. One can still create a KCModuleInfo from a KService, but
internally it'll use a KPluginInfo. This makes KCModuleInfo::service()
dangerous now though, it can be null [but only in apps that start passing
new-style KPluginInfos, so not in systemsettings5 yet].
This commits ports kcmutils away from it as much as possible.

Test Plan

kontact's configuration dialog works (with and without my
not-yet-committed port to KPluginLoader). systemsettings5 still works.
konqueror's configuration dialog still works.

Diff Detail

Repository
R295 KCMUtils
Branch
master
Lint
No Linters Available
Unit
No Unit Test Coverage
Build Status
Buildable 25099
Build 25117: arc lint + arc unit
dfaure created this revision.Apr 11 2020, 11:16 PM
Restricted Application added a project: Frameworks. · View Herald TranscriptApr 11 2020, 11:16 PM
Restricted Application added a subscriber: kde-frameworks-devel. · View Herald Transcript
dfaure requested review of this revision.Apr 11 2020, 11:16 PM
cblack added a subscriber: cblack.Apr 11 2020, 11:23 PM
cblack added inline comments.
src/kcmoduleinfo.h
130

Use @warning instead of WARNING: for better markup

WARNING:


@warning:

dfaure updated this revision to Diff 79906.Apr 12 2020, 8:36 AM

Use @warning. Thanks for the tip!

For KF6 we could also just replace KCModuleInfo with KPluginInfo. It really doesn't provide anything on top....

Any idea who could review this?

svuorela accepted this revision.Apr 24 2020, 6:07 PM
svuorela added a subscriber: svuorela.
svuorela added inline comments.
src/kcmoduleinfo.cpp
73

At a later point, I*m not sure what the purpose is for these members are - but that's probably for another changeset.

src/kcmoduleinfo.h
131

Can we mark it as deprecated?

This revision is now accepted and ready to land.Apr 24 2020, 6:07 PM

Thanks for the review! I was getting desperate to get one ;-)

src/kcmoduleinfo.cpp
73

Right, I was wondering the same. We could just implement the getters so that they call these things directly.

But then I'm also wondering what's the purpose of KCModuleInfo at all and whether we could just use KPluginInfo directly instead -- but that's a KF6 consideration, since it's part of the API for KCMultiDialog and others.

Well, we could add a addModule(KPluginInfo) overload if that's the direction we're going for; I just don't have full overview on the KCM stuff.

src/kcmoduleinfo.h
131

It's complicated.

  1. If you use the QString constructor, you know service() is usable. That's the case for all users of KCModuleInfo except KCModuleLoader. [Not that there are many]
  1. Even KCModuleLoader calls service(), to test for noDisplay().

The whole concept of NoDisplay only makes sense for desktop files, unless we want to have that in JSON metadata as well. I suppose we do, but this currently seems to be completely missing (e.g. from KPluginMetaData, if we want this in all plugins, not just KCMs). We'd have to duplicate the logic currently in KService::noDisplay().

Any volunteers to look into this? :-)

dfaure closed this revision.Apr 26 2020, 11:37 AM
kossebau added inline comments.
src/kcmoduleinfo.h
131

As I just ran into this code, a short reminder: it would be a regression not to have a noDisplay check in the case of pure JSON metadata, as the current code of KService::;noDisplay() also asks KAuth whether the page should be shown (KAuthorized::authorizeControlModule(storageId())), which some KIOSK systems or admins might rely on, but also showInCurrentDesktop() & showOnCurrentPlatform(), which also still make sense, for what I can tell.

This caused a crash in openSUSE:
https://bugs.kde.org/show_bug.cgi?id=421566

The same crash can been seen in Kubuntu when trying to launch the external software-properties app (driver manager) via systemsettings.

systemsettings uses KCModuleInfo::service() to check whether the moduleinfo is valid[1], the problem is creating a KPluginInfo from the KService based on a .desktop file with X-KDE-ServiceTypes=SystemSettingsExternalApp fails because it doesn't seem to have valid metadata. Since the KPluginInfo ctor fails, accessing d->pluginInfo.service() causes a crash, I've submitted a proposed fix at [2]. This doesn't fix the bug, but merely prevents the crash.

[1] https://invent.kde.org/plasma/systemsettings/-/blob/master/core/ModuleView.cpp#L229
[2] https://invent.kde.org/frameworks/kcmutils/-/merge_requests/1

I guess a proper fix will need to revert part of this to have the KModuleInfo ctor that took a KService not use KPluginInfo internally; better still, of course, is having the KPluginInfo ctor work for the case of X-KDE-ServiceTypes=SystemSettingsExternalApp, (I couldn't grok KPluginInfo stuff fully yet).