File indexing completed on 2024-11-10 04:56:48
0001 /* 0002 SPDX-FileCopyrightText: 2021 Dan Leinir Turthra Jensen <admin@leinir.dk> 0003 0004 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 */ 0006 0007 #include "kwindecorationsettings.h" 0008 0009 #include "decorationmodel.h" 0010 0011 #include <KLocalizedString> 0012 0013 #include <QCommandLineParser> 0014 #include <QCoreApplication> 0015 #include <QDBusConnection> 0016 #include <QDBusMessage> 0017 #include <QDebug> 0018 #include <QFileInfo> 0019 #include <QTimer> 0020 0021 int main(int argc, char **argv) 0022 { 0023 QCoreApplication app(argc, argv); 0024 int exitCode{0}; 0025 QCoreApplication::setApplicationName(QStringLiteral("kwin-applywindowdecoration")); 0026 QCoreApplication::setApplicationVersion(QStringLiteral("1.0")); 0027 QCoreApplication::setOrganizationDomain(QStringLiteral("kde.org")); 0028 KLocalizedString::setApplicationDomain(QByteArrayLiteral("kwin-applywindowdecoration")); 0029 0030 QCommandLineParser *parser = new QCommandLineParser; 0031 parser->addHelpOption(); 0032 parser->setApplicationDescription(i18n("This tool allows you to set the window decoration theme for the currently active session, without accidentally setting it to one that is either not available, or which is already set.")); 0033 parser->addPositionalArgument(QStringLiteral("theme"), i18n("The name of the window decoration theme you wish to set for KWin. Passing a full path will attempt to find a theme in that directory, and then apply that if one can be deduced.")); 0034 parser->addOption(QCommandLineOption(QStringLiteral("list-themes"), i18n("Show all the themes available on the system (and which is the current theme)"))); 0035 parser->process(app); 0036 0037 KDecoration2::Configuration::DecorationsModel *model = new KDecoration2::Configuration::DecorationsModel(&app); 0038 model->init(); 0039 KWinDecorationSettings *settings = new KWinDecorationSettings(&app); 0040 QTextStream ts(stdout); 0041 if (!parser->positionalArguments().isEmpty()) { 0042 QString requestedTheme{parser->positionalArguments().constFirst()}; 0043 if (requestedTheme.endsWith(QStringLiteral("/*"))) { 0044 // Themes installed through KNewStuff will commonly be given an installed files entry 0045 // which has the main directory name and an asterix to say the cursors are all in that directory, 0046 // and since one of the main purposes of this tool is to allow adopting things from a kns dialog, 0047 // we handle that little weirdness here. 0048 requestedTheme.remove(requestedTheme.length() - 2, 2); 0049 } 0050 0051 bool themeResolved{true}; 0052 if (requestedTheme.contains(QStringLiteral("/"))) { 0053 themeResolved = false; 0054 if (QFileInfo::exists(requestedTheme) && QFileInfo(requestedTheme).isDir()) { 0055 // Since this is the name of a directory, let's do a bit of checking to see 0056 // if we know enough about it to deduce that this is, in fact, a theme. 0057 QStringList splitTheme = requestedTheme.split(QStringLiteral("/"), Qt::SkipEmptyParts); 0058 if (splitTheme.count() > 3 && splitTheme[splitTheme.count() - 3] == QStringLiteral("aurorae") && splitTheme[splitTheme.count() - 2] == QStringLiteral("themes")) { 0059 // We think this is an aurorae theme, but let's just make a little more certain... 0060 QString file(QStringLiteral("aurorae/themes/%1/metadata.desktop").arg(splitTheme.last())); 0061 QString path = QStandardPaths::locate(QStandardPaths::GenericDataLocation, file); 0062 if (!path.isEmpty() && path == QStringLiteral("%1/metadata.desktop").arg(requestedTheme)) { 0063 requestedTheme = QString("__aurorae__svg__").append(splitTheme.last()); 0064 themeResolved = true; 0065 ts << i18n("Resolved %1 to the KWin Aurorae theme \"%2\", and will attempt to set that as your current theme.") 0066 .arg(parser->positionalArguments().first(), requestedTheme) 0067 << Qt::endl; 0068 } 0069 } 0070 } else { 0071 ts << i18n("You attempted to pass a file path, but this could not be resolved to a theme, and we will have to abort, due to having no theme to set") << Qt::endl; 0072 exitCode = -1; 0073 } 0074 } 0075 0076 if (settings->theme() == requestedTheme) { 0077 ts << i18n("The requested theme \"%1\" is already set as the window decoration theme.", requestedTheme) << Qt::endl; 0078 // not an error condition, just nothing happens 0079 } else if (themeResolved) { 0080 int index{-1}; 0081 QStringList availableThemes; 0082 for (int i = 0; i < model->rowCount(); ++i) { 0083 const QString themeName = model->data(model->index(i), KDecoration2::Configuration::DecorationsModel::ThemeNameRole).toString(); 0084 if (requestedTheme == themeName) { 0085 index = i; 0086 break; 0087 } 0088 availableThemes << themeName; 0089 } 0090 if (index > -1) { 0091 settings->setTheme(model->data(model->index(index), KDecoration2::Configuration::DecorationsModel::ThemeNameRole).toString()); 0092 settings->setPluginName(model->data(model->index(index), KDecoration2::Configuration::DecorationsModel::PluginNameRole).toString()); 0093 if (settings->save()) { 0094 // Send a signal to all kwin instances 0095 QDBusMessage message = QDBusMessage::createSignal(QStringLiteral("/KWin"), 0096 QStringLiteral("org.kde.KWin"), 0097 QStringLiteral("reloadConfig")); 0098 QDBusConnection::sessionBus().send(message); 0099 ts << i18n("Successfully applied the cursor theme %1 to your current Plasma session", 0100 model->data(model->index(index), KDecoration2::Configuration::DecorationsModel::ThemeNameRole).toString()) 0101 << Qt::endl; 0102 } else { 0103 ts << i18n("Failed to save your theme settings - the reason is unknown, but this is an unrecoverable error. You may find that simply trying again will work."); 0104 exitCode = -1; 0105 } 0106 } else { 0107 ts << i18n("Could not find theme \"%1\". The theme should be one of the following options: %2", requestedTheme, availableThemes.join(QStringLiteral(", "))) << Qt::endl; 0108 exitCode = -1; 0109 } 0110 } 0111 } else if (parser->isSet(QStringLiteral("list-themes"))) { 0112 ts << i18n("You have the following KWin window decoration themes on your system:") << Qt::endl; 0113 for (int i = 0; i < model->rowCount(); ++i) { 0114 const QString displayName = model->data(model->index(i), Qt::DisplayRole).toString(); 0115 const QString themeName = model->data(model->index(i), KDecoration2::Configuration::DecorationsModel::ThemeNameRole).toString(); 0116 if (settings->theme() == themeName) { 0117 ts << QStringLiteral(" * %1 (theme name: %2 - current theme for this Plasma session)").arg(displayName, themeName) << Qt::endl; 0118 } else { 0119 ts << QStringLiteral(" * %1 (theme name: %2)").arg(displayName, themeName) << Qt::endl; 0120 } 0121 } 0122 } else { 0123 parser->showHelp(); 0124 } 0125 QTimer::singleShot(0, &app, [&app, &exitCode]() { 0126 app.exit(exitCode); 0127 }); 0128 0129 return app.exec(); 0130 }