KWin
Loading...
Searching...
No Matches
main.cpp
Go to the documentation of this file.
1/*
2 KWin - the KDE window manager
3 This file is part of the KDE project.
4
5 SPDX-FileCopyrightText: 2008 Martin Gräßlin <mgraesslin@kde.org>
6 SPDX-FileCopyrightText: 2009 Lucas Murray <lmurray@undefinedfire.com>
7 SPDX-FileCopyrightText: 2020 Cyril Rossi <cyril.rossi@enioka.com>
8
9 SPDX-License-Identifier: GPL-2.0-or-later
10*/
11
12#include "main.h"
13#include <kwin_effects_interface.h>
14
15#include <KConfigGroup>
16#include <KLocalizedString>
17#include <KPackage/Package>
18#include <KPackage/PackageLoader>
19#include <KPluginFactory>
20#include <QDBusConnection>
21#include <QVBoxLayout>
22
24#include "kwinscreenedgedata.h"
25#include "kwinscreenedgeeffectsettings.h"
26#include "kwinscreenedgescriptsettings.h"
27#include "kwinscreenedgesettings.h"
28
29K_PLUGIN_FACTORY_WITH_JSON(KWinScreenEdgesConfigFactory, "kcm_kwinscreenedges.json", registerPlugin<KWin::KWinScreenEdgesConfig>(); registerPlugin<KWin::KWinScreenEdgeData>();)
30
31namespace KWin
32{
33
34KWinScreenEdgesConfig::KWinScreenEdgesConfig(QObject *parent, const KPluginMetaData &data)
35 : KCModule(parent, data)
36 , m_form(new KWinScreenEdgesConfigForm(widget()))
37 , m_config(KSharedConfig::openConfig("kwinrc"))
38 , m_data(new KWinScreenEdgeData(this))
39{
40 QVBoxLayout *layout = new QVBoxLayout(widget());
41 layout->addWidget(m_form);
42
43 addConfig(m_data->settings(), m_form);
44
45 monitorInit();
46
47 connect(this, &KWinScreenEdgesConfig::defaultsIndicatorsVisibleChanged, m_form, [this]() {
48 m_form->setDefaultsIndicatorsVisible(defaultsIndicatorsVisible());
49 });
50 connect(m_form, &KWinScreenEdgesConfigForm::saveNeededChanged, this, &KWinScreenEdgesConfig::unmanagedWidgetChangeState);
51 connect(m_form, &KWinScreenEdgesConfigForm::defaultChanged, this, &KWinScreenEdgesConfig::unmanagedWidgetDefaultState);
52}
53
54KWinScreenEdgesConfig::~KWinScreenEdgesConfig()
55{
56}
57
58void KWinScreenEdgesConfig::load()
59{
60 KCModule::load();
61 m_data->settings()->load();
62 for (KWinScreenEdgeScriptSettings *setting : std::as_const(m_scriptSettings)) {
63 setting->load();
64 }
65 for (KWinScreenEdgeEffectSettings *setting : std::as_const(m_effectSettings)) {
66 setting->load();
67 }
68
69 monitorLoadSettings();
70 monitorLoadDefaultSettings();
71 m_form->setRemainActiveOnFullscreen(m_data->settings()->remainActiveOnFullscreen());
72 m_form->setElectricBorderCornerRatio(m_data->settings()->electricBorderCornerRatio());
73 m_form->setDefaultElectricBorderCornerRatio(m_data->settings()->defaultElectricBorderCornerRatioValue());
74 m_form->reload();
75}
76
77void KWinScreenEdgesConfig::save()
78{
79 monitorSaveSettings();
80 m_data->settings()->setRemainActiveOnFullscreen(m_form->remainActiveOnFullscreen());
81 m_data->settings()->setElectricBorderCornerRatio(m_form->electricBorderCornerRatio());
82 m_data->settings()->save();
83 for (KWinScreenEdgeScriptSettings *setting : std::as_const(m_scriptSettings)) {
84 setting->save();
85 }
86 for (KWinScreenEdgeEffectSettings *setting : std::as_const(m_effectSettings)) {
87 setting->save();
88 }
89
90 // Reload saved settings to ScreenEdge UI
91 monitorLoadSettings();
92 m_form->setElectricBorderCornerRatio(m_data->settings()->electricBorderCornerRatio());
93 m_form->setRemainActiveOnFullscreen(m_data->settings()->remainActiveOnFullscreen());
94 m_form->reload();
95
96 // Reload KWin.
97 QDBusMessage message = QDBusMessage::createSignal("/KWin", "org.kde.KWin", "reloadConfig");
98 QDBusConnection::sessionBus().send(message);
99 // and reconfigure the effects
100 OrgKdeKwinEffectsInterface interface(QStringLiteral("org.kde.KWin"),
101 QStringLiteral("/Effects"),
102 QDBusConnection::sessionBus());
103
104 interface.reconfigureEffect(QStringLiteral("overview"));
105 interface.reconfigureEffect(QStringLiteral("windowview"));
106
107 for (const auto &effectId : std::as_const(m_effects)) {
108 interface.reconfigureEffect(effectId);
109 }
110
111 KCModule::save();
112}
113
114void KWinScreenEdgesConfig::defaults()
115{
116 m_form->setDefaults();
117
118 KCModule::defaults();
119}
120
121//-----------------------------------------------------------------------------
122// Monitor
123
124static QList<KPluginMetaData> listBuiltinEffects()
125{
126 const QString rootDirectory = QStandardPaths::locate(QStandardPaths::GenericDataLocation,
127 QStringLiteral("kwin/builtin-effects"),
128 QStandardPaths::LocateDirectory);
129
130 QList<KPluginMetaData> ret;
131
132 const QStringList nameFilters{QStringLiteral("*.json")};
133 QDirIterator it(rootDirectory, nameFilters, QDir::Files);
134 while (it.hasNext()) {
135 it.next();
136 if (const KPluginMetaData metaData = KPluginMetaData::fromJsonFile(it.filePath()); metaData.isValid()) {
137 ret.append(metaData);
138 }
139 }
140
141 return ret;
142}
143
144static QList<KPluginMetaData> listScriptedEffects()
145{
146 return KPackage::PackageLoader::self()->listPackages(QStringLiteral("KWin/Effect"), QStringLiteral("kwin/effects/"));
147}
148
149void KWinScreenEdgesConfig::monitorInit()
150{
151 m_form->monitorAddItem(i18n("No Action"));
152 m_form->monitorAddItem(i18n("Peek at Desktop"));
153 m_form->monitorAddItem(i18n("Lock Screen"));
154 m_form->monitorAddItem(i18n("Show KRunner"));
155 m_form->monitorAddItem(i18n("Activity Manager"));
156 m_form->monitorAddItem(i18n("Application Launcher"));
157
158 // TODO: Find a better way to get the display name of the present windows,
159 // Maybe install metadata.json files?
160 const QString presentWindowsName = i18n("Present Windows");
161 m_form->monitorAddItem(i18n("%1 - All Desktops", presentWindowsName));
162 m_form->monitorAddItem(i18n("%1 - Current Desktop", presentWindowsName));
163 m_form->monitorAddItem(i18n("%1 - Current Application", presentWindowsName));
164
165 m_form->monitorAddItem(i18n("Overview"));
166
167 m_form->monitorAddItem(i18n("Toggle window switching"));
168 m_form->monitorAddItem(i18n("Toggle alternative window switching"));
169
170 KConfigGroup config(m_config, QStringLiteral("Plugins"));
171 const auto effects = listBuiltinEffects() << listScriptedEffects();
172
173 for (const KPluginMetaData &effect : effects) {
174 if (!effect.value(QStringLiteral("X-KWin-Border-Activate"), false)) {
175 continue;
176 }
177
178 if (!config.readEntry(effect.pluginId() + QStringLiteral("Enabled"), effect.isEnabledByDefault())) {
179 continue;
180 }
181 m_effects << effect.pluginId();
182 m_form->monitorAddItem(effect.name());
183 m_effectSettings[effect.pluginId()] = new KWinScreenEdgeEffectSettings(effect.pluginId(), this);
184 }
185
186 const QString scriptFolder = QStringLiteral("kwin/scripts/");
187 const auto scripts = KPackage::PackageLoader::self()->listPackages(QStringLiteral("KWin/Script"), scriptFolder);
188
189 for (const KPluginMetaData &script : scripts) {
190 if (script.value(QStringLiteral("X-KWin-Border-Activate"), false) != true) {
191 continue;
192 }
193
194 if (!config.readEntry(script.pluginId() + QStringLiteral("Enabled"), script.isEnabledByDefault())) {
195 continue;
196 }
197 m_scripts << script.pluginId();
198 m_form->monitorAddItem(script.name());
199 m_scriptSettings[script.pluginId()] = new KWinScreenEdgeScriptSettings(script.pluginId(), this);
200 }
201
202 monitorShowEvent();
203}
204
205void KWinScreenEdgesConfig::monitorLoadSettings()
206{
207 // Load ElectricBorderActions
208 m_form->monitorChangeEdge(ElectricTop, KWinScreenEdgesConfig::electricBorderActionFromString(m_data->settings()->top()));
209 m_form->monitorChangeEdge(ElectricTopRight, KWinScreenEdgesConfig::electricBorderActionFromString(m_data->settings()->topRight()));
210 m_form->monitorChangeEdge(ElectricRight, KWinScreenEdgesConfig::electricBorderActionFromString(m_data->settings()->right()));
211 m_form->monitorChangeEdge(ElectricBottomRight, KWinScreenEdgesConfig::electricBorderActionFromString(m_data->settings()->bottomRight()));
212 m_form->monitorChangeEdge(ElectricBottom, KWinScreenEdgesConfig::electricBorderActionFromString(m_data->settings()->bottom()));
213 m_form->monitorChangeEdge(ElectricBottomLeft, KWinScreenEdgesConfig::electricBorderActionFromString(m_data->settings()->bottomLeft()));
214 m_form->monitorChangeEdge(ElectricLeft, KWinScreenEdgesConfig::electricBorderActionFromString(m_data->settings()->left()));
215 m_form->monitorChangeEdge(ElectricTopLeft, KWinScreenEdgesConfig::electricBorderActionFromString(m_data->settings()->topLeft()));
216
217 // Load effect-specific actions:
218
219 // PresentWindows BorderActivateAll
220 m_form->monitorChangeEdge(m_data->settings()->borderActivateAll(), PresentWindowsAll);
221
222 // PresentWindows BorderActivate
223 m_form->monitorChangeEdge(m_data->settings()->borderActivatePresentWindows(), PresentWindowsCurrent);
224
225 // PresentWindows BorderActivateClass
226 m_form->monitorChangeEdge(m_data->settings()->borderActivateClass(), PresentWindowsClass);
227
228 // Overview
229 m_form->monitorChangeEdge(m_data->settings()->borderActivateOverview(), Overview);
230
231 // TabBox
232 m_form->monitorChangeEdge(m_data->settings()->borderActivateTabBox(), TabBox);
233 // Alternative TabBox
234 m_form->monitorChangeEdge(m_data->settings()->borderAlternativeActivate(), TabBoxAlternative);
235
236 // Dinamically loaded effects
237 int lastIndex = EffectCount;
238 for (int i = 0; i < m_effects.size(); i++) {
239 m_form->monitorChangeEdge(m_effectSettings[m_effects[i]]->borderActivate(), lastIndex);
240 ++lastIndex;
241 }
242
243 // Scripts
244 for (int i = 0; i < m_scripts.size(); i++) {
245 m_form->monitorChangeEdge(m_scriptSettings[m_scripts[i]]->borderActivate(), lastIndex);
246 ++lastIndex;
247 }
248}
249
250void KWinScreenEdgesConfig::monitorLoadDefaultSettings()
251{
252 // Load ElectricBorderActions
253 m_form->monitorChangeDefaultEdge(ElectricTop, KWinScreenEdgesConfig::electricBorderActionFromString(m_data->settings()->defaultTopValue()));
254 m_form->monitorChangeDefaultEdge(ElectricTopRight, KWinScreenEdgesConfig::electricBorderActionFromString(m_data->settings()->defaultTopRightValue()));
255 m_form->monitorChangeDefaultEdge(ElectricRight, KWinScreenEdgesConfig::electricBorderActionFromString(m_data->settings()->defaultRightValue()));
256 m_form->monitorChangeDefaultEdge(ElectricBottomRight, KWinScreenEdgesConfig::electricBorderActionFromString(m_data->settings()->defaultBottomRightValue()));
257 m_form->monitorChangeDefaultEdge(ElectricBottom, KWinScreenEdgesConfig::electricBorderActionFromString(m_data->settings()->defaultBottomValue()));
258 m_form->monitorChangeDefaultEdge(ElectricBottomLeft, KWinScreenEdgesConfig::electricBorderActionFromString(m_data->settings()->defaultBottomLeftValue()));
259 m_form->monitorChangeDefaultEdge(ElectricLeft, KWinScreenEdgesConfig::electricBorderActionFromString(m_data->settings()->defaultLeftValue()));
260 m_form->monitorChangeDefaultEdge(ElectricTopLeft, KWinScreenEdgesConfig::electricBorderActionFromString(m_data->settings()->defaultTopLeftValue()));
261
262 // Load effect-specific actions:
263
264 // PresentWindows BorderActivateAll
265 m_form->monitorChangeDefaultEdge(m_data->settings()->defaultBorderActivateAllValue(), PresentWindowsAll);
266
267 // PresentWindows BorderActivate
268 m_form->monitorChangeDefaultEdge(m_data->settings()->defaultBorderActivatePresentWindowsValue(), PresentWindowsCurrent);
269
270 // PresentWindows BorderActivateClass
271 m_form->monitorChangeDefaultEdge(m_data->settings()->defaultBorderActivateClassValue(), PresentWindowsClass);
272
273 // Overview
274 m_form->monitorChangeDefaultEdge(m_data->settings()->defaultBorderActivateOverviewValue(), Overview);
275
276 // TabBox
277 m_form->monitorChangeDefaultEdge(m_data->settings()->defaultBorderActivateTabBoxValue(), TabBox);
278 // Alternative TabBox
279 m_form->monitorChangeDefaultEdge(m_data->settings()->defaultBorderAlternativeActivateValue(), TabBoxAlternative);
280}
281
282void KWinScreenEdgesConfig::monitorSaveSettings()
283{
284 // Save ElectricBorderActions
285 m_data->settings()->setTop(KWinScreenEdgesConfig::electricBorderActionToString(m_form->selectedEdgeItem(ElectricTop)));
286 m_data->settings()->setTopRight(KWinScreenEdgesConfig::electricBorderActionToString(m_form->selectedEdgeItem(ElectricTopRight)));
287 m_data->settings()->setRight(KWinScreenEdgesConfig::electricBorderActionToString(m_form->selectedEdgeItem(ElectricRight)));
288 m_data->settings()->setBottomRight(KWinScreenEdgesConfig::electricBorderActionToString(m_form->selectedEdgeItem(ElectricBottomRight)));
289 m_data->settings()->setBottom(KWinScreenEdgesConfig::electricBorderActionToString(m_form->selectedEdgeItem(ElectricBottom)));
290 m_data->settings()->setBottomLeft(KWinScreenEdgesConfig::electricBorderActionToString(m_form->selectedEdgeItem(ElectricBottomLeft)));
291 m_data->settings()->setLeft(KWinScreenEdgesConfig::electricBorderActionToString(m_form->selectedEdgeItem(ElectricLeft)));
292 m_data->settings()->setTopLeft(KWinScreenEdgesConfig::electricBorderActionToString(m_form->selectedEdgeItem(ElectricTopLeft)));
293
294 // Save effect-specific actions:
295
296 // Present Windows
297 m_data->settings()->setBorderActivateAll(m_form->monitorCheckEffectHasEdge(PresentWindowsAll));
298 m_data->settings()->setBorderActivatePresentWindows(m_form->monitorCheckEffectHasEdge(PresentWindowsCurrent));
299 m_data->settings()->setBorderActivateClass(m_form->monitorCheckEffectHasEdge(PresentWindowsClass));
300
301 // Overview
302 m_data->settings()->setBorderActivateOverview(m_form->monitorCheckEffectHasEdge(Overview));
303
304 // TabBox
305 m_data->settings()->setBorderActivateTabBox(m_form->monitorCheckEffectHasEdge(TabBox));
306 m_data->settings()->setBorderAlternativeActivate(m_form->monitorCheckEffectHasEdge(TabBoxAlternative));
307
308 // Dinamically loaded effects
309 int lastIndex = EffectCount;
310 for (int i = 0; i < m_effects.size(); i++) {
311 m_effectSettings[m_effects[i]]->setBorderActivate(m_form->monitorCheckEffectHasEdge(lastIndex));
312 ++lastIndex;
313 }
314
315 // Scripts
316 for (int i = 0; i < m_scripts.size(); i++) {
317 m_scriptSettings[m_scripts[i]]->setBorderActivate(m_form->monitorCheckEffectHasEdge(lastIndex));
318 ++lastIndex;
319 }
320}
321
322void KWinScreenEdgesConfig::monitorShowEvent()
323{
324 // Check if they are enabled
325 KConfigGroup config(m_config, QStringLiteral("Plugins"));
326
327 // Present Windows
328 bool enabled = config.readEntry("windowviewEnabled", true);
329 m_form->monitorItemSetEnabled(PresentWindowsCurrent, enabled);
330 m_form->monitorItemSetEnabled(PresentWindowsAll, enabled);
331
332 // Overview
333 m_form->monitorItemSetEnabled(Overview, config.readEntry("overviewEnabled", true));
334
335 // tabbox, depends on reasonable focus policy.
336 KConfigGroup config2(m_config, QStringLiteral("Windows"));
337 QString focusPolicy = config2.readEntry("FocusPolicy", QString());
338 bool reasonable = focusPolicy != "FocusStrictlyUnderMouse" && focusPolicy != "FocusUnderMouse";
339 m_form->monitorItemSetEnabled(TabBox, reasonable);
340 m_form->monitorItemSetEnabled(TabBoxAlternative, reasonable);
341
342 // Disable Edge if ElectricBorders group entries are immutable
343 m_form->monitorEnableEdge(ElectricTop, !m_data->settings()->isTopImmutable());
344 m_form->monitorEnableEdge(ElectricTopRight, !m_data->settings()->isTopRightImmutable());
345 m_form->monitorEnableEdge(ElectricRight, !m_data->settings()->isRightImmutable());
346 m_form->monitorEnableEdge(ElectricBottomRight, !m_data->settings()->isBottomRightImmutable());
347 m_form->monitorEnableEdge(ElectricBottom, !m_data->settings()->isBottomImmutable());
348 m_form->monitorEnableEdge(ElectricBottomLeft, !m_data->settings()->isBottomLeftImmutable());
349 m_form->monitorEnableEdge(ElectricLeft, !m_data->settings()->isLeftImmutable());
350 m_form->monitorEnableEdge(ElectricTopLeft, !m_data->settings()->isTopLeftImmutable());
351
352 // Disable ElectricBorderCornerRatio if entry is immutable
353 m_form->setElectricBorderCornerRatioEnabled(!m_data->settings()->isElectricBorderCornerRatioImmutable());
354}
355
356ElectricBorderAction KWinScreenEdgesConfig::electricBorderActionFromString(const QString &string)
357{
358 QString lowerName = string.toLower();
359 if (lowerName == QStringLiteral("showdesktop")) {
361 }
362 if (lowerName == QStringLiteral("lockscreen")) {
364 }
365 if (lowerName == QStringLiteral("krunner")) {
367 }
368 if (lowerName == QStringLiteral("activitymanager")) {
370 }
371 if (lowerName == QStringLiteral("applicationlauncher")) {
373 }
374 return ElectricActionNone;
375}
376
377QString KWinScreenEdgesConfig::electricBorderActionToString(int action)
378{
379 switch (action) {
380 case 1:
381 return QStringLiteral("ShowDesktop");
382 case 2:
383 return QStringLiteral("LockScreen");
384 case 3:
385 return QStringLiteral("KRunner");
386 case 4:
387 return QStringLiteral("ActivityManager");
388 case 5:
389 return QStringLiteral("ApplicationLauncher");
390 default:
391 return QStringLiteral("None");
392 }
393}
394
395} // namespace
396
397#include "main.moc"
398
399#include "moc_main.cpp"
K_PLUGIN_FACTORY_WITH_JSON(KCMKWinDecorationFactory, "kcm_kwindecoration.json", registerPlugin< KCMKWinDecoration >();registerPlugin< KWinDecorationData >();) namespace
Definition kcm.cpp:29
ElectricBorderAction
Definition globals.h:78
@ ElectricActionActivityManager
Definition globals.h:83
@ ElectricActionLockScreen
Definition globals.h:81
@ ElectricActionNone
Definition globals.h:79
@ ElectricActionApplicationLauncher
Definition globals.h:84
@ ElectricActionKRunner
Definition globals.h:82
@ ElectricActionShowDesktop
Definition globals.h:80
EffectsHandler * effects