From 78ce54f88aa6dc1cf2efc3a3dc4fe1cfa159115a Mon Sep 17 00:00:00 2001 From: Vlad Zagorodniy Date: Sun, 9 Sep 2018 12:28:58 +0300 Subject: [PATCH] [effects] Make scripted effects GHNS-able Summary: Currently, if one wants to install a scripted effect from the KDE Store, the effect won't show up in the Desktop Effects KCM. The reason for that is kpackagetool5 doesn't know where to install effects (they have to be installed under ${DATA_DIR}/kwin/effects). Another problem is that even if the scripted effect is installed in the right directory (e.g. ~/.local/share/kwin/effects), it won't be listed in the Desktop Effects KCM because it doesn't have a desktop file in kservices5 dir. Please notice that the effect will be "visible" for KWin, i.e. you can enable it by editing kwinrc. This diff addresses those 2 problems by: * Adding a PackageStructure plugin for effects (so they are installed under kwin/effects/); * Using KPackage::PackageLoader to get list of scripted effect in the Desktop Effects KCM. Test Plan: * Installed an effect from the KDE Store, it appeared in the Desktop Effects KCM; * Removed it. Reviewers: #kwin, mart, davidedmundson Reviewed By: #kwin, davidedmundson Subscribers: ngraham, davidedmundson, kwin Tags: #kwin Differential Revision: https://phabricator.kde.org/D15372 --- kcmkwin/kwincompositing/CMakeLists.txt | 4 +- kcmkwin/kwincompositing/model.cpp | 23 ++++--- packageplugins/CMakeLists.txt | 1 + packageplugins/effect/CMakeLists.txt | 16 +++++ packageplugins/effect/effect.cpp | 63 +++++++++++++++++++ packageplugins/effect/effect.h | 33 ++++++++++ .../kwin-packagestructure-effect.desktop | 10 +++ 7 files changed, 136 insertions(+), 14 deletions(-) create mode 100644 packageplugins/effect/CMakeLists.txt create mode 100644 packageplugins/effect/effect.cpp create mode 100644 packageplugins/effect/effect.h create mode 100644 packageplugins/effect/kwin-packagestructure-effect.desktop diff --git a/kcmkwin/kwincompositing/CMakeLists.txt b/kcmkwin/kwincompositing/CMakeLists.txt index 56a5a7ddcb..7232abde19 100644 --- a/kcmkwin/kwincompositing/CMakeLists.txt +++ b/kcmkwin/kwincompositing/CMakeLists.txt @@ -38,7 +38,7 @@ target_link_libraries(kwincompositing KF5::ConfigCore KF5::Declarative KF5::I18n - KF5::Service + KF5::Package KF5::KCMUtils KF5::NewStuff kwin4_effect_builtins @@ -72,7 +72,7 @@ if (BUILD_TESTING) KF5::ConfigCore KF5::Declarative KF5::I18n - KF5::Service + KF5::Package KF5::KCMUtils KF5::NewStuff kwineffects diff --git a/kcmkwin/kwincompositing/model.cpp b/kcmkwin/kwincompositing/model.cpp index c48caf627b..9ce0873c9b 100644 --- a/kcmkwin/kwincompositing/model.cpp +++ b/kcmkwin/kwincompositing/model.cpp @@ -26,10 +26,9 @@ #include #include -#include -#include #include #include +#include #include #include #include @@ -263,10 +262,9 @@ void EffectModel::loadBuiltInEffects(const KConfigGroup &kwinConfig, const KPlug void EffectModel::loadJavascriptEffects(const KConfigGroup &kwinConfig) { - KService::List offers = KServiceTypeTrader::self()->query("KWin/Effect", QStringLiteral("[X-Plasma-API] == 'javascript'")); - for(KService::Ptr service : offers) { - const QString effectPluginPath = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kservices5/"+ service->entryPath(), QStandardPaths::LocateFile); - KPluginInfo plugin(effectPluginPath); + const auto plugins = KPackage::PackageLoader::self()->listPackages(QStringLiteral("KWin/Effect"), QStringLiteral("kwin/effects")); + for (const KPluginMetaData &metaData : plugins) { + KPluginInfo plugin(metaData); EffectData effect; effect.name = plugin.name(); @@ -280,15 +278,16 @@ void EffectModel::loadJavascriptEffects(const KConfigGroup &kwinConfig) effect.effectStatus = effectStatus(kwinConfig.readEntry(effect.serviceName + "Enabled", plugin.isPluginEnabledByDefault())); effect.enabledByDefault = plugin.isPluginEnabledByDefault(); effect.enabledByDefaultFunction = false; - effect.video = service->property(QStringLiteral("X-KWin-Video-Url"), QVariant::Url).toUrl(); + effect.video = plugin.property(QStringLiteral("X-KWin-Video-Url")).toUrl(); effect.supported = true; - effect.exclusiveGroup = service->property(QStringLiteral("X-KWin-Exclusive-Category"), QVariant::String).toString(); - effect.internal = service->property(QStringLiteral("X-KWin-Internal"), QVariant::Bool).toBool(); + effect.exclusiveGroup = plugin.property(QStringLiteral("X-KWin-Exclusive-Category")).toString(); + effect.internal = plugin.property(QStringLiteral("X-KWin-Internal")).toBool(); effect.scripted = true; - if (!service->pluginKeyword().isEmpty()) { - // scripted effects have their pluginName() as the keyword - effect.configurable = service->property(QStringLiteral("X-KDE-ParentComponents")).toString() == service->pluginKeyword(); + const QString pluginKeyword = plugin.property(QStringLiteral("X-KDE-PluginKeyword")).toString(); + if (!pluginKeyword.isEmpty()) { + // scripted effects have their pluginName() as the keyword + effect.configurable = plugin.property(QStringLiteral("X-KDE-ParentComponents")).toString() == pluginKeyword; } else { effect.configurable = false; } diff --git a/packageplugins/CMakeLists.txt b/packageplugins/CMakeLists.txt index 92d6d1b4b1..7c3f5d15c2 100644 --- a/packageplugins/CMakeLists.txt +++ b/packageplugins/CMakeLists.txt @@ -1,4 +1,5 @@ add_subdirectory(aurorae) add_subdirectory(decoration) +add_subdirectory(effect) add_subdirectory(scripts) add_subdirectory(windowswitcher) diff --git a/packageplugins/effect/CMakeLists.txt b/packageplugins/effect/CMakeLists.txt new file mode 100644 index 0000000000..cc09ec4875 --- /dev/null +++ b/packageplugins/effect/CMakeLists.txt @@ -0,0 +1,16 @@ +add_definitions(-DTRANSLATION_DOMAIN=\"kwin_package_effect\") + +set(effect_SRCS + effect.cpp +) + +add_library(kwin_packagestructure_effect MODULE ${effect_SRCS}) + +target_link_libraries(kwin_packagestructure_effect + KF5::I18n + KF5::Package +) + +kcoreaddons_desktop_to_json(kwin_packagestructure_effect kwin-packagestructure-effect.desktop) + +install(TARGETS kwin_packagestructure_effect DESTINATION ${KDE_INSTALL_PLUGINDIR}/kpackage/packagestructure) diff --git a/packageplugins/effect/effect.cpp b/packageplugins/effect/effect.cpp new file mode 100644 index 0000000000..9b5b43e109 --- /dev/null +++ b/packageplugins/effect/effect.cpp @@ -0,0 +1,63 @@ +/****************************************************************************** +* Copyright 2018 Vlad Zagorodniy * +* * +* This library is free software; you can redistribute it and/or * +* modify it under the terms of the GNU Library General Public * +* License as published by the Free Software Foundation; either * +* version 2 of the License, or (at your option) any later version. * +* * +* This library is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * +* Library General Public License for more details. * +* * +* You should have received a copy of the GNU Library General Public License * +* along with this library; see the file COPYING.LIB. If not, write to * +* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * +* Boston, MA 02110-1301, USA. * +*******************************************************************************/ + +#include "effect.h" + +#include + +EffectPackageStructure::EffectPackageStructure(QObject *parent, const QVariantList &args) + : KPackage::PackageStructure(parent, args) +{ +} + +void EffectPackageStructure::initPackage(KPackage::Package *package) +{ + package->setDefaultPackageRoot(QStringLiteral("kwin/effects/")); + + package->addDirectoryDefinition("code", QStringLiteral("code"), i18n("Executable Scripts")); + package->setMimeTypes("code", {QStringLiteral("text/plain")}); + + package->addFileDefinition("mainscript", QStringLiteral("code/main.js"), i18n("Main Script File")); + package->setRequired("mainscript", true); + + package->addFileDefinition("config", QStringLiteral("config/main.xml"), i18n("Configuration Definition File")); + package->setMimeTypes("config", {QStringLiteral("text/xml")}); + + package->addFileDefinition("configui", QStringLiteral("ui/config.ui"), i18n("KCM User Interface File")); + package->setMimeTypes("configui", {QStringLiteral("text/xml")}); +} + +void EffectPackageStructure::pathChanged(KPackage::Package *package) +{ + if (package->path().isEmpty()) { + return; + } + + const KPluginMetaData md(package->metadata().metaDataFileName()); + const QString mainScript = md.value("X-Plasma-MainScript"); + if (mainScript.isEmpty()) { + return; + } + + package->addFileDefinition("mainscript", mainScript, i18n("Main Script File")); +} + +K_EXPORT_KPACKAGE_PACKAGE_WITH_JSON(EffectPackageStructure, "kwin-packagestructure-effect.json") + +#include "effect.moc" diff --git a/packageplugins/effect/effect.h b/packageplugins/effect/effect.h new file mode 100644 index 0000000000..48c47e64cb --- /dev/null +++ b/packageplugins/effect/effect.h @@ -0,0 +1,33 @@ +/****************************************************************************** +* Copyright 2018 Vlad Zagorodniy * +* * +* This library is free software; you can redistribute it and/or * +* modify it under the terms of the GNU Library General Public * +* License as published by the Free Software Foundation; either * +* version 2 of the License, or (at your option) any later version. * +* * +* This library is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * +* Library General Public License for more details. * +* * +* You should have received a copy of the GNU Library General Public License * +* along with this library; see the file COPYING.LIB. If not, write to * +* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * +* Boston, MA 02110-1301, USA. * +*******************************************************************************/ + +#pragma once + +#include + +class EffectPackageStructure : public KPackage::PackageStructure +{ + Q_OBJECT + +public: + EffectPackageStructure(QObject *parent = nullptr, const QVariantList &args = {}); + + void initPackage(KPackage::Package *package) override; + void pathChanged(KPackage::Package *package) override; +}; diff --git a/packageplugins/effect/kwin-packagestructure-effect.desktop b/packageplugins/effect/kwin-packagestructure-effect.desktop new file mode 100644 index 0000000000..f6d451a899 --- /dev/null +++ b/packageplugins/effect/kwin-packagestructure-effect.desktop @@ -0,0 +1,10 @@ +[Desktop Entry] +Name=KWin Effect +Type=Service +X-KDE-ServiceTypes=KPackage/PackageStructure +X-KDE-Library=kwin_packagestructure_effect + +X-KDE-PluginInfo-Author=Vlad Zagorodniy +X-KDE-PluginInfo-Email=vladzzag@gmail.com +X-KDE-PluginInfo-Name=KWin/Effect +X-KDE-PluginInfo-Version=1