Skip to content

Commit

Permalink
Implement syncing of theme preferences between SDDM and Plasma
Browse files Browse the repository at this point in the history
Summary:
This patch exposes UI options in sddm-kcm which enable users to sync their theme preferences used in Plasma with SDDM.

Syncing of UI font, font rendering, color scheme, desktop and icon theme has been implemented.

A reset button has also been added in order to allow easy removal of all SDDM syncing-related customization.

Test Plan:
For testing a different font, you need to have a file like this one:
{F6952969}
in `/home/user/.config/fontconfig/conf.d/`

Settings UI:
{F7052980}

Reviewers: #plasma, ngraham, davidedmundson, #vdg

Reviewed By: ngraham, #vdg

Subscribers: leinir, cfeck, GB_2, ndavis, plasma-devel

Tags: #plasma

Differential Revision: https://phabricator.kde.org/D22191
  • Loading branch information
flipwise committed Jul 19, 2019
1 parent edaae61 commit f9e7535
Show file tree
Hide file tree
Showing 6 changed files with 288 additions and 53 deletions.
12 changes: 12 additions & 0 deletions kcm_sddm.actions
Expand Up @@ -295,3 +295,15 @@ Description[zh_CN]=移除已经安装的 SDDM 主题
Description[zh_TW]=移除先前安裝的 SDDM 主題
Policy=auth_admin
Persistence=session

[org.kde.kcontrol.kcmsddm.sync]
Name=Synchronize Settings
Description=Synchronizes user settings with SDDM settings
Policy=auth_admin
Persistence=session

[org.kde.kcontrol.kcmsddm.reset]
Name=Reset Settings
Description=Resets SDDM settings so there are not user settings
Policy=auth_admin
Persistence=session
87 changes: 84 additions & 3 deletions sddmauthhelper.cpp
Expand Up @@ -17,6 +17,8 @@
*/
#include "sddmauthhelper.h"

#include <unistd.h>

#include <QDebug>
#include <QDir>
#include <QFile>
Expand All @@ -30,6 +32,7 @@
#include <KConfigGroup>
#include <KLocalizedString>
#include <KTar>
#include <KUser>
#include <KZip>

static QSharedPointer<KConfig> openConfig(const QString &filePath)
Expand All @@ -46,6 +49,86 @@ static QSharedPointer<KConfig> openConfig(const QString &filePath)
return QSharedPointer<KConfig>(new KConfig(file.fileName(), KConfig::SimpleConfig));
}

void SddmAuthHelper::copyFile(const QString &source, const QString &destination)
{
KUser sddmUser(QStringLiteral("sddm"));

if (QFile::exists(destination)) {
QFile::remove(destination);
}

QFile::copy(source, destination);
const char* destinationConverted = destination.toLocal8Bit().data();
if (chown(destinationConverted, sddmUser.userId().nativeId(), sddmUser.groupId().nativeId())) {
return;
}
}

