window: Create palette only when needed

Creating a `DecorationPalete` (e.g. the `KColorScheme` inside) is
relatively expensive. Currently, this is done once a client is mapped,
regardless of whether it actually has a server-side decoration.

This change makes it create the palette only when it is actually used,
e.g. the window indeed has a server-side decoration or when the user
actions menu is invoked.

Signed-off-by: Victoria Fischer <victoria.fischer@mbition.io>
This commit is contained in:
Kai Uwe Broulik 2022-08-22 08:20:51 +02:00 committed by Victoria Fischer
parent 8ca6170c91
commit b0423c32ac
2 changed files with 55 additions and 40 deletions

View file

@ -1417,16 +1417,15 @@ void Window::doMinimize()
{
}
QPalette Window::palette() const
QPalette Window::palette()
{
if (!m_palette) {
return QPalette();
}
ensurePalette();
return m_palette->palette();
}
const Decoration::DecorationPalette *Window::decorationPalette() const
const Decoration::DecorationPalette *Window::decorationPalette()
{
ensurePalette();
return m_palette.get();
}
@ -1447,40 +1446,22 @@ void Window::setColorScheme(const QString &colorScheme)
requestedColorScheme = QStringLiteral("kdeglobals");
}
if (!m_palette || m_colorScheme != requestedColorScheme) {
m_colorScheme = requestedColorScheme;
if (m_palette) {
disconnect(m_palette.get(), &Decoration::DecorationPalette::changed, this, &Window::handlePaletteChange);
}
auto it = s_palettes.find(m_colorScheme);
if (it == s_palettes.end() || it->expired()) {
m_palette = std::make_shared<Decoration::DecorationPalette>(m_colorScheme);
if (m_palette->isValid()) {
s_palettes[m_colorScheme] = m_palette;
} else {
if (!s_defaultPalette) {
s_defaultPalette = std::make_shared<Decoration::DecorationPalette>(QStringLiteral("kdeglobals"));
s_palettes[QStringLiteral("kdeglobals")] = s_defaultPalette;
}
m_palette = s_defaultPalette;
}
if (m_colorScheme == QStringLiteral("kdeglobals")) {
s_defaultPalette = m_palette;
}
} else {
m_palette = it->lock();
}
connect(m_palette.get(), &Decoration::DecorationPalette::changed, this, &Window::handlePaletteChange);
Q_EMIT paletteChanged(palette());
Q_EMIT colorSchemeChanged();
if (m_colorScheme == requestedColorScheme) {
return;
}
m_colorScheme = requestedColorScheme;
if (m_palette) {
disconnect(m_palette.get(), &Decoration::DecorationPalette::changed, this, &Window::handlePaletteChange);
m_palette.reset();
// If there already was a palette, re-create it right away
// so the signals for repainting the decoration are emitted.
ensurePalette();
}
Q_EMIT colorSchemeChanged();
}
void Window::updateColorScheme()
@ -1488,6 +1469,39 @@ void Window::updateColorScheme()
setColorScheme(preferredColorScheme());
}
void Window::ensurePalette()
{
if (m_palette) {
return;
}
auto it = s_palettes.find(m_colorScheme);
if (it == s_palettes.end() || it->expired()) {
m_palette = std::make_shared<Decoration::DecorationPalette>(m_colorScheme);
if (m_palette->isValid()) {
s_palettes[m_colorScheme] = m_palette;
} else {
if (!s_defaultPalette) {
s_defaultPalette = std::make_shared<Decoration::DecorationPalette>(QStringLiteral("kdeglobals"));
s_palettes[QStringLiteral("kdeglobals")] = s_defaultPalette;
}
m_palette = s_defaultPalette;
}
if (m_colorScheme == QStringLiteral("kdeglobals")) {
s_defaultPalette = m_palette;
}
} else {
m_palette = it->lock();
}
connect(m_palette.get(), &Decoration::DecorationPalette::changed, this, &Window::handlePaletteChange);
handlePaletteChange();
}
void Window::handlePaletteChange()
{
Q_EMIT paletteChanged(palette());

View file

@ -1033,8 +1033,8 @@ public:
Q_INVOKABLE void setMaximize(bool vertically, bool horizontally);
virtual bool noBorder() const;
virtual void setNoBorder(bool set);
QPalette palette() const;
const Decoration::DecorationPalette *decorationPalette() const;
QPalette palette();
const Decoration::DecorationPalette *decorationPalette();
/**
* Returns whether the window is resizable or has a fixed size.
*/
@ -1658,6 +1658,7 @@ protected:
void setupWindowManagementInterface();
void updateColorScheme();
void ensurePalette();
void setTransientFor(Window *transientFor);
/**
* Just removes the @p cl from the transients without any further checks.