/**
 * This file is generated by dconfig2cpp.
 * Command line arguments: /usr/lib/dtk6/DCore/bin/dconfig2cpp -o /build/treeland/src/treeland/build/src/treelandconfig.hpp -c TreelandConfig /build/treeland/src/treeland/misc/dconfig/org.deepin.dde.treeland.json
 * Generation time: 2026-08-18T12:51:56
 * JSON file version: 1.0
 * Tool version: 1.1
 *
 * WARNING: DO NOT MODIFY THIS FILE MANUALLY.
 * If you need to change the content, please modify the dconfig2cpp tool.
 */

#ifndef TREELANDCONFIG_H
#define TREELANDCONFIG_H

#define TREELANDCONFIG_DCONFIG_FILE_VERSION_MAJOR 1
#define TREELANDCONFIG_DCONFIG_FILE_VERSION_MINOR 1
#define TREELANDCONFIG_DCONFIG_FILE_copyOutputName
#define TREELANDCONFIG_DCONFIG_FILE_copyOutputOutputs
#define TREELANDCONFIG_DCONFIG_FILE_createCopyOutput
#define TREELANDCONFIG_DCONFIG_FILE_debugSource
#define TREELANDCONFIG_DCONFIG_FILE_enablePrelaunchSplash
#define TREELANDCONFIG_DCONFIG_FILE_forceSoftwareCursor
#define TREELANDCONFIG_DCONFIG_FILE_keyboardNumLock
#define TREELANDCONFIG_DCONFIG_FILE_prelaunchSplashTimeoutMs
#define TREELANDCONFIG_DCONFIG_FILE_primaryOutputId
#define TREELANDCONFIG_DCONFIG_FILE_quickSwitchTimeout
#define TREELANDCONFIG_DCONFIG_FILE_showOtherUserOption
#define TREELANDCONFIG_DCONFIG_FILE_singleOutputId

#include <QThread>
#include <QVariant>
#include <QPointer>
#include <QDebug>
#include <QAtomicPointer>
#include <QAtomicInteger>
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
#include <QProperty>
#endif
#include <QEvent>
#include <DSGApplication>
#include <DConfig>

class TreelandConfig : public QObject {
    Q_OBJECT

