KWin
Loading...
Searching...
No Matches
pluginmanager.cpp
Go to the documentation of this file.
1/*
2 SPDX-FileCopyrightText: 2020 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5*/
6
7#include "pluginmanager.h"
8#include "dbusinterface.h"
9#include "main.h"
10#include "plugin.h"
11#include "utils/common.h"
12
13#include <KConfigGroup>
14#include <KPluginFactory>
15#include <KPluginMetaData>
16#include <QPluginLoader>
17
18namespace KWin
19{
20
21static const QString s_pluginDirectory = QStringLiteral("kwin/plugins");
22
23static QJsonValue readPluginInfo(const QJsonObject &metadata, const QString &key)
24{
25 return metadata.value(QLatin1String("KPlugin")).toObject().value(key);
26}
27
29{
30 const KConfigGroup config(kwinApp()->config(), QStringLiteral("Plugins"));
31
32 auto checkEnabled = [&config](const QString &pluginId, const QJsonObject &metadata) {
33 const QString configKey = pluginId + QLatin1String("Enabled");
34 if (config.hasKey(configKey)) {
35 return config.readEntry(configKey, false);
36 }
37 return readPluginInfo(metadata, QStringLiteral("EnabledByDefault")).toBool(false);
38 };
39
40 const QList<KPluginMetaData> plugins = KPluginMetaData::findPlugins(s_pluginDirectory);
41 for (const KPluginMetaData &metadata : plugins) {
42 if (m_plugins.find(metadata.pluginId()) != m_plugins.end()) {
43 qCWarning(KWIN_CORE) << "Conflicting plugin id" << metadata.pluginId();
44 continue;
45 }
46 if (checkEnabled(metadata.pluginId(), metadata.rawData())) {
47 loadPlugin(metadata);
48 }
49 }
50
52}
53
55
57{
58 QStringList ret;
59 ret.reserve(m_plugins.size());
60 for (const auto &[key, _] : m_plugins) {
61 ret.push_back(key);
62 }
63 return ret;
64}
65
67{
68 const QList<KPluginMetaData> plugins = KPluginMetaData::findPlugins(s_pluginDirectory);
69
70 QStringList ret;
71 ret.reserve(plugins.size());
72
73 for (const KPluginMetaData &metadata : plugins) {
74 ret.append(metadata.pluginId());
75 }
76
77 return ret;
78}
79
80bool PluginManager::loadPlugin(const QString &pluginId)
81{
82 if (m_plugins.find(pluginId) != m_plugins.end()) {
83 qCDebug(KWIN_CORE) << "Plugin with id" << pluginId << "is already loaded";
84 return false;
85 }
86 const KPluginMetaData metadata = KPluginMetaData::findPluginById(s_pluginDirectory, pluginId);
87 if (metadata.isValid()) {
88 if (loadPlugin(metadata)) {
89 return true;
90 }
91 }
92 return false;
93}
94
95bool PluginManager::loadPlugin(const KPluginMetaData &metadata)
96{
97 if (!metadata.isValid()) {
98 qCDebug(KWIN_CORE) << "PluginManager::loadPlugin needs a valid plugin metadata";
99 return false;
100 }
101
102 const QString pluginId = metadata.pluginId();
103 QPluginLoader pluginLoader(metadata.fileName());
104 if (pluginLoader.metaData().value("IID").toString() != PluginFactory_iid) {
105 qCWarning(KWIN_CORE) << pluginId << "has mismatching plugin version";
106 return false;
107 }
108
109 std::unique_ptr<PluginFactory> factory(qobject_cast<PluginFactory *>(pluginLoader.instance()));
110 if (!factory) {
111 qCWarning(KWIN_CORE) << "Failed to get plugin factory for" << pluginId;
112 return false;
113 }
114
115 if (std::unique_ptr<Plugin> plugin = factory->create()) {
116 m_plugins[pluginId] = std::move(plugin);
117 return true;
118 } else {
119 return false;
120 }
121}
122
123void PluginManager::unloadPlugin(const QString &pluginId)
124{
125 auto it = m_plugins.find(pluginId);
126 if (it != m_plugins.end()) {
127 m_plugins.erase(it);
128 } else {
129 qCWarning(KWIN_CORE) << "No plugin with the specified id:" << pluginId;
130 }
131}
132
133} // namespace KWin
134
135#include "moc_pluginmanager.cpp"
QStringList loadedPlugins() const
QStringList availablePlugins() const
~PluginManager() override
bool loadPlugin(const QString &pluginId)
void unloadPlugin(const QString &pluginId)
#define PluginFactory_iid
Definition plugin.h:18