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;