    Q_PROPERTY(QString copyOutputName READ copyOutputName WRITE setCopyOutputName NOTIFY copyOutputNameChanged RESET resetCopyOutputName)
    Q_PROPERTY(QString copyOutputOutputs READ copyOutputOutputs WRITE setCopyOutputOutputs NOTIFY copyOutputOutputsChanged RESET resetCopyOutputOutputs)
    Q_PROPERTY(bool createCopyOutput READ createCopyOutput WRITE setCreateCopyOutput NOTIFY createCopyOutputChanged RESET resetCreateCopyOutput)
    Q_PROPERTY(bool debugSource READ debugSource WRITE setDebugSource NOTIFY debugSourceChanged RESET resetDebugSource)
    Q_PROPERTY(bool enablePrelaunchSplash READ enablePrelaunchSplash WRITE setEnablePrelaunchSplash NOTIFY enablePrelaunchSplashChanged RESET resetEnablePrelaunchSplash)
    Q_PROPERTY(bool forceSoftwareCursor READ forceSoftwareCursor WRITE setForceSoftwareCursor NOTIFY forceSoftwareCursorChanged RESET resetForceSoftwareCursor)
    Q_PROPERTY(bool keyboardNumLock READ keyboardNumLock WRITE setKeyboardNumLock NOTIFY keyboardNumLockChanged RESET resetKeyboardNumLock)
    Q_PROPERTY(qlonglong prelaunchSplashTimeoutMs READ prelaunchSplashTimeoutMs WRITE setPrelaunchSplashTimeoutMs NOTIFY prelaunchSplashTimeoutMsChanged RESET resetPrelaunchSplashTimeoutMs)
    Q_PROPERTY(QString primaryOutputId READ primaryOutputId WRITE setPrimaryOutputId NOTIFY primaryOutputIdChanged RESET resetPrimaryOutputId)
    Q_PROPERTY(qlonglong quickSwitchTimeout READ quickSwitchTimeout WRITE setQuickSwitchTimeout NOTIFY quickSwitchTimeoutChanged RESET resetQuickSwitchTimeout)
    Q_PROPERTY(bool showOtherUserOption READ showOtherUserOption WRITE setShowOtherUserOption NOTIFY showOtherUserOptionChanged RESET resetShowOtherUserOption)
    Q_PROPERTY(QString singleOutputId READ singleOutputId WRITE setSingleOutputId NOTIFY singleOutputIdChanged RESET resetSingleOutputId)
    Q_CLASSINFO("DConfigKeyList", "copyOutputName;copyOutputOutputs;createCopyOutput;debugSource;enablePrelaunchSplash;forceSoftwareCursor;keyboardNumLock;prelaunchSplashTimeoutMs;primaryOutputId;quickSwitchTimeout;showOtherUserOption;singleOutputId")
    Q_CLASSINFO("DConfigFileName", "org.deepin.dde.treeland")
    Q_CLASSINFO("DConfigFileVersion", "1.0")

public:
    explicit TreelandConfig(QThread *thread, DTK_CORE_NAMESPACE::DConfigBackend *backend,
                        const QString &name, const QString &appId, const QString &subpath,
                        bool isGeneric, QObject *parent)
                  : QObject(parent), m_data(new Data) {
        m_data->m_userConfig = this;
        m_data->moveToThread(this->thread());

        if (!thread->isRunning()) {
            qWarning() << QLatin1String("Warning: The provided thread is not running.");
        }
        Q_ASSERT(QThread::currentThread() != thread);
        auto worker = new QObject();
        worker->moveToThread(thread);

        QPointer<Data> safeData(m_data);

        QMetaObject::invokeMethod(worker, [safeData, backend, name, appId, subpath, isGeneric, worker]() mutable {
            delete worker;
            worker = nullptr;

            if (!safeData->m_status.testAndSetOrdered(static_cast<int>(Data::Status::Invalid),
                                                      static_cast<int>(Data::Status::Initializing))) {
                // CAS failed: status changed (e.g., set to Destroyed by destructor)
                // Schedule deletion of Data object via deleteLater to avoid direct delete in Config thread
                safeData->deleteLater();
                return;
            }

            DTK_CORE_NAMESPACE::DConfig *config = nullptr;
            if (isGeneric) {
                if (backend) {
                    config = DTK_CORE_NAMESPACE::DConfig::createGeneric(backend, name, subpath, nullptr);
                } else {
                    config = DTK_CORE_NAMESPACE::DConfig::createGeneric(name, subpath, nullptr);
                }
            } else {
                if (backend) {
                    if (appId.isNull()) {
                        config = DTK_CORE_NAMESPACE::DConfig::create(backend, DTK_CORE_NAMESPACE::DSGApplication::id(),
                                                                     name, subpath, nullptr);
                    } else {
                        config = DTK_CORE_NAMESPACE::DConfig::create(backend, appId, name, subpath, nullptr);
                    }
                } else {
                    if (appId.isNull()) {
                        config = DTK_CORE_NAMESPACE::DConfig::create(DTK_CORE_NAMESPACE::DSGApplication::id(),
                                                                     name, subpath, nullptr);
                    } else {
                        config = DTK_CORE_NAMESPACE::DConfig::create(appId, name, subpath, nullptr);
                    }
                }
            }

            if (!config || !config->isValid()) {
                qWarning() << QLatin1String("Failed to create DConfig instance.");

                QMetaObject::invokeMethod(safeData, [safeData]() {
                    if (safeData->m_status.testAndSetOrdered(static_cast<int>(Data::Status::Initializing),
                                                             static_cast<int>(Data::Status::Failed))) {
                        Q_EMIT safeData->m_userConfig->configInitializeFailed();
                    } else {
                        // CAS failed, destroy data object
                        delete safeData;
                    }
                }, Qt::QueuedConnection);

                if (config)
                    delete config;

                return;
            }
            config->moveToThread(QThread::currentThread());
            // Initialize through Data class
            safeData->initializeInConfigThread(config);

            // Queue state transition to main thread, to ensure config values are fully initialized.
            QMetaObject::invokeMethod(safeData, [safeData, config]() {
                // Try to transition from Initializing to Succeeded
                if (safeData->m_status.testAndSetOrdered(static_cast<int>(Data::Status::Initializing),
                                                         static_cast<int>(Data::Status::Succeeded))) {
                    // CAS succeeded: connect config destroyed signal to cleanup Data, then emit success signal to main thread
                    QObject::connect(config, &QObject::destroyed, safeData, &QObject::deleteLater);
                    if (safeData->m_userConfig) {
                        Q_EMIT safeData->m_userConfig->configInitializeSucceed(config);
                    }
                } else {
                    // CAS failed - state changed (e.g., set to Destroyed)
                    // We must clean up the config we just created
                    config->deleteLater();
                    safeData->deleteLater();
                }
            }, Qt::QueuedConnection);
        });
    }
    static TreelandConfig* create(const QString &appId = {}, const QString &subpath = {}, QObject *parent = nullptr, QThread *thread = DTK_CORE_NAMESPACE::DConfig::globalThread())
    { return new TreelandConfig(thread, nullptr, QStringLiteral(u"\u006f\u0072\u0067\u002e\u0064\u0065\u0065\u0070\u0069\u006e\u002e\u0064\u0064\u0065\u002e\u0074\u0072\u0065\u0065\u006c\u0061\u006e\u0064"), appId, subpath, false, parent); }
    static TreelandConfig* create(DTK_CORE_NAMESPACE::DConfigBackend *backend, const QString &appId = {}, const QString &subpath = {}, QObject *parent = nullptr, QThread *thread = DTK_CORE_NAMESPACE::DConfig::globalThread())
    { return new TreelandConfig(thread, backend, QStringLiteral(u"\u006f\u0072\u0067\u002e\u0064\u0065\u0065\u0070\u0069\u006e\u002e\u0064\u0064\u0065\u002e\u0074\u0072\u0065\u0065\u006c\u0061\u006e\u0064"), appId, subpath, false, parent); }
    static TreelandConfig* createByName(const QString &name, const QString &appId = {}, const QString &subpath = {}, QObject *parent = nullptr, QThread *thread = DTK_CORE_NAMESPACE::DConfig::globalThread())
    { return new TreelandConfig(thread, nullptr, name, appId, subpath, false, parent); }
    static TreelandConfig* createByName(DTK_CORE_NAMESPACE::DConfigBackend *backend, const QString &name, const QString &appId = {}, const QString &subpath = {}, QObject *parent = nullptr, QThread *thread = DTK_CORE_NAMESPACE::DConfig::globalThread())
    { return new TreelandConfig(thread, backend, name, appId, subpath, false, parent); }
    static TreelandConfig* createGeneric(const QString &subpath = {}, QObject *parent = nullptr, QThread *thread = DTK_CORE_NAMESPACE::DConfig::globalThread())
    { return new TreelandConfig(thread, nullptr, QStringLiteral(u"\u006f\u0072\u0067\u002e\u0064\u0065\u0065\u0070\u0069\u006e\u002e\u0064\u0064\u0065\u002e\u0074\u0072\u0065\u0065\u006c\u0061\u006e\u0064"), {}, subpath, true, parent); }
    static TreelandConfig* create(DTK_CORE_NAMESPACE::DConfigBackend *backend, const QString &subpath = {}, QObject *parent = nullptr, QThread *thread = DTK_CORE_NAMESPACE::DConfig::globalThread())
    { return new TreelandConfig(thread, backend, QStringLiteral(u"\u006f\u0072\u0067\u002e\u0064\u0065\u0065\u0070\u0069\u006e\u002e\u0064\u0064\u0065\u002e\u0074\u0072\u0065\u0065\u006c\u0061\u006e\u0064"), {}, subpath, true, parent); }
    static TreelandConfig* createGenericByName(const QString &name, const QString &subpath = {}, QObject *parent = nullptr, QThread *thread = DTK_CORE_NAMESPACE::DConfig::globalThread())
    { return new TreelandConfig(thread, nullptr, name, {}, subpath, true, parent); }
    static TreelandConfig* createGenericByName(DTK_CORE_NAMESPACE::DConfigBackend *backend, const QString &name, const QString &subpath = {}, QObject *parent = nullptr, QThread *thread = DTK_CORE_NAMESPACE::DConfig::globalThread())
    { return new TreelandConfig(thread, backend, name, {}, subpath, true, parent); }
    ~TreelandConfig() {
        m_data->m_userConfig = nullptr;
        int oldStatus = m_data->m_status.fetchAndStoreOrdered(static_cast<int>(Data::Status::Destroyed));
        if (oldStatus == static_cast<int>(Data::Status::Succeeded)) {
            // When Succeeded, release config object only
            auto config = m_data->m_config.loadRelaxed();
            Q_ASSERT(config);
            config->deleteLater();
            // m_data will be deleted by config's destroyed signal
        } else if (oldStatus == static_cast<int>(Data::Status::Failed)) {
            // When Failed state, schedule cleanup of Data object
            m_data->deleteLater();
        }
    }