ActionReply SddmAuthHelper::sync(const QVariantMap &args)
{
QDir sddmConfigLocation(args[QStringLiteral("sddmUserConfig")].toString());
if (!sddmConfigLocation.exists()) {
QDir().mkpath(sddmConfigLocation.path());
}

// copy fontconfig (font, font rendering)
if (!args[QStringLiteral("fontconfig")].isNull()) {
QDir fontconfigSource(args[QStringLiteral("fontconfig")].toString());
QStringList sourceFileEntries = fontconfigSource.entryList (QDir::Files);
QStringList sourceDirEntries = fontconfigSource.entryList (QDir::AllDirs);
QDir fontconfigDestination(sddmConfigLocation.path() + QStringLiteral("/fontconfig"));

if (!fontconfigDestination.exists()) {
QDir().mkpath(fontconfigDestination.path());
}

if (sourceDirEntries.count() != 0) {
for (int i = 0; i<sourceDirEntries.count(); i++) {
QString directoriesSource = fontconfigSource.path() + QDir::separator() + sourceDirEntries[i];
QString directoriesDestination = fontconfigDestination.path() + QDir::separator() + sourceDirEntries[i];
fontconfigSource.mkpath(directoriesDestination);
copyFile(directoriesSource, directoriesDestination);
}
}

if (sourceFileEntries.count() != 0) {
for (int i = 0; i<sourceFileEntries.count(); i++) {
QString filesSource = fontconfigSource.path() + QDir::separator() + sourceFileEntries[i];
QString filesDestination = fontconfigDestination.path() + QDir::separator() + sourceFileEntries[i];
copyFile(filesSource, filesDestination);
}
}
}

// copy kdeglobals (color scheme)
if (!args[QStringLiteral("kdeglobals")].isNull()) {
QDir kdeglobalsSource(args[QStringLiteral("kdeglobals")].toString());
QDir kdeglobalsDestination(sddmConfigLocation.path() + QStringLiteral("/kdeglobals"));
copyFile(kdeglobalsSource.path(), kdeglobalsDestination.path());
}

// copy plasmarc (icons, UI style)
if (!args[QStringLiteral("plasmarc")].isNull()) {
QDir plasmarcSource(args[QStringLiteral("plasmarc")].toString());
QDir plasmarcDestination(sddmConfigLocation.path() + QStringLiteral("/plasmarc"));
copyFile(plasmarcSource.path(), plasmarcDestination.path());
}

return ActionReply::SuccessReply();
}

ActionReply SddmAuthHelper::reset(const QVariantMap &args)
{
QDir sddmConfigLocation(args[QStringLiteral("sddmUserConfig")].toString());
QDir fontconfigDir(args[QStringLiteral("sddmUserConfig")].toString() + QStringLiteral("/fontconfig"));

fontconfigDir.removeRecursively();
QFile::remove(sddmConfigLocation.path() + QStringLiteral("/kdeglobals"));
QFile::remove(sddmConfigLocation.path() + QStringLiteral("/plasmarc"));

return ActionReply::SuccessReply();
}

ActionReply SddmAuthHelper::save(const QVariantMap &args)
{
ActionReply reply = ActionReply::HelperErrorReply();
Expand Down Expand Up @@ -76,7 +159,7 @@ ActionReply SddmAuthHelper::save(const QVariantMap &args)

// if there is an identical keyName in "sddm.conf" we want to delete it so SDDM doesn't read from the old file
// hierarchically SDDM prefers "etc/sddm.conf" to "/etc/sddm.conf.d/some_file.conf"

if (fileName == QLatin1String("kde_settings.conf")) {
sddmConfig->group(groupName).writeEntry(keyName, iterator.value());
sddmOldConfig->group(groupName).deleteEntry(keyName);
Expand Down Expand Up @@ -230,8 +313,6 @@ ActionReply SddmAuthHelper::uninstalltheme(const QVariantMap &args)
return ActionReply::SuccessReply();
}


KAUTH_HELPER_MAIN("org.kde.kcontrol.kcmsddm", SddmAuthHelper)

#include "moc_sddmauthhelper.cpp"

6 changes: 6 additions & 0 deletions sddmauthhelper.h
Expand Up @@ -24,10 +24,16 @@ using namespace KAuth;
class SddmAuthHelper: public QObject
{
Q_OBJECT

public Q_SLOTS:
ActionReply sync(const QVariantMap &args);
ActionReply reset(const QVariantMap &args);
ActionReply save(const QVariantMap &args);
ActionReply installtheme(const QVariantMap &args);
ActionReply uninstalltheme(const QVariantMap &args);

public:
void copyFile (const QString &source, const QString &destination);
};

#endif //SDDMAUTHHELPER_H
75 changes: 75 additions & 0 deletions src/advanceconfig.cpp
Expand Up @@ -24,9 +24,14 @@
#include "usersmodel.h"

#include <QDebug>
#include <QFontDatabase>
#include <QIntValidator>
#include <QStandardPaths>

#include <KAuth/KAuthActionReply>
#include <kauthexecutejob.h>
#include <KConfigGroup>
#include <KMessageBox>
#include <KUser>

const int MIN_UID = 1000;
Expand All @@ -38,6 +43,7 @@ AdvanceConfig::AdvanceConfig(const KSharedConfigPtr &config, QWidget *parent) :
{
configUi = new Ui::AdvanceConfig();
configUi->setupUi(this);
configUi->syncExplanation->setFont(QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont));

load();

Expand All @@ -54,6 +60,9 @@ AdvanceConfig::AdvanceConfig(const KSharedConfigPtr &config, QWidget *parent) :
// manually emit changed signal since QCheckBox::clicked will pass false to changed() when unchecked
connect(configUi->autoLogin, &QCheckBox::clicked, this, [this] { emit changed(); });
connect(configUi->reloginAfterQuit, &QAbstractButton::clicked, this, [this] { emit changed(); });

connect(configUi->syncSettings, &QPushButton::clicked, this, &AdvanceConfig::syncSettingsChanged);
connect(configUi->resetSettings, &QPushButton::clicked, this, &AdvanceConfig::resetSettingsChanged);
}

