Commit 7bffadad authored by Mikhail Zolotukhin's avatar Mikhail Zolotukhin
Browse files

Sync titlebar button appearance with GTK CSD apps

Currently GTK applications with Client Side Decorations always use
decorations from the respected GTK CSS theme. Because of CSS nature
different themes may handle decorations in the headerbars differently,
therefore making modifying them via user css a very hard task. However,
what we can do is to use decoration appearance syncing in our own theme
- Breeze GTK.

Breeze GTK uses svg images for the representation of decoration
buttons (close, minimize, maximize) appearance. So to achieve the goal
what we do is the following:

1. We ask KWin to render current decoration buttons to custom QPainters.
   For each button we must export every state (clicked, hovered, normal, inactive).
2. QPainters then export decoration buttons to svg's.
3. Then we save those images to assets folder in
   `~/.config/gtk-3.0/assets`
4. Then we create custom .css for Breeze GTK, that tells the theme
   to use these saved images for decorations.

All of the above is only done if the...
parent c16c9c14
......@@ -5,14 +5,17 @@ cmake_minimum_required(VERSION 3.10)
find_package(ECM REQUIRED NO_MODULE)
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules" ${ECM_MODULE_PATH})
find_package(Qt5 REQUIRED NO_MODULE COMPONENTS DBus)
find_package(Qt5 REQUIRED NO_MODULE COMPONENTS DBus Svg)
find_package(KF5CoreAddons REQUIRED)
find_package(KF5Config REQUIRED)
find_package(KF5ConfigWidgets REQUIRED)
find_package(KF5GuiAddons REQUIRED)
find_package(KF5DBusAddons REQUIRED)
find_package(KF5Service REQUIRED)
find_package(PkgConfig REQUIRED)
find_package(KDecoration2 REQUIRED)
find_package(GSettingSchemas REQUIRED)
find_package(Sass REQUIRED)
find_package(XSettingsd)
pkg_check_modules(GTK+3 REQUIRED IMPORTED_TARGET gtk+-3.0)
......@@ -37,12 +40,19 @@ set_package_properties(XSettingsd PROPERTIES
PURPOSE "Required to apply settings to GTK applications on the fly"
)
set_package_properties(Sass PROPERTIES
DESCRIPTION "SASS compiler"
URL "https://sass-lang.com/"
PURPOSE "Required for building a modification, that allows Breeze GTK to change it's window decorations' appearance"
)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.cmake kded/config.h)
add_subdirectory(gtk3proxies)
add_subdirectory(kded)
add_subdirectory(kconf_update)
add_subdirectory(color-reload-module)
add_subdirectory(window-decorations-reload-module)
# add clang-format target for all our real source files
file(GLOB_RECURSE ALL_CLANG_FORMAT_SOURCE_FILES *.cpp *.h)
......
......@@ -28,7 +28,7 @@ The daemon itself does the following:
- 🧰 Toolbar Style
- 📜 Scrollbar behavior on click
- 🌓 Dark Theme Preference (Depending on a color scheme set in Colors KCM)
- ❎ Decorations button order
- ❎ Decorations button order (all GTK themes) and appearance (Breeze GTK theme only)
- 🏃 Animations (Enable/Disable)
- 🎨 Color Scheme (Breeze GTK theme only)
......
#.rst:
# FindSass
# -----------
#
# Try to find Sass compiler.
#
# If the Sass compiler executable is not in your PATH, you can provide
# an alternative name or full path location with the ``Sass_EXECUTABLE`` variable.
# In this case, do not forget to set ``Sass_COMPILER_TYPE`` variable also.
#
# This will define the following variables:
#
# ``Sass_FOUND``
# True if sass is available.
#
# ``Sass_EXECUTABLE``
# The Sass compiler executable.
#
# ``Sass_COMPILER_TYPE``
# Sass compiler type: ``sass`` or ``sassc``.
#
# If ``Sass_FOUND`` is TRUE, it will also define the following imported
# target:
#
# ``Sass::Sass``
# The Sass compiler executable.
#
#=============================================================================
# Copyright 2018 Alexander Kernozhitsky <sh200105@mail.ru>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#=============================================================================
find_program(Sass_EXECUTABLE NAMES sassc)
if(Sass_EXECUTABLE)
if(NOT Sass_COMPILER_TYPE)
set(Sass_COMPILER_TYPE sassc)
endif()
else()
find_program(Sass_EXECUTABLE NAMES sass)
set(Sass_COMPILER_TYPE sass)
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Sass
FOUND_VAR
Sass_FOUND
REQUIRED_VARS
Sass_EXECUTABLE
)
mark_as_advanced(Sass_EXECUTABLE)
if (Sass_FOUND)
if (NOT TARGET Sass::Sass)
add_executable(Sass::Sass IMPORTED)
set_target_properties(Sass::Sass PROPERTIES
IMPORTED_LOCATION "${Sass_EXECUTABLE}"
)
endif()
endif()
add_subdirectory(kwin_bridge)
add_subdirectory(scss)
set(kscreen_daemon_SRCS
gtkconfig.cpp
configeditor.cpp
......@@ -19,14 +22,17 @@ target_include_directories(gtkconfig
)
target_link_libraries(gtkconfig
PRIVATE
KWinBridge
PUBLIC
Qt5::DBus
Qt5::Svg
KF5::CoreAddons
KF5::ConfigCore
KF5::ConfigWidgets
KF5::DBusAddons
PkgConfig::GTK+3
KF5::GuiAddons
PkgConfig::GTK+3
PkgConfig::GIO
PkgConfig::GObject
)
......
......@@ -106,9 +106,22 @@ void ConfigEditor::setGtk2ConfigValue(const QString &paramName, const QVariant &
gtkrc.write(gtkrcContents.toUtf8());
}
void ConfigEditor::setCustomClientSideDecorations(const QStringList &windowDecorationsButtonsImages)
{
saveWindowDecorationsToAssets(windowDecorationsButtonsImages);
addWindowDecorationsCssFile();
addImportStatementsToGtkCssUserFile();
addGtkModule(QStringLiteral("window-decorations-gtk-module"));
}
void ConfigEditor::disableCustomClientSideDecorations()
{
removeDecorationsImportStatementFromGtkCssUserFile();
}
void ConfigEditor::setGtk3Colors(const QMap<QString, QColor> &colorsDefinitions)
{
addImportStatementToGtkCssUserFile();
addImportStatementsToGtkCssUserFile();
modifyColorsCssFile(colorsDefinitions);
addGtkModule(QStringLiteral("colorreload-gtk-module"));
}
......@@ -152,6 +165,30 @@ void ConfigEditor::removeLegacyGtk2Strings()
gtkrc.write(gtkrcContents.toUtf8());
}
void ConfigEditor::saveWindowDecorationsToAssets(const QStringList &windowDecorationsButtonsImages)
{
QDir assetsFolder {QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + QStringLiteral("/gtk-3.0/assets")};
if (!assetsFolder.exists()) {
assetsFolder.mkpath(QStringLiteral("."));
}
for (const auto &buttonImagePath : windowDecorationsButtonsImages) {
const QString destination = assetsFolder.path() + '/' + QFileInfo(buttonImagePath).fileName();
QFile(destination).remove();
QFile(buttonImagePath).rename(buttonImagePath, destination);
}
}
void ConfigEditor::addWindowDecorationsCssFile()
{
QFile windowDecorationsCss {QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("/themes/Breeze/window_decorations.css"))};
QString windowDecorationsDestination {QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + QStringLiteral("/gtk-3.0/window_decorations.css")};
QFile(windowDecorationsDestination).remove();
windowDecorationsCss.copy(windowDecorationsDestination);
}
void ConfigEditor::addGtkModule(const QString& moduleName)
{
const QString currentModulesString = gtk3ConfigValueSettingsIni(QStringLiteral("gtk-modules"));
......@@ -167,19 +204,46 @@ void ConfigEditor::addGtkModule(const QString& moduleName)
}
}
void ConfigEditor::addImportStatementToGtkCssUserFile()
void ConfigEditor::addImportStatementsToGtkCssUserFile()
{
QString gtkCssPath = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + QStringLiteral("/gtk-3.0/gtk.css");
QFile gtkCss(gtkCssPath);
if (gtkCss.open(QIODevice::ReadWrite)) {
QByteArray gtkCssContents = gtkCss.readAll();
QByteArray gtkCssContents = gtkCss.readAll().trimmed();
static const QByteArray importStatement = QByteArrayLiteral("@import 'colors.css';");
if (!gtkCssContents.contains(importStatement)) {
QTextStream gtkCssStream(&gtkCss);
gtkCssStream << importStatement;
static const QVector<QByteArray> importStatements {
QByteArrayLiteral("\n@import 'colors.css';"),
QByteArrayLiteral("\n@import 'window_decorations.css';"),
};
for (const auto &statement : importStatements) {
if (!gtkCssContents.contains(statement.trimmed())) {
gtkCssContents.append(statement);
}
}
gtkCss.remove();
gtkCss.open(QIODevice::WriteOnly | QIODevice::Text);
gtkCss.write(gtkCssContents);
}
}
void ConfigEditor::removeDecorationsImportStatementFromGtkCssUserFile()
{
QString gtkCssPath = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + QStringLiteral("/gtk-3.0/gtk.css");
QFile gtkCss(gtkCssPath);
if (gtkCss.open(QIODevice::ReadWrite)) {
QByteArray gtkCssContents = gtkCss.readAll().trimmed();
static const QByteArray importStatement = QByteArrayLiteral("\n@import 'window_decorations.css';");
gtkCssContents.replace(importStatement.trimmed(), QByteArray());
gtkCss.remove();
gtkCss.open(QIODevice::WriteOnly | QIODevice::Text);
gtkCss.write(gtkCssContents);
}
}
......
......@@ -35,15 +35,22 @@ namespace ConfigEditor
void setGtk3ConfigValueSettingsIni(const QString &paramName, const QVariant &paramValue);
void setGtk3ConfigValueXSettingsd(const QString &paramName, const QVariant &paramValue);
void setCustomClientSideDecorations(const QStringList &windowDecorationsButtonsImages);
void disableCustomClientSideDecorations();
void setGtk3Colors(const QMap<QString, QColor> &colorsDefinitions);
QString gtk3ConfigValueSettingsIni(const QString& paramName);
void removeLegacyGtk2Strings();
void saveWindowDecorationsToAssets(const QStringList &windowDecorationsButtonsImages);
void addWindowDecorationsCssFile();
void addGtkModule(const QString &moduleName);
void addImportStatementToGtkCssUserFile();
void addImportStatementsToGtkCssUserFile();
void removeDecorationsImportStatementFromGtkCssUserFile();
void modifyColorsCssFile(const QMap<QString, QColor> &colorsDefinitions);
void replaceValueInGtkrcContents(QString &gtkrcContents, const QString &paramName, const QVariant &paramValue);
......
......@@ -23,6 +23,8 @@
#include <QColor>
#include <QMap>
#include <QList>
#include <QSvgGenerator>
#include <QDir>
#include <KConfig>
#include <KSharedConfig>
......@@ -32,6 +34,7 @@
#include <gtk/gtk.h>
#include "decorationpainter.h"
#include "configvalueprovider.h"
ConfigValueProvider::ConfigValueProvider() :
......@@ -179,6 +182,54 @@ bool ConfigValueProvider::preferDarkTheme() const
return windowBackgroundGray < 192;
}
QStringList ConfigValueProvider::windowDecorationsButtonsImages() const
{
static const QVector<QString> buttonTypes {
QStringLiteral("close"),
QStringLiteral("maximize"),
QStringLiteral("maximized"),
QStringLiteral("minimize"),
};
static const QVector<QString> buttonStates {
// Focused titlebars
QStringLiteral("normal"),
QStringLiteral("active"), // aka pressed
QStringLiteral("hover"),
// Unfocused titlebars
QStringLiteral("backdrop-normal"),
QStringLiteral("backdrop-active"),
QStringLiteral("backdrop-hover"),
};
KConfigGroup decorationGroup = kwinConfig->group(QStringLiteral("org.kde.kdecoration2"));
const QString themeName = decorationGroup.readEntry(QStringLiteral("theme"), QStringLiteral("Breeze"));
auto decorationPainter = DecorationPainter::fromThemeName(themeName);
QStringList decorationsImages {};
for (const auto &buttonType : buttonTypes) {
for (const auto &buttonState : buttonStates) {
QSvgGenerator svgGenerator {};
const QString fileDirPath = QDir::tempPath() + QStringLiteral("/plasma-csd-generator");
QDir(fileDirPath).mkpath(QStringLiteral("."));
QString filePath = QStringLiteral("%1/%2-%3.svg").arg(fileDirPath, buttonType, buttonState);
svgGenerator.setFileName(filePath);
svgGenerator.setViewBox(DecorationPainter::ButtonGeometry);
QPainter painter {&svgGenerator};
decorationPainter->paintButton(painter, buttonType, buttonState);
painter.end();
decorationsImages.append(filePath);
}
}
return decorationsImages;
}
QString ConfigValueProvider::windowDecorationsButtonsOrder() const
{
KConfigGroup configGroup = kwinConfig->group(QStringLiteral("org.kde.kdecoration2"));
......
......@@ -40,12 +40,14 @@ public:
bool scrollbarBehavior() const;
bool preferDarkTheme() const;
QString windowDecorationsButtonsOrder() const;
QStringList windowDecorationsButtonsImages() const;
bool enableAnimations() const;
QMap<QString, QColor> colors() const;
private:
QString fontStyleHelper(const QFont &font) const;
QString windowDecorationButtonsOrderInGtkNotation(const QString &kdeConfigValue) const;
QString currentWindowDecorationPluginPath() const;
KSharedConfigPtr kdeglobalsConfig;
KSharedConfigPtr inputConfig;
......
......@@ -40,7 +40,8 @@ GtkConfig::GtkConfig(QObject *parent, const QVariantList&) :
themePreviewer(new ThemePreviewer(this)),
kdeglobalsConfigWatcher(KConfigWatcher::create(KSharedConfig::openConfig(QStringLiteral("kdeglobals")))),
kwinConfigWatcher(KConfigWatcher::create(KSharedConfig::openConfig(QStringLiteral("kwinrc")))),
kcminputConfigWatcher(KConfigWatcher::create(KSharedConfig::openConfig(QStringLiteral("kcminputrc"))))
kcminputConfigWatcher(KConfigWatcher::create(KSharedConfig::openConfig(QStringLiteral("kcminputrc")))),
breezeConfigWatcher(KConfigWatcher::create(KSharedConfig::openConfig(QStringLiteral("breezerc"))))
{
QDBusConnection dbus = QDBusConnection::sessionBus();
dbus.registerService(QStringLiteral("org.kde.GtkConfig"));
......@@ -49,6 +50,7 @@ GtkConfig::GtkConfig(QObject *parent, const QVariantList&) :
connect(kdeglobalsConfigWatcher.data(), &KConfigWatcher::configChanged, this, &GtkConfig::onKdeglobalsSettingsChange);
connect(kwinConfigWatcher.data(), &KConfigWatcher::configChanged, this, &GtkConfig::onKWinSettingsChange);
connect(kcminputConfigWatcher.data(), &KConfigWatcher::configChanged, this, &GtkConfig::onKCMInputSettingsChange);
connect(breezeConfigWatcher.data(), &KConfigWatcher::configChanged, this, &GtkConfig::onBreezeSettingsChange);
ConfigEditor::removeLegacyGtk2Strings();
applyAllSettings();
......@@ -67,6 +69,9 @@ void GtkConfig::setGtkTheme(const QString &themeName) const
ConfigEditor::setGtk3ConfigValueGSettings(QStringLiteral("gtk-theme"), themeName);
ConfigEditor::setGtk3ConfigValueSettingsIni(QStringLiteral("gtk-theme-name"), themeName);
ConfigEditor::setGtk3ConfigValueXSettingsd(QStringLiteral("Net/ThemeName"), themeName);
// Window decorations are part of the theme, in case of Breeze we inject custom ones from KWin
setWindowDecorationsAppearance();
}
QString GtkConfig::gtkTheme() const
......@@ -154,6 +159,16 @@ void GtkConfig::setDarkThemePreference() const
ConfigEditor::setGtk3ConfigValueSettingsIni(QStringLiteral("gtk-application-prefer-dark-theme"), preferDarkTheme);
}
void GtkConfig::setWindowDecorationsAppearance() const
{
if (gtkTheme() == QStringLiteral("Breeze")) { // Only Breeze GTK supports custom decoration buttons
const auto windowDecorationsButtonsImages = configValueProvider->windowDecorationsButtonsImages();
ConfigEditor::setCustomClientSideDecorations(windowDecorationsButtonsImages);
} else {
ConfigEditor::disableCustomClientSideDecorations();
}
}
void GtkConfig::setWindowDecorationsButtonsOrder() const
{
const QString windowDecorationsButtonOrder = configValueProvider->windowDecorationsButtonsOrder();
......@@ -188,6 +203,7 @@ void GtkConfig::applyAllSettings() const
setToolbarStyle();
setScrollbarBehavior();
setDarkThemePreference();
setWindowDecorationsAppearance();
setWindowDecorationsButtonsOrder();
setEnableAnimations();
setColors();
......@@ -219,6 +235,7 @@ void GtkConfig::onKdeglobalsSettingsChange(const KConfigGroup &group, const QByt
if (names.contains(QByteArrayLiteral("ColorScheme"))) {
setColors();
setDarkThemePreference();
setWindowDecorationsAppearance(); // Decorations' color can depend on the current color scheme
}
} else if (group.name() == QStringLiteral("Toolbar style")) {
if (names.contains(QByteArrayLiteral("ToolButtonStyle"))) {
......@@ -229,9 +246,14 @@ void GtkConfig::onKdeglobalsSettingsChange(const KConfigGroup &group, const QByt
void GtkConfig::onKWinSettingsChange(const KConfigGroup &group, const QByteArrayList &names) const
{
if (group.name() == QStringLiteral("org.kde.kdecoration2")
&& (names.contains("ButtonsOnRight") || names.contains("ButtonsOnLeft"))) {
setWindowDecorationsButtonsOrder();
if (group.name() == QStringLiteral("org.kde.kdecoration2")) {
if (names.contains(QByteArrayLiteral("ButtonsOnRight"))
|| names.contains(QByteArrayLiteral("ButtonsOnLeft"))) {
setWindowDecorationsButtonsOrder();
}
if (names.contains(QByteArrayLiteral("theme"))) {
setWindowDecorationsAppearance();
}
}
}
......@@ -247,5 +269,13 @@ void GtkConfig::onKCMInputSettingsChange(const KConfigGroup& group, const QByteA
}
}
void GtkConfig::onBreezeSettingsChange(const KConfigGroup& group, const QByteArrayList& names) const
{
if (group.name() == QStringLiteral("Common")
&& names.contains("OutlineCloseButton")) {
setWindowDecorationsAppearance();
}
}
#include "gtkconfig.moc"
......@@ -46,6 +46,7 @@ public:
void setToolbarStyle() const;
void setScrollbarBehavior() const;
void setDarkThemePreference() const;
void setWindowDecorationsAppearance() const;
void setWindowDecorationsButtonsOrder() const;
void setEnableAnimations() const;
void setColors() const;
......@@ -60,6 +61,7 @@ public Q_SLOTS:
void onKdeglobalsSettingsChange(const KConfigGroup &group, const QByteArrayList &names) const;
void onKWinSettingsChange(const KConfigGroup &group, const QByteArrayList &names) const;
void onKCMInputSettingsChange(const KConfigGroup &group, const QByteArrayList &names) const;
void onBreezeSettingsChange(const KConfigGroup &group, const QByteArrayList &names) const;
private:
QScopedPointer<ConfigValueProvider> configValueProvider;
......@@ -67,4 +69,5 @@ private:
KConfigWatcher::Ptr kdeglobalsConfigWatcher;
KConfigWatcher::Ptr kwinConfigWatcher;
KConfigWatcher::Ptr kcminputConfigWatcher;
KConfigWatcher::Ptr breezeConfigWatcher;
};
add_library(KWinBridge STATIC
dummydecoratedclient.cpp
dummydecorationbridge.cpp
dummydecorationsettings.cpp
decorationpalette.cpp
decorationpainter.cpp
auroraedecorationpainter.cpp
standarddecorationpainter.cpp
)
target_link_libraries(KWinBridge
PUBLIC
KDecoration2::KDecoration
PRIVATE
KDecoration2::KDecoration2Private
KF5::Service
KF5::ConfigWidgets
Qt5::Svg
)
/*
* Copyright 2020 Mikhail Zolotukhin <zomial@protonmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License or (at your option) version 3 or any later version
* accepted by the membership of KDE e.V. (or its successor approved
* by the membership of KDE e.V.), which shall act as a proxy
* defined in Section 14 of version 3 of the license.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <QFile>
#include <QStandardPaths>
#include <QSvgRenderer>
#include "auroraedecorationpainter.h"
const QString AuroraeDecorationPainter::s_auroraeThemesPath = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("/aurorae/themes/");
AuroraeDecorationPainter::AuroraeDecorationPainter(const QString& themeName)
: DecorationPainter()
, m_themeName(themeName)
, m_themePath(s_auroraeThemesPath + themeName + '/')
{
}
void AuroraeDecorationPainter::paintButton(QPainter &painter, const QString &buttonType, const QString &buttonState) const
{
const QString buttonFileName = buttonTypeToFileName(buttonType);
const QString elementIdName = buttonStateToElementId(buttonState);
QSvgRenderer buttonRenderer {m_themePath + buttonFileName};
buttonRenderer.render(&painter, elementIdName, DecorationPainter::ButtonGeometry);
}
QString AuroraeDecorationPainter::buttonTypeToFileName(const QString &buttonType) const
{
if (buttonType == QStringLiteral("maximized")) {
static const QString restoreButtonFileName = QStringLiteral("restore.svg");
if (QFile(m_themePath + restoreButtonFileName).exists()) {
return restoreButtonFileName;
} else {
return QStringLiteral("maximize.svg");
}
} else {
return buttonType + QStringLiteral(".svg");
}
}
QString AuroraeDecorationPainter::buttonStateToElementId(const QString& buttonState) const
{
// Aurorae themes do not contain pressed and hovered inactive states,
// so we put backdrop option to the end, so that first we use pressed and hover ones
if (buttonState.contains(QStringLiteral("active"))) {
return QStringLiteral("pressed-center");
} else if (buttonState.contains(QStringLiteral("hover"))) {
return QStringLiteral("hover-center");
} else if (buttonState.contains(QStringLiteral("backdrop"))) {
return QStringLiteral("inactive-center");
} else {
return QStringLiteral("active-center");
}
}
/*
* Copyright 2020 Mikhail Zolotukhin <zomial@protonmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License or (at your option) version 3 or any later version
* accepted by the membership of KDE e.V. (or its successor approved
* by the membership of KDE e.V.), which shall act as a proxy
* defined in Section 14 of version 3 of the license.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <QString>
#include "decorationpainter.h"
class AuroraeDecorationPainter : public DecorationPainter
{