11#include <config-kwin.h>
23#include <KDecoration2/DecoratedClient>
24#include <KDecoration2/Decoration>
25#include <KDecoration2/DecorationSettings>
28#include <KPluginFactory>
29#include <KPluginMetaData>
32#include <QMetaProperty>
40static const QString s_aurorae = QStringLiteral(
"org.kde.kwin.aurorae");
41static const QString s_pluginName = QStringLiteral(
"org.kde.kdecoration2");
43static const QString s_defaultPlugin = BREEZE_KDECORATION_PLUGIN_ID;
45static const QString s_defaultPlugin = s_aurorae;
50 , m_showToolTips(false)
54 readDecorationOptions();
57QString DecorationBridge::readPlugin()
59 return kwinApp()->config()->group(s_pluginName).readEntry(
"library", s_defaultPlugin);
62static bool readNoPlugin()
64 return kwinApp()->config()->group(s_pluginName).readEntry(
"NoPlugin",
false);
67QString DecorationBridge::readTheme()
const
69 return kwinApp()->config()->group(s_pluginName).readEntry(
"theme", m_defaultTheme);
72void DecorationBridge::readDecorationOptions()
74 m_showToolTips = kwinApp()->config()->group(s_pluginName).readEntry(
"ShowToolTips",
true);
83 return !bridge->m_noPlugin && bridge->m_factory;
88 m_noPlugin = readNoPlugin();
95 m_plugin = readPlugin();
96 m_settings = std::make_shared<KDecoration2::DecorationSettings>(
this);
98 if (m_plugin != s_defaultPlugin) {
100 m_plugin = s_defaultPlugin;
105 m_plugin = s_aurorae;
114bool DecorationBridge::initPlugin()
116 const KPluginMetaData metaData = KPluginMetaData::findPluginById(s_pluginName, m_plugin);
117 if (!metaData.isValid()) {
118 qCWarning(KWIN_DECORATIONS) <<
"Could not locate decoration plugin" << m_plugin;
121 qCDebug(KWIN_DECORATIONS) <<
"Trying to load decoration plugin: " << metaData.fileName();
122 if (
auto factoryResult = KPluginFactory::loadFactory(metaData)) {
123 m_factory.reset(factoryResult.plugin);
124 loadMetaData(metaData.rawData());
127 qCWarning(KWIN_DECORATIONS) <<
"Error loading plugin:" << factoryResult.errorText;
132static void recreateDecorations()
135 window->invalidateDecoration();
141 readDecorationOptions();
143 if (m_noPlugin != readNoPlugin()) {
144 m_noPlugin = !m_noPlugin;
148 m_plugin = QString();
155 recreateDecorations();
159 const QString newPlugin = readPlugin();
160 if (newPlugin != m_plugin) {
162 auto oldFactory = std::move(m_factory);
163 const auto oldPluginName = m_plugin;
164 m_plugin = newPlugin;
167 m_factory = std::move(oldFactory);
168 m_plugin = oldPluginName;
170 recreateDecorations();
175 const QString oldTheme = m_theme;
176 m_theme = readTheme();
177 if (m_theme != oldTheme) {
178 recreateDecorations();
183void DecorationBridge::loadMetaData(
const QJsonObject &
object)
186 m_recommendedBorderSize = QString();
188 m_defaultTheme = QString();
191 const QJsonValue decoSettings =
object.value(s_pluginName);
192 if (decoSettings.isUndefined()) {
196 const QVariantMap decoSettingsMap = decoSettings.toObject().toVariantMap();
197 auto recBorderSizeIt = decoSettingsMap.find(QStringLiteral(
"recommendedBorderSize"));
198 if (recBorderSizeIt != decoSettingsMap.end()) {
199 m_recommendedBorderSize = recBorderSizeIt.value().toString();
201 findTheme(decoSettingsMap);
206void DecorationBridge::findTheme(
const QVariantMap &map)
208 auto it = map.find(QStringLiteral(
"themes"));
209 if (it == map.end()) {
212 if (!it.value().toBool()) {
215 it = map.find(QStringLiteral(
"defaultTheme"));
216 m_defaultTheme = it != map.end() ? it.value().toString() : QString();
217 m_theme = readTheme();
222 return std::unique_ptr<DecoratedClientImpl>(
new DecoratedClientImpl(
static_cast<Window *
>(decoration->parent()), client, decoration));
227 return std::unique_ptr<SettingsImpl>(
new SettingsImpl(parent));
238 QVariantMap args({{QStringLiteral(
"bridge"), QVariant::fromValue(
this)}});
240 if (!m_theme.isEmpty()) {
241 args.insert(QStringLiteral(
"theme"), m_theme);
243 auto deco = m_factory->create<KDecoration2::Decoration>(window, QVariantList{args});
244 deco->setSettings(m_settings);
249static QString settingsProperty(
const QVariant &variant)
251 if (QLatin1String(variant.typeName()) == QLatin1String(
"KDecoration2::BorderSize")) {
252 return QString::number(variant.toInt());
253 }
else if (QLatin1String(variant.typeName()) == QLatin1String(
"QList<KDecoration2::DecorationButtonType>")) {
254 const auto &b = variant.value<QList<KDecoration2::DecorationButtonType>>();
256 for (
auto it = b.begin(); it != b.end(); ++it) {
257 if (it != b.begin()) {
258 buffer.append(QStringLiteral(
", "));
260 buffer.append(QString::number(
int(*it)));
264 return variant.toString();
271 b.append(QStringLiteral(
"Decorations are disabled"));
273 b.append(QStringLiteral(
"Plugin: %1\n").arg(m_plugin));
274 b.append(QStringLiteral(
"Theme: %1\n").arg(m_theme));
275 b.append(QStringLiteral(
"Plugin recommends border size: %1\n").arg(m_recommendedBorderSize.isNull() ?
"No" : m_recommendedBorderSize));
276 const QMetaObject *metaOptions = m_settings->metaObject();
277 for (
int i = 0; i < metaOptions->propertyCount(); ++i) {
278 const QMetaProperty
property = metaOptions->property(i);
279 if (QLatin1String(property.name()) == QLatin1String(
"objectName")) {
282 b.append(QStringLiteral(
"%1: %2\n").arg(property.name(), settingsProperty(m_settings->property(property.name()))));
291#include "moc_decorationbridge.cpp"
std::unique_ptr< KDecoration2::DecoratedClientPrivate > createClient(KDecoration2::DecoratedClient *client, KDecoration2::Decoration *decoration) override
QString supportInformation() const
KDecoration2::Decoration * createDecoration(Window *window)
const std::shared_ptr< KDecoration2::DecorationSettings > & settings() const
void setDefaultMode(Mode mode)
ServerSideDecorationManagerInterface * decorationManager() const
void forEachWindow(std::function< void(Window *)> func)
Decoration::DecorationBridge * decorationBridge() const
static Workspace * self()
WaylandServer * waylandServer()