    Q_INVOKABLE DTK_CORE_NAMESPACE::DConfig *config() const {
        return m_data->m_config.loadRelaxed();
    }
    // Deprecated: Use isInitializeSucceeded() instead
    Q_INVOKABLE Q_DECL_DEPRECATED_X("Use isInitializeSucceeded() instead")
    bool isInitializeSucceed() const {
        return isInitializeSucceeded();
    }
    Q_INVOKABLE bool isInitializeSucceeded() const {
        return m_data->m_status.loadRelaxed() == static_cast<int>(Data::Status::Succeeded);
    }
    Q_INVOKABLE bool isInitializeFailed() const {
        return m_data->m_status.loadRelaxed() == static_cast<int>(Data::Status::Failed);
    }
    Q_INVOKABLE bool isInitializing() const {
        return m_data->m_status.loadRelaxed() == static_cast<int>(Data::Status::Initializing);
    }

    Q_INVOKABLE QStringList keyList() const {
        return { QStringLiteral("copyOutputName"),
                 QStringLiteral("copyOutputOutputs"),
                 QStringLiteral("createCopyOutput"),
                 QStringLiteral("debugSource"),
                 QStringLiteral("enablePrelaunchSplash"),
                 QStringLiteral("forceSoftwareCursor"),
                 QStringLiteral("keyboardNumLock"),
                 QStringLiteral("prelaunchSplashTimeoutMs"),
                 QStringLiteral("primaryOutputId"),
                 QStringLiteral("quickSwitchTimeout"),
                 QStringLiteral("showOtherUserOption"),
                 QStringLiteral("singleOutputId")};
    }

    Q_INVOKABLE bool isDefaultValue(const QString &key) const {
        if (key == QStringLiteral("copyOutputName"))
            return copyOutputNameIsDefaultValue();
        if (key == QStringLiteral("copyOutputOutputs"))
            return copyOutputOutputsIsDefaultValue();
        if (key == QStringLiteral("createCopyOutput"))
            return createCopyOutputIsDefaultValue();
        if (key == QStringLiteral("debugSource"))
            return debugSourceIsDefaultValue();
        if (key == QStringLiteral("enablePrelaunchSplash"))
            return enablePrelaunchSplashIsDefaultValue();
        if (key == QStringLiteral("forceSoftwareCursor"))
            return forceSoftwareCursorIsDefaultValue();
        if (key == QStringLiteral("keyboardNumLock"))
            return keyboardNumLockIsDefaultValue();
        if (key == QStringLiteral("prelaunchSplashTimeoutMs"))
            return prelaunchSplashTimeoutMsIsDefaultValue();
        if (key == QStringLiteral("primaryOutputId"))
            return primaryOutputIdIsDefaultValue();
        if (key == QStringLiteral("quickSwitchTimeout"))
            return quickSwitchTimeoutIsDefaultValue();
        if (key == QStringLiteral("showOtherUserOption"))
            return showOtherUserOptionIsDefaultValue();
        if (key == QStringLiteral("singleOutputId"))
            return singleOutputIdIsDefaultValue();
        return false;
    }

