diff --git a/clients/aurorae/src/CMakeLists.txt b/clients/aurorae/src/CMakeLists.txt
index 7cf2d0e994..d58008b4e4 100644
--- a/clients/aurorae/src/CMakeLists.txt
+++ b/clients/aurorae/src/CMakeLists.txt
@@ -22,7 +22,9 @@ target_link_libraries(kwin3_aurorae
kdecorations
)
-install(TARGETS kwin3_aurorae DESTINATION ${PLUGIN_INSTALL_DIR} )
+kservice_desktop_to_json(kwin3_aurorae aurorae.desktop)
+
+install(TARGETS kwin3_aurorae DESTINATION ${PLUGIN_INSTALL_DIR}/kwin/kdecorations )
set(decoration_plugin_SRCS
decorationplugin.cpp
@@ -41,7 +43,6 @@ install(TARGETS decorationplugin DESTINATION ${QML_INSTALL_DIR}/org/kde/kwin/dec
########### install files ###############
-install( FILES aurorae.desktop DESTINATION ${DATA_INSTALL_DIR}/kwin )
install( FILES aurorae.knsrc DESTINATION ${CONFIG_INSTALL_DIR} )
install( FILES
qml/aurorae.qml
diff --git a/clients/aurorae/src/aurorae.cpp b/clients/aurorae/src/aurorae.cpp
index 9601f38d04..ec61faa4c5 100644
--- a/clients/aurorae/src/aurorae.cpp
+++ b/clients/aurorae/src/aurorae.cpp
@@ -37,8 +37,9 @@ along with this program. If not, see .
#include
#include
-K_PLUGIN_FACTORY(AuroraePluginFactory,
- registerPlugin(QString(), &Aurorae::AuroraeFactory::createInstance);)
+K_PLUGIN_FACTORY_WITH_JSON(AuroraePluginFactory,
+ "aurorae.json",
+ registerPlugin(QString(), &Aurorae::AuroraeFactory::createInstance);)
K_EXPORT_PLUGIN_VERSION(KWIN_DECORATION_API_VERSION)
namespace Aurorae
diff --git a/clients/aurorae/src/aurorae.desktop b/clients/aurorae/src/aurorae.desktop
index 0c8c382c14..8ca12e866d 100644
--- a/clients/aurorae/src/aurorae.desktop
+++ b/clients/aurorae/src/aurorae.desktop
@@ -65,4 +65,4 @@ Name[wa]=Moteur di tinme di gåyotaedje Aurorae
Name[x-test]=xxAurorae Decoration Theme Enginexx
Name[zh_CN]=Aurorae 装饰主题引擎
Name[zh_TW]=Aurorae 裝飾主題引擎
-X-KDE-Library=kwin3_aurorae
+X-KDE-PluginInfo-Name=aurorae
diff --git a/clients/oxygen/CMakeLists.txt b/clients/oxygen/CMakeLists.txt
index 9e6dcdfe1a..4829faac46 100644
--- a/clients/oxygen/CMakeLists.txt
+++ b/clients/oxygen/CMakeLists.txt
@@ -30,11 +30,10 @@ target_link_libraries(kwin3_oxygen kdecorations)
target_link_libraries(kwin3_oxygen oxygenstyle)
+kservice_desktop_to_json(kwin3_oxygen oxygenclient.desktop)
+
if(X11_FOUND)
target_link_libraries(kwin3_oxygen XCB::XCB)
endif()
-install(TARGETS kwin3_oxygen DESTINATION ${PLUGIN_INSTALL_DIR})
-
-########### install files ###############
-install(FILES oxygenclient.desktop DESTINATION ${DATA_INSTALL_DIR}/kwin/)
+install(TARGETS kwin3_oxygen DESTINATION ${PLUGIN_INSTALL_DIR}/kwin/kdecorations)
diff --git a/clients/oxygen/config/CMakeLists.txt b/clients/oxygen/config/CMakeLists.txt
index ebd6066924..82352fcefe 100644
--- a/clients/oxygen/config/CMakeLists.txt
+++ b/clients/oxygen/config/CMakeLists.txt
@@ -34,4 +34,4 @@ if(X11_FOUND)
target_link_libraries(kwin_oxygen_config Qt5::X11Extras)
endif()
-install(TARGETS kwin_oxygen_config DESTINATION ${QT_PLUGIN_INSTALL_DIR}/kf5)
+install(TARGETS kwin_oxygen_config DESTINATION ${QT_PLUGIN_INSTALL_DIR}/kf5/kwin/kdecorations/config)
diff --git a/clients/oxygen/config/config.json b/clients/oxygen/config/config.json
new file mode 100644
index 0000000000..a157e529d0
--- /dev/null
+++ b/clients/oxygen/config/config.json
@@ -0,0 +1,3 @@
+{
+ "X-KDE-PluginInfo-Name": "Oxygen"
+}
diff --git a/clients/oxygen/config/oxygenconfig.cpp b/clients/oxygen/config/oxygenconfig.cpp
index 877f1a65ea..bb9d7f2102 100644
--- a/clients/oxygen/config/oxygenconfig.cpp
+++ b/clients/oxygen/config/oxygenconfig.cpp
@@ -44,7 +44,9 @@
//_______________________________________________________________________
-K_PLUGIN_FACTORY(OxygenConfigPlugin, registerPlugin(QString(), &Oxygen::Config::create); )
+K_PLUGIN_FACTORY_WITH_JSON(OxygenConfigPlugin,
+ "config.json",
+ registerPlugin(QString(), &Oxygen::Config::create); )
namespace Oxygen
{
diff --git a/clients/oxygen/oxygenclient.desktop b/clients/oxygen/oxygenclient.desktop
index 33d6a47afd..a3ff5f8b8f 100644
--- a/clients/oxygen/oxygenclient.desktop
+++ b/clients/oxygen/oxygenclient.desktop
@@ -169,8 +169,6 @@ Comment[x-test]=xxStyling of the next generation desktopxx
Comment[zh_CN]=下一代桌面的风格
Comment[zh_TW]=下一代桌面的樣式
-X-KDE-Library=kwin3_oxygen
-
X-KDE-PluginInfo-Author=Nuno Pinheiro, Casper Boemann, Riccardo Iaconelli, Huynh Huu Long, Thomas Luebking, Hugo Pereira Da Costa, Matthew Woehlke
X-KDE-PluginInfo-Email=nuno@oxygen-icons.org, cbr@boemann.dk, riccardo@kde.org, long.upcase@googlemail.com, thomas.luebking@web.de, hugo.pereira@free.fr, mw_triad@users.sourceforge.net
X-KDE-PluginInfo-Name=Oxygen
diff --git a/clients/oxygen/oxygenfactory.cpp b/clients/oxygen/oxygenfactory.cpp
index f197fcc207..f5abc854e3 100644
--- a/clients/oxygen/oxygenfactory.cpp
+++ b/clients/oxygen/oxygenfactory.cpp
@@ -33,7 +33,7 @@
#include
#include
-KWIN_DECORATION(OxygenPluginFactory, Oxygen::Factory)
+KWIN_DECORATION(OxygenPluginFactory, "oxygenclient.json", Oxygen::Factory)
namespace Oxygen
{
diff --git a/decorations.cpp b/decorations.cpp
index 627c98b14a..523e4d5d1a 100644
--- a/decorations.cpp
+++ b/decorations.cpp
@@ -39,9 +39,9 @@ DecorationPlugin::DecorationPlugin(QObject *parent)
, KDecorationPlugins(KSharedConfig::openConfig())
, m_disabled(false)
{
- defaultPlugin = QStringLiteral("kwin3_oxygen");
+ defaultPlugin = QStringLiteral("Oxygen");
#ifndef KWIN_BUILD_OXYGEN
- defaultPlugin = QStringLiteral("kwin3_aurorae");
+ defaultPlugin = QStringLiteral("aurorae");
#endif
#ifdef KWIN_BUILD_DECORATIONS
loadPlugin(QString()); // load the plugin specified in cfg file
diff --git a/kcmkwin/kwindecoration/configdialog.cpp b/kcmkwin/kwindecoration/configdialog.cpp
index fd607a6d01..a58806e991 100644
--- a/kcmkwin/kwindecoration/configdialog.cpp
+++ b/kcmkwin/kwindecoration/configdialog.cpp
@@ -25,8 +25,7 @@ along with this program. If not, see .
#include
#include
#include
-#include
-#include
+#include
#include
#include
@@ -89,25 +88,24 @@ KWinDecorationConfigDialog::KWinDecorationConfigDialog(QString deco, const QList
connect(m_buttons, SIGNAL(accepted()), SLOT(accept()));
connect(m_buttons, SIGNAL(rejected()), SLOT(reject()));
- KPluginLoader loader(styleToConfigLib(deco));
- KPluginFactory *factory = loader.factory();
- if (factory) {
- m_pluginConfigWidget = new QWidget(this);
- m_pluginConfigWidget->setLayout(new QVBoxLayout);
- m_pluginObject = factory->create(m_pluginConfigWidget, m_pluginConfigWidget, QString(),
- QVariantList() << QStringLiteral("kwinrc") << QStringLiteral("Style"));
-
+ m_pluginConfigWidget = new QWidget(this);
+ m_pluginConfigWidget->setLayout(new QVBoxLayout);
+ m_pluginObject = KPluginTrader::self()->createInstanceFromQuery(QStringLiteral("kf5/kwin/kdecorations/config"),
+ QString(),
+ QStringLiteral("[X-KDE-PluginInfo-Name] == '%1'").arg(deco),
+ m_pluginConfigWidget,
+ m_pluginConfigWidget,
+ QVariantList() << QStringLiteral("kwinrc") << QStringLiteral("Style"));
+ if (m_pluginObject) {
// connect required signals and slots together...
connect(this, SIGNAL(accepted()), this, SLOT(slotAccepted()));
connect(m_pluginObject, SIGNAL(changed()), this, SLOT(slotSelectionChanged()));
connect(this, SIGNAL(pluginSave(KConfigGroup&)), m_pluginObject, SLOT(save(KConfigGroup&)));
connect(m_buttons->button(QDialogButtonBox::RestoreDefaults), SIGNAL(clicked(bool)), m_pluginObject, SLOT(defaults()));
connect(m_buttons->button(QDialogButtonBox::RestoreDefaults), SIGNAL(clicked(bool)), SLOT(slotDefault()));
- }
-
- if (m_pluginConfigWidget) {
layout->addWidget(m_pluginConfigWidget);
}
+
layout->addWidget(m_buttons);
if (borderSizes.count() >= 2) {
@@ -160,14 +158,6 @@ void KWinDecorationConfigDialog::slotSelectionChanged()
m_buttons->button(QDialogButtonBox::Reset)->setEnabled(true);
}
-QString KWinDecorationConfigDialog::styleToConfigLib(const QString& styleLib) const
-{
- if (styleLib.startsWith(QLatin1String("kwin3_")))
- return "kwin_" + styleLib.mid(6) + "_config";
- else
- return styleLib + "_config";
-}
-
void KWinDecorationConfigDialog::slotDefault()
{
if (m_borderSizes.count() >= 2)
diff --git a/kcmkwin/kwindecoration/configdialog.h b/kcmkwin/kwindecoration/configdialog.h
index 1b99f39d17..1d8cc8666a 100644
--- a/kcmkwin/kwindecoration/configdialog.h
+++ b/kcmkwin/kwindecoration/configdialog.h
@@ -70,7 +70,6 @@ private Q_SLOTS:
private:
int borderSizeToIndex(KDecorationDefines::BorderSize size, const QList& sizes);
- QString styleToConfigLib(const QString& styleLib) const;
private:
KWinDecorationConfigForm* m_ui;
diff --git a/kcmkwin/kwindecoration/decorationmodel.cpp b/kcmkwin/kwindecoration/decorationmodel.cpp
index 3050ccbfc3..a3d8a4a2fa 100644
--- a/kcmkwin/kwindecoration/decorationmodel.cpp
+++ b/kcmkwin/kwindecoration/decorationmodel.cpp
@@ -33,6 +33,7 @@ along with this program. If not, see .
#include
#include
#include
+#include
#include "kwindecoration.h"
/* WARNING -------------------------------------------------------------------------
@@ -47,6 +48,8 @@ along with this program. If not, see .
* (which is invoked on deco deconstruction)
* WARNING ------------------------------------------------------------------------ */
+static const QString s_auroraePluginName = QStringLiteral("aurorae");
+
namespace KWin
{
@@ -87,41 +90,33 @@ void DecorationModel::reload()
void DecorationModel::findDecorations()
{
beginResetModel();
- const QStringList dirList = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, "kwin", QStandardPaths::LocateDirectory);
-
- foreach (const QString & dir, dirList) {
- QDir d(dir);
- if (d.exists()) {
- foreach (const QFileInfo & fi, d.entryInfoList()) {
- const QString filename(fi.absoluteFilePath());
- if (KDesktopFile::isDesktopFile(filename)) {
- const KDesktopFile desktopFile(filename);
- const QString libName = desktopFile.desktopGroup().readEntry("X-KDE-Library");
-
- if (!libName.isEmpty() && libName.startsWith(QLatin1String("kwin3_"))) {
- if (libName == "kwin3_aurorae") {
- // read the Aurorae themes
- findAuroraeThemes();
- continue;
- }
- DecorationModelData data;
- data.name = desktopFile.readName();
- data.libraryName = libName;
- data.type = DecorationModelData::NativeDecoration;
- data.borderSize = KDecorationDefines::BorderNormal;
- data.closeDblClick = false;
- metaData(data, desktopFile);
- m_decorations.append(data);
- }
- }
- }
+ const auto decorations = KPluginTrader::self()->query(QStringLiteral("kf5/kwin/kdecorations"));
+ for (const KPluginInfo &plugin : decorations) {
+ if (plugin.pluginName() == s_auroraePluginName) {
+ // read the Aurorae themes
+ findAuroraeThemes();
+ continue;
}
+ DecorationModelData data;
+ data.name = plugin.name();
+ data.pluginName = plugin.pluginName();
+ data.type = DecorationModelData::NativeDecoration;
+ data.borderSize = KDecorationDefines::BorderNormal;
+ data.closeDblClick = false;
+ data.comment = plugin.comment();
+ data.author = plugin.author();
+ data.email = plugin.email();
+ data.version = plugin.version();
+ data.license = plugin.license();
+ data.website = plugin.website();
+ m_decorations.append(data);
}
+
KService::List offers = KServiceTypeTrader::self()->query("KWin/Decoration");
foreach (KService::Ptr service, offers) {
DecorationModelData data;
data.name = service->name();
- data.libraryName = "kwin3_aurorae";
+ data.pluginName = s_auroraePluginName;
data.type = DecorationModelData::QmlDecoration;
data.auroraeName = service->property("X-KDE-PluginInfo-Name").toString();
QString scriptName = service->property("X-Plasma-MainScript").toString();
@@ -178,7 +173,7 @@ void DecorationModel::findAuroraeThemes()
DecorationModelData data;
data.name = name;
- data.libraryName = "kwin3_aurorae";
+ data.pluginName = s_auroraePluginName;
data.type = DecorationModelData::AuroraeDecoration;
data.auroraeName = packageName;
KConfigGroup config(m_config, data.auroraeName);
@@ -216,7 +211,7 @@ QVariant DecorationModel::data(const QModelIndex& index, int role) const
case NameRole:
return m_decorations[ index.row()].name;
case LibraryNameRole:
- return m_decorations[ index.row()].libraryName;
+ return m_decorations[ index.row()].pluginName;
case TypeRole:
return m_decorations[ index.row()].type;
case AuroraeNameRole:
@@ -238,7 +233,7 @@ QVariant DecorationModel::data(const QModelIndex& index, int role) const
case BorderSizesRole: {
QList< QVariant > sizes;
const bool mustDisablePreview = m_plugins->factory() && m_plugins->factory() == m_preview->factory();
- if (m_plugins->loadPlugin(m_decorations[index.row()].libraryName) && m_plugins->factory()) {
+ if (m_plugins->loadPlugin(m_decorations[index.row()].pluginName) && m_plugins->factory()) {
foreach (KDecorationDefines::BorderSize size, m_plugins->factory()->borderSizes()) // krazy:exclude=foreach
sizes << int(size);
if (mustDisablePreview) // it's nuked with destroyPreviousPlugin()
@@ -321,7 +316,7 @@ void DecorationModel::setButtons(bool custom, const QList= BorderTiny && bsize < BordersCount)
borderSize = static_cast< BorderSize >(bsize);
- if (libraryName == "kwin3_aurorae") {
+ if (libraryName == "aurorae") {
KConfig auroraeConfig("auroraerc");
KConfigGroup group(&auroraeConfig, "Engine");
const QString themeName = group.readEntry("ThemeName", "example-deco");
diff --git a/libkdecorations/kdecoration.h b/libkdecorations/kdecoration.h
index 2fb206ca2b..77de623aa0 100644
--- a/libkdecorations/kdecoration.h
+++ b/libkdecorations/kdecoration.h
@@ -43,13 +43,17 @@ DEALINGS IN THE SOFTWARE.
* The KPluginFactory sub class returns a new instance of the specified KDecorationFactory.
*
* @param pluginfactoryname The name to be used for the KPluginFactory, passed to K_PLUGIN_FACTORY
+ * @param jsonFile Name of the json file to be compiled into the decoration plugin as metadata
* @param classname The class name of the KDecorationFactory subclass
*
* Example:
* @code
- * KWIN_DECORATION(MyDecoPluginFactory, MyDeco::Factory)
+ * KWIN_DECORATION(MyDecoPluginFactory, "mydeco.json", MyDeco::Factory)
* @endcode
*
+ * Please refer to the documentation of K_PLUGIN_FACTORY_WITH_JSON in KF5::Service for how to
+ * create and use the json file.
+ *
* In case the decoration plugin wants to have more control over the created factory (e.g. a singleton)
* it is recommended to not use this convenience macro, but specify an own K_PLUGIN_FACTORY. In that
* case it is also required to add
@@ -59,9 +63,9 @@ DEALINGS IN THE SOFTWARE.
*
* to add the correct plugin version. This is also handled by this macro in the default case.
**/
-#define KWIN_DECORATION( pluginfactoryname, classname ) \
+#define KWIN_DECORATION( pluginfactoryname, json, classname ) \
QObject *createDecorationFactory(QWidget *, QObject *, const QList &) { return new classname(); } \
- K_PLUGIN_FACTORY(pluginfactoryname, registerPlugin(QString(), &createDecorationFactory);) \
+ K_PLUGIN_FACTORY_WITH_JSON(pluginfactoryname, json, registerPlugin(QString(), &createDecorationFactory);) \
K_EXPORT_PLUGIN_VERSION(KWIN_DECORATION_API_VERSION)
#define KWIN_DECORATION_BRIDGE_API_VERSION 1
diff --git a/libkdecorations/kdecoration_plugins_p.cpp b/libkdecorations/kdecoration_plugins_p.cpp
index 03b8595751..15aa119a6e 100644
--- a/libkdecorations/kdecoration_plugins_p.cpp
+++ b/libkdecorations/kdecoration_plugins_p.cpp
@@ -31,6 +31,7 @@ DEALINGS IN THE SOFTWARE.
#include
#include
#include
+#include
#include
#include
#include
@@ -44,7 +45,7 @@ DEALINGS IN THE SOFTWARE.
KDecorationPlugins::KDecorationPlugins(const KSharedConfigPtr &cfg)
: fact(nullptr),
old_fact(nullptr),
- pluginStr(QStringLiteral("kwin3_undefined ")),
+ pluginStr(QStringLiteral("undefined ")),
config(cfg)
{
}
@@ -105,7 +106,13 @@ bool KDecorationPlugins::loadPlugin(QString nameStr)
auto createFactory = [](const QString &pluginName) -> KDecorationFactory* {
qDebug() << "Trying to load decoration plugin" << pluginName;
- KPluginLoader loader(pluginName);
+ const QString query = QStringLiteral("[X-KDE-PluginInfo-Name] == '%1'").arg(pluginName);
+ const auto offers = KPluginTrader::self()->query(QStringLiteral("kf5/kwin/kdecorations"), QString(), query);
+ if (offers.isEmpty()) {
+ qDebug() << "Decoration plugin not found";
+ return nullptr;
+ }
+ KPluginLoader loader(offers.first().libraryPath());
if (loader.pluginVersion() != KWIN_DECORATION_API_VERSION) {
qWarning() << i18n("The library %1 has wrong API version %2", loader.pluginName(), loader.pluginVersion());
return nullptr;