Advance Wayland and KDE package bring-up
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
# SPDX-FileCopyrightText: 2023 Alexander Lohnau <alexander.lohnau@gmx.de>
|
||||
# SPDX-License-Identifier: BSD-2-Clause
|
||||
|
||||
add_library(KF6ConfigQml)
|
||||
add_library(KF6::ConfigQml ALIAS KF6ConfigQml)
|
||||
|
||||
ecm_add_qml_module(KF6ConfigQml URI org.kde.config GENERATE_PLUGIN_SOURCE)
|
||||
|
||||
set_target_properties(KF6ConfigQml PROPERTIES
|
||||
VERSION ${KCONFIG_VERSION}
|
||||
SOVERSION ${KCONFIG_SOVERSION}
|
||||
EXPORT_NAME ConfigQml
|
||||
)
|
||||
|
||||
target_sources(KF6ConfigQml PRIVATE
|
||||
kconfigpropertymap.cpp
|
||||
kwindowstatesaverquick.cpp
|
||||
types.cpp
|
||||
)
|
||||
|
||||
ecm_qt_declare_logging_category(KF6ConfigQml
|
||||
HEADER kconfig_qml_log_settings.h
|
||||
IDENTIFIER KCONFIG_QML_LOG
|
||||
CATEGORY_NAME kf.config.qml
|
||||
DESCRIPTION "KConfig QML"
|
||||
EXPORT KCONFIG
|
||||
)
|
||||
|
||||
ecm_generate_export_header(KF6ConfigQml
|
||||
BASE_NAME KConfigQml
|
||||
GROUP_BASE_NAME KF
|
||||
VERSION ${KF_VERSION}
|
||||
USE_VERSION_HEADER
|
||||
VERSION_BASE_NAME KConfig
|
||||
DEPRECATED_BASE_VERSION 0
|
||||
EXCLUDE_DEPRECATED_BEFORE_AND_AT ${EXCLUDE_DEPRECATED_BEFORE_AND_AT}
|
||||
)
|
||||
|
||||
target_link_libraries(KF6ConfigQml
|
||||
PUBLIC
|
||||
KF6::ConfigCore # KCoreConfigSkeleton, in ConfigPropertyMap
|
||||
KF6::ConfigGui # KWindowStateSaver
|
||||
Qt6::Qml
|
||||
PRIVATE
|
||||
Qt6::Quick
|
||||
)
|
||||
|
||||
ecm_generate_headers(KConfigQml_HEADERS
|
||||
HEADER_NAMES
|
||||
KConfigPropertyMap
|
||||
|
||||
REQUIRED_HEADERS KConfigQml_HEADERS
|
||||
)
|
||||
target_include_directories(KF6ConfigQml
|
||||
INTERFACE "$<INSTALL_INTERFACE:${KDE_INSTALL_INCLUDEDIR_KF}/KConfig;${KDE_INSTALL_INCLUDEDIR_KF}/KConfigQml>")
|
||||
|
||||
install(TARGETS KF6ConfigQml EXPORT KF6ConfigTargets ${KF_INSTALL_TARGETS_DEFAULT_ARGS})
|
||||
install(FILES
|
||||
${CMAKE_CURRENT_BINARY_DIR}/kconfigqml_export.h
|
||||
${KConfigQml_HEADERS}
|
||||
DESTINATION ${KDE_INSTALL_INCLUDEDIR_KF}/KConfigQml COMPONENT Devel
|
||||
)
|
||||
|
||||
ecm_finalize_qml_module(KF6ConfigQml DESTINATION ${KDE_INSTALL_QMLDIR} EXPORT KF6ConfigTargets)
|
||||
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
SPDX-FileCopyrightText: 2013 Marco Martin <notmart@gmail.com>
|
||||
SPDX-FileCopyrightText: 2020 David Edmundson <davidedmundson@kde.org>
|
||||
SPDX-FileCopyrightText: 2021 Alexander Lohnau <alexander.lohnau@gmx.de>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "kconfigpropertymap.h"
|
||||
|
||||
#include <KCoreConfigSkeleton>
|
||||
#include <QJSValue>
|
||||
#include <QPointer>
|
||||
|
||||
#include <functional>
|
||||
|
||||
class KConfigPropertyMapPrivate
|
||||
{
|
||||
public:
|
||||
KConfigPropertyMapPrivate(KConfigPropertyMap *map)
|
||||
: q(map)
|
||||
{
|
||||
}
|
||||
|
||||
enum LoadConfigOption {
|
||||
DontEmitValueChanged,
|
||||
EmitValueChanged,
|
||||
};
|
||||
|
||||
void loadConfig(LoadConfigOption option);
|
||||
void writeConfig();
|
||||
void writeConfigValue(const QString &key, const QVariant &value);
|
||||
|
||||
KConfigPropertyMap *q;
|
||||
QPointer<KCoreConfigSkeleton> config;
|
||||
bool updatingConfigValue = false;
|
||||
bool notify = false;
|
||||
};
|
||||
|
||||
KConfigPropertyMap::KConfigPropertyMap(KCoreConfigSkeleton *config, QObject *parent)
|
||||
: QQmlPropertyMap(this, parent)
|
||||
, d(new KConfigPropertyMapPrivate(this))
|
||||
{
|
||||
Q_ASSERT(config);
|
||||
d->config = config;
|
||||
|
||||
// Reload the config only if the change signal has *not* been emitted by ourselves updating the config
|
||||
connect(config, &KCoreConfigSkeleton::configChanged, this, [this]() {
|
||||
if (!d->updatingConfigValue) {
|
||||
d->loadConfig(KConfigPropertyMapPrivate::EmitValueChanged);
|
||||
}
|
||||
});
|
||||
connect(this, &KConfigPropertyMap::valueChanged, this, [this](const QString &key, const QVariant &value) {
|
||||
d->writeConfigValue(key, value);
|
||||
});
|
||||
|
||||
d->loadConfig(KConfigPropertyMapPrivate::DontEmitValueChanged);
|
||||
}
|
||||
|
||||
KConfigPropertyMap::~KConfigPropertyMap() = default;
|
||||
|
||||
bool KConfigPropertyMap::isNotify() const
|
||||
{
|
||||
return d->notify;
|
||||
}
|
||||
|
||||
void KConfigPropertyMap::setNotify(bool notify)
|
||||
{
|
||||
d->notify = notify;
|
||||
}
|
||||
|
||||
void KConfigPropertyMap::writeConfig()
|
||||
{
|
||||
d->writeConfig();
|
||||
}
|
||||
|
||||
QVariant KConfigPropertyMap::updateValue(const QString &key, const QVariant &input)
|
||||
{
|
||||
Q_UNUSED(key);
|
||||
if (input.userType() == qMetaTypeId<QJSValue>()) {
|
||||
return input.value<QJSValue>().toVariant();
|
||||
}
|
||||
return input;
|
||||
}
|
||||
|
||||
bool KConfigPropertyMap::isImmutable(const QString &key) const
|
||||
{
|
||||
KConfigSkeletonItem *item = d->config.data()->findItem(key);
|
||||
if (item) {
|
||||
return item->isImmutable();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void KConfigPropertyMapPrivate::loadConfig(KConfigPropertyMapPrivate::LoadConfigOption option)
|
||||
{
|
||||
if (!config) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto &items = config.data()->items();
|
||||
for (KConfigSkeletonItem *item : items) {
|
||||
q->insert(item->key() + QStringLiteral("Default"), item->getDefault());
|
||||
q->insert(item->key(), item->property());
|
||||
if (option == EmitValueChanged) {
|
||||
Q_EMIT q->valueChanged(item->key(), item->property());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KConfigPropertyMapPrivate::writeConfig()
|
||||
{
|
||||
if (!config) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto lstItems = config.data()->items();
|
||||
for (KConfigSkeletonItem *item : lstItems) {
|
||||
item->setWriteFlags(notify ? KConfigBase::Notify : KConfigBase::Normal);
|
||||
item->setProperty(q->value(item->key()));
|
||||
}
|
||||
// Internally sync the config. This way we ensure the config file is written, even if the process crashed
|
||||
config.data()->save();
|
||||
}
|
||||
|
||||
void KConfigPropertyMapPrivate::writeConfigValue(const QString &key, const QVariant &value)
|
||||
{
|
||||
KConfigSkeletonItem *item = config.data()->findItem(key);
|
||||
if (item) {
|
||||
updatingConfigValue = true;
|
||||
item->setWriteFlags(notify ? KConfigBase::Notify : KConfigBase::Normal);
|
||||
item->setProperty(value);
|
||||
updatingConfigValue = false;
|
||||
}
|
||||
}
|
||||
|
||||
#include "moc_kconfigpropertymap.cpp"
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
SPDX-FileCopyrightText: 2013 Marco Martin <notmart@gmail.com>
|
||||
SPDX-FileCopyrightText: 2020 David Edmundson <davidedmundson@kde.org>
|
||||
SPDX-FileCopyrightText: 2021 Alexander Lohnau <alexander.lohnau@gmx.de>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef KCONFIGPROPERTYMAP_H
|
||||
#define KCONFIGPROPERTYMAP_H
|
||||
|
||||
#include <QQmlPropertyMap>
|
||||
#include <memory>
|
||||
#include <qqmlregistration.h>
|
||||
|
||||
class KCoreConfigSkeleton;
|
||||
|
||||
#include <kconfigqml_export.h>
|
||||
|
||||
class KConfigPropertyMapPrivate;
|
||||
|
||||
/**
|
||||
* @class KConfigPropertyMap configpropertymap.h ConfigPropertyMap
|
||||
*
|
||||
* An object that (optionally) automatically saves changes in a
|
||||
* property map to a configuration object (e.g. a KConfig file).
|
||||
* @since 5.89
|
||||
*/
|
||||
class KCONFIGQML_EXPORT KConfigPropertyMap : public QQmlPropertyMap
|
||||
{
|
||||
Q_OBJECT
|
||||
QML_ANONYMOUS
|
||||
|
||||
public:
|
||||
KConfigPropertyMap(KCoreConfigSkeleton *config, QObject *parent = nullptr);
|
||||
~KConfigPropertyMap() override;
|
||||
|
||||
/**
|
||||
* Whether notifications on config changes are enabled. Disabled by default.
|
||||
* @see KConfigBase::Notify
|
||||
* @return true if writes send (dbus) notifications
|
||||
*/
|
||||
bool isNotify() const;
|
||||
|
||||
/**
|
||||
* Enable or disable notifications on config changes.
|
||||
* @see KConfigBase::Notify
|
||||
* @param notify whether to send notifications
|
||||
*/
|
||||
void setNotify(bool notify);
|
||||
|
||||
/**
|
||||
* @brief Whether the value at the given key is immutable
|
||||
*
|
||||
* @return true if the value is immutable, false if it isn't or it doesn't exist
|
||||
*/
|
||||
Q_INVOKABLE bool isImmutable(const QString &key) const;
|
||||
|
||||
/**
|
||||
* Saves the state of the property map on disk.
|
||||
*/
|
||||
Q_INVOKABLE void writeConfig();
|
||||
|
||||
protected:
|
||||
QVariant updateValue(const QString &key, const QVariant &input) override;
|
||||
|
||||
private:
|
||||
std::unique_ptr<KConfigPropertyMapPrivate> const d;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,54 @@
|
||||
// SPDX-FileCopyrightText: 2024 Joshua Goins <josh@redstrate.com>
|
||||
// SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
|
||||
#include "kwindowstatesaverquick.h"
|
||||
#include "kconfig_qml_log_settings.h"
|
||||
|
||||
#include <QQuickItem>
|
||||
#include <QQuickWindow>
|
||||
|
||||
#include <KWindowStateSaver>
|
||||
|
||||
void KWindowStateSaverQuick::classBegin()
|
||||
{
|
||||
}
|
||||
|
||||
void KWindowStateSaverQuick::componentComplete()
|
||||
{
|
||||
const auto parentItem = qobject_cast<QQuickItem *>(parent());
|
||||
if (!parentItem) {
|
||||
qCWarning(KCONFIG_QML_LOG) << "WindowStateSaver requires a parent item";
|
||||
return;
|
||||
}
|
||||
|
||||
const auto window = qobject_cast<QWindow *>(parentItem->window());
|
||||
if (!window) {
|
||||
qCWarning(KCONFIG_QML_LOG) << "WindowStateSaver requires the parent to be a type that inherits QWindow";
|
||||
return;
|
||||
}
|
||||
|
||||
new KWindowStateSaver(window, m_configGroupName);
|
||||
|
||||
// To work around oddities in QtQuick window visibility handling.
|
||||
// If we do not set the window visible now, then our window state is
|
||||
// overwritten during QQuickWindowQmlImpl::setWindowVisibility() because
|
||||
// QQuickWindow is AutomaticVisibility by default.
|
||||
if (window->windowState() == Qt::WindowMaximized) {
|
||||
window->setVisibility(QWindow::Visibility::Maximized);
|
||||
}
|
||||
}
|
||||
|
||||
void KWindowStateSaverQuick::setConfigGroupName(const QString &name)
|
||||
{
|
||||
if (m_configGroupName != name) {
|
||||
m_configGroupName = name;
|
||||
Q_EMIT configGroupNameChanged();
|
||||
}
|
||||
}
|
||||
|
||||
QString KWindowStateSaverQuick::configGroupName() const
|
||||
{
|
||||
return m_configGroupName;
|
||||
}
|
||||
|
||||
#include "moc_kwindowstatesaverquick.cpp"
|
||||
@@ -0,0 +1,54 @@
|
||||
// SPDX-FileCopyrightText: 2024 Joshua Goins <josh@redstrate.com>
|
||||
// SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
|
||||
#ifndef KWINDOWSTATESAVER_QUICK_H
|
||||
#define KWINDOWSTATESAVER_QUICK_H
|
||||
|
||||
#include <QQmlEngine>
|
||||
|
||||
/**
|
||||
* @brief Creates a @c KWindowStateSaver in QML, and assigns it to the window it's parented to.
|
||||
*
|
||||
* Functions exactly as KWindowStateSaver in C++, as it's a small wrapper around it.
|
||||
*
|
||||
* @code
|
||||
* import org.kde.config as KConfig
|
||||
*
|
||||
* Kirigami.ApplicationWindow {
|
||||
* id: root
|
||||
*
|
||||
* title: i18n("My Window")
|
||||
*
|
||||
* KConfig.WindowStateSaver {
|
||||
* configGroupName: "Main"
|
||||
* }
|
||||
* }
|
||||
* @endcode
|
||||
* @since 6.5
|
||||
*
|
||||
* @sa KWindowStateSaver
|
||||
*/
|
||||
class KWindowStateSaverQuick : public QObject, public QQmlParserStatus
|
||||
{
|
||||
Q_OBJECT
|
||||
QML_ELEMENT
|
||||
QML_NAMED_ELEMENT(WindowStateSaver)
|
||||
Q_INTERFACES(QQmlParserStatus)
|
||||
|
||||
Q_PROPERTY(QString configGroupName READ configGroupName WRITE setConfigGroupName NOTIFY configGroupNameChanged REQUIRED)
|
||||
|
||||
public:
|
||||
void classBegin() override;
|
||||
void componentComplete() override;
|
||||
|
||||
void setConfigGroupName(const QString &name);
|
||||
QString configGroupName() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
void configGroupNameChanged();
|
||||
|
||||
private:
|
||||
QString m_configGroupName;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,4 @@
|
||||
// SPDX-FileCopyrightText: 2023 Nicolas Fella <nicolas.fella@gmx.de>
|
||||
// SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
|
||||
#include "moc_types.cpp"
|
||||
@@ -0,0 +1,25 @@
|
||||
// SPDX-FileCopyrightText: 2023 Nicolas Fella <nicolas.fella@gmx.de>
|
||||
// SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
|
||||
#ifndef KCONFIGTYPES_H
|
||||
#define KCONFIGTYPES_H
|
||||
|
||||
#include <QQmlEngine>
|
||||
|
||||
#include <kauthorized.h>
|
||||
#include <kcoreconfigskeleton.h>
|
||||
|
||||
struct KAuthorizedForeign {
|
||||
Q_GADGET
|
||||
QML_NAMED_ELEMENT(KAuthorized)
|
||||
QML_SINGLETON
|
||||
QML_FOREIGN(KAuthorized)
|
||||
};
|
||||
|
||||
struct KCoreConfigSkeletonForeign {
|
||||
Q_GADGET
|
||||
QML_ANONYMOUS
|
||||
QML_FOREIGN(KCoreConfigSkeleton)
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user