    QString copyOutputName() const {
        return m_data->p_copyOutputName;
    }
    void setCopyOutputName(const QString &value) {
        auto oldValue = m_data->p_copyOutputName;
        m_data->p_copyOutputName = value;
        m_data->markPropertySet(0);
        if (auto config = m_data->m_config.loadRelaxed()) {
            QMetaObject::invokeMethod(config, [config, value]() {
                config->setValue(QStringLiteral("copyOutputName"), value);
            });
        }
        if (m_data->p_copyOutputName != oldValue) {
            Q_EMIT copyOutputNameChanged();
            Q_EMIT valueChanged(QStringLiteral("copyOutputName"), value);
        }
    }
    void resetCopyOutputName() {
        if (auto config = m_data->m_config.loadRelaxed()) {
            QMetaObject::invokeMethod(config, [config]() {
                config->reset(QStringLiteral("copyOutputName"));
            });
        }
    }
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
    QBindable<QString> bindableCopyOutputName() {
        return QBindable<QString>(this, "copyOutputName");
    }
#endif
    Q_INVOKABLE bool copyOutputNameIsDefaultValue() const {
        return !m_data->testPropertySet(0);
    }
    QString copyOutputOutputs() const {
        return m_data->p_copyOutputOutputs;
    }
    void setCopyOutputOutputs(const QString &value) {
        auto oldValue = m_data->p_copyOutputOutputs;
        m_data->p_copyOutputOutputs = value;
        m_data->markPropertySet(1);
        if (auto config = m_data->m_config.loadRelaxed()) {
            QMetaObject::invokeMethod(config, [config, value]() {
                config->setValue(QStringLiteral("copyOutputOutputs"), value);
            });
        }
        if (m_data->p_copyOutputOutputs != oldValue) {
            Q_EMIT copyOutputOutputsChanged();
            Q_EMIT valueChanged(QStringLiteral("copyOutputOutputs"), value);
        }
    }
    void resetCopyOutputOutputs() {
        if (auto config = m_data->m_config.loadRelaxed()) {
            QMetaObject::invokeMethod(config, [config]() {
                config->reset(QStringLiteral("copyOutputOutputs"));
            });
        }
    }
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
    QBindable<QString> bindableCopyOutputOutputs() {
        return QBindable<QString>(this, "copyOutputOutputs");
    }
#endif
    Q_INVOKABLE bool copyOutputOutputsIsDefaultValue() const {
        return !m_data->testPropertySet(1);
    }
    bool createCopyOutput() const {
        return m_data->p_createCopyOutput;
    }
    void setCreateCopyOutput(const bool &value) {
        auto oldValue = m_data->p_createCopyOutput;
        m_data->p_createCopyOutput = value;
        m_data->markPropertySet(2);
        if (auto config = m_data->m_config.loadRelaxed()) {
            QMetaObject::invokeMethod(config, [config, value]() {
                config->setValue(QStringLiteral("createCopyOutput"), value);
            });
        }
        if (m_data->p_createCopyOutput != oldValue) {
            Q_EMIT createCopyOutputChanged();
            Q_EMIT valueChanged(QStringLiteral("createCopyOutput"), value);
        }
    }
    void resetCreateCopyOutput() {
        if (auto config = m_data->m_config.loadRelaxed()) {
            QMetaObject::invokeMethod(config, [config]() {
                config->reset(QStringLiteral("createCopyOutput"));
            });
        }
    }
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
    QBindable<bool> bindableCreateCopyOutput() {
        return QBindable<bool>(this, "createCopyOutput");
    }
#endif
    Q_INVOKABLE bool createCopyOutputIsDefaultValue() const {
        return !m_data->testPropertySet(2);
    }
    bool debugSource() const {
        return m_data->p_debugSource;
    }
    void setDebugSource(const bool &value) {
        auto oldValue = m_data->p_debugSource;
        m_data->p_debugSource = value;
        m_data->markPropertySet(3);
        if (auto config = m_data->m_config.loadRelaxed()) {
            QMetaObject::invokeMethod(config, [config, value]() {
                config->setValue(QStringLiteral("debugSource"), value);
            });
        }
        if (m_data->p_debugSource != oldValue) {
            Q_EMIT debugSourceChanged();
            Q_EMIT valueChanged(QStringLiteral("debugSource"), value);
        }
    }
    void resetDebugSource() {
        if (auto config = m_data->m_config.loadRelaxed()) {
            QMetaObject::invokeMethod(config, [config]() {
                config->reset(QStringLiteral("debugSource"));
            });
        }
    }
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
    QBindable<bool> bindableDebugSource() {
        return QBindable<bool>(this, "debugSource");
    }
#endif
    Q_INVOKABLE bool debugSourceIsDefaultValue() const {
        return !m_data->testPropertySet(3);
    }
    bool enablePrelaunchSplash() const {
        return m_data->p_enablePrelaunchSplash;
    }
    void setEnablePrelaunchSplash(const bool &value) {
        auto oldValue = m_data->p_enablePrelaunchSplash;
        m_data->p_enablePrelaunchSplash = value;
        m_data->markPropertySet(4);
        if (auto config = m_data->m_config.loadRelaxed()) {
            QMetaObject::invokeMethod(config, [config, value]() {
                config->setValue(QStringLiteral("enablePrelaunchSplash"), value);
            });
        }
        if (m_data->p_enablePrelaunchSplash != oldValue) {
            Q_EMIT enablePrelaunchSplashChanged();
            Q_EMIT valueChanged(QStringLiteral("enablePrelaunchSplash"), value);
        }
    }
    void resetEnablePrelaunchSplash() {
        if (auto config = m_data->m_config.loadRelaxed()) {
            QMetaObject::invokeMethod(config, [config]() {
                config->reset(QStringLiteral("enablePrelaunchSplash"));
            });
        }
    }
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
    QBindable<bool> bindableEnablePrelaunchSplash() {
        return QBindable<bool>(this, "enablePrelaunchSplash");
    }
#endif
    Q_INVOKABLE bool enablePrelaunchSplashIsDefaultValue() const {
        return !m_data->testPropertySet(4);
    }
    bool forceSoftwareCursor() const {
        return m_data->p_forceSoftwareCursor;
    }
    void setForceSoftwareCursor(const bool &value) {
        auto oldValue = m_data->p_forceSoftwareCursor;
        m_data->p_forceSoftwareCursor = value;
        m_data->markPropertySet(5);
        if (auto config = m_data->m_config.loadRelaxed()) {
            QMetaObject::invokeMethod(config, [config, value]() {
                config->setValue(QStringLiteral("forceSoftwareCursor"), value);
            });
        }
        if (m_data->p_forceSoftwareCursor != oldValue) {
            Q_EMIT forceSoftwareCursorChanged();
            Q_EMIT valueChanged(QStringLiteral("forceSoftwareCursor"), value);
        }
    }
    void resetForceSoftwareCursor() {
        if (auto config = m_data->m_config.loadRelaxed()) {
            QMetaObject::invokeMethod(config, [config]() {
                config->reset(QStringLiteral("forceSoftwareCursor"));
            });
        }
    }
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
    QBindable<bool> bindableForceSoftwareCursor() {
        return QBindable<bool>(this, "forceSoftwareCursor");
    }
#endif
    Q_INVOKABLE bool forceSoftwareCursorIsDefaultValue() const {
        return !m_data->testPropertySet(5);
    }
    bool keyboardNumLock() const {
        return m_data->p_keyboardNumLock;
    }
    void setKeyboardNumLock(const bool &value) {
        auto oldValue = m_data->p_keyboardNumLock;
        m_data->p_keyboardNumLock = value;
        m_data->markPropertySet(6);
        if (auto config = m_data->m_config.loadRelaxed()) {
            QMetaObject::invokeMethod(config, [config, value]() {
                config->setValue(QStringLiteral("keyboardNumLock"), value);
            });
        }
        if (m_data->p_keyboardNumLock != oldValue) {
            Q_EMIT keyboardNumLockChanged();
            Q_EMIT valueChanged(QStringLiteral("keyboardNumLock"), value);
        }
    }
    void resetKeyboardNumLock() {
        if (auto config = m_data->m_config.loadRelaxed()) {
            QMetaObject::invokeMethod(config, [config]() {
                config->reset(QStringLiteral("keyboardNumLock"));
            });
        }
    }
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
    QBindable<bool> bindableKeyboardNumLock() {
        return QBindable<bool>(this, "keyboardNumLock");
    }
#endif
    Q_INVOKABLE bool keyboardNumLockIsDefaultValue() const {
        return !m_data->testPropertySet(6);
    }
    qlonglong prelaunchSplashTimeoutMs() const {
        return m_data->p_prelaunchSplashTimeoutMs;
    }
    void setPrelaunchSplashTimeoutMs(const qlonglong &value) {
        auto oldValue = m_data->p_prelaunchSplashTimeoutMs;
        m_data->p_prelaunchSplashTimeoutMs = value;
        m_data->markPropertySet(7);
        if (auto config = m_data->m_config.loadRelaxed()) {
            QMetaObject::invokeMethod(config, [config, value]() {
                config->setValue(QStringLiteral("prelaunchSplashTimeoutMs"), value);
            });
        }
        if (m_data->p_prelaunchSplashTimeoutMs != oldValue) {
            Q_EMIT prelaunchSplashTimeoutMsChanged();
            Q_EMIT valueChanged(QStringLiteral("prelaunchSplashTimeoutMs"), value);
        }
    }
    void resetPrelaunchSplashTimeoutMs() {
        if (auto config = m_data->m_config.loadRelaxed()) {
            QMetaObject::invokeMethod(config, [config]() {
                config->reset(QStringLiteral("prelaunchSplashTimeoutMs"));
            });
        }
    }
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
    QBindable<qlonglong> bindablePrelaunchSplashTimeoutMs() {
        return QBindable<qlonglong>(this, "prelaunchSplashTimeoutMs");
    }
#endif
    Q_INVOKABLE bool prelaunchSplashTimeoutMsIsDefaultValue() const {
        return !m_data->testPropertySet(7);
    }
    QString primaryOutputId() const {
        return m_data->p_primaryOutputId;
    }
    void setPrimaryOutputId(const QString &value) {
        auto oldValue = m_data->p_primaryOutputId;
        m_data->p_primaryOutputId = value;
        m_data->markPropertySet(8);
        if (auto config = m_data->m_config.loadRelaxed()) {
            QMetaObject::invokeMethod(config, [config, value]() {
                config->setValue(QStringLiteral("primaryOutputId"), value);
            });
        }
        if (m_data->p_primaryOutputId != oldValue) {
            Q_EMIT primaryOutputIdChanged();
            Q_EMIT valueChanged(QStringLiteral("primaryOutputId"), value);
        }
    }
    void resetPrimaryOutputId() {
        if (auto config = m_data->m_config.loadRelaxed()) {
            QMetaObject::invokeMethod(config, [config]() {
                config->reset(QStringLiteral("primaryOutputId"));
            });
        }
    }
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
    QBindable<QString> bindablePrimaryOutputId() {
        return QBindable<QString>(this, "primaryOutputId");
    }
#endif
    Q_INVOKABLE bool primaryOutputIdIsDefaultValue() const {
        return !m_data->testPropertySet(8);
    }
    qlonglong quickSwitchTimeout() const {
        return m_data->p_quickSwitchTimeout;
    }
    void setQuickSwitchTimeout(const qlonglong &value) {
        auto oldValue = m_data->p_quickSwitchTimeout;
        m_data->p_quickSwitchTimeout = value;
        m_data->markPropertySet(9);
        if (auto config = m_data->m_config.loadRelaxed()) {
            QMetaObject::invokeMethod(config, [config, value]() {
                config->setValue(QStringLiteral("quickSwitchTimeout"), value);
            });
        }
        if (m_data->p_quickSwitchTimeout != oldValue) {
            Q_EMIT quickSwitchTimeoutChanged();
            Q_EMIT valueChanged(QStringLiteral("quickSwitchTimeout"), value);
        }
    }
    void resetQuickSwitchTimeout() {
        if (auto config = m_data->m_config.loadRelaxed()) {
            QMetaObject::invokeMethod(config, [config]() {
                config->reset(QStringLiteral("quickSwitchTimeout"));
            });
        }
    }
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
    QBindable<qlonglong> bindableQuickSwitchTimeout() {
        return QBindable<qlonglong>(this, "quickSwitchTimeout");
    }
#endif
    Q_INVOKABLE bool quickSwitchTimeoutIsDefaultValue() const {
        return !m_data->testPropertySet(9);
    }
    bool showOtherUserOption() const {
        return m_data->p_showOtherUserOption;
    }
    void setShowOtherUserOption(const bool &value) {
        auto oldValue = m_data->p_showOtherUserOption;
        m_data->p_showOtherUserOption = value;
        m_data->markPropertySet(10);
        if (auto config = m_data->m_config.loadRelaxed()) {
            QMetaObject::invokeMethod(config, [config, value]() {
                config->setValue(QStringLiteral("showOtherUserOption"), value);
            });
        }
        if (m_data->p_showOtherUserOption != oldValue) {
            Q_EMIT showOtherUserOptionChanged();
            Q_EMIT valueChanged(QStringLiteral("showOtherUserOption"), value);
        }
    }
    void resetShowOtherUserOption() {
        if (auto config = m_data->m_config.loadRelaxed()) {
            QMetaObject::invokeMethod(config, [config]() {
                config->reset(QStringLiteral("showOtherUserOption"));
            });
        }
    }
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
    QBindable<bool> bindableShowOtherUserOption() {
        return QBindable<bool>(this, "showOtherUserOption");
    }
#endif
    Q_INVOKABLE bool showOtherUserOptionIsDefaultValue() const {
        return !m_data->testPropertySet(10);
    }
    QString singleOutputId() const {
        return m_data->p_singleOutputId;
    }
    void setSingleOutputId(const QString &value) {
        auto oldValue = m_data->p_singleOutputId;
        m_data->p_singleOutputId = value;
        m_data->markPropertySet(11);
        if (auto config = m_data->m_config.loadRelaxed()) {
            QMetaObject::invokeMethod(config, [config, value]() {
                config->setValue(QStringLiteral("singleOutputId"), value);
            });
        }
        if (m_data->p_singleOutputId != oldValue) {
            Q_EMIT singleOutputIdChanged();
            Q_EMIT valueChanged(QStringLiteral("singleOutputId"), value);
        }
    }
    void resetSingleOutputId() {
        if (auto config = m_data->m_config.loadRelaxed()) {
            QMetaObject::invokeMethod(config, [config]() {
                config->reset(QStringLiteral("singleOutputId"));
            });
        }
    }
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
    QBindable<QString> bindableSingleOutputId() {
        return QBindable<QString>(this, "singleOutputId");
    }
#endif
    Q_INVOKABLE bool singleOutputIdIsDefaultValue() const {
        return !m_data->testPropertySet(11);
    }
protected:
    bool event(QEvent *e) override {
        if (e->type() == QEvent::ThreadChange) {
            Q_ASSERT(this->thread() == m_data->thread());
        }
        return QObject::event(e);
    }
Q_SIGNALS:
    void configInitializeFailed();
    void configInitializeSucceed(DTK_CORE_NAMESPACE::DConfig *config);
    void valueChanged(const QString &key, const QVariant &value);
    void copyOutputNameChanged();
    void copyOutputOutputsChanged();
    void createCopyOutputChanged();
    void debugSourceChanged();
    void enablePrelaunchSplashChanged();
    void forceSoftwareCursorChanged();
    void keyboardNumLockChanged();
    void prelaunchSplashTimeoutMsChanged();
    void primaryOutputIdChanged();
    void quickSwitchTimeoutChanged();
    void showOtherUserOptionChanged();
    void singleOutputIdChanged();

private:
    // Prevent external moveToThread calls
    using QObject::moveToThread;
    class Data : public QObject {
    public:
        enum class Status {
            Invalid = 0,
            Initializing = 1,
            Succeeded = 2,
            Failed = 3,
            Destroyed = 4
        };

