diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -193,6 +193,7 @@ KF5::Notifications KF5::CoreAddons KF5::ConfigGui + KF5::Package KF5::WindowSystem KF5::XmlGui ${X11_LIBRARIES} diff --git a/greeter/greeterapp.cpp b/greeter/greeterapp.cpp --- a/greeter/greeterapp.cpp +++ b/greeter/greeterapp.cpp @@ -195,7 +195,7 @@ m_mainQmlPath = package.fileUrl("lockscreenmainscript"); m_wallpaperIntegration->setConfig(KScreenSaverSettingsBase::self()->sharedConfig()); - m_wallpaperIntegration->setPluginName(KScreenSaverSettingsBase::self()->wallpaperPlugin()); + m_wallpaperIntegration->setPluginName(KScreenSaverSettingsBase::self()->wallpaperPluginId()); m_wallpaperIntegration->init(); m_lnfIntegration->setPackage(package); diff --git a/kcfg/kscreenlockersettings.kcfg b/kcfg/kscreenlockersettings.kcfg --- a/kcfg/kscreenlockersettings.kcfg +++ b/kcfg/kscreenlockersettings.kcfg @@ -38,7 +38,7 @@ - + org.kde.image diff --git a/kcm/kcm.h b/kcm/kcm.h --- a/kcm/kcm.h +++ b/kcm/kcm.h @@ -68,7 +68,6 @@ void updateState(); private: - void loadWallpapers(); void selectWallpaper(const QString &pluginId); void loadWallpaperConfig(); void loadLnfConfig(); @@ -94,6 +93,8 @@ QObject(parent), q(parent) { + connect(q, &ScreenLockerKcm::wallpaperConfigurationChanged, this, &ScreenLockerProxy::wallpaperConfigurationChanged); + connect(q, &ScreenLockerKcm::currentWallpaperChanged, this, &ScreenLockerProxy::currentWallpaperChanged); } KDeclarative::ConfigPropertyMap *wallpaperConfiguration() const { diff --git a/kcm/kcm.cpp b/kcm/kcm.cpp --- a/kcm/kcm.cpp +++ b/kcm/kcm.cpp @@ -40,8 +40,6 @@ #include #include -static const QString s_defaultWallpaperPackage = QStringLiteral("org.kde.image"); - class ScreenLockerKcmForm : public QWidget, public Ui::ScreenLockerKcmForm { Q_OBJECT @@ -68,56 +66,33 @@ { QVBoxLayout* layout = new QVBoxLayout(this); layout->addWidget(m_ui); - - addConfig(m_settings, m_ui); - - loadWallpapers(); - connect(m_ui->wallpaperCombo, static_cast(&QComboBox::currentIndexChanged), + for (const auto &pluginInfo : m_settings->availableWallpaperPlugins()) { + m_ui->kcfg_wallpaperPluginIndex->addItem(pluginInfo.name, pluginInfo.id); + } + connect(m_ui->kcfg_wallpaperPluginIndex, static_cast(&QComboBox::currentIndexChanged), this, &ScreenLockerKcm::loadWallpaperConfig); - - m_ui->wallpaperCombo->installEventFilter(this); + m_ui->kcfg_wallpaperPluginIndex->installEventFilter(this); + m_ui->installEventFilter(this); auto proxy = new ScreenLockerProxy(this); + m_ui->wallpaperConfigWidget->setClearColor(m_ui->palette().color(QPalette::Active, QPalette::Window)); m_ui->wallpaperConfigWidget->rootContext()->setContextProperty(QStringLiteral("configDialog"), proxy); - - m_ui->lnfConfigWidget->setClearColor(m_ui->palette().color(QPalette::Active, QPalette::Window)); - m_ui->lnfConfigWidget->rootContext()->setContextProperty(QStringLiteral("configDialog"), proxy); - - - - connect(this, &ScreenLockerKcm::wallpaperConfigurationChanged, proxy, &ScreenLockerProxy::wallpaperConfigurationChanged); - connect(this, &ScreenLockerKcm::currentWallpaperChanged, proxy, &ScreenLockerProxy::currentWallpaperChanged); - m_ui->wallpaperConfigWidget->setSource(QUrl(QStringLiteral("qrc:/kscreenlocker-kcm-resources/wallpaperconfig.qml"))); connect(m_ui->wallpaperConfigWidget->rootObject(), SIGNAL(configurationChanged()), this, SLOT(updateState())); + m_ui->lnfConfigWidget->setClearColor(m_ui->palette().color(QPalette::Active, QPalette::Window)); + m_ui->lnfConfigWidget->rootContext()->setContextProperty(QStringLiteral("configDialog"), proxy); m_ui->lnfConfigWidget->setSource(QUrl(QStringLiteral("qrc:/kscreenlocker-kcm-resources/lnfconfig.qml"))); connect(m_ui->lnfConfigWidget->rootObject(), SIGNAL(configurationChanged()), this, SLOT(updateState())); - m_ui->installEventFilter(this); + addConfig(m_settings, m_ui); } void ScreenLockerKcm::load() { KCModule::load(); - // Because the wallpaper plugin is currently handled wrongly - m_settings->load(); - m_package = KPackage::PackageLoader::self()->loadPackage(QStringLiteral("Plasma/LookAndFeel")); - KConfigGroup cg(KSharedConfig::openConfig(QStringLiteral("kdeglobals")), "KDE"); - const QString packageName = cg.readEntry("LookAndFeelPackage", QString()); - if (!packageName.isEmpty()) { - m_package.setPath(packageName); - } - - m_lnfIntegration = new ScreenLocker::LnFIntegration(this); - m_lnfIntegration->setPackage(m_package); - m_lnfIntegration->setConfig(m_settings->sharedConfig()); - m_lnfIntegration->init(); - m_lnfSettings = m_lnfIntegration->configScheme(); - - selectWallpaper(m_settings->wallpaperPlugin()); loadWallpaperConfig(); loadLnfConfig(); @@ -159,7 +134,6 @@ void ScreenLockerKcm::defaults() { KCModule::defaults(); - selectWallpaper(s_defaultWallpaperPackage); if (m_lnfSettings) { m_lnfSettings->setDefaults(); @@ -193,33 +167,10 @@ emit defaulted(isDefaults); } -void ScreenLockerKcm::loadWallpapers() -{ - const auto wallpaperPackages = KPackage::PackageLoader::self()->listPackages(QStringLiteral("Plasma/Wallpaper")); - for (auto &package : wallpaperPackages) { - m_ui->wallpaperCombo->addItem(package.name(), package.pluginId()); - } -} - -void ScreenLockerKcm::selectWallpaper(const QString &pluginId) -{ - const auto index = m_ui->wallpaperCombo->findData(pluginId); - if (index != -1) { - m_ui->wallpaperCombo->setCurrentIndex(index); - } else if (pluginId != s_defaultWallpaperPackage) { - // fall back to default plugin - selectWallpaper(s_defaultWallpaperPackage); - } -} - void ScreenLockerKcm::loadWallpaperConfig() { - // set the wallpaper config - m_settings->setWallpaperPlugin(m_ui->wallpaperCombo->currentData().toString()); - updateState(); - if (m_wallpaperIntegration) { - if (m_wallpaperIntegration->pluginName() == m_ui->wallpaperCombo->currentData().toString()) { + if (m_wallpaperIntegration->pluginName() == m_ui->kcfg_wallpaperPluginIndex->currentData().toString()) { // nothing changed return; } @@ -229,7 +180,7 @@ m_wallpaperIntegration = new ScreenLocker::WallpaperIntegration(this); m_wallpaperIntegration->setConfig(m_settings->sharedConfig()); - m_wallpaperIntegration->setPluginName(m_ui->wallpaperCombo->currentData().toString()); + m_wallpaperIntegration->setPluginName(m_ui->kcfg_wallpaperPluginIndex->currentData().toString()); m_wallpaperIntegration->init(); m_wallpaperSettings = m_wallpaperIntegration->configScheme(); m_ui->wallpaperConfigWidget->rootContext()->setContextProperty(QStringLiteral("wallpaper"), m_wallpaperIntegration); @@ -239,6 +190,25 @@ void ScreenLockerKcm::loadLnfConfig() { + if (m_package.isValid() && m_lnfIntegration) { + return; + } + + Q_ASSERT(!m_package.isValid() && !m_lnfIntegration); + + m_package = KPackage::PackageLoader::self()->loadPackage(QStringLiteral("Plasma/LookAndFeel")); + KConfigGroup cg(KSharedConfig::openConfig(QStringLiteral("kdeglobals")), "KDE"); + const QString packageName = cg.readEntry("LookAndFeelPackage", QString()); + if (!packageName.isEmpty()) { + m_package.setPath(packageName); + } + + m_lnfIntegration = new ScreenLocker::LnFIntegration(this); + m_lnfIntegration->setPackage(m_package); + m_lnfIntegration->setConfig(m_settings->sharedConfig()); + m_lnfIntegration->init(); + m_lnfSettings = m_lnfIntegration->configScheme(); + auto sourceFile = m_package.fileUrl(QByteArrayLiteral("lockscreen"), QStringLiteral("config.qml")); if (sourceFile.isEmpty()) { m_ui->lnfConfigWidget->hide(); @@ -266,7 +236,7 @@ QString ScreenLockerKcm::currentWallpaper() const { - return m_ui->wallpaperCombo->currentData().toString(); + return m_ui->kcfg_wallpaperPluginIndex->currentData().toString(); } bool ScreenLockerKcm::eventFilter(QObject *watched, QEvent *event) @@ -277,17 +247,17 @@ } return false; } - if (watched != m_ui->wallpaperCombo) { + if (watched != m_ui->kcfg_wallpaperPluginIndex) { return false; } if (event->type() == QEvent::Move) { if (auto object = m_ui->wallpaperConfigWidget->rootObject()) { // QtQuick Layouts have a hardcoded 5 px spacing by default - object->setProperty("formAlignment", m_ui->wallpaperCombo->x() + 5); + object->setProperty("formAlignment", m_ui->kcfg_wallpaperPluginIndex->x() + 5); } if (auto object = m_ui->lnfConfigWidget->rootObject()) { // QtQuick Layouts have a hardcoded 5 px spacing by default - object->setProperty("formAlignment", m_ui->wallpaperCombo->x() + 5); + object->setProperty("formAlignment", m_ui->kcfg_wallpaperPluginIndex->x() + 5); } } diff --git a/kcm/kcm.ui b/kcm/kcm.ui --- a/kcm/kcm.ui +++ b/kcm/kcm.ui @@ -141,12 +141,12 @@ Wallpaper &type: - wallpaperCombo + kcfg_wallpaperPluginIndex - + diff --git a/kscreensaversettings.h b/kscreensaversettings.h --- a/kscreensaversettings.h +++ b/kscreensaversettings.h @@ -28,16 +28,30 @@ { Q_OBJECT Q_PROPERTY(QKeySequence shortcut READ shortcut WRITE setShortcut) + Q_PROPERTY(int wallpaperPluginIndex READ wallpaperPluginIndex WRITE setWallpaperPluginIndex) public: + struct WallpaperInfo { + QString name; + QString id; + }; + static QList defaultShortcuts(); + static QString defaultWallpaperPlugin(); KScreenSaverSettings(QObject *parent = nullptr); ~KScreenSaverSettings() override; + QVector availableWallpaperPlugins() const; + int wallpaperPluginIndex() const; + void setWallpaperPluginIndex(int index); + QKeySequence shortcut() const; void setShortcut(const QKeySequence &sequence); private: + int indexFromWallpaperPluginId(const QString &id) const; + + QVector m_availableWallpaperPlugins; KActionCollection *m_actionCollection; QAction *m_lockAction; }; diff --git a/kscreensaversettings.cpp b/kscreensaversettings.cpp --- a/kscreensaversettings.cpp +++ b/kscreensaversettings.cpp @@ -22,6 +22,8 @@ #include #include #include +#include +#include QList KScreenSaverSettings::defaultShortcuts() { @@ -32,26 +34,59 @@ }; } +QString KScreenSaverSettings::defaultWallpaperPlugin() +{ + return QStringLiteral("org.kde.image"); +} + KScreenSaverSettings::KScreenSaverSettings(QObject *parent) : KScreenSaverSettingsBase() , m_actionCollection(new KActionCollection(this, QStringLiteral("ksmserver"))) , m_lockAction(nullptr) { setParent(parent); + const auto wallpaperPackages = KPackage::PackageLoader::self()->listPackages(QStringLiteral("Plasma/Wallpaper")); + for (auto &package : wallpaperPackages) { + m_availableWallpaperPlugins.append({package.name(), package.pluginId()}); + } + m_actionCollection->setConfigGlobal(true); m_lockAction = m_actionCollection->addAction(QStringLiteral("Lock Session")); m_lockAction->setProperty("isConfigurationAction", true); m_lockAction->setText(i18n("Lock Session")); KGlobalAccel::self()->setShortcut(m_lockAction, defaultShortcuts()); addItem(new KPropertySkeletonItem(this, "shortcut", defaultShortcuts().first()), QStringLiteral("lockscreenShortcut")); + addItem(new KPropertySkeletonItem(this, "wallpaperPluginIndex", indexFromWallpaperPluginId(defaultWallpaperPlugin())), + QStringLiteral("wallpaperPluginIndex")); } KScreenSaverSettings::~KScreenSaverSettings() { } +QVector KScreenSaverSettings::availableWallpaperPlugins() const +{ + return m_availableWallpaperPlugins; +} + +int KScreenSaverSettings::wallpaperPluginIndex() const +{ + return indexFromWallpaperPluginId(wallpaperPluginId()); +} + +void KScreenSaverSettings::setWallpaperPluginIndex(int index) +{ + Q_ASSERT(index >=0 && index < m_availableWallpaperPlugins.size()); + setWallpaperPluginId(m_availableWallpaperPlugins[index].id); + + // We get in this function during save, but wallpaperPluginId might + // have been written already, since we're tempering with its value here + // we make sure it really reaches the config object. + findItem(QStringLiteral("wallpaperPluginId"))->writeConfig(config()); +} + QKeySequence KScreenSaverSettings::shortcut() const { return KGlobalAccel::self()->shortcut(m_lockAction).first(); @@ -67,3 +102,16 @@ shortcuts[0] = sequence; KGlobalAccel::self()->setShortcut(m_lockAction, shortcuts, KGlobalAccel::NoAutoloading); } + +int KScreenSaverSettings::indexFromWallpaperPluginId(const QString &id) const +{ + const auto it = std::find_if(m_availableWallpaperPlugins.cbegin(), m_availableWallpaperPlugins.cend(), + [id] (const WallpaperInfo &info) { return info.id == id; }); + if (it != m_availableWallpaperPlugins.cend()) { + return it - m_availableWallpaperPlugins.cbegin(); + } else if (id != defaultWallpaperPlugin()) { + return indexFromWallpaperPluginId(defaultWallpaperPlugin()); + } else { + return -1; + } +}