KWin
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
settings.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: 2014 Martin Gräßlin <mgraesslin@kde.org>
6
7 SPDX-License-Identifier: GPL-2.0-or-later
8*/
9#include <config-kwin.h>
10
11#include "appmenu.h"
12#include "compositor.h"
13#include "decorationbridge.h"
14#include "settings.h"
15#include "virtualdesktops.h"
16#include "workspace.h"
17
18#include <KConfigGroup>
19#include <KDecoration2/DecorationSettings>
20
21#include <QFontDatabase>
22
23namespace KWin
24{
25namespace Decoration
26{
27SettingsImpl::SettingsImpl(KDecoration2::DecorationSettings *parent)
28 : QObject()
29 , DecorationSettingsPrivate(parent)
30 , m_borderSize(KDecoration2::BorderSize::Normal)
31{
32 readSettings();
33
35 parent, &KDecoration2::DecorationSettings::alphaChannelSupportedChanged);
36 connect(VirtualDesktopManager::self(), &VirtualDesktopManager::countChanged, this, [parent](uint previous, uint current) {
37 if (previous != 1 && current != 1) {
38 return;
39 }
40 Q_EMIT parent->onAllDesktopsAvailableChanged(current > 1);
41 });
42 // prevent changes in Decoration due to Compositor being destroyed
43 connect(Compositor::self(), &Compositor::aboutToDestroy, this, [c]() {
44 disconnect(c);
45 });
46 connect(Workspace::self(), &Workspace::configChanged, this, &SettingsImpl::readSettings);
47 connect(Workspace::self()->decorationBridge(), &DecorationBridge::metaDataLoaded, this, &SettingsImpl::readSettings);
48}
49
51
56
58{
59 return VirtualDesktopManager::self()->count() > 1;
60}
61
63{
64 return m_closeDoubleClickMenu;
65}
66
67static QHash<KDecoration2::DecorationButtonType, QChar> s_buttonNames;
68static void initButtons()
69{
70 if (!s_buttonNames.isEmpty()) {
71 return;
72 }
73 s_buttonNames[KDecoration2::DecorationButtonType::Menu] = QChar('M');
74 s_buttonNames[KDecoration2::DecorationButtonType::ApplicationMenu] = QChar('N');
75 s_buttonNames[KDecoration2::DecorationButtonType::OnAllDesktops] = QChar('S');
76 s_buttonNames[KDecoration2::DecorationButtonType::ContextHelp] = QChar('H');
77 s_buttonNames[KDecoration2::DecorationButtonType::Minimize] = QChar('I');
78 s_buttonNames[KDecoration2::DecorationButtonType::Maximize] = QChar('A');
79 s_buttonNames[KDecoration2::DecorationButtonType::Close] = QChar('X');
80 s_buttonNames[KDecoration2::DecorationButtonType::KeepAbove] = QChar('F');
81 s_buttonNames[KDecoration2::DecorationButtonType::KeepBelow] = QChar('B');
82 s_buttonNames[KDecoration2::DecorationButtonType::Shade] = QChar('L');
83 s_buttonNames[KDecoration2::DecorationButtonType::Spacer] = QChar('_');
84}
85
86static QString buttonsToString(const QList<KDecoration2::DecorationButtonType> &buttons)
87{
88 auto buttonToString = [](KDecoration2::DecorationButtonType button) -> QChar {
89 const auto it = s_buttonNames.constFind(button);
90 if (it != s_buttonNames.constEnd()) {
91 return it.value();
92 }
93 return QChar();
94 };
95 QString ret;
96 for (auto button : buttons) {
97 ret.append(buttonToString(button));
98 }
99 return ret;
100}
101
102QList<KDecoration2::DecorationButtonType> SettingsImpl::readDecorationButtons(const KConfigGroup &config,
103 const char *key,
104 const QList<KDecoration2::DecorationButtonType> &defaultValue) const
105{
106 initButtons();
107 auto buttonsFromString = [](const QString &buttons) -> QList<KDecoration2::DecorationButtonType> {
108 QList<KDecoration2::DecorationButtonType> ret;
109 for (auto it = buttons.begin(); it != buttons.end(); ++it) {
110 for (auto it2 = s_buttonNames.constBegin(); it2 != s_buttonNames.constEnd(); ++it2) {
111 if (it2.value() == (*it)) {
112 ret << it2.key();
113 }
114 }
115 }
116 return ret;
117 };
118 return buttonsFromString(config.readEntry(key, buttonsToString(defaultValue)));
119}
120
121static KDecoration2::BorderSize stringToSize(const QString &name)
122{
123 static const QMap<QString, KDecoration2::BorderSize> s_sizes = QMap<QString, KDecoration2::BorderSize>({{QStringLiteral("None"), KDecoration2::BorderSize::None},
124 {QStringLiteral("NoSides"), KDecoration2::BorderSize::NoSides},
125 {QStringLiteral("Tiny"), KDecoration2::BorderSize::Tiny},
126 {QStringLiteral("Normal"), KDecoration2::BorderSize::Normal},
127 {QStringLiteral("Large"), KDecoration2::BorderSize::Large},
128 {QStringLiteral("VeryLarge"), KDecoration2::BorderSize::VeryLarge},
129 {QStringLiteral("Huge"), KDecoration2::BorderSize::Huge},
130 {QStringLiteral("VeryHuge"), KDecoration2::BorderSize::VeryHuge},
131 {QStringLiteral("Oversized"), KDecoration2::BorderSize::Oversized}});
132 auto it = s_sizes.constFind(name);
133 if (it == s_sizes.constEnd()) {
134 // non sense values are interpreted just like normal
135 return KDecoration2::BorderSize::Normal;
136 }
137 return it.value();
138}
139
140void SettingsImpl::readSettings()
141{
142 KConfigGroup config = kwinApp()->config()->group(QStringLiteral("org.kde.kdecoration2"));
143 const auto &left = readDecorationButtons(config, "ButtonsOnLeft", QList<KDecoration2::DecorationButtonType>({KDecoration2::DecorationButtonType::Menu, KDecoration2::DecorationButtonType::OnAllDesktops}));
144 if (left != m_leftButtons) {
145 m_leftButtons = left;
146 Q_EMIT decorationSettings()->decorationButtonsLeftChanged(m_leftButtons);
147 }
148 const auto &right = readDecorationButtons(config, "ButtonsOnRight", QList<KDecoration2::DecorationButtonType>({KDecoration2::DecorationButtonType::ContextHelp, KDecoration2::DecorationButtonType::Minimize, KDecoration2::DecorationButtonType::Maximize, KDecoration2::DecorationButtonType::Close}));
149 if (right != m_rightButtons) {
150 m_rightButtons = right;
151 Q_EMIT decorationSettings()->decorationButtonsRightChanged(m_rightButtons);
152 }
153 Workspace::self()->applicationMenu()->setViewEnabled(left.contains(KDecoration2::DecorationButtonType::ApplicationMenu) || right.contains(KDecoration2::DecorationButtonType::ApplicationMenu));
154 const bool close = config.readEntry("CloseOnDoubleClickOnMenu", false);
155 if (close != m_closeDoubleClickMenu) {
156 m_closeDoubleClickMenu = close;
157 Q_EMIT decorationSettings()->closeOnDoubleClickOnMenuChanged(m_closeDoubleClickMenu);
158 }
159 m_autoBorderSize = config.readEntry("BorderSizeAuto", true);
160
161 auto size = stringToSize(config.readEntry("BorderSize", QStringLiteral("Normal")));
162 if (m_autoBorderSize) {
163 /* Falls back to Normal border size, if the plugin does not provide a valid recommendation. */
164 size = stringToSize(Workspace::self()->decorationBridge()->recommendedBorderSize());
165 }
166 if (size != m_borderSize) {
167 m_borderSize = size;
168 Q_EMIT decorationSettings()->borderSizeChanged(m_borderSize);
169 }
170 const QFont font = QFontDatabase::systemFont(QFontDatabase::TitleFont);
171 if (font != m_font) {
172 m_font = font;
173 Q_EMIT decorationSettings()->fontChanged(m_font);
174 }
175
176 Q_EMIT decorationSettings()->reconfigured();
177}
178
179}
180}
181
182#include "moc_settings.cpp"
void setViewEnabled(bool enabled)
Definition appmenu.cpp:54
void compositingToggled(bool active)
static bool compositing()
Static check to test whether the Compositor is available and active.
Definition compositor.h:78
static Compositor * self()
bool isCloseOnDoubleClickOnMenu() const override
Definition settings.cpp:62
SettingsImpl(KDecoration2::DecorationSettings *parent)
Definition settings.cpp:27
bool isOnAllDesktopsAvailable() const override
Definition settings.cpp:57
bool isAlphaChannelSupported() const override
Definition settings.cpp:52
QFont font() const override
Definition settings.h:43
void countChanged(uint previousCount, uint newCount)
ApplicationMenu * applicationMenu() const
static Workspace * self()
Definition workspace.h:91
void configChanged()
DecorationButtonsList buttonsFromString(const QString &buttons)
Definition utils.cpp:69