From 77e59801d0306d11a071cc7e7b7796f2d1fc16e0 Mon Sep 17 00:00:00 2001 From: Devin Lin Date: Wed, 20 Dec 2023 22:45:14 -0800 Subject: [PATCH] wallpaperimageplugin: Add plugin to allow for wallpaper editing in the shell --- components/CMakeLists.txt | 1 + .../wallpaperimageplugin/CMakeLists.txt | 34 ++ .../qml/WallpaperPluginConfigLoader.qml | 106 ++++++ .../wallpaperimageplugin/wallpaperplugin.cpp | 360 ++++++++++++++++++ .../wallpaperimageplugin/wallpaperplugin.h | 105 +++++ kcms/hotspot/ui/main.qml | 3 + kcms/virtualkeyboard/ui/main.qml | 4 +- 7 files changed, 610 insertions(+), 3 deletions(-) create mode 100644 components/wallpaperimageplugin/CMakeLists.txt create mode 100644 components/wallpaperimageplugin/qml/WallpaperPluginConfigLoader.qml create mode 100644 components/wallpaperimageplugin/wallpaperplugin.cpp create mode 100644 components/wallpaperimageplugin/wallpaperplugin.h diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index c43e16b6..8bdcbb76 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -9,3 +9,4 @@ add_subdirectory(mobileshellstate) add_subdirectory(quicksettingsplugin) add_subdirectory(windowplugin) add_subdirectory(shellsettingsplugin) +add_subdirectory(wallpaperimageplugin) diff --git a/components/wallpaperimageplugin/CMakeLists.txt b/components/wallpaperimageplugin/CMakeLists.txt new file mode 100644 index 00000000..898fbdef --- /dev/null +++ b/components/wallpaperimageplugin/CMakeLists.txt @@ -0,0 +1,34 @@ +# SPDX-FileCopyrightText: 2023 Devin Lin +# SPDX-License-Identifier: GPL-2.0-or-later + +ecm_add_qml_module(wallpaperimageplugin URI org.kde.plasma.private.mobileshell.wallpaperimageplugin GENERATE_PLUGIN_SOURCE) +target_sources(wallpaperimageplugin PRIVATE + wallpaperplugin.cpp +) + +# Include qml and js files within ./qml/ +file(GLOB_RECURSE _qml_sources + "qml/*.qml" + "qml/*.js" +) +ecm_target_qml_sources(wallpaperimageplugin SOURCES ${_qml_sources}) + +target_link_libraries(wallpaperimageplugin PRIVATE + Qt::Qml + Qt::Gui + Qt::Quick + Qt::DBus + Qt::Widgets + Plasma::Plasma + Plasma::PlasmaQuick + KF6::CoreAddons + KF6::I18n + KF6::ConfigCore + KF6::ConfigGui + KF6::ConfigQml + KF6::Package + QCoro::DBus + PW::KWorkspace +) + +ecm_finalize_qml_module(wallpaperimageplugin) diff --git a/components/wallpaperimageplugin/qml/WallpaperPluginConfigLoader.qml b/components/wallpaperimageplugin/qml/WallpaperPluginConfigLoader.qml new file mode 100644 index 00000000..206c5e1e --- /dev/null +++ b/components/wallpaperimageplugin/qml/WallpaperPluginConfigLoader.qml @@ -0,0 +1,106 @@ +// SPDX-FileCopyrightText: 2013 Marco Martin +// SPDX-FileCopyrightText: 2014 Kai Uwe Broulik +// SPDX-FileCopyrightText: 2019 David Redondo +// SPDX-FileCopyrightText: 2023 Méven Car +// SPDX-FileCopyrightText: 2023 Devin Lin +// SPDX-License-Identifier: LGPL-2.0-or-later + +import QtQuick +import QtQuick.Controls as QQC2 +import org.kde.plasma.private.mobileshell.wallpaperimageplugin as WallpaperImagePlugin + +QQC2.StackView { + id: root + + property string wallpaperPlugin + property string wallpaperPluginSource + property var wallpaperPluginConfig + property var wallpaperPluginModel + + property var configDialog: QtObject { + property string currentWallpaper: root.wallpaperPlugin + } + + function onConfigurationChanged() { + for (var key in root.wallpaperPluginConfig) { + const cfgKey = "cfg_" + key; + if (root.currentItem[cfgKey] !== undefined) { + root.wallpaperPluginConfig[key] = root.currentItem[cfgKey] + } + } + } + + onWallpaperPluginSourceChanged: { + loadSourceFile(); + } + + onWallpaperPluginConfigChanged: { + onWallpaperConfigurationChanged(); + } + + function onWallpaperConfigurationChanged() { + let wallpaperConfig = root.wallpaperPluginConfig + if (!wallpaperConfig || !root.currentItem) { + return; + } + wallpaperConfig.keys().forEach(key => { + const cfgKey = "cfg_" + key; + if (cfgKey in root.currentItem) { + + var changedSignal = root.currentItem[cfgKey + "Changed"] + if (changedSignal) { + changedSignal.disconnect(root.onConfigurationChanged); + } + root.currentItem[cfgKey] = wallpaperConfig[key]; + + changedSignal = root.currentItem[cfgKey + "Changed"] + if (changedSignal) { + changedSignal.connect(root.onConfigurationChanged) + } + } + }) + } + + function loadSourceFile() { + let wallpaperConfig = root.wallpaperPluginConfig; + let wallpaperPluginSource = root.wallpaperPluginSource; + + // BUG 407619: wallpaperConfig can be null before calling `ContainmentItem::loadWallpaper()` + if (wallpaperConfig && wallpaperPluginSource) { + var props = { + "configDialog": root.configDialog, + "wallpaperConfiguration": wallpaperConfig + }; + + wallpaperConfig.keys().forEach(key => { + // Preview is not part of the config, only of the WallpaperObject + if (!key.startsWith("Preview")) { + props["cfg_" + key] = wallpaperConfig[key]; + } + }); + + var newItem = replace(Qt.resolvedUrl(wallpaperPluginSource), props) + + wallpaperConfig.keys().forEach(key => { + const cfgKey = "cfg_" + key; + if (cfgKey in root.currentItem) { + var changedSignal = root.currentItem[cfgKey + "Changed"] + if (changedSignal) { + changedSignal.connect(root.onConfigurationChanged) + } + } + }); + + const configurationChangedSignal = newItem.configurationChanged + if (configurationChangedSignal) { + configurationChangedSignal.connect(root.onConfigurationChanged) + } + } else { + replace(emptyConfig) + } + } + + Item { + id: emptyConfig + } +} diff --git a/components/wallpaperimageplugin/wallpaperplugin.cpp b/components/wallpaperimageplugin/wallpaperplugin.cpp new file mode 100644 index 00000000..f9d10952 --- /dev/null +++ b/components/wallpaperimageplugin/wallpaperplugin.cpp @@ -0,0 +1,360 @@ +// SPDX-FileCopyrightText: 2023 Méven Car +// SPDX-FileCopyrightText: 2023 Devin Lin +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "wallpaperplugin.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +WallpaperPlugin::WallpaperPlugin(QObject *parent) + : QObject{parent} + , m_homescreenConfig{new QQmlPropertyMap{this}} + , m_lockscreenConfig{new QQmlPropertyMap{this}} + , m_homescreenConfigFile{KSharedConfig::openConfig("plasma-org.kde.plasma.mobileshell-appletsrc", KConfig::SimpleConfig)} + , m_lockscreenConfigFile{KSharedConfig::openConfig("kscreenlockerrc", KConfig::SimpleConfig)} +{ + m_lockscreenConfigWatcher = KConfigWatcher::create(m_lockscreenConfigFile); + + const bool connected = QDBusConnection::sessionBus().connect(QStringLiteral("org.kde.plasmashell"), + QStringLiteral("/PlasmaShell"), + QStringLiteral("org.kde.PlasmaShell"), + QStringLiteral("wallpaperChanged"), + this, + SLOT(loadHomescreenSettings())); + if (!connected) { + qWarning() << "Could not connect to dbus service org.kde.plasmashell to listen to wallpaperChanged"; + } + + connect(m_lockscreenConfigWatcher.data(), &KConfigWatcher::configChanged, this, [this](const KConfigGroup &group, const QByteArrayList &names) { + loadLockscreenSettings(); + }); + + loadLockscreenSettings(); + loadHomescreenSettings(); +} + +PlasmaQuick::ConfigModel *WallpaperPlugin::wallpaperPluginModel() +{ + if (!m_wallpaperPluginModel) { + m_wallpaperPluginModel = new WallpaperConfigModel(this); + QDBusConnection::sessionBus().connect(QString(), + QStringLiteral("/KPackage/Plasma/Wallpaper"), + QStringLiteral("org.kde.plasma.kpackage"), + QStringLiteral("packageInstalled"), + m_wallpaperPluginModel, + SLOT(repopulate())); + QDBusConnection::sessionBus().connect(QString(), + QStringLiteral("/KPackage/Plasma/Wallpaper"), + QStringLiteral("org.kde.plasma.kpackage"), + QStringLiteral("packageUpdated"), + m_wallpaperPluginModel, + SLOT(repopulate())); + QDBusConnection::sessionBus().connect(QString(), + QStringLiteral("/KPackage/Plasma/Wallpaper"), + QStringLiteral("org.kde.plasma.kpackage"), + QStringLiteral("packageUninstalled"), + m_wallpaperPluginModel, + SLOT(repopulate())); + } + return m_wallpaperPluginModel; +} + +QQmlPropertyMap *WallpaperPlugin::homescreenConfiguration() const +{ + return m_homescreenConfig; +} + +QQmlPropertyMap *WallpaperPlugin::lockscreenConfiguration() const +{ + return m_lockscreenConfig; +} + +QString WallpaperPlugin::homescreenWallpaperPlugin() const +{ + return m_homescreenWallpaperPlugin; +} + +QString WallpaperPlugin::homescreenWallpaperPluginSource() +{ + if (m_homescreenWallpaperPlugin.isEmpty()) { + return QString(); + } + + const auto model = wallpaperPluginModel(); + const auto wallpaperPluginCount = model->count(); + for (int i = 0; i < wallpaperPluginCount; ++i) { + if (model->data(model->index(i), PlasmaQuick::ConfigModel::PluginNameRole) == m_homescreenWallpaperPlugin) { + return model->data(model->index(i), PlasmaQuick::ConfigModel::SourceRole).toString(); + } + } + + return QString(); +} + +void WallpaperPlugin::setHomescreenWallpaperPlugin(const QString &wallpaperPlugin) +{ + auto containmentsGroup = m_homescreenConfigFile->group(QStringLiteral("Containments")); + + for (const auto &contIndex : containmentsGroup.groupList()) { + const auto contConfig = containmentsGroup.group(contIndex); + if (contConfig.readEntry("activityId").isEmpty()) { + continue; + } + + QString containmentIdx = contIndex; + auto containmentConfigGroup = containmentsGroup.group(containmentIdx); + + // pick first screen that is found to load the wallpaper plugin + m_homescreenConfig = loadConfiguration(containmentConfigGroup, wallpaperPlugin, true); + m_homescreenWallpaperPlugin = wallpaperPlugin; + break; + } + + // saveHomescreenSettings(); + Q_EMIT homescreenWallpaperPluginChanged(); +} + +QString WallpaperPlugin::lockscreenWallpaperPlugin() const +{ + return m_lockscreenWallpaperPlugin; +} + +QString WallpaperPlugin::lockscreenWallpaperPluginSource() +{ + if (m_lockscreenWallpaperPlugin.isEmpty()) { + return QString(); + } + + const auto model = wallpaperPluginModel(); + const auto wallpaperPluginCount = model->count(); + for (int i = 0; i < wallpaperPluginCount; ++i) { + if (model->data(model->index(i), PlasmaQuick::ConfigModel::PluginNameRole) == m_lockscreenWallpaperPlugin) { + return model->data(model->index(i), PlasmaQuick::ConfigModel::SourceRole).toString(); + } + } + + return QString(); +} + +void WallpaperPlugin::setLockscreenWallpaperPlugin(const QString &wallpaperPlugin) +{ + KConfigGroup greeterGroup = m_lockscreenConfigFile->group(QStringLiteral("Greeter")).group(QStringLiteral("Wallpaper")).group(wallpaperPlugin); + + m_homescreenConfig = loadConfiguration(greeterGroup, wallpaperPlugin, true); + m_lockscreenWallpaperPlugin = wallpaperPlugin; + saveLockscreenSettings(); + + Q_EMIT lockscreenWallpaperPluginChanged(); +} + +QCoro::Task WallpaperPlugin::setHomescreenWallpaper(const QString &path) +{ + auto message = QDBusMessage::createMethodCall(QLatin1String("org.kde.plasmashell"), + QLatin1String("/PlasmaShell"), + QLatin1String("org.kde.PlasmaShell"), + QLatin1String("setWallpaper")); + + for (uint screen = 0; screen < qApp->screens().size(); screen++) { + message.setArguments({"org.kde.image", QVariantMap{{"Image", path}}, screen}); + + const QDBusReply reply = co_await QDBusConnection::sessionBus().asyncCall(message); + if (!reply.isValid()) { + qWarning() << "Failed to set wallpaper for screen" << screen << ":" << reply.error(); + } + } +} + +void WallpaperPlugin::setLockscreenWallpaper(const QString &path) +{ + auto greeterGroup = m_lockscreenConfigFile->group(QStringLiteral("Greeter")) + .group(QStringLiteral("Wallpaper")) + .group(QStringLiteral("org.kde.image")) + .group(QStringLiteral("General")); + greeterGroup.writeEntry("Image", path, KConfigGroup::Notify); + + greeterGroup = m_lockscreenConfigFile->group(QStringLiteral("Greeter")); + greeterGroup.writeEntry("WallpaperPlugin", "org.kde.image", KConfigGroup::Notify); + + m_lockscreenConfigFile->sync(); +} + +QString WallpaperPlugin::homescreenWallpaperPath() +{ + return m_homescreenWallpaperPath; +} + +QString WallpaperPlugin::lockscreenWallpaperPath() +{ + return m_lockscreenWallpaperPath; +} + +QCoro::Task WallpaperPlugin::loadHomescreenSettings() +{ + auto message = QDBusMessage::createMethodCall(QLatin1String("org.kde.plasmashell"), + QLatin1String("/PlasmaShell"), + QLatin1String("org.kde.PlasmaShell"), + QLatin1String("wallpaper")); + message.setArguments({(uint)0}); // assume wallpaper on first screen + + QDBusReply reply = co_await QDBusConnection::sessionBus().asyncCall(message); + if (!reply.isValid()) { + qWarning() << "unable to load homescreen wallpaper settings:" << reply.error(); + co_return; + } + + QVariantMap map = reply.value(); + m_homescreenWallpaperPath = QString{}; + + if (!map.contains("wallpaperPlugin")) { + qWarning() << "wallpaperPlugin not found in response from org.kde.PlasmaShell wallpaper(), could not retrieve wallpaper"; + Q_EMIT homescreenWallpaperPathChanged(); + co_return; + } + + // load wallpaper plugin config + if (m_homescreenConfig) { + m_homescreenConfig->deleteLater(); + } + m_homescreenConfig = new QQmlPropertyMap{this}; + + for (const auto &key : map.keys()) { + if (key != QStringLiteral("wallpaperPlugin")) { + m_homescreenConfig->insert(key, map[key]); + } + } + + // get wallpaper plugin + m_homescreenWallpaperPlugin = map["wallpaperPlugin"].toString(); + + // parse image configuration + if (m_homescreenWallpaperPlugin == QStringLiteral("org.kde.image")) { + m_homescreenWallpaperPath = map["Image"].toString(); + } + + Q_EMIT homescreenConfigurationChanged(); + Q_EMIT homescreenWallpaperPluginChanged(); + Q_EMIT homescreenWallpaperPathChanged(); +} + +void WallpaperPlugin::loadLockscreenSettings() +{ + auto greeterGroup = m_lockscreenConfigFile->group(QStringLiteral("Greeter")); + m_lockscreenWallpaperPlugin = greeterGroup.readEntry(QStringLiteral("WallpaperPlugin"), QString()); + m_lockscreenWallpaperPath = QString{}; + + greeterGroup = m_lockscreenConfigFile->group(QStringLiteral("Greeter")).group(QStringLiteral("Wallpaper")).group(m_lockscreenWallpaperPlugin); + + m_lockscreenConfig = static_cast(loadConfiguration(greeterGroup, m_lockscreenWallpaperPlugin, true)); + + if (m_lockscreenWallpaperPlugin == QStringLiteral("org.kde.image")) { + m_lockscreenWallpaperPath = greeterGroup.group(QStringLiteral("General")).readEntry(QStringLiteral("Image"), QString()); + } + + Q_EMIT lockscreenWallpaperPluginChanged(); + Q_EMIT lockscreenConfigurationChanged(); + Q_EMIT lockscreenWallpaperPathChanged(); +} + +QQmlPropertyMap *WallpaperPlugin::loadConfiguration(KConfigGroup group, QString wallpaperPlugin, bool loadDefaults) +{ + auto packages = KPackage::PackageLoader::self()->listPackages(QStringLiteral("Plasma/Wallpaper"), "plasma/wallpapers"); + KPackage::Package pkg; + bool found = false; + + for (auto &metaData : packages) { + if (metaData.pluginId() == wallpaperPlugin) { + found = true; + pkg = KPackage::PackageLoader::self()->loadPackage(QStringLiteral("Plasma/Wallpaper"), QFileInfo(metaData.fileName()).path()); + break; + } + } + + if (!found || !pkg.isValid()) { + qWarning() << "Could not find wallpaper plugin" << wallpaperPlugin; + return nullptr; + } + + QFile file(pkg.fileUrl("config", "main.xml").toLocalFile()); + + auto *configLoader = new KConfigLoader(group, &file, this); + if (loadDefaults) { + configLoader->setDefaults(); + } + auto config = new KConfigPropertyMap(configLoader, this); + return config; +} + +QCoro::Task WallpaperPlugin::saveHomescreenSettings() +{ + auto iface = new QDBusInterface("org.kde.plasmashell", "/PlasmaShell", "org.kde.PlasmaShell", QDBusConnection::sessionBus(), this); + if (!iface->isValid()) { + qWarning() << "Failed to connect to wallpaper dbus:" << qPrintable(QDBusConnection::sessionBus().lastError().message()); + co_return; + } + + QVariantMap params; + for (const auto &key : m_homescreenConfig->keys()) { + params.insert(key, m_homescreenConfig->value(key).toString()); + } + + if (m_homescreenWallpaperPlugin == "org.kde.image") { + params.remove("PreviewImage"); + } + + for (uint screen = 0; screen < qApp->screens().size(); screen++) { + QList args = {m_homescreenWallpaperPlugin, params, screen}; + const QDBusReply response = co_await iface->asyncCallWithArgumentList(QStringLiteral("setWallpaper"), args); + if (!response.isValid()) { + qWarning() << "Failed to set wallpaper:" << response.error(); + } + } +} + +void WallpaperPlugin::saveLockscreenSettings() +{ + auto greeterGroup = m_lockscreenConfigFile->group(QStringLiteral("Greeter")) + .group(QStringLiteral("Wallpaper")) + .group(m_lockscreenWallpaperPlugin) + .group(QStringLiteral("General")); + for (const auto &key : m_lockscreenConfig->keys()) { + greeterGroup.writeEntry(key, m_lockscreenConfig->value(key), KConfigGroup::Notify); + } + + greeterGroup = m_lockscreenConfigFile->group(QStringLiteral("Greeter")); + greeterGroup.writeEntry("WallpaperPlugin", m_lockscreenWallpaperPlugin, KConfigGroup::Notify); + + m_lockscreenConfigFile->sync(); +} + +WallpaperConfigModel::WallpaperConfigModel(QObject *parent) + : PlasmaQuick::ConfigModel(parent) +{ + repopulate(); +} + +void WallpaperConfigModel::repopulate() +{ + clear(); + for (const KPluginMetaData &m : KPackage::PackageLoader::self()->listPackages(QStringLiteral("Plasma/Wallpaper"))) { + KPackage::Package pkg = KPackage::PackageLoader::self()->loadPackage(QStringLiteral("Plasma/Wallpaper"), m.pluginId()); + if (!pkg.isValid()) { + continue; + } + appendCategory(pkg.metadata().iconName(), pkg.metadata().name(), pkg.fileUrl("ui", QStringLiteral("config.qml")).toString(), m.pluginId()); + } +} + +#include "wallpaperplugin.moc" \ No newline at end of file diff --git a/components/wallpaperimageplugin/wallpaperplugin.h b/components/wallpaperimageplugin/wallpaperplugin.h new file mode 100644 index 00000000..d73afb0a --- /dev/null +++ b/components/wallpaperimageplugin/wallpaperplugin.h @@ -0,0 +1,105 @@ +// SPDX-FileCopyrightText: 2023 Méven Car +// SPDX-FileCopyrightText: 2023 Devin Lin +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include + +class WallpaperConfigModel; +class WallpaperPlugin : public QObject +{ + Q_OBJECT + QML_ELEMENT + QML_SINGLETON + + Q_PROPERTY(QString homescreenWallpaperPath READ homescreenWallpaperPath NOTIFY homescreenWallpaperPathChanged) + Q_PROPERTY(QString lockscreenWallpaperPath READ lockscreenWallpaperPath NOTIFY lockscreenWallpaperPathChanged) + + Q_PROPERTY(QQmlPropertyMap *homescreenConfiguration READ homescreenConfiguration NOTIFY homescreenConfigurationChanged) + Q_PROPERTY(QQmlPropertyMap *lockscreenConfiguration READ lockscreenConfiguration NOTIFY lockscreenConfigurationChanged) + Q_PROPERTY(PlasmaQuick::ConfigModel *wallpaperPluginModel READ wallpaperPluginModel CONSTANT) + + Q_PROPERTY(QString homescreenWallpaperPlugin READ homescreenWallpaperPlugin WRITE setHomescreenWallpaperPlugin NOTIFY homescreenWallpaperPluginChanged) + Q_PROPERTY(QString homescreenWallpaperPluginSource READ homescreenWallpaperPluginSource NOTIFY homescreenWallpaperPluginChanged) + Q_PROPERTY(QString lockscreenWallpaperPlugin READ lockscreenWallpaperPlugin WRITE setLockscreenWallpaperPlugin NOTIFY lockscreenWallpaperPluginChanged) + Q_PROPERTY(QString lockscreenWallpaperPluginSource READ lockscreenWallpaperPluginSource NOTIFY lockscreenWallpaperPluginChanged) + +public: + WallpaperPlugin(QObject *parent = nullptr); + + PlasmaQuick::ConfigModel *wallpaperPluginModel(); + QQmlPropertyMap *homescreenConfiguration() const; + QQmlPropertyMap *lockscreenConfiguration() const; + + QString homescreenWallpaperPlugin() const; + QString homescreenWallpaperPluginSource(); + Q_INVOKABLE void setHomescreenWallpaperPlugin(const QString &wallpaperPlugin); + QString lockscreenWallpaperPlugin() const; + QString lockscreenWallpaperPluginSource(); + Q_INVOKABLE void setLockscreenWallpaperPlugin(const QString &wallpaperPlugin); + + // changes the plugin to org.kde.image and sets an image + Q_INVOKABLE QCoro::Task setHomescreenWallpaper(const QString &path); + Q_INVOKABLE void setLockscreenWallpaper(const QString &path); + + QString homescreenWallpaperPath(); + QString lockscreenWallpaperPath(); + + Q_INVOKABLE QCoro::Task saveHomescreenSettings(); + Q_INVOKABLE void saveLockscreenSettings(); + +public Q_SLOTS: + QCoro::Task loadHomescreenSettings(); + void loadLockscreenSettings(); + +Q_SIGNALS: + void homescreenWallpaperPathChanged(); + void lockscreenWallpaperPathChanged(); + void homescreenConfigurationChanged(); + void lockscreenConfigurationChanged(); + void currentWallpaperPluginChanged(); + void homescreenWallpaperPluginChanged(); + void lockscreenWallpaperPluginChanged(); + +private: + QQmlPropertyMap *loadConfiguration(KConfigGroup group, QString wallpaperPlugin, bool loadDefaults); + + QString m_homescreenWallpaperPlugin; + QString m_lockscreenWallpaperPlugin; + + QString m_homescreenWallpaperPath; + QString m_lockscreenWallpaperPath; + + QQmlPropertyMap *m_homescreenConfig{nullptr}; + QQmlPropertyMap *m_lockscreenConfig{nullptr}; + + KSharedConfig::Ptr m_homescreenConfigFile{nullptr}; + KSharedConfig::Ptr m_lockscreenConfigFile{nullptr}; + KConfigWatcher::Ptr m_lockscreenConfigWatcher{nullptr}; + + WallpaperConfigModel *m_wallpaperPluginModel = nullptr; +}; + +class WallpaperConfigModel : public PlasmaQuick::ConfigModel +{ + Q_OBJECT + +public: + WallpaperConfigModel(QObject *parent); +public Q_SLOTS: + void repopulate(); +}; diff --git a/kcms/hotspot/ui/main.qml b/kcms/hotspot/ui/main.qml index 6e473287..8670ee3c 100644 --- a/kcms/hotspot/ui/main.qml +++ b/kcms/hotspot/ui/main.qml @@ -99,6 +99,7 @@ SimpleKCM { FormCard.FormTextDelegate { id: hotspotSSIDText + enabled: !hotspotToggle.checked text: i18n("Hotspot SSID") description: PlasmaNM.Configuration.hotspotName } @@ -107,6 +108,7 @@ SimpleKCM { FormCard.FormTextDelegate { id: hotspotPasswordText + enabled: !hotspotToggle.checked text: i18n("Hotspot Password") description: PlasmaNM.Configuration.hotspotPassword } @@ -114,6 +116,7 @@ SimpleKCM { FormCard.FormDelegateSeparator {} FormCard.FormButtonDelegate { + enabled: !hotspotToggle.checked text: i18n('Configure') onClicked: hotspotDialog.open() } diff --git a/kcms/virtualkeyboard/ui/main.qml b/kcms/virtualkeyboard/ui/main.qml index 0333f499..4095cf11 100644 --- a/kcms/virtualkeyboard/ui/main.qml +++ b/kcms/virtualkeyboard/ui/main.qml @@ -21,7 +21,7 @@ KCM.SimpleKCM { leftPadding: 0 rightPadding: 0 - topPadding: 0 + topPadding: Kirigami.Units.gridUnit bottomPadding: Kirigami.Units.gridUnit ColumnLayout { @@ -29,8 +29,6 @@ KCM.SimpleKCM { width: parent.width FormCard.FormCard { - Layout.topMargin: Kirigami.Units.largeSpacing - FormCard.FormTextFieldDelegate { label: i18n("Type anything here…") }