KWin
Loading...
Searching...
No Matches
previewbridge.cpp
Go to the documentation of this file.
1/*
2 SPDX-FileCopyrightText: 2014 Martin Gräßlin <mgraesslin@kde.org>
3
4 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
5*/
6#include "previewbridge.h"
7#include "previewclient.h"
8#include "previewitem.h"
9#include "previewsettings.h"
10
11#include <KDecoration2/DecoratedClient>
12#include <KDecoration2/Decoration>
13
14#include <KCModule>
15#include <KCMultiDialog>
16#include <KPluginFactory>
17#include <KPluginMetaData>
18
19#include <QDBusConnection>
20#include <QDBusMessage>
21#include <QDebug>
22#include <QDialog>
23#include <QDialogButtonBox>
24#include <QPushButton>
25#include <QQuickItem>
26#include <QQuickRenderControl>
27#include <QQuickWindow>
28#include <QVBoxLayout>
29#include <QWindow>
30
31namespace KDecoration2
32{
33namespace Preview
34{
35
36static const QString s_pluginName = QStringLiteral("org.kde.kdecoration2");
37static const QString s_kcmName = QStringLiteral("org.kde.kdecoration2.kcm");
38
40 : DecorationBridge(parent)
41 , m_lastCreatedClient(nullptr)
42 , m_lastCreatedSettings(nullptr)
43 , m_valid(false)
44{
45 connect(this, &PreviewBridge::pluginChanged, this, &PreviewBridge::createFactory);
46}
47
49
50std::unique_ptr<DecoratedClientPrivate> PreviewBridge::createClient(DecoratedClient *client, Decoration *decoration)
51{
52 auto ptr = std::unique_ptr<PreviewClient>(new PreviewClient(client, decoration));
53 m_lastCreatedClient = ptr.get();
54 return ptr;
55}
56
57std::unique_ptr<DecorationSettingsPrivate> PreviewBridge::settings(DecorationSettings *parent)
58{
59 auto ptr = std::unique_ptr<PreviewSettings>(new PreviewSettings(parent));
60 m_lastCreatedSettings = ptr.get();
61 return ptr;
62}
63
65{
66 m_previewItems.append(item);
67}
68
70{
71 m_previewItems.removeAll(item);
72}
73
74void PreviewBridge::setPlugin(const QString &plugin)
75{
76 if (m_plugin == plugin) {
77 return;
78 }
79 m_plugin = plugin;
80 Q_EMIT pluginChanged();
81}
82
83QString PreviewBridge::theme() const
84{
85 return m_theme;
86}
87
88void PreviewBridge::setTheme(const QString &theme)
89{
90 if (m_theme == theme) {
91 return;
92 }
93 m_theme = theme;
94 Q_EMIT themeChanged();
95}
96
98{
99 return m_kcmoduleName;
100}
101
102void PreviewBridge::setKcmoduleName(const QString &kcmoduleName)
103{
104 if (m_kcmoduleName == kcmoduleName) {
105 return;
106 }
107 m_kcmoduleName = kcmoduleName;
108 Q_EMIT themeChanged();
109}
110
112{
113 return m_plugin;
114}
115
116void PreviewBridge::createFactory()
117{
118 m_factory.clear();
119
120 if (m_plugin.isNull()) {
121 setValid(false);
122 qWarning() << "Plugin not set";
123 return;
124 }
125
126 const auto offers = KPluginMetaData::findPlugins(s_pluginName);
127 auto item = std::find_if(offers.constBegin(), offers.constEnd(), [this](const auto &plugin) {
128 return plugin.pluginId() == m_plugin;
129 });
130 if (item != offers.constEnd()) {
131 m_factory = KPluginFactory::loadFactory(*item).plugin;
132 }
133
134 setValid(!m_factory.isNull());
135}
136
138{
139 return m_valid;
140}
141
142void PreviewBridge::setValid(bool valid)
143{
144 if (m_valid == valid) {
145 return;
146 }
147 m_valid = valid;
148 Q_EMIT validChanged();
149}
150
151Decoration *PreviewBridge::createDecoration(QObject *parent)
152{
153 if (!m_valid) {
154 return nullptr;
155 }
156 QVariantMap args({{QStringLiteral("bridge"), QVariant::fromValue(this)}});
157 if (!m_theme.isNull()) {
158 args.insert(QStringLiteral("theme"), m_theme);
159 }
160 return m_factory->create<KDecoration2::Decoration>(parent, QVariantList({args}));
161}
162
163DecorationButton *PreviewBridge::createButton(KDecoration2::Decoration *decoration, KDecoration2::DecorationButtonType type, QObject *parent)
164{
165 if (!m_valid) {
166 return nullptr;
167 }
168 return m_factory->create<KDecoration2::DecorationButton>(parent, QVariantList({QVariant::fromValue(type), QVariant::fromValue(decoration)}));
169}
170
171void PreviewBridge::configure(QQuickItem *ctx)
172{
173 if (!m_valid) {
174 qWarning() << "Cannot show an invalid decoration's configuration dialog";
175 return;
176 }
177
178 KCMultiDialog *dialog = new KCMultiDialog;
179 dialog->setAttribute(Qt::WA_DeleteOnClose);
180
181 if (m_lastCreatedClient) {
182 dialog->setWindowTitle(m_lastCreatedClient->caption());
183 }
184
185 QVariantMap args;
186 if (!m_theme.isNull()) {
187 args.insert(QStringLiteral("theme"), m_theme);
188 }
189 Q_ASSERT(!m_kcmoduleName.isEmpty());
190
191 dialog->addModule(KPluginMetaData(s_kcmName + QLatin1Char('/') + m_kcmoduleName), {args});
192
193 connect(dialog, &KCMultiDialog::configCommitted, this, [this] {
194 if (m_lastCreatedSettings) {
195 Q_EMIT m_lastCreatedSettings->decorationSettings()->reconfigured();
196 }
197 // Send signal to all kwin instances
198 QDBusMessage message = QDBusMessage::createSignal(QStringLiteral("/KWin"),
199 QStringLiteral("org.kde.KWin"),
200 QStringLiteral("reloadConfig"));
201 QDBusConnection::sessionBus().send(message);
202 });
203
204 if (ctx->window()) {
205 dialog->winId(); // so it creates windowHandle
206 dialog->windowHandle()->setTransientParent(QQuickRenderControl::renderWindowFor(ctx->window()));
207 dialog->setModal(true);
208 }
209
210 dialog->show();
211}
212
214 : QObject(parent)
215 , m_bridge(new PreviewBridge())
216{
217 connect(m_bridge, &PreviewBridge::themeChanged, this, &BridgeItem::themeChanged);
219 connect(m_bridge, &PreviewBridge::validChanged, this, &BridgeItem::validChanged);
221}
222
224{
225 m_bridge->deleteLater();
226}
227
228}
229}
230
231#include "moc_previewbridge.cpp"
BridgeItem(QObject *parent=nullptr)
void registerPreviewItem(PreviewItem *item)
PreviewBridge(QObject *parent=nullptr)
KDecoration2::Decoration * createDecoration(QObject *parent=nullptr)
std::unique_ptr< DecorationSettingsPrivate > settings(DecorationSettings *parent) override
KDecoration2::DecorationButton * createButton(KDecoration2::Decoration *decoration, KDecoration2::DecorationButtonType type, QObject *parent=nullptr)
std::unique_ptr< DecoratedClientPrivate > createClient(DecoratedClient *client, Decoration *decoration) override
void unregisterPreviewItem(PreviewItem *item)
void setTheme(const QString &theme)
void setKcmoduleName(const QString &name)
void setPlugin(const QString &plugin)