**
**
** KRDB - puts current KDE color scheme into preprocessor statements
** cats specially written application default files and uses xrdb -merge to
** write to RESOURCE_MANAGER. Thus it gives a simple way to make non-KDE
** applications fit in with the desktop
**
** Copyright (C) 1998 by Mark Donohoe
** Copyright (C) 1999 by Dirk A. Mueller (reworked for KDE 2.0)
** Copyright (C) 2001 by Matthias Ettrich (add support for GTK applications )
** Copyright (C) 2001 by Waldo Bastian <bastian@kde.org>
** Copyright (C) 2002 by Karol Szwed <gallium@kde.org>
** This application is freely distributable under the GNU Public License.
**
*****************************************************************************/
#include <config-workspace.h>
#include <config-X11.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#undef Unsorted
#include <QApplication>
#include <QBuffer>
#include <QDir>
#include <QFontDatabase>
#include <QSettings>
#include <QTextCodec>
#include <QPixmap>
#include <QByteArray>
#include <QTextStream>
#include <QDateTime>
#include <QDBusConnection>
#include <klauncher_iface.h>
#include <KColorUtils>
#include <kcolorscheme.h>
#include <kconfig.h>
#include <kconfiggroup.h>
#include <kprocess.h>
#include <KLocalizedString>
#include <kdelibs4migration.h>
#include <KWindowSystem>
#include "krdb.h"
#if HAVE_X11
#include <X11/Xlib.h>
#include <QX11Info>
#endif
inline const char * gtkEnvVar(int version)
{
return 2==version ? "GTK2_RC_FILES" : "GTK_RC_FILES";
}
inline const char * sysGtkrc(int version)
{
if(2==version)
{
if(access("/etc/opt/gnome/gtk-2.0", F_OK) == 0)
return "/etc/opt/gnome/gtk-2.0/gtkrc";
else
return "/etc/gtk-2.0/gtkrc";
}
else
{
if(access("/etc/opt/gnome/gtk", F_OK) == 0)
return "/etc/opt/gnome/gtk/gtkrc";
else
return "/etc/gtk/gtkrc";
}
}
inline const char * userGtkrc(int version)
{
return 2==version ? "/.gtkrc-2.0" : "/.gtkrc";
}
static QString writableGtkrc(int version)
{
QString gtkrc = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation);
QDir dir;
dir.mkpath(gtkrc);
gtkrc += 2==version?"/gtkrc-2.0":"/gtkrc";
return gtkrc;
}
static void applyGtkStyles(bool active, int version)
{
QString gtkkde = writableGtkrc(version);
QByteArray gtkrc = getenv(gtkEnvVar(version));
QStringList list = QFile::decodeName(gtkrc).split( QLatin1Char(':'));
QString userHomeGtkrc = QDir::homePath()+userGtkrc(version);
if (!list.contains(userHomeGtkrc))
list.prepend(userHomeGtkrc);
QLatin1String systemGtkrc = QLatin1String(sysGtkrc(version));
if (!list.contains(systemGtkrc))
list.prepend(systemGtkrc);
list.removeAll(QLatin1String(""));
list.removeAll(gtkkde);
list.append(gtkkde);
QString name = gtkEnvVar(version);
QString value = list.join(QLatin1Char(':'));
org::kde::KLauncher klauncher(QStringLiteral("org.kde.klauncher5"), QStringLiteral("/KLauncher"), QDBusConnection::sessionBus());
klauncher.setLaunchEnv(name, value);
}
static void applyQtColors( KSharedConfigPtr kglobalcfg, QSettings& settings, QPalette& newPal )
{
QStringList actcg, inactcg, discg;
int i;
for (i = 0; i < QPalette::NColorRoles; i++)
actcg << newPal.color(QPalette::Active,
(QPalette::ColorRole) i).name();
for (i = 0; i < QPalette::NColorRoles; i++)
inactcg << newPal.color(QPalette::Inactive,
(QPalette::ColorRole) i).name();
for (i = 0; i < QPalette::NColorRoles; i++)
discg << newPal.color(QPalette::Disabled,
(QPalette::ColorRole) i).name();
settings.setValue(QStringLiteral("/qt/Palette/active"), actcg);
settings.setValue(QStringLiteral("/qt/Palette/inactive"), inactcg);
settings.setValue(QStringLiteral("/qt/Palette/disabled"), discg);
KConfigGroup wmCfgGroup(kglobalcfg, "WM");
QColor clr = newPal.color( QPalette::Active, QPalette::Window );
clr = wmCfgGroup.readEntry("activeBackground", clr);
settings.setValue(QStringLiteral("/qt/KWinPalette/activeBackground"), clr.name());
if (QPixmap::defaultDepth() > 8)
clr = clr.darker(110);
clr = wmCfgGroup.readEntry("activeBlend", clr);
settings.setValue(QStringLiteral("/qt/KWinPalette/activeBlend"), clr.name());
clr = newPal.color( QPalette::Active, QPalette::HighlightedText );
clr = wmCfgGroup.readEntry("activeForeground", clr);
settings.setValue(QStringLiteral("/qt/KWinPalette/activeForeground"), clr.name());
clr = newPal.color( QPalette::Active,QPalette::Window );
clr = wmCfgGroup.readEntry("frame", clr);
settings.setValue(QStringLiteral("/qt/KWinPalette/frame"), clr.name());
clr = wmCfgGroup.readEntry("activeTitleBtnBg", clr);
settings.setValue(QStringLiteral("/qt/KWinPalette/activeTitleBtnBg"), clr.name());
clr = newPal.color(QPalette::Inactive, QPalette::Window);
clr = wmCfgGroup.readEntry("inactiveBackground", clr);
settings.setValue(QStringLiteral("/qt/KWinPalette/inactiveBackground"), clr.name());
if (QPixmap::defaultDepth() > 8)
clr = clr.darker(110);
clr = wmCfgGroup.readEntry("inactiveBlend", clr);
settings.setValue(QStringLiteral("/qt/KWinPalette/inactiveBlend"), clr.name());
clr = newPal.color(QPalette::Inactive, QPalette::Window).darker();
clr = wmCfgGroup.readEntry("inactiveForeground", clr);
settings.setValue(QStringLiteral("/qt/KWinPalette/inactiveForeground"), clr.name());
clr = newPal.color(QPalette::Inactive, QPalette::Window);
clr = wmCfgGroup.readEntry("inactiveFrame", clr);
settings.setValue(QStringLiteral("/qt/KWinPalette/inactiveFrame"), clr.name());
clr = wmCfgGroup.readEntry("inactiveTitleBtnBg", clr);
settings.setValue(QStringLiteral("/qt/KWinPalette/inactiveTitleBtnBg"), clr.name());
KConfigGroup kdeCfgGroup(kglobalcfg, "KDE");
settings.setValue(QStringLiteral("/qt/KDE/contrast"), kdeCfgGroup.readEntry("contrast", 7));
}
static void applyQtSettings( KSharedConfigPtr kglobalcfg, QSettings& settings )
{
QFont defaultFont(QStringLiteral("Noto Sans"), 10, -1);
defaultFont.setStyleHint(QFont::SansSerif);
const KConfigGroup configGroup(KSharedConfig::openConfig(), QStringLiteral("General"));
const QString fontInfo = configGroup.readEntry(QStringLiteral("font"), QString());
if (!fontInfo.isEmpty()) {
defaultFont.fromString(fontInfo);
}
settings.setValue(QStringLiteral("/qt/font"), defaultFont.toString());
KConfigGroup kdeCfgGroup(kglobalcfg, "General");
bool effectsEnabled = kdeCfgGroup.readEntry("EffectsEnabled", false);
bool fadeMenus = kdeCfgGroup.readEntry("EffectFadeMenu", false);
bool fadeTooltips = kdeCfgGroup.readEntry("EffectFadeTooltip", false);
bool animateCombobox = kdeCfgGroup.readEntry("EffectAnimateCombo", false);
QStringList guieffects;
if (effectsEnabled) {
guieffects << QStringLiteral("general");
if (fadeMenus)
guieffects << QStringLiteral("fademenu");
if (animateCombobox)
guieffects << QStringLiteral("animatecombo");
if (fadeTooltips)
guieffects << QStringLiteral("fadetooltip");
}
else
guieffects << QStringLiteral("none");
settings.setValue(QStringLiteral("/qt/GUIEffects"), guieffects);
}
static void addColorDef(QString& s, const char* n, const QColor& col)
{
QString tmp;
tmp.sprintf("#define %s #%02x%02x%02x\n",
n, col.red(), col.green(), col.blue());
s += tmp;
}
static void copyFile(QFile& tmp, QString const& filename, bool )
{
QFile f( filename );
if ( f.open(QIODevice::ReadOnly) ) {
QByteArray buf( 8192, ' ' );
while ( !f.atEnd() ) {
int read = f.read( buf.data(), buf.size() );
if ( read > 0 )
tmp.write( buf.data(), read );
}
}
}
static QString item( int i ) {
return QString::number( i / 255.0, 'f', 3 );
}
static QString color( const QColor& col )
{
return QStringLiteral( "{ %1, %2, %3 }" ).arg( item( col.red() ) ).arg( item( col.green() ) ).arg( item( col.blue() ) );
}
static void createGtkrc( bool exportColors, const QPalette& cg, bool exportGtkTheme, const QString& gtkTheme, int version )
{
QSaveFile saveFile( writableGtkrc(version) );
if ( !saveFile.open(QIODevice::WriteOnly) )
return;
QTextStream t ( &saveFile );
t.setCodec( QTextCodec::codecForLocale () );
t << i18n(
"# created by KDE Plasma, %1\n"
"#\n"
"# If you do not want Plasma to override your GTK settings, select\n"
"# Colors in the System Settings and disable the checkbox\n"
"# \"Apply colors to non-Qt applications\"\n"
"#\n"
"#\n", QDateTime::currentDateTime().toString());
if ( 2==version ) {
t << endl;
t << "gtk-alternative-button-order = 1" << endl;
t << endl;
}
if (exportGtkTheme)
{
QString gtkStyle;
if (gtkTheme.toLower() == QLatin1String("oxygen"))
gtkStyle = QStringLiteral("oxygen-gtk");
else
gtkStyle = gtkTheme;
bool exist_gtkrc = false;
QByteArray gtkrc = getenv(gtkEnvVar(version));
QStringList listGtkrc = QFile::decodeName(gtkrc).split(QLatin1Char(':'));
if (listGtkrc.contains(saveFile.fileName()))
listGtkrc.removeAll(saveFile.fileName());
listGtkrc.append(QDir::homePath() + userGtkrc(version));
listGtkrc.append(QDir::homePath() + "/.gtkrc-2.0-kde");
listGtkrc.append(QDir::homePath() + "/.gtkrc-2.0-kde4");
listGtkrc.removeAll(QLatin1String(""));
listGtkrc.removeDuplicates();
for (int i = 0; i < listGtkrc.size(); ++i)
{
if ((exist_gtkrc = QFile::exists(listGtkrc.at(i))))
break;
}
if (!exist_gtkrc)
{
QString gtk2ThemeFilename;
gtk2ThemeFilename = QStringLiteral("%1/.themes/%2/gtk-2.0/gtkrc").arg(QDir::homePath()).arg(gtkStyle);
if (!QFile::exists(gtk2ThemeFilename)) {
QStringList gtk2ThemePath;
gtk2ThemeFilename.clear();
QByteArray xdgDataDirs = getenv("XDG_DATA_DIRS");
gtk2ThemePath.append(QDir::homePath() + "/.local");
gtk2ThemePath.append(QFile::decodeName(xdgDataDirs).split(QLatin1Char(':')));
gtk2ThemePath.removeDuplicates();
for (int i = 0; i < gtk2ThemePath.size(); ++i)
{
gtk2ThemeFilename = QStringLiteral("%1/themes/%2/gtk-2.0/gtkrc").arg(gtk2ThemePath.at(i)).arg(gtkStyle);
if (QFile::exists(gtk2ThemeFilename))
break;
else
gtk2ThemeFilename.clear();
}
}
if (!gtk2ThemeFilename.isEmpty())
{
t << "include \"" << gtk2ThemeFilename << "\"" << endl;
t << endl;
t << "gtk-theme-name=\"" << gtkStyle << "\"" << endl;
t << endl;
if (gtkStyle == QLatin1String("oxygen-gtk"))
exportColors = false;
}
}
}
if (exportColors)
{
t << "style \"default\"" << endl;
t << "{" << endl;
t << " bg[NORMAL] = " << color( cg.color( QPalette::Active, QPalette::Window ) ) << endl;
t << " bg[SELECTED] = " << color( cg.color(QPalette::Active, QPalette::Highlight) ) << endl;
t << " bg[INSENSITIVE] = " << color( cg.color( QPalette::Active, QPalette::Window ) ) << endl;
t << " bg[ACTIVE] = " << color( cg.color( QPalette::Active, QPalette::Mid ) ) << endl;
t << " bg[PRELIGHT] = " << color( cg.color( QPalette::Active, QPalette::Window ) ) << endl;
t << endl;
t << " base[NORMAL] = " << color( cg.color( QPalette::Active, QPalette::Base ) ) << endl;
t << " base[SELECTED] = " << color( cg.color(QPalette::Active, QPalette::Highlight) ) << endl;
t << " base[INSENSITIVE] = " << color( cg.color( QPalette::Active, QPalette::Window ) ) << endl;
t << " base[ACTIVE] = " << color( cg.color(QPalette::Active, QPalette::Highlight) ) << endl;
t << " base[PRELIGHT] = " << color( cg.color(QPalette::Active, QPalette::Highlight) ) << endl;
t << endl;
t << " text[NORMAL] = " << color( cg.color(QPalette::Active, QPalette::Text) ) << endl;
t << " text[SELECTED] = " << color( cg.color(QPalette::Active, QPalette::HighlightedText) ) << endl;
t << " text[INSENSITIVE] = " << color( cg.color( QPalette::Active, QPalette::Mid ) ) << endl;
t << " text[ACTIVE] = " << color( cg.color(QPalette::Active, QPalette::HighlightedText) ) << endl;
t << " text[PRELIGHT] = " << color( cg.color(QPalette::Active, QPalette::HighlightedText) ) << endl;
t << endl;
t << " fg[NORMAL] = " << color ( cg.color( QPalette::Active, QPalette::WindowText ) ) << endl;
t << " fg[SELECTED] = " << color( cg.color(QPalette::Active, QPalette::HighlightedText) ) << endl;
t << " fg[INSENSITIVE] = " << color( cg.color( QPalette::Active, QPalette::Mid ) ) << endl;
t << " fg[ACTIVE] = " << color( cg.color( QPalette::Active, QPalette::WindowText ) ) << endl;
t << " fg[PRELIGHT] = " << color( cg.color( QPalette::Active, QPalette::WindowText ) ) << endl;
t << "}" << endl;
t << endl;
t << "class \"*\" style \"default\"" << endl;
t << endl;
t << "style \"ToolTip\"" << endl;
t << "{" << endl;
t << " bg[NORMAL] = " << color( cg.color( QPalette::ToolTipBase ) ) << endl;
t << " base[NORMAL] = " << color( cg.color( QPalette::ToolTipBase ) ) << endl;
t << " text[NORMAL] = " << color( cg.color( QPalette::ToolTipText ) ) << endl;
t << " fg[NORMAL] = " << color( cg.color( QPalette::ToolTipText ) ) << endl;
t << "}" << endl;
t << endl;
t << "widget \"gtk-tooltip\" style \"ToolTip\"" << endl;
t << "widget \"gtk-tooltips\" style \"ToolTip\"" << endl;
t << "widget \"gtk-tooltip*\" style \"ToolTip\"" << endl;
t << endl;
t << "style \"MenuItem\"" << endl;
t << "{" << endl;
t << " bg[PRELIGHT] = " << color( cg.color(QPalette::Highlight) ) << endl;
t << " fg[PRELIGHT] = " << color( cg.color(QPalette::HighlightedText) ) << endl;
t << "}" << endl;
t << endl;
t << "class \"*MenuItem\" style \"MenuItem\"" << endl;
t << endl;
}
saveFile.commit();
}
QString gtkColorsHelper(const QString &name, const QString &color)
{
return QStringLiteral("@define-color %1 %2;\n").arg(name, color);
}
void checkGtkCss()
{
QFile gtkCss(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + "/gtk-3.0/gtk.css");
if (gtkCss.open(QIODevice::ReadWrite)) {
QTextStream gtkStream(>kCss);
bool hasImport = false;
while (!gtkStream.atEnd()) {
QString line = gtkStream.readLine();
if (line.contains("@import 'colors.css';")) {
hasImport = true;
}
}
if (!hasImport) {
gtkStream << "@import 'colors.css';";
}
}
}
void exportGtkColors(QList<KColorScheme> activeColorSchemes, QList<KColorScheme> inactiveColorSchemes, QList<KColorScheme> disabledColorSchemes, KConfigGroup groupWMTheme, QTextStream& colorsStream)
{
Normal (Non Backdrop, Non Insensitive)
*/
colorsStream << gtkColorsHelper("theme_fg_color", activeColorSchemes[1].foreground(KColorScheme::NormalText).color().name());
colorsStream << gtkColorsHelper("theme_bg_color", activeColorSchemes[1].background(KColorScheme::NormalBackground).color().name());
colorsStream << gtkColorsHelper("theme_text_color", activeColorSchemes[0].foreground(KColorScheme::NormalText).color().name());
colorsStream << gtkColorsHelper("theme_base_color", activeColorSchemes[0].background(KColorScheme::NormalBackground).color().name());
colorsStream << gtkColorsHelper("theme_view_hover_decoration_color", activeColorSchemes[0].decoration(KColorScheme::HoverColor).color().name());
colorsStream << gtkColorsHelper("theme_hovering_selected_bg_color", activeColorSchemes[3].decoration(KColorScheme::HoverColor).color().name());
colorsStream << gtkColorsHelper("theme_selected_bg_color", activeColorSchemes[3].background(KColorScheme::NormalBackground).color().name());
colorsStream << gtkColorsHelper("theme_selected_fg_color", activeColorSchemes[3].foreground(KColorScheme::NormalText).color().name());
colorsStream << gtkColorsHelper("theme_view_active_decoration_color", activeColorSchemes[0].decoration(KColorScheme::HoverColor).color().name());
colorsStream << gtkColorsHelper("theme_button_background_normal", activeColorSchemes[2].background(KColorScheme::NormalBackground).color().name());
colorsStream << gtkColorsHelper("theme_button_decoration_hover", activeColorSchemes[2].decoration(KColorScheme::HoverColor).color().name());
colorsStream << gtkColorsHelper("theme_button_decoration_focus", activeColorSchemes[2].decoration(KColorScheme::FocusColor).color().name());
colorsStream << gtkColorsHelper("theme_button_foreground_normal", activeColorSchemes[2].foreground(KColorScheme::NormalText).color().name());
colorsStream << gtkColorsHelper("theme_button_foreground_active", activeColorSchemes[3].foreground(KColorScheme::NormalText).color().name());
QColor windowForegroundColor = activeColorSchemes[1].foreground(KColorScheme::NormalText).color();
QColor windowBackgroundColor = activeColorSchemes[1].background(KColorScheme::NormalBackground).color();
QColor bordersColor = KColorUtils::mix(windowBackgroundColor,windowForegroundColor, 0.25);
colorsStream << gtkColorsHelper("borders", bordersColor.name());
colorsStream << gtkColorsHelper("warning_color", activeColorSchemes[0].foreground(KColorScheme::NeutralText).color().name());
colorsStream << gtkColorsHelper("success_color", activeColorSchemes[0].foreground(KColorScheme::PositiveText).color().name());
colorsStream << gtkColorsHelper("error_color", activeColorSchemes[0].foreground(KColorScheme::NegativeText).color().name());
Backdrop (Inactive)
*/
colorsStream << gtkColorsHelper("theme_unfocused_fg_color",inactiveColorSchemes[1].foreground(KColorScheme::NormalText).color().name());
colorsStream << gtkColorsHelper("theme_unfocused_text_color", inactiveColorSchemes[0].foreground(KColorScheme::NormalText).color().name());
colorsStream << gtkColorsHelper("theme_unfocused_bg_color", inactiveColorSchemes[1].background(KColorScheme::NormalBackground).color().name());
colorsStream << gtkColorsHelper("theme_unfocused_base_color", inactiveColorSchemes[0].background(KColorScheme::NormalBackground).color().name());
colorsStream << gtkColorsHelper("theme_unfocused_selected_bg_color_alt", inactiveColorSchemes[3].background(KColorScheme::NormalBackground).color().name());
colorsStream << gtkColorsHelper("theme_unfocused_selected_bg_color", inactiveColorSchemes[3].background(KColorScheme::NormalBackground).color().name());
colorsStream << gtkColorsHelper("theme_unfocused_selected_fg_color", inactiveColorSchemes[3].foreground(KColorScheme::NormalText).color().name());
colorsStream << gtkColorsHelper("theme_button_background_backdrop", inactiveColorSchemes[2].background(KColorScheme::NormalBackground).color().name());
colorsStream << gtkColorsHelper("theme_button_decoration_hover_backdrop", inactiveColorSchemes[2].decoration(KColorScheme::HoverColor).color().name());
colorsStream << gtkColorsHelper("theme_button_decoration_focus_backdrop", inactiveColorSchemes[2].decoration(KColorScheme::FocusColor).color().name());
colorsStream << gtkColorsHelper("theme_button_foreground_backdrop", inactiveColorSchemes[2].foreground(KColorScheme::NormalText).color().name());
colorsStream << gtkColorsHelper("theme_button_foreground_active_backdrop", inactiveColorSchemes[3].foreground(KColorScheme::NormalText).color().name());
QColor inactiveWindowForegroundColor = inactiveColorSchemes[1].foreground(KColorScheme::NormalText).color();
QColor inactiveWindowBackgroundColor = inactiveColorSchemes[1].background(KColorScheme::NormalBackground).color();
QColor inactiveBordersColor = KColorUtils::mix(inactiveWindowBackgroundColor,inactiveWindowForegroundColor, 0.25);
colorsStream << gtkColorsHelper("unfocused_borders", inactiveBordersColor.name());
colorsStream << gtkColorsHelper("warning_color_backdrop", inactiveColorSchemes[0].foreground(KColorScheme::NeutralText).color().name());
colorsStream << gtkColorsHelper("success_color_backdrop", inactiveColorSchemes[0].foreground(KColorScheme::PositiveText).color().name());
colorsStream << gtkColorsHelper("error_color_backdrop", inactiveColorSchemes[0].foreground(KColorScheme::NegativeText).color().name());
Insensitive (Disabled)
*/
colorsStream << gtkColorsHelper("insensitive_fg_color",disabledColorSchemes[1].foreground(KColorScheme::NormalText).color().name());
colorsStream << gtkColorsHelper("insensitive_base_fg_color", disabledColorSchemes[0].foreground(KColorScheme::NormalText).color().name());
colorsStream << gtkColorsHelper("insensitive_bg_color", disabledColorSchemes[1].background(KColorScheme::NormalBackground).color().name());
colorsStream << gtkColorsHelper("insensitive_base_color", disabledColorSchemes[0].background(KColorScheme::NormalBackground).color().name());
colorsStream << gtkColorsHelper("insensitive_selected_bg_color", disabledColorSchemes[3].background(KColorScheme::NormalBackground).color().name());
colorsStream << gtkColorsHelper("insensitive_selected_fg_color", disabledColorSchemes[3].foreground(KColorScheme::NormalText).color().name());
colorsStream << gtkColorsHelper("theme_button_background_insensitive", disabledColorSchemes[2].background(KColorScheme::NormalBackground).color().name());
colorsStream << gtkColorsHelper("theme_button_decoration_hover_insensitive", disabledColorSchemes[2].decoration(KColorScheme::HoverColor).color().name());
colorsStream << gtkColorsHelper("theme_button_decoration_focus_insensitive", disabledColorSchemes[2].decoration(KColorScheme::FocusColor).color().name());
colorsStream << gtkColorsHelper("theme_button_foreground_insensitive", disabledColorSchemes[2].foreground(KColorScheme::NormalText).color().name());
colorsStream << gtkColorsHelper("theme_button_foreground_active_insensitive", disabledColorSchemes[3].foreground(KColorScheme::NormalText).color().name());
QColor disabledWindowForegroundColor = disabledColorSchemes[1].foreground(KColorScheme::NormalText).color();
QColor disabledWindowBackgroundColor = disabledColorSchemes[1].background(KColorScheme::NormalBackground).color();
QColor disabledBordersColor = KColorUtils::mix(disabledWindowBackgroundColor,disabledWindowForegroundColor, 0.25);
colorsStream << gtkColorsHelper("insensitive_borders", disabledBordersColor.name());
colorsStream << gtkColorsHelper("warning_color_insensitive", disabledColorSchemes[0].foreground(KColorScheme::NeutralText).color().name());
colorsStream << gtkColorsHelper("success_color_insensitive", disabledColorSchemes[0].foreground(KColorScheme::PositiveText).color().name());
colorsStream << gtkColorsHelper("error_color_insensitive", disabledColorSchemes[0].foreground(KColorScheme::NegativeText).color().name());
Insensitive Backdrop (Inactive Disabled) These pretty much have the same appearance as regular inactive colors, but they're seperate in case we decide to make
them different in the future.
*/
colorsStream << gtkColorsHelper("insensitive_unfocused_fg_color",disabledColorSchemes[1].foreground(KColorScheme::NormalText).color().name());
colorsStream << gtkColorsHelper("theme_unfocused_view_text_color", disabledColorSchemes[0].foreground(KColorScheme::NormalText).color().name());
colorsStream << gtkColorsHelper("insensitive_unfocused_bg_color", disabledColorSchemes[1].background(KColorScheme::NormalBackground).color().name());
colorsStream << gtkColorsHelper("theme_unfocused_view_bg_color", disabledColorSchemes[0].background(KColorScheme::NormalBackground).color().name());
colorsStream << gtkColorsHelper("insensitive_unfocused_selected_bg_color", disabledColorSchemes[3].background(KColorScheme::NormalBackground).color().name());
colorsStream << gtkColorsHelper("insensitive_unfocused_selected_fg_color", disabledColorSchemes[3].foreground(KColorScheme::NormalText).color().name());
colorsStream << gtkColorsHelper("theme_button_background_backdrop_insensitive", disabledColorSchemes[2].background(KColorScheme::NormalBackground).color().name());
colorsStream << gtkColorsHelper("theme_button_decoration_hover_backdrop_insensitive", disabledColorSchemes[2].decoration(KColorScheme::HoverColor).color().name());
colorsStream << gtkColorsHelper("theme_button_decoration_focus_backdrop_insensitive", disabledColorSchemes[2].decoration(KColorScheme::FocusColor).color().name());
colorsStream << gtkColorsHelper("theme_button_foreground_backdrop_insensitive", disabledColorSchemes[2].foreground(KColorScheme::NormalText).color().name());
colorsStream << gtkColorsHelper("theme_button_foreground_active_backdrop_insensitive", disabledColorSchemes[3].foreground(KColorScheme::NormalText).color().name());
QColor unfocusedDisabledWindowForegroundColor = disabledColorSchemes[1].foreground(KColorScheme::NormalText).color();
QColor unfocusedDisabledWindowBackgroundColor = disabledColorSchemes[1].background(KColorScheme::NormalBackground).color();
QColor unfocusedDisabledBordersColor = KColorUtils::mix(unfocusedDisabledWindowBackgroundColor,unfocusedDisabledWindowForegroundColor, 0.25);
colorsStream << gtkColorsHelper("unfocused_insensitive_borders", unfocusedDisabledBordersColor.name());
colorsStream << gtkColorsHelper("warning_color_insensitive_backdrop", disabledColorSchemes[0].foreground(KColorScheme::NeutralText).color().name());
colorsStream << gtkColorsHelper("success_color_insensitive_backdrop", disabledColorSchemes[0].foreground(KColorScheme::PositiveText).color().name());
colorsStream << gtkColorsHelper("error_color_insensitive_backdrop", disabledColorSchemes[0].foreground(KColorScheme::NegativeText).color().name());
Ignorant Colors (These colors do not care about backdrop or insensitive states)
*/
colorsStream << gtkColorsHelper("link_color", activeColorSchemes[0].foreground(KColorScheme::LinkText).color().name());
colorsStream << gtkColorsHelper("link_visited_color", activeColorSchemes[0].foreground(KColorScheme::VisitedText).color().name());
QColor tooltipForegroundColor = activeColorSchemes[4].foreground(KColorScheme::NormalText).color();
QColor tooltipBackgroundColor = activeColorSchemes[4].background(KColorScheme::NormalBackground).color();
QColor tooltipBorderColor = KColorUtils::mix(tooltipBackgroundColor, tooltipForegroundColor, 0.25);
colorsStream << gtkColorsHelper("tooltip_text", tooltipForegroundColor.name());
colorsStream << gtkColorsHelper("tooltip_background", tooltipBackgroundColor.name());
colorsStream << gtkColorsHelper("tooltip_border", tooltipBorderColor.name());
colorsStream << gtkColorsHelper("content_view_bg", activeColorSchemes[0].background(KColorScheme::NormalBackground).color().name());
colorsStream << gtkColorsHelper("theme_titlebar_background", "rgb(" + groupWMTheme.readEntry("activeBackground", "") + QLatin1Char(')'));
colorsStream << gtkColorsHelper("theme_titlebar_foreground", "rgb(" + groupWMTheme.readEntry("activeForeground", "") + QLatin1Char(')'));
colorsStream << gtkColorsHelper("theme_titlebar_background_light", activeColorSchemes[1].background(KColorScheme::NormalBackground).color().name());
colorsStream << gtkColorsHelper("theme_titlebar_foreground_backdrop", "rgb(" + groupWMTheme.readEntry("inactiveForeground", "") + QLatin1Char(')'));
colorsStream << gtkColorsHelper("theme_titlebar_background_backdrop", "rgb(" + groupWMTheme.readEntry("inactiveBackground", "") + QLatin1Char(')'));
colorsStream << gtkColorsHelper("theme_titlebar_foreground_insensitive", "rgb(" + groupWMTheme.readEntry("inactiveForeground", "") + QLatin1Char(')'));
colorsStream << gtkColorsHelper("theme_titlebar_foreground_insensitive_backdrop", "rgb(" + groupWMTheme.readEntry("inactiveForeground", "") + QLatin1Char(')'));
}
void saveGtkColors(KSharedConfigPtr& config)
{
checkGtkCss();
QFile colorsCss(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + "/gtk-3.0/colors.css");
if (colorsCss.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
QTextStream colorsStream(&colorsCss);
0 Active View
1 Active Window
2 Active Button
3 Active Selection
4 Active Tooltip
5 Active Complimentary
*/
QList<KColorScheme> activeColorSchemes{
KColorScheme(QPalette::Active, KColorScheme::View, config),
KColorScheme(QPalette::Active, KColorScheme::Window, config),
KColorScheme(QPalette::Active, KColorScheme::Button, config),
KColorScheme(QPalette::Active, KColorScheme::Selection, config),
KColorScheme(QPalette::Active, KColorScheme::Tooltip, config),
KColorScheme(QPalette::Active, KColorScheme::Complementary, config)
};
QList<KColorScheme> inactiveColorSchemes{
KColorScheme(QPalette::Inactive, KColorScheme::View, config),
KColorScheme(QPalette::Inactive, KColorScheme::Window, config),
KColorScheme(QPalette::Inactive, KColorScheme::Button, config),
KColorScheme(QPalette::Inactive, KColorScheme::Selection, config),
KColorScheme(QPalette::Inactive, KColorScheme::Tooltip, config),
KColorScheme(QPalette::Inactive, KColorScheme::Complementary, config)
};
QList<KColorScheme> disabledColorSchemes{
KColorScheme(QPalette::Disabled, KColorScheme::View, config),
KColorScheme(QPalette::Disabled, KColorScheme::Window, config),
KColorScheme(QPalette::Disabled, KColorScheme::Button, config),
KColorScheme(QPalette::Disabled, KColorScheme::Selection, config),
KColorScheme(QPalette::Disabled, KColorScheme::Tooltip, config),
KColorScheme(QPalette::Disabled, KColorScheme::Complementary, config)
};
KConfigGroup groupWMTheme(config, "WM");
exportGtkColors(activeColorSchemes, inactiveColorSchemes, disabledColorSchemes, groupWMTheme, colorsStream);
}
}
void saveGtkColors()
{
checkGtkCss();
QFile colorsCss(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + "/gtk-3.0/colors.css");
KConfigGroup groupWMTheme(KSharedConfig::openConfig(), "WM");
if (colorsCss.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
QTextStream colorsStream(&colorsCss);
0 Active View
1 Active Window
2 Active Button
3 Active Selection
4 Active Tooltip
5 Active Complimentary
*/
QList<KColorScheme> activeColorSchemes{
KColorScheme(QPalette::Active, KColorScheme::View),
KColorScheme(QPalette::Active, KColorScheme::Window),
KColorScheme(QPalette::Active, KColorScheme::Button),
KColorScheme(QPalette::Active, KColorScheme::Selection),
KColorScheme(QPalette::Active, KColorScheme::Tooltip),
KColorScheme(QPalette::Active, KColorScheme::Complementary)
};
QList<KColorScheme> inactiveColorSchemes{
KColorScheme(QPalette::Inactive, KColorScheme::View),
KColorScheme(QPalette::Inactive, KColorScheme::Window),
KColorScheme(QPalette::Inactive, KColorScheme::Button),
KColorScheme(QPalette::Inactive, KColorScheme::Selection),
KColorScheme(QPalette::Inactive, KColorScheme::Tooltip),
KColorScheme(QPalette::Inactive, KColorScheme::Complementary)
};
QList<KColorScheme> disabledColorSchemes{
KColorScheme(QPalette::Disabled, KColorScheme::View),
KColorScheme(QPalette::Disabled, KColorScheme::Window),
KColorScheme(QPalette::Disabled, KColorScheme::Button),
KColorScheme(QPalette::Disabled, KColorScheme::Selection),
KColorScheme(QPalette::Disabled, KColorScheme::Tooltip),
KColorScheme(QPalette::Disabled, KColorScheme::Complementary)
};
exportGtkColors(activeColorSchemes, inactiveColorSchemes, disabledColorSchemes, groupWMTheme, colorsStream);
}
}
void runRdb( uint flags )
{
bool exportColors = flags & KRdbExportColors;
bool exportQtColors = flags & KRdbExportQtColors;
bool exportQtSettings = flags & KRdbExportQtSettings;
bool exportXftSettings = flags & KRdbExportXftSettings;
bool exportGtkTheme = flags & KRdbExportGtkTheme;
bool exportGtkColors = flags & KRdbExportGtkColors;
KSharedConfigPtr kglobalcfg = KSharedConfig::openConfig( QStringLiteral("kdeglobals") );
KConfigGroup kglobals(kglobalcfg, "KDE");
QPalette newPal = KColorScheme::createApplicationPalette(kglobalcfg);
QTemporaryFile tmpFile;
if (!tmpFile.open())
{
qDebug() << "Couldn't open temp file";
exit(0);
}
KConfigGroup generalCfgGroup(kglobalcfg, "General");
QString gtkTheme;
if (kglobals.hasKey("widgetStyle"))
gtkTheme = kglobals.readEntry("widgetStyle");
else
gtkTheme = QStringLiteral("oxygen");
createGtkrc( exportColors, newPal, exportGtkTheme, gtkTheme, 1 );
createGtkrc( exportColors, newPal, exportGtkTheme, gtkTheme, 2 );
if (exportColors)
{
KConfigGroup g(KSharedConfig::openConfig(), "WM");
QString preproc;
QColor backCol = newPal.color( QPalette::Active, QPalette::Window );
addColorDef(preproc, "FOREGROUND" , newPal.color( QPalette::Active, QPalette::WindowText ) );
addColorDef(preproc, "BACKGROUND" , backCol);
addColorDef(preproc, "HIGHLIGHT" , backCol.lighter(100+(2*KColorScheme::contrast()+4)*16/1));
addColorDef(preproc, "LOWLIGHT" , backCol.darker(100+(2*KColorScheme::contrast()+4)*10));
addColorDef(preproc, "SELECT_BACKGROUND" , newPal.color( QPalette::Active, QPalette::Highlight));
addColorDef(preproc, "SELECT_FOREGROUND" , newPal.color( QPalette::Active, QPalette::HighlightedText));
addColorDef(preproc, "WINDOW_BACKGROUND" , newPal.color( QPalette::Active, QPalette::Base ) );
addColorDef(preproc, "WINDOW_FOREGROUND" , newPal.color( QPalette::Active, QPalette::Text ) );
addColorDef(preproc, "INACTIVE_BACKGROUND", g.readEntry("inactiveBackground", QColor(224, 223, 222)));
addColorDef(preproc, "INACTIVE_FOREGROUND", g.readEntry("inactiveBackground", QColor(224, 223, 222)));
addColorDef(preproc, "ACTIVE_BACKGROUND" , g.readEntry("activeBackground", QColor(48, 174, 232)));
addColorDef(preproc, "ACTIVE_FOREGROUND" , g.readEntry("activeBackground", QColor(48, 174, 232)));
tmpFile.write( preproc.toLatin1(), preproc.length() );
QStringList list;
const QStringList adPaths = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation,
QStringLiteral("kdisplay/app-defaults/"), QStandardPaths::LocateDirectory);
for (QStringList::ConstIterator it = adPaths.constBegin(); it != adPaths.constEnd(); ++it) {
QDir dSys( *it );
if ( dSys.exists() ) {
dSys.setFilter( QDir::Files );
dSys.setSorting( QDir::Name );
dSys.setNameFilters(QStringList(QStringLiteral("*.ad")));
list += dSys.entryList();
}
}
for (QStringList::ConstIterator it = list.constBegin(); it != list.constEnd(); ++it)
copyFile(tmpFile, QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kdisplay/app-defaults/"+(*it)), true);
}
QString homeDir = QDir::homePath();
QString xResources = homeDir + "/.Xresources";
if ( QFile::exists( xResources ) )
copyFile(tmpFile, xResources, true);
else
copyFile(tmpFile, homeDir + "/.Xdefaults", true);
KConfigGroup mousecfg(KSharedConfig::openConfig( QStringLiteral("kcminputrc") ), "Mouse" );
QString theme = mousecfg.readEntry("cursorTheme", QString());
QString size = mousecfg.readEntry("cursorSize", QString());
QString contents;
if (!theme.isNull())
contents = "Xcursor.theme: " + theme + '\n';
if (!size.isNull())
contents += "Xcursor.size: " + size + '\n';
if (exportXftSettings)
{
contents += QLatin1String("Xft.antialias: ");
if(generalCfgGroup.readEntry("XftAntialias", true))
contents += QLatin1String("1\n");
else
contents += QLatin1String("0\n");
QString hintStyle = generalCfgGroup.readEntry("XftHintStyle", "hintslight");
contents += QLatin1String("Xft.hinting: ");
if(hintStyle.isEmpty())
contents += QLatin1String("-1\n");
else
{
if(hintStyle!=QLatin1String("hintnone"))
contents += QLatin1String("1\n");
else
contents += QLatin1String("0\n");
contents += "Xft.hintstyle: " + hintStyle + '\n';
}
QString subPixel = generalCfgGroup.readEntry("XftSubPixel", "rgb");
if(!subPixel.isEmpty())
contents += "Xft.rgba: " + subPixel + '\n';
KConfig _cfgfonts( QStringLiteral("kcmfonts") );
KConfigGroup cfgfonts(&_cfgfonts, "General");
int dpi;
if (KWindowSystem::isPlatformWayland()) {
dpi = cfgfonts.readEntry( "forceFontDPIWayland", 0);
if (dpi == 0) {
dpi = 96;
}
} else {
dpi = cfgfonts.readEntry( "forceFontDPI", 0);
}
if( dpi != 0 )
contents += "Xft.dpi: " + QString::number(dpi) + '\n';
else
{
KProcess proc;
proc << QStringLiteral("xrdb") << QStringLiteral("-quiet") << QStringLiteral("-remove") << QStringLiteral("-nocpp");
proc.start();
if (proc.waitForStarted())
{
proc.write( QByteArray( "Xft.dpi\n" ) );
proc.closeWriteChannel();
proc.waitForFinished();
}
}
}
if (contents.length() > 0)
tmpFile.write( contents.toLatin1(), contents.length() );
tmpFile.flush();
KProcess proc;
#ifndef NDEBUG
proc << QStringLiteral("xrdb") << QStringLiteral("-merge") << tmpFile.fileName();
#else
proc << "xrdb" << "-quiet" << "-merge" << tmpFile.fileName();
#endif
proc.execute();
applyGtkStyles(exportColors, 1);
applyGtkStyles(exportColors, 2);
if ( exportQtColors || exportQtSettings )
{
QSettings* settings = new QSettings(QStringLiteral("Trolltech"));
if ( exportQtColors )
applyQtColors( kglobalcfg, *settings, newPal );
if ( exportQtSettings )
applyQtSettings( kglobalcfg, *settings );
delete settings;
QApplication::flush();
#if HAVE_X11
if (qApp->platformName() == QLatin1String("xcb")) {
QDateTime settingsstamp = QDateTime::currentDateTime();
static Atom qt_settings_timestamp = 0;
if (!qt_settings_timestamp) {
QString atomname(QStringLiteral("_QT_SETTINGS_TIMESTAMP_"));
atomname += XDisplayName( nullptr );
qt_settings_timestamp = XInternAtom( QX11Info::display(), atomname.toLatin1(), False);
}
QBuffer stamp;
QDataStream s(&stamp.buffer(), QIODevice::WriteOnly);
s << settingsstamp;
XChangeProperty( QX11Info::display(), QX11Info::appRootWindow(), qt_settings_timestamp,
qt_settings_timestamp, 8, PropModeReplace,
(unsigned char*) stamp.buffer().data(),
stamp.buffer().size() );
QApplication::flush();
}
#endif
}
Kdelibs4Migration migration;
KConfigGroup generalGroup(kglobalcfg, "General");
KConfigGroup iconsGroup(kglobalcfg, "Icons");
const QString colorSchemeName = generalGroup.readEntry("ColorScheme", QString());
if (colorSchemeName.isEmpty()) {
return;
}
QString colorSchemeSrcFile;
if (colorSchemeName != QLatin1String("Default")) {
QString colorSchemeFilename = colorSchemeName;
colorSchemeFilename.remove('\'');
QRegExp fixer(QStringLiteral("[\\W,.-]+(.?)"));
int offset;
while ((offset = fixer.indexIn(colorSchemeFilename)) >= 0)
colorSchemeFilename.replace(offset, fixer.matchedLength(), fixer.cap(1).toUpper());
colorSchemeFilename.replace(0, 1, colorSchemeFilename.at(0).toUpper());
colorSchemeSrcFile = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "color-schemes/" + colorSchemeFilename + ".colors");
const QString dest = migration.saveLocation("data", QStringLiteral("color-schemes")) + colorSchemeName + ".colors";
QFile::remove(dest);
QFile::copy(colorSchemeSrcFile, dest);
}
QString configFilePath = migration.saveLocation("config") + "kdeglobals";
if (configFilePath.isEmpty()) {
return;
}
KConfig kde4config(configFilePath, KConfig::SimpleConfig);
KConfigGroup kde4generalGroup(&kde4config, "General");
kde4generalGroup.writeEntry("ColorScheme", colorSchemeName);
QString font = generalGroup.readEntry("font", QString());
if (!font.isEmpty()) {
kde4generalGroup.writeEntry("font", font);
}
font = generalGroup.readEntry("desktopFont", QString());
if (!font.isEmpty()) {
kde4generalGroup.writeEntry("desktopFont", font);
}
font = generalGroup.readEntry("menuFont", QString());
if (!font.isEmpty()) {
kde4generalGroup.writeEntry("menuFont", font);
}
font = generalGroup.readEntry("smallestReadableFont", QString());
if (!font.isEmpty()) {
kde4generalGroup.writeEntry("smallestReadableFont", font);
}
font = generalGroup.readEntry("taskbarFont", QString());
if (!font.isEmpty()) {
kde4generalGroup.writeEntry("taskbarFont", font);
}
font = generalGroup.readEntry("toolBarFont", QString());
if (!font.isEmpty()) {
kde4generalGroup.writeEntry("toolBarFont", font);
}
kde4generalGroup.sync();
KConfigGroup kde4IconGroup(&kde4config, "Icons");
QString iconTheme = iconsGroup.readEntry("Theme", QString());
if (!iconTheme.isEmpty()) {
kde4IconGroup.writeEntry("Theme", iconTheme);
}
kde4IconGroup.sync();
if (!colorSchemeSrcFile.isEmpty()) {
KSharedConfigPtr kde4ColorConfig = KSharedConfig::openConfig(colorSchemeSrcFile, KConfig::SimpleConfig);
foreach (const QString &grp, kde4ColorConfig->groupList()) {
KConfigGroup cg(kde4ColorConfig, grp);
KConfigGroup cg2(&kde4config, grp);
cg.copyTo(&cg2);
}
}
KConfigGroup kglobals4(&kde4config, "KDE");
kglobals4.writeEntry("ShowIconsInMenuItems", kglobals.readEntry("ShowIconsInMenuItems", true));
kglobals4.writeEntry("ShowIconsOnPushButtons", kglobals.readEntry("ShowIconsOnPushButtons", true));
kglobals4.writeEntry("contrast", kglobals.readEntry("contrast", 4));
kde4generalGroup.writeEntry("widgetStyle", kglobals.readEntry("widgetStyle", "breeze"));
KConfigGroup toolbars4(&kde4config, "Toolbar style");
KConfigGroup toolbars5(kglobalcfg, "Toolbar style");
toolbars4.writeEntry("ToolButtonStyle", toolbars5.readEntry("ToolButtonStyle", "TextBesideIcon"));
toolbars4.writeEntry("ToolButtonStyleOtherToolbars", toolbars5.readEntry("ToolButtonStyleOtherToolbars", "TextBesideIcon"));
if (exportGtkColors) {
saveGtkColors();
}
}