[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
This commit is contained in:
Vlad Zagorodniy 2018-09-09 12:28:58 +03:00
parent 1de9648a89
commit 78ce54f88a
7 changed files with 136 additions and 14 deletions

View file

@ -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

View file

@ -26,10 +26,9 @@
#include <effect_builtins.h>
#include <KLocalizedString>
#include <KService>
#include <KServiceTypeTrader>
#include <KSharedConfig>
#include <KCModuleProxy>
#include <KPackage/PackageLoader>
#include <KPluginTrader>
#include <kdeclarative/kdeclarative.h>
#include <KPluginLoader>
@ -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;
}

View file

@ -1,4 +1,5 @@
add_subdirectory(aurorae)
add_subdirectory(decoration)
add_subdirectory(effect)
add_subdirectory(scripts)
add_subdirectory(windowswitcher)

View file

@ -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)

View file

@ -0,0 +1,63 @@
/******************************************************************************
* Copyright 2018 Vlad Zagorodniy <vladzzag@gmail.com> *
* *
* 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 <KLocalizedString>
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"

View file

@ -0,0 +1,33 @@
/******************************************************************************
* Copyright 2018 Vlad Zagorodniy <vladzzag@gmail.com> *
* *
* 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 <KPackage/PackageStructure>
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;
};

View file

@ -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