        explicit Data()
            : QObject(nullptr) {}

        inline void initializeInConfigThread(DTK_CORE_NAMESPACE::DConfig *config) {
            Q_ASSERT(!m_config.loadRelaxed());
            m_config.storeRelaxed(config);
            if (testPropertySet(0)) {
                config->setValue(QStringLiteral("copyOutputName"), QVariant::fromValue(p_copyOutputName));
            } else {
                updateValue(QStringLiteral("copyOutputName"), QVariant::fromValue(p_copyOutputName));
            }
            if (testPropertySet(1)) {
                config->setValue(QStringLiteral("copyOutputOutputs"), QVariant::fromValue(p_copyOutputOutputs));
            } else {
                updateValue(QStringLiteral("copyOutputOutputs"), QVariant::fromValue(p_copyOutputOutputs));
            }
            if (testPropertySet(2)) {
                config->setValue(QStringLiteral("createCopyOutput"), QVariant::fromValue(p_createCopyOutput));
            } else {
                updateValue(QStringLiteral("createCopyOutput"), QVariant::fromValue(p_createCopyOutput));
            }
            if (testPropertySet(3)) {
                config->setValue(QStringLiteral("debugSource"), QVariant::fromValue(p_debugSource));
            } else {
                updateValue(QStringLiteral("debugSource"), QVariant::fromValue(p_debugSource));
            }
            if (testPropertySet(4)) {
                config->setValue(QStringLiteral("enablePrelaunchSplash"), QVariant::fromValue(p_enablePrelaunchSplash));
            } else {
                updateValue(QStringLiteral("enablePrelaunchSplash"), QVariant::fromValue(p_enablePrelaunchSplash));
            }
            if (testPropertySet(5)) {
                config->setValue(QStringLiteral("forceSoftwareCursor"), QVariant::fromValue(p_forceSoftwareCursor));
            } else {
                updateValue(QStringLiteral("forceSoftwareCursor"), QVariant::fromValue(p_forceSoftwareCursor));
            }
            if (testPropertySet(6)) {
                config->setValue(QStringLiteral("keyboardNumLock"), QVariant::fromValue(p_keyboardNumLock));
            } else {
                updateValue(QStringLiteral("keyboardNumLock"), QVariant::fromValue(p_keyboardNumLock));
            }
            if (testPropertySet(7)) {
                config->setValue(QStringLiteral("prelaunchSplashTimeoutMs"), QVariant::fromValue(p_prelaunchSplashTimeoutMs));
            } else {
                updateValue(QStringLiteral("prelaunchSplashTimeoutMs"), QVariant::fromValue(p_prelaunchSplashTimeoutMs));
            }
            if (testPropertySet(8)) {
                config->setValue(QStringLiteral("primaryOutputId"), QVariant::fromValue(p_primaryOutputId));
            } else {
                updateValue(QStringLiteral("primaryOutputId"), QVariant::fromValue(p_primaryOutputId));
            }
            if (testPropertySet(9)) {
                config->setValue(QStringLiteral("quickSwitchTimeout"), QVariant::fromValue(p_quickSwitchTimeout));
            } else {
                updateValue(QStringLiteral("quickSwitchTimeout"), QVariant::fromValue(p_quickSwitchTimeout));
            }
            if (testPropertySet(10)) {
                config->setValue(QStringLiteral("showOtherUserOption"), QVariant::fromValue(p_showOtherUserOption));
            } else {
                updateValue(QStringLiteral("showOtherUserOption"), QVariant::fromValue(p_showOtherUserOption));
            }
            if (testPropertySet(11)) {
                config->setValue(QStringLiteral("singleOutputId"), QVariant::fromValue(p_singleOutputId));
            } else {
                updateValue(QStringLiteral("singleOutputId"), QVariant::fromValue(p_singleOutputId));
            }
            connect(config, &DTK_CORE_NAMESPACE::DConfig::valueChanged, this, [this](const QString &key) {
                updateValue(key);
            }, Qt::DirectConnection);
        }

