File indexing completed on 2024-10-13 13:11:20
0001 /* 0002 * SPDX-FileCopyrightText: 2019 Mikhail Zolotukhin <zomial@protonmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 */ 0006 0007 #include <QColor> 0008 #include <QDir> 0009 #include <QFont> 0010 #include <QList> 0011 #include <QMap> 0012 #include <QString> 0013 #include <QSvgGenerator> 0014 0015 #include <KColorScheme> 0016 #include <KColorUtils> 0017 #include <KConfig> 0018 #include <KConfigGroup> 0019 #include <KWindowSystem> 0020 0021 #include <gtk/gtk.h> 0022 0023 #include <algorithm> 0024 0025 #include "configvalueprovider.h" 0026 #include "decorationpainter.h" 0027 0028 constexpr int MAX_GDK_SCALE = 5; 0029 0030 constexpr int DEFAULT_DPI = 96; 0031 constexpr int MIN_FONT_DPI = DEFAULT_DPI / 2; 0032 constexpr int MAX_FONT_DPI = DEFAULT_DPI * 5; 0033 0034 ConfigValueProvider::ConfigValueProvider() 0035 : kdeglobalsConfig(KSharedConfig::openConfig()) 0036 , fontsConfig(KSharedConfig::openConfig(QStringLiteral("kcmfonts"))) 0037 , inputConfig(KSharedConfig::openConfig(QStringLiteral("kcminputrc"))) 0038 , kwinConfig(KSharedConfig::openConfig(QStringLiteral("kwinrc"))) 0039 , generatedCSDTempPath(QDir::tempPath() + QStringLiteral("/plasma-csd-generator")) 0040 { 0041 } 0042 0043 QString ConfigValueProvider::fontName() const 0044 { 0045 static const QFont defaultFont(QStringLiteral("Noto Sans"), 10); 0046 0047 KConfigGroup configGroup = kdeglobalsConfig->group(QStringLiteral("General")); 0048 QString fontAsString = configGroup.readEntry(QStringLiteral("font"), defaultFont.toString()); 0049 static QFont font; 0050 font.fromString(fontAsString); 0051 const QString fontStyle = fontStyleHelper(font); 0052 return font.family() + QStringLiteral(", ") + fontStyle + ' ' + QString::number(font.pointSize()); 0053 } 0054 0055 QString ConfigValueProvider::fontStyleHelper(const QFont &font) const 0056 { 0057 // BUG: 333146 0058 // Since Qt sometimes gives us wrong font style name, 0059 // we ought to use this big helper function to construct 0060 // the style ourselves. Some fonts will not work 0061 auto weight = font.weight(); 0062 QString result; 0063 if (weight > QFont::Normal) { 0064 if (weight >= QFont::Black) { 0065 result = QStringLiteral("Black"); 0066 } else if (weight >= QFont::ExtraBold) { 0067 result = QStringLiteral("Extra Bold"); 0068 } else if (weight >= QFont::Bold) { 0069 result = QStringLiteral("Bold"); 0070 } else if (weight >= QFont::DemiBold) { 0071 result = QStringLiteral("Demi Bold"); 0072 } else if (weight >= QFont::Medium) { 0073 result = QStringLiteral("Medium"); 0074 } 0075 } else { 0076 if (weight <= QFont::Thin) { 0077 result = QStringLiteral("Thin"); 0078 } else if (weight <= QFont::ExtraLight) { 0079 result = QStringLiteral("Extra Light"); 0080 } else if (weight <= QFont::Light) { 0081 result = QStringLiteral("Light"); 0082 } 0083 } 0084 0085 auto style = font.style(); 0086 if (style == QFont::StyleItalic) { 0087 result += QLatin1Char(' ') + QStringLiteral("Italic"); 0088 } else if (style == QFont::StyleOblique) { 0089 result += QLatin1Char(' ') + QStringLiteral("Oblique"); 0090 } 0091 0092 auto stretch = font.stretch(); 0093 if (stretch == QFont::UltraCondensed) { 0094 result += QLatin1Char(' ') + QStringLiteral("UltraCondensed"); 0095 } else if (stretch == QFont::ExtraCondensed) { 0096 result += QLatin1Char(' ') + QStringLiteral("ExtraCondensed"); 0097 } else if (stretch == QFont::Condensed) { 0098 result += QLatin1Char(' ') + QStringLiteral("Condensed"); 0099 } else if (stretch == QFont::SemiCondensed) { 0100 result += QLatin1Char(' ') + QStringLiteral("SemiCondensed"); 0101 } else if (stretch == QFont::Unstretched) { 0102 result += QLatin1Char(' ') + QStringLiteral("Unstretched"); 0103 } else if (stretch == QFont::SemiExpanded) { 0104 result += QLatin1Char(' ') + QStringLiteral("SemiExpanded"); 0105 } else if (stretch == QFont::Expanded) { 0106 result += QLatin1Char(' ') + QStringLiteral("Expanded"); 0107 } else if (stretch == QFont::ExtraExpanded) { 0108 result += QLatin1Char(' ') + QStringLiteral("ExtraExpanded"); 0109 } else if (stretch == QFont::UltraExpanded) { 0110 result += QLatin1Char(' ') + QStringLiteral("UltraExpanded"); 0111 } 0112 0113 return result.simplified(); 0114 } 0115 0116 QString ConfigValueProvider::iconThemeName() const 0117 { 0118 KConfigGroup configGroup = kdeglobalsConfig->group(QStringLiteral("Icons")); 0119 return configGroup.readEntry(QStringLiteral("Theme"), QStringLiteral("breeze")); 0120 } 0121 0122 QString ConfigValueProvider::cursorThemeName() const 0123 { 0124 KConfigGroup configGroup = inputConfig->group(QStringLiteral("Mouse")); 0125 return configGroup.readEntry(QStringLiteral("cursorTheme"), QStringLiteral("breeze_cursors")); 0126 } 0127 0128 int ConfigValueProvider::cursorSize() const 0129 { 0130 KConfigGroup configGroup = inputConfig->group(QStringLiteral("Mouse")); 0131 return configGroup.readEntry(QStringLiteral("cursorSize"), 24); 0132 } 0133 0134 bool ConfigValueProvider::iconsOnButtons() const 0135 { 0136 KConfigGroup configGroup = kdeglobalsConfig->group(QStringLiteral("KDE")); 0137 return configGroup.readEntry(QStringLiteral("ShowIconsOnPushButtons"), true); 0138 } 0139 0140 bool ConfigValueProvider::iconsInMenus() const 0141 { 0142 KConfigGroup configGroup = kdeglobalsConfig->group(QStringLiteral("KDE")); 0143 return configGroup.readEntry(QStringLiteral("ShowIconsInMenuItems"), true); 0144 } 0145 0146 int ConfigValueProvider::toolbarStyle() const 0147 { 0148 KConfigGroup configGroup = kdeglobalsConfig->group(QStringLiteral("Toolbar style")); 0149 QString kdeConfigValue = configGroup.readEntry(QStringLiteral("ToolButtonStyle"), "TextBesideIcon"); 0150 0151 if (kdeConfigValue == QStringLiteral("NoText")) { 0152 return GtkToolbarStyle::GTK_TOOLBAR_ICONS; 0153 } else if (kdeConfigValue == QStringLiteral("TextOnly")) { 0154 return GtkToolbarStyle::GTK_TOOLBAR_TEXT; 0155 } else if (kdeConfigValue == QStringLiteral("TextBesideIcon")) { 0156 return GtkToolbarStyle::GTK_TOOLBAR_BOTH_HORIZ; 0157 } else { 0158 return GtkToolbarStyle::GTK_TOOLBAR_BOTH; 0159 } 0160 } 0161 0162 bool ConfigValueProvider::scrollbarBehavior() const 0163 { 0164 KConfigGroup configGroup = kdeglobalsConfig->group(QStringLiteral("KDE")); 0165 bool kdeConfigValue = configGroup.readEntry(QStringLiteral("ScrollbarLeftClickNavigatesByPage"), true); 0166 return !kdeConfigValue; // GTK setting is inverted 0167 } 0168 0169 bool ConfigValueProvider::preferDarkTheme() const 0170 { 0171 KConfigGroup colorsConfigGroup = kdeglobalsConfig->group(QStringLiteral("Colors:Window")); 0172 QColor windowBackgroundColor = colorsConfigGroup.readEntry(QStringLiteral("BackgroundNormal"), QColor(239, 240, 241)); 0173 const int windowBackgroundGray = qGray(windowBackgroundColor.rgb()); 0174 0175 // We use heuristic to determine if current color scheme is dark or not 0176 return windowBackgroundGray < 192; 0177 } 0178 0179 QStringList ConfigValueProvider::windowDecorationsButtonsImages() const 0180 { 0181 static const QVector<QString> buttonTypes{ 0182 QStringLiteral("close"), 0183 QStringLiteral("maximize"), 0184 QStringLiteral("maximized"), 0185 QStringLiteral("minimize"), 0186 }; 0187 0188 static const QVector<QString> buttonStates{ 0189 // Focused titlebars 0190 QStringLiteral("normal"), 0191 QStringLiteral("active"), // aka pressed 0192 QStringLiteral("hover"), 0193 // Unfocused titlebars 0194 QStringLiteral("backdrop-normal"), 0195 QStringLiteral("backdrop-active"), 0196 QStringLiteral("backdrop-hover"), 0197 }; 0198 0199 KConfigGroup decorationGroup = kwinConfig->group(QStringLiteral("org.kde.kdecoration2")); 0200 const QString themeName = decorationGroup.readEntry(QStringLiteral("theme"), QStringLiteral("Breeze")); 0201 0202 auto decorationPainter = DecorationPainter::fromThemeName(themeName); 0203 QStringList decorationsImages{}; 0204 0205 for (const auto &buttonType : buttonTypes) { 0206 for (const auto &buttonState : buttonStates) { 0207 QSvgGenerator svgGenerator{}; 0208 0209 QString filePath = generatedCSDTempPath.filePath(QStringLiteral("%1-%2.svg").arg(buttonType, buttonState)); 0210 0211 svgGenerator.setFileName(filePath); 0212 svgGenerator.setViewBox(DecorationPainter::ButtonGeometry); 0213 0214 QPainter painter{&svgGenerator}; 0215 decorationPainter->paintButton(painter, buttonType, buttonState); 0216 painter.end(); 0217 0218 decorationsImages.append(filePath); 0219 } 0220 } 0221 0222 return decorationsImages; 0223 } 0224 0225 QString ConfigValueProvider::windowDecorationsButtonsOrder() const 0226 { 0227 KConfigGroup configGroup = kwinConfig->group(QStringLiteral("org.kde.kdecoration2")); 0228 QString buttonsOnLeftKdeConfigValue = configGroup.readEntry(QStringLiteral("ButtonsOnLeft"), "MS"); 0229 QString buttonsOnRightKdeConfigValue = configGroup.readEntry(QStringLiteral("ButtonsOnRight"), "HIAX"); 0230 0231 QString buttonsOnLeftInGtkNotation = windowDecorationButtonsOrderInGtkNotation(buttonsOnLeftKdeConfigValue); 0232 QString buttonsOnRightInGtkNotation = windowDecorationButtonsOrderInGtkNotation(buttonsOnRightKdeConfigValue); 0233 0234 return buttonsOnLeftInGtkNotation + QStringLiteral(":") + buttonsOnRightInGtkNotation; 0235 } 0236 0237 bool ConfigValueProvider::enableAnimations() const 0238 { 0239 KConfigGroup generalCfg = kdeglobalsConfig->group(QStringLiteral("KDE")); 0240 const qreal animationSpeedModifier = qMax(0.0, generalCfg.readEntry("AnimationDurationFactor", 1.0)); 0241 0242 return !qFuzzyIsNull(animationSpeedModifier); 0243 } 0244 0245 QMap<QString, QColor> ConfigValueProvider::colors() const 0246 { 0247 using KCS = KColorScheme; 0248 0249 // Color Schemes Collection 0250 QHash<QString, QHash<QString, KCS>> csc{ 0251 {QStringLiteral("active"), 0252 { 0253 {QStringLiteral("view"), KCS(QPalette::Active, KCS::View)}, 0254 {QStringLiteral("window"), KCS(QPalette::Active, KCS::Window)}, 0255 {QStringLiteral("button"), KCS(QPalette::Active, KCS::Button)}, 0256 {QStringLiteral("selection"), KCS(QPalette::Active, KCS::Selection)}, 0257 {QStringLiteral("tooltip"), KCS(QPalette::Active, KCS::Tooltip)}, 0258 {QStringLiteral("complementary"), KCS(QPalette::Active, KCS::Complementary)}, 0259 {QStringLiteral("header"), KCS(QPalette::Active, KCS::Header)}, 0260 }}, 0261 {QStringLiteral("inactive"), 0262 { 0263 {QStringLiteral("view"), KCS(QPalette::Inactive, KCS::View)}, 0264 {QStringLiteral("window"), KCS(QPalette::Inactive, KCS::Window)}, 0265 {QStringLiteral("button"), KCS(QPalette::Inactive, KCS::Button)}, 0266 {QStringLiteral("selection"), KCS(QPalette::Inactive, KCS::Selection)}, 0267 {QStringLiteral("tooltip"), KCS(QPalette::Inactive, KCS::Tooltip)}, 0268 {QStringLiteral("complementary"), KCS(QPalette::Inactive, KCS::Complementary)}, 0269 {QStringLiteral("header"), KCS(QPalette::Inactive, KCS::Header)}, 0270 }}, 0271 {QStringLiteral("disabled"), 0272 { 0273 {QStringLiteral("view"), KCS(QPalette::Disabled, KCS::View)}, 0274 {QStringLiteral("window"), KCS(QPalette::Disabled, KCS::Window)}, 0275 {QStringLiteral("button"), KCS(QPalette::Disabled, KCS::Button)}, 0276 {QStringLiteral("selection"), KCS(QPalette::Disabled, KCS::Selection)}, 0277 {QStringLiteral("tooltip"), KCS(QPalette::Disabled, KCS::Tooltip)}, 0278 {QStringLiteral("complementary"), KCS(QPalette::Disabled, KCS::Complementary)}, 0279 {QStringLiteral("header"), KCS(QPalette::Disabled, KCS::Header)}, 0280 }}, 0281 }; 0282 0283 // Color mixing 0284 QColor windowForegroundColor = csc["active"]["window"].foreground(KCS::NormalText).color(); 0285 QColor windowBackgroundColor = csc["active"]["window"].background(KCS::NormalBackground).color(); 0286 QColor bordersColor = KColorUtils::mix(windowBackgroundColor, windowForegroundColor, 0.25); 0287 0288 QColor inactiveWindowForegroundColor = csc["inactive"]["window"].foreground(KCS::NormalText).color(); 0289 QColor inactiveWindowBackgroundColor = csc["inactive"]["window"].background(KCS::NormalBackground).color(); 0290 QColor inactiveBordersColor = KColorUtils::mix(inactiveWindowBackgroundColor, inactiveWindowForegroundColor, 0.25); 0291 0292 QColor disabledWindowForegroundColor = csc["disabled"]["window"].foreground(KCS::NormalText).color(); 0293 QColor disabledWindowBackgroundColor = csc["disabled"]["window"].background(KCS::NormalBackground).color(); 0294 QColor disabledBordersColor = KColorUtils::mix(disabledWindowBackgroundColor, disabledWindowForegroundColor, 0.25); 0295 0296 QColor unfocusedDisabledWindowForegroundColor = csc["disabled"]["window"].foreground(KCS::NormalText).color(); 0297 QColor unfocusedDisabledWindowBackgroundColor = csc["disabled"]["window"].background(KCS::NormalBackground).color(); 0298 QColor unfocusedDisabledBordersColor = KColorUtils::mix(unfocusedDisabledWindowBackgroundColor, unfocusedDisabledWindowForegroundColor, 0.25); 0299 0300 QColor tooltipForegroundColor = csc["active"]["tooltip"].foreground(KCS::NormalText).color(); 0301 QColor tooltipBackgroundColor = csc["active"]["tooltip"].background(KCS::NormalBackground).color(); 0302 QColor tooltipBorderColor = KColorUtils::mix(tooltipBackgroundColor, tooltipForegroundColor, 0.25); 0303 0304 KConfigGroup windowManagerConfig = kdeglobalsConfig->group(QStringLiteral("WM")); 0305 0306 QMap<QString, QColor> result = { 0307 /* 0308 * Normal (Non Backdrop, Non Insensitive) 0309 */ 0310 0311 // General Colors 0312 {"theme_fg_color_breeze", csc["active"]["window"].foreground(KCS::NormalText).color()}, 0313 {"theme_bg_color_breeze", csc["active"]["window"].background(KCS::NormalBackground).color()}, 0314 {"theme_text_color_breeze", csc["active"]["view"].foreground(KCS::NormalText).color()}, 0315 {"theme_base_color_breeze", csc["active"]["view"].background(KCS::NormalBackground).color()}, 0316 {"theme_view_hover_decoration_color_breeze", csc["active"]["view"].decoration(KCS::HoverColor).color()}, 0317 {"theme_hovering_selected_bg_color_breeze", csc["active"]["selection"].decoration(KCS::HoverColor).color()}, 0318 {"theme_selected_bg_color_breeze", csc["active"]["selection"].background(KCS::NormalBackground).color()}, 0319 {"theme_selected_fg_color_breeze", csc["active"]["selection"].foreground(KCS::NormalText).color()}, 0320 {"theme_view_active_decoration_color_breeze", csc["active"]["view"].decoration(KCS::HoverColor).color()}, 0321 0322 // Button Colors 0323 {"theme_button_background_normal_breeze", csc["active"]["button"].background(KCS::NormalBackground).color()}, 0324 {"theme_button_decoration_hover_breeze", csc["active"]["button"].decoration(KCS::HoverColor).color()}, 0325 {"theme_button_decoration_focus_breeze", csc["active"]["button"].decoration(KCS::FocusColor).color()}, 0326 {"theme_button_foreground_normal_breeze", csc["active"]["button"].foreground(KCS::NormalText).color()}, 0327 {"theme_button_foreground_active_breeze", csc["active"]["selection"].foreground(KCS::NormalText).color()}, 0328 0329 // Misc Colors 0330 {"borders_breeze", bordersColor}, 0331 {"warning_color_breeze", csc["active"]["view"].foreground(KCS::NeutralText).color()}, 0332 {"success_color_breeze", csc["active"]["view"].foreground(KCS::PositiveText).color()}, 0333 {"error_color_breeze", csc["active"]["view"].foreground(KCS::NegativeText).color()}, 0334 0335 /* 0336 * Backdrop (Inactive) 0337 */ 0338 0339 // General 0340 {"theme_unfocused_fg_color_breeze", csc["inactive"]["window"].foreground(KCS::NormalText).color()}, 0341 {"theme_unfocused_text_color_breeze", csc["inactive"]["view"].foreground(KCS::NormalText).color()}, 0342 {"theme_unfocused_bg_color_breeze", csc["inactive"]["window"].background(KCS::NormalBackground).color()}, 0343 {"theme_unfocused_base_color_breeze", csc["inactive"]["view"].background(KCS::NormalBackground).color()}, 0344 {"theme_unfocused_selected_bg_color_alt_breeze", csc["inactive"]["selection"].background(KCS::NormalBackground).color()}, 0345 {"theme_unfocused_selected_bg_color_breeze", csc["inactive"]["selection"].background(KCS::NormalBackground).color()}, 0346 {"theme_unfocused_selected_fg_color_breeze", csc["inactive"]["selection"].foreground(KCS::NormalText).color()}, 0347 0348 // Button 0349 {"theme_button_background_backdrop_breeze", csc["inactive"]["button"].background(KCS::NormalBackground).color()}, 0350 {"theme_button_decoration_hover_backdrop_breeze", csc["inactive"]["button"].decoration(KCS::HoverColor).color()}, 0351 {"theme_button_decoration_focus_backdrop_breeze", csc["inactive"]["button"].decoration(KCS::FocusColor).color()}, 0352 {"theme_button_foreground_backdrop_breeze", csc["inactive"]["button"].foreground(KCS::NormalText).color()}, 0353 {"theme_button_foreground_active_backdrop_breeze", csc["inactive"]["selection"].foreground(KCS::NormalText).color()}, 0354 0355 // Misc Colors 0356 {"unfocused_borders_breeze", inactiveBordersColor}, 0357 {"warning_color_backdrop_breeze", csc["inactive"]["view"].foreground(KCS::NeutralText).color()}, 0358 {"success_color_backdrop_breeze", csc["inactive"]["view"].foreground(KCS::PositiveText).color()}, 0359 {"error_color_backdrop_breeze", csc["inactive"]["view"].foreground(KCS::NegativeText).color()}, 0360 0361 /* 0362 * Insensitive (Disabled) 0363 */ 0364 0365 // General 0366 {"insensitive_fg_color_breeze", csc["disabled"]["window"].foreground(KCS::NormalText).color()}, 0367 {"insensitive_base_fg_color_breeze", csc["disabled"]["view"].foreground(KCS::NormalText).color()}, 0368 {"insensitive_bg_color_breeze", csc["disabled"]["window"].background(KCS::NormalBackground).color()}, 0369 {"insensitive_base_color_breeze", csc["disabled"]["view"].background(KCS::NormalBackground).color()}, 0370 {"insensitive_selected_bg_color_breeze", csc["disabled"]["selection"].background(KCS::NormalBackground).color()}, 0371 {"insensitive_selected_fg_color_breeze", csc["disabled"]["selection"].foreground(KCS::NormalText).color()}, 0372 0373 // Button 0374 {"theme_button_background_insensitive_breeze", csc["disabled"]["button"].background(KCS::NormalBackground).color()}, 0375 {"theme_button_decoration_hover_insensitive_breeze", csc["disabled"]["button"].decoration(KCS::HoverColor).color()}, 0376 {"theme_button_decoration_focus_insensitive_breeze", csc["disabled"]["button"].decoration(KCS::FocusColor).color()}, 0377 {"theme_button_foreground_insensitive_breeze", csc["disabled"]["button"].foreground(KCS::NormalText).color()}, 0378 {"theme_button_foreground_active_insensitive_breeze", csc["disabled"]["selection"].foreground(KCS::NormalText).color()}, 0379 0380 // Misc Colors 0381 {"insensitive_borders_breeze", disabledBordersColor}, 0382 {"warning_color_insensitive_breeze", csc["disabled"]["view"].foreground(KCS::NeutralText).color()}, 0383 {"success_color_insensitive_breeze", csc["disabled"]["view"].foreground(KCS::PositiveText).color()}, 0384 {"error_color_insensitive_breeze", csc["disabled"]["view"].foreground(KCS::NegativeText).color()}, 0385 0386 /* 0387 * Insensitive Backdrop (Inactive Disabled) 0388 * These pretty much have the same appearance as regular inactive colors, 0389 * but they're separate in case we decide to make them different in the future. 0390 */ 0391 0392 // General 0393 {"insensitive_unfocused_fg_color_breeze", csc["disabled"]["window"].foreground(KCS::NormalText).color()}, 0394 {"theme_unfocused_view_text_color_breeze", csc["disabled"]["view"].foreground(KCS::NormalText).color()}, 0395 {"insensitive_unfocused_bg_color_breeze", csc["disabled"]["window"].background(KCS::NormalBackground).color()}, 0396 {"theme_unfocused_view_bg_color_breeze", csc["disabled"]["view"].background(KCS::NormalBackground).color()}, 0397 {"insensitive_unfocused_selected_bg_color_breeze", csc["disabled"]["selection"].background(KCS::NormalBackground).color()}, 0398 {"insensitive_unfocused_selected_fg_color_breeze", csc["disabled"]["selection"].foreground(KCS::NormalText).color()}, 0399 0400 // Button 0401 {"theme_button_background_backdrop_insensitive_breeze", csc["disabled"]["button"].background(KCS::NormalBackground).color()}, 0402 {"theme_button_decoration_hover_backdrop_insensitive_breeze", csc["disabled"]["button"].decoration(KCS::HoverColor).color()}, 0403 {"theme_button_decoration_focus_backdrop_insensitive_breeze", csc["disabled"]["button"].decoration(KCS::FocusColor).color()}, 0404 {"theme_button_foreground_backdrop_insensitive_breeze", csc["disabled"]["button"].foreground(KCS::NormalText).color()}, 0405 {"theme_button_foreground_active_backdrop_insensitive_breeze", csc["disabled"]["selection"].foreground(KCS::NormalText).color()}, 0406 0407 // Misc Colors 0408 {"unfocused_insensitive_borders_breeze", unfocusedDisabledBordersColor}, 0409 {"warning_color_insensitive_backdrop_breeze", csc["disabled"]["view"].foreground(KCS::NeutralText).color()}, 0410 {"success_color_insensitive_backdrop_breeze", csc["disabled"]["view"].foreground(KCS::PositiveText).color()}, 0411 {"error_color_insensitive_backdrop_breeze", csc["disabled"]["view"].foreground(KCS::NegativeText).color()}, 0412 0413 /* 0414 * Ignorant Colors (These colors do not care about backdrop or insensitive states) 0415 */ 0416 0417 {"link_color_breeze", csc["active"]["view"].foreground(KCS::LinkText).color()}, 0418 {"link_visited_color_breeze", csc["active"]["view"].foreground(KCS::VisitedText).color()}, 0419 0420 {"tooltip_text_breeze", tooltipForegroundColor}, 0421 {"tooltip_background_breeze", tooltipBackgroundColor}, 0422 {"tooltip_border_breeze", tooltipBorderColor}, 0423 0424 {"content_view_bg_breeze", csc["active"]["view"].background(KCS::NormalBackground).color()}, 0425 0426 }; 0427 // Handle Headers (menu bars and some of toolbars) 0428 if (KCS::isColorSetSupported(kdeglobalsConfig, KCS::Header)) { 0429 // If we have a separate Header color set, use it for both titlebar and header coloring... 0430 result.insert({{"theme_header_background_breeze", csc["active"]["header"].background().color()}, 0431 {"theme_header_foreground_breeze", csc["active"]["header"].foreground().color()}, 0432 {"theme_header_background_light_breeze", csc["active"]["window"].background().color()}, 0433 {"theme_header_foreground_backdrop_breeze", csc["inactive"]["header"].foreground().color()}, 0434 {"theme_header_background_backdrop_breeze", csc["inactive"]["header"].background().color()}, 0435 {"theme_header_foreground_insensitive_breeze", csc["inactive"]["header"].foreground().color()}, 0436 {"theme_header_foreground_insensitive_backdrop_breeze", csc["inactive"]["header"].foreground().color()}, 0437 0438 {"theme_titlebar_background_breeze", csc["active"]["header"].background().color()}, 0439 {"theme_titlebar_foreground_breeze", csc["active"]["header"].foreground().color()}, 0440 {"theme_titlebar_background_light_breeze", csc["active"]["window"].background().color()}, 0441 {"theme_titlebar_foreground_backdrop_breeze", csc["inactive"]["header"].foreground().color()}, 0442 {"theme_titlebar_background_backdrop_breeze", csc["inactive"]["header"].background().color()}, 0443 {"theme_titlebar_foreground_insensitive_breeze", csc["inactive"]["header"].foreground().color()}, 0444 {"theme_titlebar_foreground_insensitive_backdrop_breeze", csc["inactive"]["header"].foreground().color()}}); 0445 } else { 0446 //... if we don't we'll use regular window colors for headerbar and WM group for a titlebar 0447 result.insert({ 0448 {"theme_header_background_breeze", csc["active"]["window"].background().color()}, 0449 {"theme_header_foreground_breeze", csc["active"]["window"].foreground().color()}, 0450 {"theme_header_background_light_breeze", csc["active"]["window"].background().color()}, 0451 {"theme_header_foreground_backdrop_breeze", csc["inactive"]["window"].foreground().color()}, 0452 {"theme_header_background_backdrop_breeze", csc["inactive"]["window"].background().color()}, 0453 {"theme_header_foreground_insensitive_breeze", csc["inactive"]["window"].foreground().color()}, 0454 {"theme_header_foreground_insensitive_backdrop_breeze", csc["inactive"]["window"].foreground().color()}, 0455 0456 {"theme_titlebar_background_breeze", windowManagerConfig.readEntry("activeBackground", QColor())}, 0457 {"theme_titlebar_foreground_breeze", windowManagerConfig.readEntry("activeForeground", QColor())}, 0458 {"theme_titlebar_background_light_breeze", csc["active"]["window"].background(KCS::NormalBackground).color()}, 0459 {"theme_titlebar_foreground_backdrop_breeze", windowManagerConfig.readEntry("inactiveForeground", QColor())}, 0460 {"theme_titlebar_background_backdrop_breeze", windowManagerConfig.readEntry("inactiveBackground", QColor())}, 0461 {"theme_titlebar_foreground_insensitive_breeze", windowManagerConfig.readEntry("inactiveForeground", QColor())}, 0462 {"theme_titlebar_foreground_insensitive_backdrop_breeze", windowManagerConfig.readEntry("inactiveForeground", QColor())}, 0463 }); 0464 } 0465 0466 return result; 0467 } 0468 0469 double ConfigValueProvider::x11GlobalScaleFactor() const 0470 { 0471 double scaleFactor; 0472 0473 if (KWindowSystem::isPlatformX11()) { 0474 KConfigGroup configGroup = kdeglobalsConfig->group(QStringLiteral("KScreen")); 0475 scaleFactor = configGroup.readEntry(QStringLiteral("ScaleFactor"), 1.0); 0476 } else { 0477 KConfigGroup xwaylandGroup = kwinConfig->group(QStringLiteral("Xwayland")); 0478 scaleFactor = xwaylandGroup.readEntry(QStringLiteral("Scale"), 1.0); 0479 } 0480 0481 return std::clamp(scaleFactor, 1.0, double(MAX_GDK_SCALE)); 0482 } 0483 0484 int ConfigValueProvider::fontDpi() const 0485 { 0486 KConfigGroup configGroup = fontsConfig->group(QStringLiteral("General")); 0487 int fontDpi = 0; 0488 0489 if (KWindowSystem::isPlatformX11()) { 0490 fontDpi = configGroup.readEntry(QStringLiteral("forceFontDPI"), 0); 0491 } else { 0492 fontDpi = configGroup.readEntry(QStringLiteral("forceFontDPIWayland"), 0); 0493 } 0494 0495 if (fontDpi <= 0) { 0496 return 0; 0497 } 0498 0499 return std::clamp(fontDpi, MIN_FONT_DPI, MAX_FONT_DPI); 0500 } 0501 0502 QString ConfigValueProvider::windowDecorationButtonsOrderInGtkNotation(const QString &kdeConfigValue) const 0503 { 0504 QString gtkNotation; 0505 0506 for (const QChar &buttonAbbreviation : kdeConfigValue) { 0507 if (buttonAbbreviation == 'X') { 0508 gtkNotation += QStringLiteral("close,"); 0509 } else if (buttonAbbreviation == 'I') { 0510 gtkNotation += QStringLiteral("minimize,"); 0511 } else if (buttonAbbreviation == 'A') { 0512 gtkNotation += QStringLiteral("maximize,"); 0513 } else if (buttonAbbreviation == 'M') { 0514 gtkNotation += QStringLiteral("icon,"); 0515 } 0516 } 0517 gtkNotation.chop(1); 0518 0519 return gtkNotation; 0520 }