diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 622454916..412b03d78 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -137,6 +137,8 @@ qt_add_qml_module(libtreeland core/imcandidatepanelmanager.h core/shellhandler.cpp core/shellhandler.h + core/systemdconfigmanager.cpp + core/systemdconfigmanager.h core/treeland.cpp core/treeland.h core/windowpicker.cpp diff --git a/src/core/systemdconfigmanager.cpp b/src/core/systemdconfigmanager.cpp new file mode 100644 index 000000000..e50954389 --- /dev/null +++ b/src/core/systemdconfigmanager.cpp @@ -0,0 +1,159 @@ +// Copyright (C) 2026 UnionTech Software Technology Co., Ltd. +// SPDX-License-Identifier: Apache-2.0 OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "systemdconfigmanager.h" + +#include "appconfig.hpp" +#include "outputconfig.hpp" +#include "seatuserconfig.hpp" +#include "treelandconfig.hpp" +#include "treelanduserconfig.hpp" + +#include + +namespace { + +QString configSubpath(const QString &name) +{ + return QStringLiteral("/") + name; +} + +} + +SystemDConfigManager *SystemDConfigManager::s_instance = nullptr; + +SystemDConfigManager::SystemDConfigManager(QObject *parent) + : QObject(parent) +{ + Q_ASSERT(!s_instance); + s_instance = this; + + m_globalConfig = TreelandConfig::create(QStringLiteral("org.deepin.dde.treeland"), + QString(), + this); + Q_ASSERT(m_globalConfig); + + connect(m_globalConfig, + &TreelandConfig::configInitializeSucceed, + this, + [this](DTK_CORE_NAMESPACE::DConfig *) { Q_EMIT InitializeSucceed(); }, + Qt::SingleShotConnection); + connect(m_globalConfig, + &TreelandConfig::configInitializeFailed, + this, + [this] { Q_EMIT InitializeFailed(); }, + Qt::SingleShotConnection); +} + +SystemDConfigManager::~SystemDConfigManager() +{ + if (s_instance == this) { + s_instance = nullptr; + } +} + +SystemDConfigManager *SystemDConfigManager::instance() +{ + return s_instance; +} + +bool SystemDConfigManager::isInitializeSucceeded() const +{ + return m_globalConfig && m_globalConfig->isInitializeSucceeded(); +} + +bool SystemDConfigManager::isInitializeFailed() const +{ + return !m_globalConfig || m_globalConfig->isInitializeFailed(); +} + +TreelandConfig *SystemDConfigManager::globalConfig() const +{ + return m_globalConfig; +} + +TreelandUserConfig *SystemDConfigManager::userConfig(const QString &userName) +{ + if (userName.isEmpty()) { + return nullptr; + } + + if (auto *config = m_userConfigs.value(userName)) { + return config; + } + + auto *config = TreelandUserConfig::createByName(QStringLiteral("org.deepin.dde.treeland.user"), + QStringLiteral("org.deepin.dde.treeland"), + configSubpath(userName), + this); + m_userConfigs.insert(userName, config); + return config; +} + +SeatUserDConfig *SystemDConfigManager::seatUserConfig(const QString &userName) +{ + if (userName.isEmpty()) { + return nullptr; + } + + if (auto *config = m_seatUserConfigs.value(userName)) { + return config; + } + + auto *config = SeatUserDConfig::createByName( + QStringLiteral("org.deepin.dde.treeland.user.seat"), + QStringLiteral("org.deepin.dde.treeland"), + configSubpath(userName), + this); + m_seatUserConfigs.insert(userName, config); + return config; +} + +OutputConfig *SystemDConfigManager::outputConfig(const QString &outputName) +{ + if (outputName.isEmpty()) { + return nullptr; + } + + if (auto *config = m_outputConfigs.value(outputName)) { + return config; + } + + auto *config = OutputConfig::createByName(QStringLiteral("org.deepin.dde.treeland.output"), + QStringLiteral("org.deepin.dde.treeland"), + configSubpath(outputName), + this); + m_outputConfigs.insert(outputName, config); + return config; +} + +AppConfig *SystemDConfigManager::appConfig(const QString &appId) +{ + if (appId.isEmpty()) { + return nullptr; + } + + if (auto *config = m_appConfigs.value(appId)) { + return config; + } + + auto *config = AppConfig::create(QStringLiteral("org.deepin.dde.treeland"), + configSubpath(appId), + this); + m_appConfigs.insert(appId, config); + return config; +} + +bool SystemDConfigManager::initializeUserConfigs(const QString &userName) +{ + m_initialUserConfig = userConfig(userName); + const auto *seatConfig = seatUserConfig(userName); + return m_initialUserConfig && seatConfig + && m_initialUserConfig->isInitializeSucceeded() + && seatConfig->isInitializeSucceeded(); +} + +TreelandUserConfig *SystemDConfigManager::initialUserConfig() const +{ + return m_initialUserConfig; +} diff --git a/src/core/systemdconfigmanager.h b/src/core/systemdconfigmanager.h new file mode 100644 index 000000000..cabab3095 --- /dev/null +++ b/src/core/systemdconfigmanager.h @@ -0,0 +1,54 @@ +// Copyright (C) 2026 UnionTech Software Technology Co., Ltd. +// SPDX-License-Identifier: Apache-2.0 OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#pragma once + +#include +#include +#include + +class AppConfig; +class OutputConfig; +class SeatUserDConfig; +class TreelandConfig; +class TreelandUserConfig; + +class SystemDConfigManager : public QObject +{ + Q_OBJECT + +public: + explicit SystemDConfigManager(QObject *parent = nullptr); + ~SystemDConfigManager() override; + + static SystemDConfigManager *instance(); + + bool isInitializeSucceeded() const; + bool isInitializeFailed() const; + + TreelandConfig *globalConfig() const; + TreelandUserConfig *userConfig(const QString &userName); + SeatUserDConfig *seatUserConfig(const QString &userName); + OutputConfig *outputConfig(const QString &outputName); + AppConfig *appConfig(const QString &appId); + + // Creates and caches the initial user's configs. Returns true only when both + // configs have already finished successfully; callers should listen for + // their initialization signals when this returns false. + bool initializeUserConfigs(const QString &userName); + TreelandUserConfig *initialUserConfig() const; + +Q_SIGNALS: + void InitializeSucceed(); + void InitializeFailed(); + +private: + static SystemDConfigManager *s_instance; + + TreelandConfig *m_globalConfig = nullptr; + QHash m_userConfigs; + QHash m_seatUserConfigs; + QHash m_outputConfigs; + QHash m_appConfigs; + TreelandUserConfig *m_initialUserConfig = nullptr; +}; diff --git a/src/core/treeland.cpp b/src/core/treeland.cpp index f642fd3e7..7945c3051 100644 --- a/src/core/treeland.cpp +++ b/src/core/treeland.cpp @@ -4,11 +4,14 @@ #include "treeland.h" #include "core/qmlengine.h" +#include "core/systemdconfigmanager.h" #include "greeter/usermodel.h" #include "interfaces/multitaskviewinterface.h" #include "interfaces/plugininterface.h" #include "seat/helper.h" +#include "seatuserconfig.hpp" #include "session/session.h" +#include "treelanduserconfig.hpp" #include "utils/cmdline.h" #include "common/treelandlogging.h" #include "common/constants.h" @@ -33,6 +36,7 @@ #include #include +#include #include #include #include @@ -56,7 +60,7 @@ class TreelandPrivate : public QObject { } - void init() + void init(std::function onInitialized) { qmlEngine = new QmlEngine(this); qmlEngine->addImportPath(QString("%1/qt/qml").arg(QCoreApplication::applicationDirPath())); @@ -70,23 +74,97 @@ class TreelandPrivate : public QObject // assert(wlroots: assert(wl_list_empty(&cur->events.button.listener_list))) // failed during quit(If the quit call is from the cursor's button press/release event) connect(qmlEngine, &QQmlEngine::quit, q, &Treeland::quit, Qt::QueuedConnection); - helper = qmlEngine->singletonInstance("Treeland", "Helper"); - connect(helper, &Helper::requestQuit, q, &Treeland::quit, Qt::QueuedConnection); - - qputenv("WLR_XWAYLAND", QByteArray(LIBEXEC_DIR) + "/treeland-xwayland"); - helper->init(q); #ifndef DISABLE_DDM auto userModel = qmlEngine->singletonInstance("Treeland", "UserModel"); + const QString initialUserName = userModel ? userModel->currentUserName() + : QStringLiteral("dde"); +#else + const QString initialUserName = QStringLiteral("dde"); +#endif + auto initializeTreeland = [this, q, onInitialized = std::move(onInitialized) +#ifndef DISABLE_DDM + , userModel +#endif + ] { + helper = qmlEngine->singletonInstance("Treeland", "Helper"); + connect(helper, &Helper::requestQuit, q, &Treeland::quit, Qt::QueuedConnection); - auto updateUser = [this, userModel] { - auto user = userModel->currentUser(); - onCurrentChanged(user ? user->UID() : getuid()); - }; + qputenv("WLR_XWAYLAND", QByteArray(LIBEXEC_DIR) + "/treeland-xwayland"); + helper->init(q); + +#ifndef DISABLE_DDM + auto updateUser = [this, userModel] { + auto user = userModel->currentUser(); + onCurrentChanged(user ? user->UID() : getuid()); + }; - connect(userModel, &UserModel::currentUserNameChanged, this, updateUser); - updateUser(); + connect(userModel, &UserModel::currentUserNameChanged, this, updateUser); + updateUser(); #endif + onInitialized(); + }; + + auto *configManager = SystemDConfigManager::instance(); + if (!configManager || configManager->initializeUserConfigs(initialUserName)) { + initializeTreeland(); + return; + } + + auto *userConfig = configManager->initialUserConfig(); + auto *seatConfig = configManager->seatUserConfig(initialUserName); + auto initialized = std::make_shared(false); + auto initializeWhenReady = [initializeTreeland, + userConfig, + seatConfig, + initialized] { + if (*initialized) { + return; + } + + const bool userSucceeded = userConfig && userConfig->isInitializeSucceeded(); + const bool seatSucceeded = seatConfig && seatConfig->isInitializeSucceeded(); + const bool userFinished = !userConfig || userSucceeded + || userConfig->isInitializeFailed(); + const bool seatFinished = !seatConfig || seatSucceeded + || seatConfig->isInitializeFailed(); + if (!userFinished || !seatFinished) { + return; + } + + *initialized = true; + if (!userSucceeded || !seatSucceeded) { + qCWarning(lcTlCore) + << "Initial user DConfig initialization failed; Treeland will continue with generated defaults."; + } + initializeTreeland(); + }; + + if (userConfig) { + connect(userConfig, + &TreelandUserConfig::configInitializeSucceed, + this, + initializeWhenReady, + Qt::SingleShotConnection); + connect(userConfig, + &TreelandUserConfig::configInitializeFailed, + this, + initializeWhenReady, + Qt::SingleShotConnection); + } + if (seatConfig) { + connect(seatConfig, + &SeatUserDConfig::configInitializeSucceed, + this, + initializeWhenReady, + Qt::SingleShotConnection); + connect(seatConfig, + &SeatUserDConfig::configInitializeFailed, + this, + initializeWhenReady, + Qt::SingleShotConnection); + } + initializeWhenReady(); } ~TreelandPrivate() @@ -311,7 +389,12 @@ Treeland::Treeland() qmlRegisterModule("Treeland.Protocols", 1, 0); - d->init(); + d->init([this] { initialize(); }); +} + +void Treeland::initialize() +{ + Q_D(Treeland); auto globalSession = d->helper->sessionManager()->globalSession(); Q_ASSERT(globalSession); diff --git a/src/core/treeland.h b/src/core/treeland.h index 3ba2bbf9c..7dc2a68a4 100644 --- a/src/core/treeland.h +++ b/src/core/treeland.h @@ -50,6 +50,7 @@ public Q_SLOTS: void XWaylandName(); private: + void initialize(); void quit(); std::unique_ptr d_ptr; diff --git a/src/core/windowconfigstore.cpp b/src/core/windowconfigstore.cpp index ce4e08d68..488d2b376 100644 --- a/src/core/windowconfigstore.cpp +++ b/src/core/windowconfigstore.cpp @@ -3,6 +3,7 @@ #include "core/windowconfigstore.h" +#include "core/systemdconfigmanager.h" #include "appconfig.hpp" #include "common/treelandlogging.h" @@ -19,15 +20,9 @@ AppConfig *WindowConfigStore::configForApp(const QString &appId) const return nullptr; } - if (auto *config = m_appConfigs.value(appId)) { - return config; - } - - auto *config = AppConfig::create(QStringLiteral("org.deepin.dde.treeland"), - "/" + appId, - const_cast(this)); - m_appConfigs.insert(appId, config); - return config; + auto *configManager = SystemDConfigManager::instance(); + Q_ASSERT(configManager); + return configManager->appConfig(appId); } void WindowConfigStore::saveLastSize(const QString &appId, const QSize &size) diff --git a/src/core/windowconfigstore.h b/src/core/windowconfigstore.h index 4108f03d4..067d198a2 100644 --- a/src/core/windowconfigstore.h +++ b/src/core/windowconfigstore.h @@ -2,7 +2,6 @@ // SPDX-License-Identifier: Apache-2.0 OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #pragma once -#include #include #include #include @@ -31,6 +30,4 @@ class WindowConfigStore : public QObject private: AppConfig *configForApp(const QString &appId) const; - - mutable QHash m_appConfigs; }; diff --git a/src/input/inputmanager.cpp b/src/input/inputmanager.cpp index 0f3809b20..59610b8f5 100644 --- a/src/input/inputmanager.cpp +++ b/src/input/inputmanager.cpp @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "inputmanager.h" +#include "core/systemdconfigmanager.h" #include "seatuserconfig.hpp" #include "treelandconfig.hpp" #include "helper.h" @@ -59,20 +60,17 @@ InputManager::InputManager(QObject *parent) InputManager::~InputManager() { - if (m_seatDConfig) { - delete m_seatDConfig; - } } void InputManager::setupSeatUserConfig(const QString &userName) { - if (m_seatDConfig) { - delete m_seatDConfig; - } + auto *configManager = SystemDConfigManager::instance(); + Q_ASSERT(configManager); + + auto *config = configManager->seatUserConfig(userName); + Q_ASSERT(config); - m_seatDConfig = SeatUserDConfig::createByName("org.deepin.dde.treeland.user.seat", - "org.deepin.dde.treeland", - "/" + userName); + m_seatDConfig = config; if (isSeatDConfigInitialized(m_seatDConfig)) { onConfigInitializeSucceed(); @@ -80,7 +78,11 @@ void InputManager::setupSeatUserConfig(const QString &userName) connect(m_seatDConfig, &SeatUserDConfig::configInitializeSucceed, this, - &InputManager::onConfigInitializeSucceed, + [this, config] { + if (m_seatDConfig == config) { + onConfigInitializeSucceed(); + } + }, Qt::SingleShotConnection); } } @@ -102,7 +104,8 @@ void InputManager::onConfigInitializeSucceed() connect(backend, &WBackend::inputAdded, this, - &InputManager::onInputAdded); + &InputManager::onInputAdded, + Qt::UniqueConnection); const auto inputDevices = backend->inputDeviceList(); for (WInputDevice *device : inputDevices) { onInputAdded(device); diff --git a/src/main.cpp b/src/main.cpp index 9d3909978..b882a2ab0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,6 +2,8 @@ // SPDX-License-Identifier: Apache-2.0 OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "core/treeland.h" +#include "core/systemdconfigmanager.h" +#include "common/treelandlogging.h" #include "utils/cmdline.h" #include @@ -16,6 +18,8 @@ #include #include +#include + #if QT_VERSION >= QT_VERSION_CHECK(6, 10, 0) # include #else @@ -84,9 +88,39 @@ int main(int argc, char *argv[]) int quitCode = 0; { - Treeland::Treeland treeland; - - quitCode = app.exec(); + SystemDConfigManager systemDConfigManager(&app); + std::unique_ptr treeland; + + auto startTreeland = [&treeland] { + if (!treeland) { + treeland = std::make_unique(); + } + }; + + QObject::connect(&systemDConfigManager, + &SystemDConfigManager::InitializeSucceed, + &app, + startTreeland); + QObject::connect(&systemDConfigManager, + &SystemDConfigManager::InitializeFailed, + &app, + [&app] { + qCCritical(lcTlCore) + << "Global DConfig initialization failed; aborting Treeland startup."; + app.exit(1); + }); + + if (systemDConfigManager.isInitializeFailed()) { + qCCritical(lcTlCore) + << "Global DConfig initialization failed before the event loop started."; + quitCode = 1; + } else { + if (systemDConfigManager.isInitializeSucceeded()) { + startTreeland(); + } + + quitCode = app.exec(); + } } Q_ASSERT(qw_buffer::get_objects().isEmpty()); diff --git a/src/output/output.cpp b/src/output/output.cpp index 75f37b548..bec7414e9 100644 --- a/src/output/output.cpp +++ b/src/output/output.cpp @@ -6,6 +6,7 @@ #include "cmdline.h" #include "common/treelandlogging.h" #include "core/rootsurfacecontainer.h" +#include "core/systemdconfigmanager.h" #include "outputconfig.hpp" #include "seat/helper.h" #include "surface/surfacewrapper.h" @@ -152,9 +153,9 @@ Output::Output(WOutputItem *output, QObject *parent) m_outputViewport = output->property("screenViewport").value(); QString outputName = WallpaperManager::getOutputId(output->output()->nativeHandle()); - m_config = OutputConfig::createByName("org.deepin.dde.treeland.output", - "org.deepin.dde.treeland", - "/" + outputName, this); + auto *configManager = SystemDConfigManager::instance(); + Q_ASSERT(configManager); + m_config = configManager ? configManager->outputConfig(outputName) : nullptr; } Output::~Output() diff --git a/src/seat/helper.cpp b/src/seat/helper.cpp index 707b9721c..f365d6e56 100644 --- a/src/seat/helper.cpp +++ b/src/seat/helper.cpp @@ -27,6 +27,7 @@ #include "core/qmlengine.h" #include "core/rootsurfacecontainer.h" #include "core/shellhandler.h" +#include "core/systemdconfigmanager.h" #include "core/treeland.h" #include "core/windowpicker.h" #include "greeter/greeterproxy.h" @@ -148,6 +149,7 @@ #include #include #include +#include #include #include #include @@ -299,12 +301,13 @@ Helper::Helper(QObject *parent) Q_ASSERT(!m_instance); m_instance = this; - Q_ASSERT(!m_config); - m_config.reset(TreelandUserConfig::createByName("org.deepin.dde.treeland.user", - "org.deepin.dde.treeland", - "/dde")); // will update user path in Helper::init - m_globalConfig.reset(TreelandConfig::create("org.deepin.dde.treeland", - QString())); + if (auto *configManager = SystemDConfigManager::instance()) { + m_config = configManager->initialUserConfig(); + m_globalConfig = configManager->globalConfig(); + } + + Q_ASSERT(m_config); + Q_ASSERT(m_globalConfig); m_renderWindow->setColor(Qt::black); m_rootSurfaceContainer->setFlag(QQuickItem::ItemIsFocusScope, true); @@ -319,7 +322,7 @@ Helper::Helper(QObject *parent) &WallpaperManager::syncAddWorkspace); tryInitRemoteSource(); - m_outputManagerHelper = new OutputManager(m_rootSurfaceContainer, m_globalConfig.get(), this); + m_outputManagerHelper = new OutputManager(m_rootSurfaceContainer, m_globalConfig, this); connect(m_outputManagerHelper, &OutputManager::copyOutputConfigurationChanged, this, @@ -397,12 +400,12 @@ Helper *Helper::instance() TreelandUserConfig *Helper::config() { - return m_config.get(); + return m_config; } TreelandConfig *Helper::globalConfig() { - return m_globalConfig.get(); + return m_globalConfig; } void Helper::syncPaletteTypeWithWindowThemeType(int32_t themeType) @@ -563,7 +566,7 @@ void Helper::onOutputAdded(WOutput *output) } if (scanned && m_mode == OutputMode::Extension) { const QString addedOutputId = WallpaperManager::getOutputId(o); - runWhenTreelandConfigInitialized(m_globalConfig.get(), this, [this, addedOutputId] { + runWhenTreelandConfigInitialized(m_globalConfig, this, [this, addedOutputId] { QMetaObject::invokeMethod(this, [this, addedOutputId] { if (m_mode != OutputMode::Extension || !m_globalConfig->createCopyOutput()) { return; @@ -743,7 +746,7 @@ void Helper::onOutputAdded(WOutput *output) [this, restoreOutputConfig = std::move(restoreOutputConfig), outputObject = QPointer(o)]() mutable { - runWhenTreelandConfigInitialized(m_globalConfig.get(), + runWhenTreelandConfigInitialized(m_globalConfig, outputObject, std::move(restoreOutputConfig)); }); @@ -1840,29 +1843,55 @@ void Helper::init(Treeland::Treeland *treeland) m_personalizationInterfaceV1 = m_server->attach(); auto updateCurrentUser = [this] { - m_config.reset(TreelandUserConfig::createByName("org.deepin.dde.treeland.user", - "org.deepin.dde.treeland", - "/" + m_userModel->currentUserName())); + const auto userName = m_userModel->currentUserName(); + auto *config = SystemDConfigManager::instance() + ? SystemDConfigManager::instance()->userConfig(userName) + : nullptr; + if (!config) { + config = m_config; + } + + const bool configPointerChanged = config != m_config; + if (configPointerChanged) { + if (m_config) { + disconnect(m_config, + &TreelandUserConfig::cursorThemeNameChanged, + m_sessionManager, + &SessionManager::syncActiveSessionCursorSettings); + disconnect(m_config, + &TreelandUserConfig::cursorSizeChanged, + m_sessionManager, + &SessionManager::syncActiveSessionCursorSettings); + } + m_config = config; + } // Notify QML that the config pointer has changed so bindings (e.g. sourceSize // on WQuickCursor) reconnect their notifiers to the new TreelandUserConfig object. - Q_EMIT configChanged(); - connect(m_config.get(), + if (configPointerChanged) { + Q_EMIT configChanged(); + } + connect(m_config, &TreelandUserConfig::cursorThemeNameChanged, m_sessionManager, - &SessionManager::syncActiveSessionCursorSettings); - connect(m_config.get(), + &SessionManager::syncActiveSessionCursorSettings, + Qt::UniqueConnection); + connect(m_config, &TreelandUserConfig::cursorSizeChanged, m_sessionManager, - &SessionManager::syncActiveSessionCursorSettings); + &SessionManager::syncActiveSessionCursorSettings, + Qt::UniqueConnection); auto user = m_userModel->currentUser(); m_personalizationInterfaceV1->setUserId(user ? user->UID() : getuid()); // TODO(YaoBing Xiao): remove "dde" - if (m_userModel->currentUserName() == "dde") { + if (userName == "dde") { return; } - m_inputManager->setupSeatUserConfig(m_userModel->currentUserName()); - auto onConfigInitialized = [this] { + m_inputManager->setupSeatUserConfig(userName); + auto onConfigInitialized = [this, config = m_config] { + if (m_config != config) { + return; + } m_sessionManager->syncActiveSessionCursorSettings(); syncPaletteTypeWithWindowThemeType(m_config->windowThemeType()); m_wallpaperManager->updateWallpaperConfig(); @@ -1879,7 +1908,7 @@ void Helper::init(Treeland::Treeland *treeland) #endif onConfigInitialized(); } else { - connect(m_config.get(), + connect(m_config, &TreelandUserConfig::configInitializeSucceed, this, onConfigInitialized); @@ -3735,7 +3764,7 @@ void Helper::restoreExtensionModeFromConfig(bool preserveSingleOutputConfig) void Helper::restoreInitialOutputConfiguration() { - runWhenTreelandConfigInitialized(m_globalConfig.get(), this, [this] { + runWhenTreelandConfigInitialized(m_globalConfig, this, [this] { const QString singleOutputId = m_globalConfig->singleOutputId(); if (!singleOutputId.isEmpty()) { if (findOutputById(singleOutputId)) { diff --git a/src/seat/helper.h b/src/seat/helper.h index 52cdb4940..d71581014 100644 --- a/src/seat/helper.h +++ b/src/seat/helper.h @@ -399,8 +399,8 @@ private Q_SLOTS: WSeat *m_currentEventSeat = nullptr; static Helper *m_instance; - std::unique_ptr m_config; - std::unique_ptr m_globalConfig; + TreelandUserConfig *m_config = nullptr; + TreelandConfig *m_globalConfig = nullptr; Treeland::Treeland *m_treeland = nullptr; FpsDisplayManager *m_fpsManager = nullptr; SessionManager *m_sessionManager = nullptr;