AdvanceConfig::~AdvanceConfig()
Expand Down Expand Up @@ -160,3 +169,69 @@ bool AdvanceConfig::isUidRangeValid(int minUid, int maxUid) const

return true;
}

void AdvanceConfig::syncSettingsChanged()
{
const QString fontconfigPath = QStandardPaths::locate(QStandardPaths::GenericConfigLocation, QStringLiteral("fontconfig"), QStandardPaths::LocateDirectory);
const QString kdeglobalsPath = QStandardPaths::locate(QStandardPaths::GenericConfigLocation, QStringLiteral("kdeglobals"));
const QString plasmarcPath = QStandardPaths::locate(QStandardPaths::GenericConfigLocation, QStringLiteral("plasmarc"));
const QString sddmUserConfigPath = KUser("sddm").homeDir() + QStringLiteral("/.config");

if (fontconfigPath.isEmpty()) {
qDebug() << "fontconfig folder not found";
}
if (kdeglobalsPath.isEmpty()) {
qDebug() << "kdeglobals file not found";
}
if (plasmarcPath.isEmpty()) {
qDebug() << "plasmarc file not found";
}

QVariantMap args;
args[QStringLiteral("fontconfig")] = fontconfigPath;
args[QStringLiteral("kdeglobals")] = kdeglobalsPath;
args[QStringLiteral("plasmarc")] = plasmarcPath;
args[QStringLiteral("sddmUserConfig")] = sddmUserConfigPath;

KAuth::Action syncAction(QStringLiteral("org.kde.kcontrol.kcmsddm.sync"));
syncAction.setHelperId(QStringLiteral("org.kde.kcontrol.kcmsddm"));
syncAction.setArguments(args);

auto job = syncAction.execute();
job->exec();

if (job->error()){
qDebug() << "Synchronization failed";
qDebug() << job->errorString();
qDebug() << job->errorText();
KMessageBox::error(this, job->errorText());
} else {
changed(false);
qDebug() << "Synchronization successful";
}
}

void AdvanceConfig::resetSettingsChanged()
{
const QString sddmUserConfigPath = KUser("sddm").homeDir() + QStringLiteral("/.config");

QVariantMap args;
args[QStringLiteral("sddmUserConfig")] = sddmUserConfigPath;

KAuth::Action resetAction(QStringLiteral("org.kde.kcontrol.kcmsddm.reset"));
resetAction.setHelperId(QStringLiteral("org.kde.kcontrol.kcmsddm"));
resetAction.setArguments(args);

auto job = resetAction.execute();
job->exec();

if (job->error()){
qDebug() << "Reset failed";
qDebug() << job->errorString();
qDebug() << job->errorText();
KMessageBox::error(this, job->errorText());
} else {
changed(false);
qDebug() << "Reset successful";
}
}
4 changes: 4 additions & 0 deletions src/advanceconfig.h
Expand Up @@ -41,6 +41,10 @@ class AdvanceConfig : public QWidget
Q_SIGNALS:
void changed(bool changed=true);

public Q_SLOTS:
void syncSettingsChanged();
void resetSettingsChanged();

private Q_SLOTS:
void slotUidRangeChanged();

Expand Down

0 comments on commit f9e7535

Please sign in to comment.