        inline void updateValue(const QString &key, const QVariant &fallback = QVariant()) {
            if (!m_config.loadRelaxed())
                return;
            Q_ASSERT(QThread::currentThread() == m_config.loadRelaxed()->thread());
            const QVariant &value = m_config.loadRelaxed()->value(key, fallback);
            if (key == QStringLiteral("copyOutputName")) {
                markPropertySet(0, !m_config.loadRelaxed()->isDefaultValue(key));
                auto newValue = qvariant_cast<QString>(value);
                QMetaObject::invokeMethod(this, [this, newValue, key, value]() {
                    if (m_userConfig && p_copyOutputName != newValue) {
                        Q_ASSERT(QThread::currentThread() == m_userConfig->thread());
                        p_copyOutputName = newValue;
                        Q_EMIT m_userConfig->copyOutputNameChanged();
                        Q_EMIT m_userConfig->valueChanged(key, value);
                    }
                });
                return;
            }
            if (key == QStringLiteral("copyOutputOutputs")) {
                markPropertySet(1, !m_config.loadRelaxed()->isDefaultValue(key));
                auto newValue = qvariant_cast<QString>(value);
                QMetaObject::invokeMethod(this, [this, newValue, key, value]() {
                    if (m_userConfig && p_copyOutputOutputs != newValue) {
                        Q_ASSERT(QThread::currentThread() == m_userConfig->thread());
                        p_copyOutputOutputs = newValue;
                        Q_EMIT m_userConfig->copyOutputOutputsChanged();
                        Q_EMIT m_userConfig->valueChanged(key, value);
                    }
                });
                return;
            }
            if (key == QStringLiteral("createCopyOutput")) {
                markPropertySet(2, !m_config.loadRelaxed()->isDefaultValue(key));
                auto newValue = qvariant_cast<bool>(value);
                QMetaObject::invokeMethod(this, [this, newValue, key, value]() {
                    if (m_userConfig && p_createCopyOutput != newValue) {
                        Q_ASSERT(QThread::currentThread() == m_userConfig->thread());
                        p_createCopyOutput = newValue;
                        Q_EMIT m_userConfig->createCopyOutputChanged();
                        Q_EMIT m_userConfig->valueChanged(key, value);
                    }
                });
                return;
            }
            if (key == QStringLiteral("debugSource")) {
                markPropertySet(3, !m_config.loadRelaxed()->isDefaultValue(key));
                auto newValue = qvariant_cast<bool>(value);
                QMetaObject::invokeMethod(this, [this, newValue, key, value]() {
                    if (m_userConfig && p_debugSource != newValue) {
                        Q_ASSERT(QThread::currentThread() == m_userConfig->thread());
                        p_debugSource = newValue;
                        Q_EMIT m_userConfig->debugSourceChanged();
                        Q_EMIT m_userConfig->valueChanged(key, value);
                    }
                });
                return;
            }
            if (key == QStringLiteral("enablePrelaunchSplash")) {
                markPropertySet(4, !m_config.loadRelaxed()->isDefaultValue(key));
                auto newValue = qvariant_cast<bool>(value);
                QMetaObject::invokeMethod(this, [this, newValue, key, value]() {
                    if (m_userConfig && p_enablePrelaunchSplash != newValue) {
                        Q_ASSERT(QThread::currentThread() == m_userConfig->thread());
                        p_enablePrelaunchSplash = newValue;
                        Q_EMIT m_userConfig->enablePrelaunchSplashChanged();
                        Q_EMIT m_userConfig->valueChanged(key, value);
                    }
                });
                return;
            }
            if (key == QStringLiteral("forceSoftwareCursor")) {
                markPropertySet(5, !m_config.loadRelaxed()->isDefaultValue(key));
                auto newValue = qvariant_cast<bool>(value);
                QMetaObject::invokeMethod(this, [this, newValue, key, value]() {
                    if (m_userConfig && p_forceSoftwareCursor != newValue) {
                        Q_ASSERT(QThread::currentThread() == m_userConfig->thread());
                        p_forceSoftwareCursor = newValue;
                        Q_EMIT m_userConfig->forceSoftwareCursorChanged();
                        Q_EMIT m_userConfig->valueChanged(key, value);
                    }
                });
                return;
            }
            if (key == QStringLiteral("keyboardNumLock")) {
                markPropertySet(6, !m_config.loadRelaxed()->isDefaultValue(key));
                auto newValue = qvariant_cast<bool>(value);
                QMetaObject::invokeMethod(this, [this, newValue, key, value]() {
                    if (m_userConfig && p_keyboardNumLock != newValue) {
                        Q_ASSERT(QThread::currentThread() == m_userConfig->thread());
                        p_keyboardNumLock = newValue;
                        Q_EMIT m_userConfig->keyboardNumLockChanged();
                        Q_EMIT m_userConfig->valueChanged(key, value);
                    }
                });
                return;
            }
            if (key == QStringLiteral("prelaunchSplashTimeoutMs")) {
                markPropertySet(7, !m_config.loadRelaxed()->isDefaultValue(key));
                auto newValue = qvariant_cast<qlonglong>(value);
                QMetaObject::invokeMethod(this, [this, newValue, key, value]() {
                    if (m_userConfig && p_prelaunchSplashTimeoutMs != newValue) {
                        Q_ASSERT(QThread::currentThread() == m_userConfig->thread());
                        p_prelaunchSplashTimeoutMs = newValue;
                        Q_EMIT m_userConfig->prelaunchSplashTimeoutMsChanged();
                        Q_EMIT m_userConfig->valueChanged(key, value);
                    }
                });
                return;
            }
            if (key == QStringLiteral("primaryOutputId")) {
                markPropertySet(8, !m_config.loadRelaxed()->isDefaultValue(key));
                auto newValue = qvariant_cast<QString>(value);
                QMetaObject::invokeMethod(this, [this, newValue, key, value]() {
                    if (m_userConfig && p_primaryOutputId != newValue) {
                        Q_ASSERT(QThread::currentThread() == m_userConfig->thread());
                        p_primaryOutputId = newValue;
                        Q_EMIT m_userConfig->primaryOutputIdChanged();
                        Q_EMIT m_userConfig->valueChanged(key, value);
                    }
                });
                return;
            }
            if (key == QStringLiteral("quickSwitchTimeout")) {
                markPropertySet(9, !m_config.loadRelaxed()->isDefaultValue(key));
                auto newValue = qvariant_cast<qlonglong>(value);
                QMetaObject::invokeMethod(this, [this, newValue, key, value]() {
                    if (m_userConfig && p_quickSwitchTimeout != newValue) {
                        Q_ASSERT(QThread::currentThread() == m_userConfig->thread());
                        p_quickSwitchTimeout = newValue;
                        Q_EMIT m_userConfig->quickSwitchTimeoutChanged();
                        Q_EMIT m_userConfig->valueChanged(key, value);
                    }
                });
                return;
            }
            if (key == QStringLiteral("showOtherUserOption")) {
                markPropertySet(10, !m_config.loadRelaxed()->isDefaultValue(key));
                auto newValue = qvariant_cast<bool>(value);
                QMetaObject::invokeMethod(this, [this, newValue, key, value]() {
                    if (m_userConfig && p_showOtherUserOption != newValue) {
                        Q_ASSERT(QThread::currentThread() == m_userConfig->thread());
                        p_showOtherUserOption = newValue;
                        Q_EMIT m_userConfig->showOtherUserOptionChanged();
                        Q_EMIT m_userConfig->valueChanged(key, value);
                    }
                });
                return;
            }
            if (key == QStringLiteral("singleOutputId")) {
                markPropertySet(11, !m_config.loadRelaxed()->isDefaultValue(key));
                auto newValue = qvariant_cast<QString>(value);
                QMetaObject::invokeMethod(this, [this, newValue, key, value]() {
                    if (m_userConfig && p_singleOutputId != newValue) {
                        Q_ASSERT(QThread::currentThread() == m_userConfig->thread());
                        p_singleOutputId = newValue;
                        Q_EMIT m_userConfig->singleOutputIdChanged();
                        Q_EMIT m_userConfig->valueChanged(key, value);
                    }
                });
                return;
            }
        }
        inline void markPropertySet(const int index, bool on = true) {
            if (index < 32) {
                if (on)
                    m_propertySetStatus0.fetchAndOrOrdered(1 << (index - 0));
                else
                    m_propertySetStatus0.fetchAndAndOrdered(~(1 << (index - 0)));
                return;
            }
            Q_UNREACHABLE();
        }
        inline bool testPropertySet(const int index) const {
            if (index < 32) {
                return (m_propertySetStatus0.loadRelaxed() & (1 << (index - 0)));
            }
            Q_UNREACHABLE();
        }
        // Member variables
        QAtomicPointer<DTK_CORE_NAMESPACE::DConfig> m_config = nullptr;
        QAtomicInteger<int> m_status = static_cast<int>(Status::Invalid);
        QPointer<TreelandConfig> m_userConfig = nullptr;
        QAtomicInteger<quint32> m_propertySetStatus0 = 0;

        // Property storage
        // Default value: ""
        QString p_copyOutputName { QLatin1String("") };
        // Default value: ""
        QString p_copyOutputOutputs { QLatin1String("") };
        bool p_createCopyOutput { false };
        bool p_debugSource { false };
        bool p_enablePrelaunchSplash { true };
        bool p_forceSoftwareCursor { false };
        bool p_keyboardNumLock { true };
        qlonglong p_prelaunchSplashTimeoutMs { 5000 };
        // Default value: ""
        QString p_primaryOutputId { QLatin1String("") };
        qlonglong p_quickSwitchTimeout { 120 };
        bool p_showOtherUserOption { false };
        // Default value: ""
        QString p_singleOutputId { QLatin1String("") };
    };

    QPointer<Data> m_data;
};

#endif // TREELANDCONFIG_H
