From d73018acb4ff9ff4ae25439f3571d2efb00adcc7 Mon Sep 17 00:00:00 2001 From: April & May & June Date: Wed, 25 Feb 2026 19:27:29 +0800 Subject: [PATCH 1/3] feat: Upgrade treeland-ddm protocol to version 2 In this upgrade we rewrite all treeland-ddm interactions, includes those originally in SocketServer / GreeterProxy, into wayland communication. There's only one true treeland-ddm interaction which should on behalf of the Wayland protocol. --- src/modules/ddm/CMakeLists.txt | 8 +- src/modules/ddm/ddminterfacev1.cpp | 136 ------------- src/modules/ddm/ddminterfacev1.h | 23 --- src/modules/ddm/ddminterfacev2.cpp | 314 +++++++++++++++++++++++++++++ src/modules/ddm/ddminterfacev2.h | 59 ++++++ src/seat/helper.cpp | 15 +- src/seat/helper.h | 6 +- 7 files changed, 388 insertions(+), 173 deletions(-) delete mode 100644 src/modules/ddm/ddminterfacev1.cpp delete mode 100644 src/modules/ddm/ddminterfacev1.h create mode 100644 src/modules/ddm/ddminterfacev2.cpp create mode 100644 src/modules/ddm/ddminterfacev2.h diff --git a/src/modules/ddm/CMakeLists.txt b/src/modules/ddm/CMakeLists.txt index d1f10ae16..38c3fa6bd 100644 --- a/src/modules/ddm/CMakeLists.txt +++ b/src/modules/ddm/CMakeLists.txt @@ -1,14 +1,14 @@ find_package(TreelandProtocols REQUIRED) -ws_generate_local(server ${TREELAND_PROTOCOLS_DATA_DIR}/treeland-ddm-v1.xml treeland-ddm-v1-protocol) +ws_generate_local(server ${TREELAND_PROTOCOLS_DATA_DIR}/treeland-ddm-v2.xml treeland-ddm-v2-protocol) impl_treeland( NAME module_ddm SOURCE - ${CMAKE_SOURCE_DIR}/src/modules/ddm/ddminterfacev1.h - ${CMAKE_SOURCE_DIR}/src/modules/ddm/ddminterfacev1.cpp - ${WAYLAND_PROTOCOLS_OUTPUTDIR}/treeland-ddm-v1-protocol.c + ${CMAKE_SOURCE_DIR}/src/modules/ddm/ddminterfacev2.h + ${CMAKE_SOURCE_DIR}/src/modules/ddm/ddminterfacev2.cpp + ${WAYLAND_PROTOCOLS_OUTPUTDIR}/treeland-ddm-v2-protocol.c INCLUDE $ ) diff --git a/src/modules/ddm/ddminterfacev1.cpp b/src/modules/ddm/ddminterfacev1.cpp deleted file mode 100644 index 327fdf05b..000000000 --- a/src/modules/ddm/ddminterfacev1.cpp +++ /dev/null @@ -1,136 +0,0 @@ -// Copyright (C) 2025 April Lu . -// SPDX-License-Identifier: Apache-2.0 OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only - -#include "ddminterfacev1.h" -#include "treeland-ddm-v1-protocol.h" -#include "common/treelandlogging.h" -#include "helper.h" -#include "usermodel.h" - -#include -#include -#include -#include - -struct treeland_ddm { - wl_resource *resource; -}; - -// request implementation - -static void switchToGreeter([[maybe_unused]] struct wl_client *client, [[maybe_unused]] struct wl_resource *resource) { - Helper::instance()->showLockScreen(false); -} - -static void switchToUser([[maybe_unused]] struct wl_client *client, [[maybe_unused]] struct wl_resource *resource, const char *username) { - auto user = QString::fromLocal8Bit(username); - auto helper = Helper::instance(); - if (user == "ddm") { - helper->showLockScreen(false); - } else if (user != helper->userModel()->currentUserName()) { - helper->userModel()->setCurrentUserName(QString(username)); - helper->showLockScreen(false); - } -} - -static void activateSession([[maybe_unused]] struct wl_client *client, [[maybe_unused]] struct wl_resource *resource) { - Helper::instance()->activateSession(); -} - -static void deactivateSession([[maybe_unused]] struct wl_client *client, [[maybe_unused]] struct wl_resource *resource) { - Helper::instance()->deactivateSession(); -} - -static void enableRender([[maybe_unused]] struct wl_client *client, [[maybe_unused]] struct wl_resource *resource) { - Helper::instance()->enableRender(); -} - -static void disableRender(struct wl_client *client, [[maybe_unused]] struct wl_resource *resource, uint32_t id) { - Helper::instance()->disableRender(); - auto callback = wl_resource_create(client, &wl_callback_interface, 1, id); - auto serial = wl_display_get_serial(wl_client_get_display(client)); - wl_callback_send_done(callback, serial); - wl_resource_destroy(callback); -} - -static const struct treeland_ddm_v1_interface treeland_ddm_impl { - .switch_to_greeter = switchToGreeter, - .switch_to_user = switchToUser, - .activate_session = activateSession, - .deactivate_session = deactivateSession, - .enable_render = enableRender, - .disable_render = disableRender, -}; - -// wayland object binding - -static void handleResourceDestroy(struct wl_resource *resource) { - qCWarning(treelandCore) << "DDM connection lost"; - auto ddm = static_cast(wl_resource_get_user_data(resource)); - ddm->resource = nullptr; -} - -void handleBindingGlobal(struct wl_client *client, void *data, uint32_t version, uint32_t id) { - auto ddm = static_cast(data); - auto *resource = wl_resource_create(client, &treeland_ddm_v1_interface, version, id); - wl_resource_set_implementation(resource, &treeland_ddm_impl, ddm, handleResourceDestroy); - ddm->resource = resource; - qCDebug(treelandCore) << "DDM connection established"; - - treeland_ddm_v1_send_acquire_vt(resource, 0); -} - -// DDMInterfaceV1 - -DDMInterfaceV1::DDMInterfaceV1() { - -} - -DDMInterfaceV1::~DDMInterfaceV1() { -} - -QByteArrayView DDMInterfaceV1::interfaceName() const { - static const QByteArray arr(treeland_ddm_v1_interface.name); - return QByteArrayView(arr); -} - -bool DDMInterfaceV1::isConnected() const { - auto ddm = static_cast(m_handle); - return ddm && ddm->resource; -} - -void DDMInterfaceV1::create(WServer *server) { - auto ddm = new treeland_ddm { .resource = nullptr }; - m_handle = ddm; - m_global = wl_global_create(server->handle()->handle(), &treeland_ddm_v1_interface, - treeland_ddm_v1_interface.version, ddm, handleBindingGlobal); -} - -void DDMInterfaceV1::destroy([[maybe_unused]] WServer *server) { - wl_global_destroy(m_global); - auto ddm = static_cast(m_handle); - delete ddm; - m_handle = nullptr; -} - -wl_global *DDMInterfaceV1::global() const { - return m_global; -} - -// Event wrapper - -void DDMInterfaceV1::switchToVt(const int vtnr) { - auto ddm = static_cast(m_handle); - if (isConnected()) - treeland_ddm_v1_send_switch_to_vt(ddm->resource, vtnr); - else - qCWarning(treelandCore) << "DDM is not connected when trying to call switchToVt"; -} - -void DDMInterfaceV1::acquireVt(const int vtnr) { - auto ddm = static_cast(m_handle); - if (isConnected()) - treeland_ddm_v1_send_acquire_vt(ddm->resource, vtnr); - else - qCWarning(treelandCore) << "DDM is not connected when trying to call acquireVt"; -} diff --git a/src/modules/ddm/ddminterfacev1.h b/src/modules/ddm/ddminterfacev1.h deleted file mode 100644 index 5bd796911..000000000 --- a/src/modules/ddm/ddminterfacev1.h +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (C) 2025 April Lu . -// SPDX-License-Identifier: Apache-2.0 OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only - -#include "wserver.h" - -/** - * The server-side wrapper for treeland private protocol. - */ -class DDMInterfaceV1 : public Waylib::Server::WServerInterface { -public: - DDMInterfaceV1(); - ~DDMInterfaceV1() override; - QByteArrayView interfaceName() const override; - bool isConnected() const; - void switchToVt(const int vtnr); - void acquireVt(const int vtnr); -protected: - void create(Waylib::Server::WServer *server) override; - void destroy(Waylib::Server::WServer *server) override; - wl_global *global() const override; -private: - struct wl_global *m_global { nullptr }; -}; diff --git a/src/modules/ddm/ddminterfacev2.cpp b/src/modules/ddm/ddminterfacev2.cpp new file mode 100644 index 000000000..95ef2cf97 --- /dev/null +++ b/src/modules/ddm/ddminterfacev2.cpp @@ -0,0 +1,314 @@ +// 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 "ddminterfacev2.h" + +#include "common/treelandlogging.h" +#include "helper.h" +#include "treeland-ddm-v2-protocol.h" +#include "usermodel.h" + +#include +#include +#include + +#include + +///////////////////////////// +// Request Implementations // +///////////////////////////// + +// Sync + +static void capabilities([[maybe_unused]] struct wl_client *client, + struct wl_resource *resource, + uint32_t capabilities) +{ + auto interface = static_cast(wl_resource_get_user_data(resource)); + Q_EMIT interface->capabilities(capabilities); +} + +static void userLoggedIn([[maybe_unused]] struct wl_client *client, + struct wl_resource *resource, + const char *username, + const char *session) +{ + auto interface = static_cast(wl_resource_get_user_data(resource)); + Q_EMIT interface->userLoggedIn(QString::fromLocal8Bit(username), QString::fromLocal8Bit(session)); +} + +// Authentication + +static void authenticationFailed([[maybe_unused]] struct wl_client *client, + struct wl_resource *resource, + uint32_t error) +{ + auto interface = static_cast(wl_resource_get_user_data(resource)); + Q_EMIT interface->authenticationFailed(error); +} + +// Greeter + +static void switchToGreeter([[maybe_unused]] struct wl_client *client, + [[maybe_unused]] struct wl_resource *resource) +{ + Helper::instance()->showLockScreen(false); +} + +static void switchToUser([[maybe_unused]] struct wl_client *client, + [[maybe_unused]] struct wl_resource *resource, + const char *username) +{ + auto user = QString::fromLocal8Bit(username); + auto helper = Helper::instance(); + if (user == "dde") { + helper->showLockScreen(false); + } else if (user != helper->userModel()->currentUserName()) { + helper->userModel()->setCurrentUserName(user); + helper->showLockScreen(false); + } +} + +// DRM Control + +static void activateSession([[maybe_unused]] struct wl_client *client, + [[maybe_unused]] struct wl_resource *resource) +{ + Helper::instance()->activateSession(); +} + +static void deactivateSession([[maybe_unused]] struct wl_client *client, + [[maybe_unused]] struct wl_resource *resource) +{ + Helper::instance()->deactivateSession(); +} + +static void enableRender([[maybe_unused]] struct wl_client *client, + [[maybe_unused]] struct wl_resource *resource) +{ + Helper::instance()->enableRender(); +} + +static void disableRender(struct wl_client *client, + [[maybe_unused]] struct wl_resource *resource, + uint32_t id) +{ + Helper::instance()->disableRender(); + auto callback = wl_resource_create(client, &wl_callback_interface, 1, id); + auto serial = wl_display_get_serial(wl_client_get_display(client)); + wl_callback_send_done(callback, serial); + wl_resource_destroy(callback); +} + +//////////////////////////// +// Wayland Object Binding // +//////////////////////////// + +static const struct treeland_ddm_v2_interface treeland_ddm_v2_impl{ + .capabilities = capabilities, + .user_logged_in = userLoggedIn, + .authentication_failed = authenticationFailed, + .switch_to_greeter = switchToGreeter, + .switch_to_user = switchToUser, + .activate_session = activateSession, + .deactivate_session = deactivateSession, + .enable_render = enableRender, + .disable_render = disableRender, +}; + +static void handleResourceDestroy(struct wl_resource *resource) +{ + qCWarning(treelandCore) << "DDM connection lost"; + auto interface = static_cast(wl_resource_get_user_data(resource)); + interface->setHandle(nullptr); + Q_EMIT interface->disconnected(); +} + +static void handleBindingGlobal(struct wl_client *client, void *data, uint32_t version, uint32_t id) +{ + auto interface = static_cast(data); + auto *resource = wl_resource_create(client, &treeland_ddm_v2_interface, version, id); + wl_resource_set_user_data(resource, interface); + wl_resource_set_implementation(resource, &treeland_ddm_v2_impl, interface, handleResourceDestroy); + interface->setHandle(resource); + qCDebug(treelandCore) << "DDM connection established"; + Q_EMIT interface->connected(); +} + +///////////// +// Methods // +///////////// + +QByteArrayView DDMInterfaceV2::interfaceName() const +{ + return treeland_ddm_v2_interface.name; +} + +void DDMInterfaceV2::setHandle(struct wl_resource *handle) +{ + m_handle = handle; +} + +QString DDMInterfaceV2::authErrorToString(uint32_t error) +{ + switch (error) { + case TREELAND_DDM_V2_AUTH_ERROR_AUTHENTICATION_FAILED: + return "Authentication failed"; + case TREELAND_DDM_V2_AUTH_ERROR_INVALID_USER: + return "Invalid user"; + case TREELAND_DDM_V2_AUTH_ERROR_INVALID_SESSION: + return "Invalid session"; + case TREELAND_DDM_V2_AUTH_ERROR_EXISTING_AUTHENTICATION_ONGOING: + return "Existing authentication ongoing"; + case TREELAND_DDM_V2_AUTH_ERROR_INTERNAL_ERROR: + return "Internal error"; + default: + return QString("Unknown error: %1").arg(error); + } +} + +void DDMInterfaceV2::create(WServer *server) +{ + m_global = wl_global_create(server->handle()->handle(), + &treeland_ddm_v2_interface, + treeland_ddm_v2_interface.version, + this, + handleBindingGlobal); +} + +void DDMInterfaceV2::destroy([[maybe_unused]] WServer *server) +{ + if (m_handle) { + wl_resource_destroy(static_cast(m_handle)); + m_handle = nullptr; + } + if (m_global) { + wl_global_destroy(m_global); + m_global = nullptr; + } +} + +wl_global *DDMInterfaceV2::global() const +{ + return m_global; +} + +//////////////////// +// Event Wrappers // +//////////////////// + +// Session Management + +void DDMInterfaceV2::login(const QString &username, + const QString &password, + DDM::Session::Type sessionType, + const QString &sessionFile) const +{ + if (isValid()) { + treeland_ddm_v2_send_login(static_cast(m_handle), + qPrintable(username), + qPrintable(password), + sessionType, + qPrintable(sessionFile)); + wl_display_flush_clients(wl_global_get_display(m_global)); + } else { + qCWarning(treelandCore) << "DDM is not connected when trying to call login"; + } +} + +void DDMInterfaceV2::logout(const QString &session) const +{ + if (isValid()) { + treeland_ddm_v2_send_logout(static_cast(m_handle), + qPrintable(session)); + wl_display_flush_clients(wl_global_get_display(m_global)); + } else { + qCWarning(treelandCore) << "DDM is not connected when trying to call logout"; + } +} + +void DDMInterfaceV2::lock(const QString &session) const +{ + if (isValid()) { + treeland_ddm_v2_send_lock(static_cast(m_handle), qPrintable(session)); + wl_display_flush_clients(wl_global_get_display(m_global)); + } else { + qCWarning(treelandCore) << "DDM is not connected when trying to call lock"; + } +} + +void DDMInterfaceV2::unlock(const QString &session, const QString &password) const +{ + if (isValid()) { + treeland_ddm_v2_send_unlock(static_cast(m_handle), + qPrintable(session), + qPrintable(password)); + wl_display_flush_clients(wl_global_get_display(m_global)); + } else { + qCWarning(treelandCore) << "DDM is not connected when trying to call unlock"; + } +} + +// Power Management + +void DDMInterfaceV2::powerOff() const +{ + if (isValid()) { + treeland_ddm_v2_send_poweroff(static_cast(m_handle)); + wl_display_flush_clients(wl_global_get_display(m_global)); + } else { + qCWarning(treelandCore) << "DDM is not connected when trying to call powerOff"; + } +} + +void DDMInterfaceV2::reboot() const +{ + if (isValid()) { + treeland_ddm_v2_send_reboot(static_cast(m_handle)); + wl_display_flush_clients(wl_global_get_display(m_global)); + } else { + qCWarning(treelandCore) << "DDM is not connected when trying to call reboot"; + } +} + +void DDMInterfaceV2::suspend() const +{ + if (isValid()) { + treeland_ddm_v2_send_suspend(static_cast(m_handle)); + wl_display_flush_clients(wl_global_get_display(m_global)); + } else { + qCWarning(treelandCore) << "DDM is not connected when trying to call suspend"; + } +} + +void DDMInterfaceV2::hibernate() const +{ + if (isValid()) { + treeland_ddm_v2_send_hibernate(static_cast(m_handle)); + wl_display_flush_clients(wl_global_get_display(m_global)); + } else { + qCWarning(treelandCore) << "DDM is not connected when trying to call hibernate"; + } +} + +void DDMInterfaceV2::hybridSleep() const +{ + if (isValid()) { + treeland_ddm_v2_send_hybrid_sleep(static_cast(m_handle)); + wl_display_flush_clients(wl_global_get_display(m_global)); + } else { + qCWarning(treelandCore) << "DDM is not connected when trying to call hybridSleep"; + } +} + +// DRM Control + +void DDMInterfaceV2::switchToVt(int vtnr) const +{ + if (isValid()) { + treeland_ddm_v2_send_switch_to_vt(static_cast(m_handle), vtnr); + wl_display_flush_clients(wl_global_get_display(m_global)); + } else { + qCWarning(treelandCore) << "DDM is not connected when trying to call switchToVt"; + } +} diff --git a/src/modules/ddm/ddminterfacev2.h b/src/modules/ddm/ddminterfacev2.h new file mode 100644 index 000000000..ca6d06269 --- /dev/null +++ b/src/modules/ddm/ddminterfacev2.h @@ -0,0 +1,59 @@ +// 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 "wserver.h" + +#include + +/** + * Server-side wrapper for treeland-ddm protocol. + */ +class DDMInterfaceV2 : public QObject, public Waylib::Server::WServerInterface +{ + Q_OBJECT +public: + QByteArrayView interfaceName() const override; + void setHandle(struct wl_resource *handle); + static QString authErrorToString(uint32_t error); + + //////////////////// + // Event Wrappers // + //////////////////// + +public Q_SLOTS: + void login(const QString &username, + const QString &password, + DDM::Session::Type sessionType, + const QString &sessionFile) const; + void logout(const QString &session) const; + void lock(const QString &session) const; + void unlock(const QString &session, const QString &password) const; + void powerOff() const; + void reboot() const; + void suspend() const; + void hibernate() const; + void hybridSleep() const; + void switchToVt(int vtnr) const; + +Q_SIGNALS: + void connected(); + void disconnected(); + + /////////////////////////// + // Signals from Requests // + /////////////////////////// + + void capabilities(uint32_t capabilities); + void userLoggedIn(const QString &username, const QString &session); + void authenticationFailed(uint32_t error); + +protected: + void create(Waylib::Server::WServer *server) override; + void destroy(Waylib::Server::WServer *server) override; + wl_global *global() const override; + +private: + struct wl_global *m_global{ nullptr }; +}; diff --git a/src/seat/helper.cpp b/src/seat/helper.cpp index ffc4f4817..d0f3f2b43 100644 --- a/src/seat/helper.cpp +++ b/src/seat/helper.cpp @@ -27,7 +27,7 @@ #include "modules/capture/capture.h" #include "modules/dde-shell/ddeshellattached.h" #include "modules/dde-shell/ddeshellmanagerinterfacev1.h" -#include "modules/ddm/ddminterfacev1.h" +#include "modules/ddm/ddminterfacev2.h" #include "modules/keystate/keystate.h" #include "modules/output-manager/outputmanagement.h" #include "modules/personalization/personalizationmanager.h" @@ -1171,6 +1171,9 @@ void Helper::init(Treeland::Treeland *treeland) m_userModel = engine->singletonInstance("Treeland", "UserModel"); m_sessionModel = engine->singletonInstance("Treeland", "SessionModel"); + m_ddmInterfaceV2 = m_server->attach(); + m_greeterProxy->connectDDM(m_ddmInterfaceV2); + engine->setContextForObject(m_renderWindow, engine->rootContext()); engine->setContextForObject(m_renderWindow->contentItem(), engine->rootContext()); m_rootSurfaceContainer->setQmlEngine(engine); @@ -1193,8 +1196,6 @@ void Helper::init(Treeland::Treeland *treeland) m_seat->detachInputDevice(device); }); - m_ddmInterfaceV1 = m_server->attach(); - m_outputManager = m_server->attach(); connect(m_backend, &WBackend::outputAdded, this, &Helper::onOutputAdded); connect(m_backend, &WBackend::outputRemoved, this, &Helper::onOutputRemoved); @@ -1627,8 +1628,8 @@ bool Helper::beforeDisposeEvent(WSeat *seat, QWindow *, QInputEvent *event) // Check if the backend is active to avoid this. if (key >= Qt::Key_F1 && key <= Qt::Key_F12 && m_backend->isSessionActive()) { const int vtnr = key - Qt::Key_F1 + 1; - if (m_ddmInterfaceV1 && m_ddmInterfaceV1->isConnected()) { - m_ddmInterfaceV1->switchToVt(vtnr); + if (m_ddmInterfaceV2 && m_ddmInterfaceV2->isValid()) { + m_ddmInterfaceV2->switchToVt(vtnr); } else { qCDebug(treelandCore) << "DDM is not connected"; showLockScreen(false); @@ -2447,8 +2448,8 @@ void Helper::onPrepareForSleep(bool sleep) } } -DDMInterfaceV1 *Helper::ddmInterfaceV1() const { - return m_ddmInterfaceV1; +DDMInterfaceV2 *Helper::ddmInterfaceV2() const { + return m_ddmInterfaceV2; } void Helper::activateSession() { diff --git a/src/seat/helper.h b/src/seat/helper.h index 634716651..df910a70a 100644 --- a/src/seat/helper.h +++ b/src/seat/helper.h @@ -84,7 +84,7 @@ QW_USE_NAMESPACE class CaptureSourceSelector; class DDEShellManagerInterfaceV1; -class DDMInterfaceV1; +class DDMInterfaceV2; class ForeignToplevelV1; class FpsDisplayManager; class GreeterProxy; @@ -223,7 +223,7 @@ class Helper : public WSeatEventFilter inline UserModel *userModel() const { return m_userModel; }; inline SessionModel *sessionModel() const { return m_sessionModel; }; - DDMInterfaceV1 *ddmInterfaceV1() const; + DDMInterfaceV2 *ddmInterfaceV2() const; void activateSession(); void deactivateSession(); @@ -376,7 +376,7 @@ private Q_SLOTS: PrelaunchSplash *m_prelaunchSplash = nullptr; // treeland prelaunch splash protocol VirtualOutputV1 *m_virtualOutput = nullptr; OutputManagerV1 *m_outputManagerV1 = nullptr; - DDMInterfaceV1 *m_ddmInterfaceV1 = nullptr; + DDMInterfaceV2 *m_ddmInterfaceV2 = nullptr; ScreensaverInterfaceV1 *m_screensaverInterfaceV1 = nullptr; TreelandWallpaperManagerInterfaceV1 *m_wallpaperManagerInterfaceV1 = nullptr; TreelandWallpaperNotifierInterfaceV1 *m_wallpaperNotifierInterfaceV1 = nullptr; From e848e10481ae0fb52cace1dd4acd41aae95b8b2c Mon Sep 17 00:00:00 2001 From: April & May & June Date: Wed, 25 Feb 2026 19:30:56 +0800 Subject: [PATCH 2/3] feat: Upgrade GreeterProxy to unify ddm communication with Wayland With the upgrade we did in previous commit, communication with ddm using QLocalSocket is not needed now, and we shall reform GreeterProxy, the communication method with our display manager the DDM, to use the newly formed Wayland protocol. --- src/greeter/greeterproxy.cpp | 399 ++++++++++++++--------------------- src/greeter/greeterproxy.h | 43 ++-- 2 files changed, 177 insertions(+), 265 deletions(-) diff --git a/src/greeter/greeterproxy.cpp b/src/greeter/greeterproxy.cpp index 44915c9d2..4aca2cc9f 100644 --- a/src/greeter/greeterproxy.cpp +++ b/src/greeter/greeterproxy.cpp @@ -4,37 +4,30 @@ #include "greeterproxy.h" // Treeland +#include "common/treelandlogging.h" +#include "core/lockscreen.h" #include "greeter/sessionmodel.h" #include "greeter/usermodel.h" +#include "modules/ddm/ddminterfacev2.h" #include "seat/helper.h" #include "session/session.h" -#include "common/treelandlogging.h" -#include "core/lockscreen.h" // DDM #include #include #include -#include // Qt -#include -#include #include #include #include #include -#include #include #include -// Waylib -#include - // System #include #include -#include using namespace DDM; @@ -90,14 +83,6 @@ static inline SessionModel *sessionModel() GreeterProxy::GreeterProxy(QObject *parent) : QObject(parent) { - m_socket = new QLocalSocket(this); - - // connect signals - connect(m_socket, &QLocalSocket::connected, this, &GreeterProxy::connected); - connect(m_socket, &QLocalSocket::disconnected, this, &GreeterProxy::disconnected); - connect(m_socket, &QLocalSocket::readyRead, this, &GreeterProxy::readyRead); - connect(m_socket, &QLocalSocket::errorOccurred, this, &GreeterProxy::error); - auto conn = QDBusConnection::systemBus(); conn.connect(Logind::serviceName(), Logind::managerPath(), @@ -111,23 +96,27 @@ GreeterProxy::GreeterProxy(QObject *parent) "SessionRemoved", this, SLOT(onSessionRemoved(QString, QDBusObjectPath))); - conn.connect("org.deepin.DisplayManager", - "/org/deepin/DisplayManager", - "org.deepin.DisplayManager", - "AuthInfoChanged", - this, - SLOT(updateAuthSocket())); - - updateAuthSocket(); } GreeterProxy::~GreeterProxy() { } +void GreeterProxy::connectDDM(DDMInterfaceV2 *interface) +{ + m_ddmInterface = interface; + connect(interface, &DDMInterfaceV2::capabilities, this, &GreeterProxy::capabilities); + connect(interface, &DDMInterfaceV2::userLoggedIn, this, &GreeterProxy::userLoggedIn); + connect(interface, + &DDMInterfaceV2::authenticationFailed, + this, + &GreeterProxy::authenticationFailed); +} + //////////////////////// // Properties setters // //////////////////////// -void GreeterProxy::setShowShutdownView(bool show) { +void GreeterProxy::setShowShutdownView(bool show) +{ if (m_showShutdownView != show) { m_showShutdownView = show; Q_EMIT showShutdownViewChanged(show); @@ -159,89 +148,183 @@ void GreeterProxy::setLock(bool isLocked) void GreeterProxy::powerOff() { - SocketWriter(m_socket) << quint32(GreeterMessages::PowerOff); + if (m_ddmInterface && m_ddmInterface->isValid()) + m_ddmInterface->powerOff(); } void GreeterProxy::reboot() { - SocketWriter(m_socket) << quint32(GreeterMessages::Reboot); + if (m_ddmInterface && m_ddmInterface->isValid()) + m_ddmInterface->reboot(); } void GreeterProxy::suspend() { - SocketWriter(m_socket) << quint32(GreeterMessages::Suspend); + if (m_ddmInterface && m_ddmInterface->isValid()) + m_ddmInterface->suspend(); } void GreeterProxy::hibernate() { - SocketWriter(m_socket) << quint32(GreeterMessages::Hibernate); + if (m_ddmInterface && m_ddmInterface->isValid()) + m_ddmInterface->hibernate(); } void GreeterProxy::hybridSleep() { - SocketWriter(m_socket) << quint32(GreeterMessages::HybridSleep); + if (m_ddmInterface && m_ddmInterface->isValid()) + m_ddmInterface->hybridSleep(); } void GreeterProxy::login(const QString &user, const QString &password, const int sessionIndex) { - if (!m_socket->isValid()) { - qCDebug(treelandGreeter) << "Socket is not valid. Local password check."; + if (m_ddmInterface && m_ddmInterface->isValid()) { + // get model index + QModelIndex index = sessionModel()->index(sessionIndex, 0); + // send command to the daemon + DDM::Session::Type sessionType = static_cast( + sessionModel()->data(index, SessionModel::TypeRole).toInt()); + QString sessionFile = sessionModel()->data(index, SessionModel::FileRole).toString(); + qCInfo(treelandGreeter) << "Logging user" << user << "in with" << sessionType << "session" + << sessionFile; + m_ddmInterface->login(user, password, sessionType, sessionFile); + } else { + qCInfo(treelandGreeter) << "DDM is not valid. Local password check."; if (localValidation(user, password)) { setLock(false); } else { Q_EMIT failedAttemptsChanged(++m_failedAttempts); } - return; } - - // get model index - QModelIndex index = sessionModel()->index(sessionIndex, 0); - - // send command to the daemon - DDM::Session::Type type = - static_cast(sessionModel()->data(index, SessionModel::TypeRole).toInt()); - QString name = sessionModel()->data(index, SessionModel::FileRole).toString(); - qCInfo(treelandGreeter) << "Logging user" << user << "in with" << type << "session" << name; - DDM::Session session(type, name); - SocketWriter(m_socket) << quint32(GreeterMessages::Login) << user << password << session; } void GreeterProxy::unlock(const QString &user, const QString &password) { - if (!m_socket->isValid()) { - qCDebug(treelandGreeter) << "Socket is not valid. Local password check."; + if (m_ddmInterface && m_ddmInterface->isValid()) { + auto session = Helper::instance()->sessionManager()->sessionForUser(user); + if (session) { + qCInfo(treelandGreeter) << "Unlocking session" << session->id() << "for user" << user; + m_ddmInterface->unlock(session->id(), password); + } else { + qCWarning(treelandGreeter) << "Trying to unlock session for user" << user + << "but no session found."; + // [TODO] Further actions + } + } else { + qCInfo(treelandGreeter) << "DDM is not valid. Local password check."; if (localValidation(user, password)) { setLock(false); } else { Q_EMIT failedAttemptsChanged(++m_failedAttempts); } - return; - } - - auto userInfo = userModel()->get(user); - if (userInfo.isValid()) { - qCInfo(treelandGreeter) << "Unlocking user" << user; - SocketWriter(m_socket) << quint32(GreeterMessages::Unlock) << user << password; } } void GreeterProxy::logout() { - auto session = Helper::instance()->sessionManager()->activeSession().lock(); - qCInfo(treelandGreeter) << "Logging user" << session->username() << "out with session id" << session->id(); - SocketWriter(m_socket) << quint32(GreeterMessages::Logout) << session->id(); + if (m_ddmInterface && m_ddmInterface->isValid()) { + auto session = Helper::instance()->sessionManager()->activeSession().lock(); + if (session) { + qCInfo(treelandGreeter) << "Logging user" << session->username() << "out with session id" + << session->id(); + m_ddmInterface->logout(session->id()); + } else { + qCWarning(treelandGreeter) + << "Trying to logout when no active session, show lockscreen directly."; + setLock(true); + } + } else { + qCInfo(treelandGreeter) + << "Trying to logout when DDM is not available, show lockscreen directly."; + setLock(true); + } } void GreeterProxy::lock() { auto session = Helper::instance()->sessionManager()->activeSession().lock(); if (!session || session->username() == "dde") { - qCInfo(treelandGreeter) << "Trying to lock when no user session active, show lockscreen directly."; + qCInfo(treelandGreeter) + << "Trying to lock when no user session active, show lockscreen directly."; setLock(true); - return; + } else if (!m_ddmInterface || !m_ddmInterface->isValid()) { + qCInfo(treelandGreeter) + << "Trying to lock when DDM is not available, show lockscreen directly."; + setLock(true); + } else { + qCInfo(treelandGreeter) << "Locking user" << session->username() << "with session id" + << session->id(); + m_ddmInterface->lock(session->id()); + } +} + +////////////////////// +// Signals from DDM // +////////////////////// + +void GreeterProxy::capabilities(uint32_t capabilities) +{ + // parse capabilities + m_canPowerOff = capabilities & Capability::PowerOff; + m_canReboot = capabilities & Capability::Reboot; + m_canSuspend = capabilities & Capability::Suspend; + m_canHibernate = capabilities & Capability::Hibernate; + m_canHybridSleep = capabilities & Capability::HybridSleep; + + // Q_EMIT signals + Q_EMIT canPowerOffChanged(m_canPowerOff); + Q_EMIT canRebootChanged(m_canReboot); + Q_EMIT canSuspendChanged(m_canSuspend); + Q_EMIT canHibernateChanged(m_canHibernate); + Q_EMIT canHybridSleepChanged(m_canHybridSleep); +} + +void GreeterProxy::userLoggedIn(const QString &username, const QString &session) +{ + // This will happen after a crash recovery of treeland + qCInfo(treelandGreeter) << "User " << username << " is already logged in with session" + << session; + auto userPtr = userModel()->getUser(username); + if (userPtr) { + userModel()->updateUserLoginState(username, true); + Q_EMIT userModel()->userLoggedIn(username, session); + QThreadPool::globalInstance()->start([this, session] { + // Connect to Lock/Unlock signals + auto conn = QDBusConnection::systemBus(); + OrgFreedesktopLogin1ManagerInterface manager(Logind::serviceName(), + Logind::managerPath(), + conn); + auto reply = manager.GetSession(session); + reply.waitForFinished(); + if (!reply.isValid()) { + qCWarning(treelandGreeter) << "Failed to get session path for session" << session + << ", error:" << reply.error().message(); + return; + } + auto path = reply.value(); + conn.connect(Logind::serviceName(), + path.path(), + Logind::sessionIfaceName(), + "Lock", + this, + SLOT(onSessionLock())); + conn.connect(Logind::serviceName(), + path.path(), + Logind::sessionIfaceName(), + "Unlock", + this, + SLOT(onSessionUnlock())); + }); + } else { + qCWarning(treelandGreeter) << "User " << username << " logged in but not found"; } - qCInfo(treelandGreeter) << "Locking user" << session->username() << "with session id" << session->id(); - SocketWriter(m_socket) << quint32(GreeterMessages::Lock) << session->id(); +} + +void GreeterProxy::authenticationFailed(uint32_t error) +{ + qCDebug(treelandGreeter) << "Message received from DDM: Authentication Failed:" + << DDMInterfaceV2::authErrorToString(error); + Q_EMIT failedAttemptsChanged(++m_failedAttempts); } ////////////////////////////// @@ -274,7 +357,7 @@ void GreeterProxy::onSessionNew(const QString &id, [[maybe_unused]] const QDBusO qCInfo(treelandGreeter) << "New session added: id=" << id << ", user=" << user; userModel()->updateUserLoginState(user, true); // userLoggedIn signal is connected with Helper::updateActiveUserSession - Q_EMIT userModel()->userLoggedIn(user, id.toInt()); + Q_EMIT userModel()->userLoggedIn(user, id); // Connect to Lock/Unlock signals auto conn = QDBusConnection::systemBus(); @@ -317,7 +400,7 @@ void GreeterProxy::onSessionRemoved(const QString &id, [[maybe_unused]] const QD this, SLOT(onSessionUnlock())); - auto session = Helper::instance()->sessionManager()->sessionForId(id.toInt()); + auto session = Helper::instance()->sessionManager()->sessionForId(id); if (session) { QString username = session->username(); qCInfo(treelandGreeter) << "Session removed: id=" << id << ", user=" << username; @@ -340,7 +423,7 @@ void GreeterProxy::onSessionLock() OrgFreedesktopLogin1SessionInterface session("org.freedesktop.login1", path, QDBusConnection::systemBus()); - int id = session.id().toInt(); + QString id = session.id(); qCInfo(treelandGreeter) << "Lock signal received for session id:" << id; auto activeSession = Helper::instance()->sessionManager()->activeSession().lock(); if (!activeSession) @@ -363,7 +446,7 @@ void GreeterProxy::onSessionUnlock() OrgFreedesktopLogin1SessionInterface session("org.freedesktop.login1", path, QDBusConnection::systemBus()); - int id = session.id().toInt(); + QString id = session.id(); const QString username = session.name(); qCInfo(treelandGreeter) << "Unlock signal received for session id:" << id; auto activeSession = Helper::instance()->sessionManager()->activeSession().lock(); @@ -374,7 +457,12 @@ void GreeterProxy::onSessionUnlock() qCWarning(treelandGreeter) << "Unlock signal received for non-active session id:" << id << ", lock it back."; QMetaObject::invokeMethod(this, [this, id] { - SocketWriter(m_socket) << quint32(GreeterMessages::Lock) << QString::number(id); + if (m_ddmInterface && m_ddmInterface->isValid()) { + m_ddmInterface->lock(id); + } else { + qCInfo(treelandGreeter) << "Trying to lock when DDM is not available, show lockscreen directly." << id; + setLock(true); + } }); } else { QMetaObject::invokeMethod(this, [this] { @@ -383,180 +471,3 @@ void GreeterProxy::onSessionUnlock() } }); } - -/////////////////////// -// DDM Communication // -/////////////////////// - -bool GreeterProxy::isConnected() const -{ - return m_socket->state() == QLocalSocket::ConnectedState; -} - -void GreeterProxy::connected() -{ - qCInfo(treelandGreeter) << "Connected to the ddm"; - - SocketWriter(m_socket) - << quint32(GreeterMessages::Connect) - << Helper::instance()->sessionManager()->globalSession()->socket()->fullServerName(); -} - -void GreeterProxy::disconnected() -{ - qCWarning(treelandGreeter) << "Disconnected from the ddm"; - - Q_EMIT socketDisconnected(); -} - -void GreeterProxy::error() -{ - qCCritical(treelandGreeter) << "Socket error: " << m_socket->errorString(); -} - -void GreeterProxy::readyRead() -{ - // input stream - QDataStream input(m_socket); - - while (input.device()->bytesAvailable()) { - // read message - quint32 message; - input >> message; - - switch (DaemonMessages(message)) { - case DaemonMessages::Capabilities: { - // log message - qCDebug(treelandGreeter) << "Message received from daemon: Capabilities"; - - // read capabilities - quint32 capabilities; - input >> capabilities; - - // parse capabilities - m_canPowerOff = capabilities & Capability::PowerOff; - m_canReboot = capabilities & Capability::Reboot; - m_canSuspend = capabilities & Capability::Suspend; - m_canHibernate = capabilities & Capability::Hibernate; - m_canHybridSleep = capabilities & Capability::HybridSleep; - - // Q_EMIT signals - Q_EMIT canPowerOffChanged(m_canPowerOff); - Q_EMIT canRebootChanged(m_canReboot); - Q_EMIT canSuspendChanged(m_canSuspend); - Q_EMIT canHibernateChanged(m_canHibernate); - Q_EMIT canHybridSleepChanged(m_canHybridSleep); - } break; - case DaemonMessages::HostName: { - qCDebug(treelandGreeter) << "Message received from daemon: HostName"; - - // read host name - input >> m_hostName; - - // Q_EMIT signal - Q_EMIT hostNameChanged(m_hostName); - } break; - case DaemonMessages::LoginFailed: { - QString user; - input >> user; - - qCDebug(treelandGreeter) << "Message received from daemon: LoginFailed" << user; - - Q_EMIT failedAttemptsChanged(++m_failedAttempts); - } break; - case DaemonMessages::InformationMessage: { - QString message; - input >> message; - - qCDebug(treelandGreeter) << "Information Message received from daemon: " << message; - Q_EMIT informationMessage(message); - } break; - case DaemonMessages::SwitchToGreeter: { - qCInfo(treelandGreeter) << "switch to greeter"; - lock(); - } break; - case DaemonMessages::UserActivateMessage: { - QString user; - int sessionId; - input >> user >> sessionId; - - // NOTE: maybe DDM will active dde user. - if (!userModel()->getUser(user)) { - qCInfo(treelandGreeter) << "activate user, but switch to greeter"; - lock(); - break; - } - - userModel()->setCurrentUserName(user); - - qCInfo(treelandGreeter) << "activate successfully: " << user << ", XDG_SESSION_ID: " << sessionId; - } break; - case DaemonMessages::UserLoggedIn: { - QString user; - int sessionId; - input >> user >> sessionId; - - // This will happen after a crash recovery of treeland - qCInfo(treelandGreeter) << "User " << user << " is already logged in"; - auto userPtr = userModel()->getUser(user); - if (userPtr) { - userModel()->updateUserLoginState(user, true); - Q_EMIT userModel()->userLoggedIn(user, sessionId); - QThreadPool::globalInstance()->start([this, sessionId] { - // Connect to Lock/Unlock signals - auto conn = QDBusConnection::systemBus(); - OrgFreedesktopLogin1ManagerInterface manager("org.freedesktop.login1", - Logind::managerPath(), - conn); - auto reply = manager.GetSession(QString::number(sessionId)); - reply.waitForFinished(); - if (!reply.isValid()) { - qCWarning(treelandGreeter) << "Failed to get session path for session id:" << sessionId << ", error:" << reply.error().message(); - return; - } - auto path = reply.value(); - conn.connect(Logind::serviceName(), - path.path(), - Logind::sessionIfaceName(), - "Lock", - this, - SLOT(onSessionLock())); - conn.connect(Logind::serviceName(), - path.path(), - Logind::sessionIfaceName(), - "Unlock", - this, - SLOT(onSessionUnlock())); - }); - } else { - qCWarning(treelandGreeter) << "User " << user << " logged in but not found"; - } - } break; - default: { - qCWarning(treelandGreeter) << "Unknown message received from daemon." << message; - } - } - } -} - -void GreeterProxy::updateAuthSocket() -{ - QThreadPool::globalInstance()->start([this]() { - QDBusInterface manager("org.deepin.DisplayManager", - "/org/deepin/DisplayManager", - "org.deepin.DisplayManager", - QDBusConnection::systemBus()); - QDBusReply reply = manager.call("AuthInfo"); - if (!reply.isValid()) { - qCWarning(treelandGreeter) << "Failed to get auth info from display manager:" << reply.error().message(); - return; - } - const QString &socket = reply.value(); - QMetaObject::invokeMethod(this, [this, socket] { - if (m_socket->state() == QLocalSocket::ConnectedState) - m_socket->disconnectFromServer(); - - m_socket->connectToServer(socket); - }); - }); -} diff --git a/src/greeter/greeterproxy.h b/src/greeter/greeterproxy.h index e628e0a51..95762abc1 100644 --- a/src/greeter/greeterproxy.h +++ b/src/greeter/greeterproxy.h @@ -10,6 +10,7 @@ class QLocalSocket; +class DDMInterfaceV2; class LockScreen; class GreeterProxy @@ -43,6 +44,8 @@ class GreeterProxy explicit GreeterProxy(QObject *parent = nullptr); ~GreeterProxy(); + void connectDDM(DDMInterfaceV2 *interface); + ////////////////////// // Property getters // ////////////////////// @@ -93,7 +96,9 @@ class GreeterProxy /** * @brief Get the number of failed login attempts (password incorrect) + * * The value is reset to 0 when unlocked successfully + * * QML elements should listen to this property to detect failed login/unlock attempts * * @return Number of failed attempts @@ -102,6 +107,7 @@ class GreeterProxy /** * @brief Get whether the shutdown view is shown + * * QML elements should listen to this property to show/hide the shutdown view * * @return true if shutdown view is shown @@ -110,6 +116,7 @@ class GreeterProxy /** * @brief Get whether to show animation on lock/unlock + * * QML elements should listen to this property to enable/disable animation * * @return true if show animation @@ -118,6 +125,7 @@ class GreeterProxy /** * @brief Get whether there is an active user session + * * QML elements should listen to this property to show/hide session related UI * * @return true if has active session @@ -130,6 +138,7 @@ class GreeterProxy /** * @brief Set whether to show the shutdown view + * * QML elements should set this property to show/hide the shutdown view * * @param show true to show shutdown view, false to hide @@ -140,14 +149,9 @@ class GreeterProxy // Public methods // //////////////////// - /** - * @brief Check if the DDM socket is connected - * @return true if connected - */ - bool isConnected() const; - /** * @brief Set the LockScreen instance + * * This is necessary for the GreeterProxy to control the lock screen visibility * * @param lockScreen LockScreen instance @@ -176,6 +180,7 @@ public Q_SLOTS: void hybridSleep(); /** @brief Login given user with given password for given desktop session. + * * This function will call DDM to perform the login. * * Listen to org.freedesktop.login1.Manager.SessionNew signal to @@ -189,6 +194,7 @@ public Q_SLOTS: void login(const QString &user, const QString &password, int sessionIndex); /** @brief Lock the current active session. + * * This function will call DDM to perform the lock. * * Listen to org.freedesktop.login1.Session.Lock signal to detect @@ -197,6 +203,7 @@ public Q_SLOTS: void lock(); /** @brief Unlock given user with given password. + * * This function will call DDM to perform the unlock. * * Listen to org.freedesktop.login1.Session.Unlock signal to @@ -209,6 +216,7 @@ public Q_SLOTS: void unlock(const QString &user, const QString &password); /** @brief Logout the current active session. + * * This function will call DDM to perform the logout. * * Listen to org.freedesktop.login1.Manager.SessionRemoved signal to @@ -218,14 +226,13 @@ public Q_SLOTS: private Q_SLOTS: - /////////////////////// - // DDM Communication // - /////////////////////// + ////////////////////// + // Signals from DDM // + ////////////////////// - void connected(); - void disconnected(); - void readyRead(); - void error(); + void capabilities(uint32_t capabilities); + void userLoggedIn(const QString &username, const QString &session); + void authenticationFailed(uint32_t error); ////////////////////////////// // Logind session listeners // @@ -244,8 +251,6 @@ private Q_SLOTS: void onSessionUnlock(); Q_SIGNALS: - void informationMessage(const QString &message); - void switchUser(); void socketDisconnected(); @@ -295,6 +300,7 @@ private Q_SLOTS: /** * @brief Set the lock state + * * This is the internal method to set the lock state (lockscreen * visibility, etc.) directly without calling DDM and * communicating with systemd-logind. @@ -303,16 +309,11 @@ private Q_SLOTS: */ void setLock(bool isLocked); - /** - * @brief Update the DDM communication socket - */ - void updateAuthSocket(); - ///////////////////// // Property values // ///////////////////// - QLocalSocket *m_socket{ nullptr }; + DDMInterfaceV2 *m_ddmInterface{ nullptr }; LockScreen *m_lockScreen{ nullptr }; QString m_hostName{}; From 24774db7901abfb68820d12ea61bae7111cb4b2d Mon Sep 17 00:00:00 2001 From: April & May & June Date: Wed, 25 Feb 2026 19:31:39 +0800 Subject: [PATCH 3/3] feat: Use string for logind session id instead of int Although the logind session id is exactly an integer in current systemd-logind, but this is an UB according to systemd documentation. Systemd advertise us to treat it as a string and we shall adapt it. --- src/greeter/usermodel.h | 2 +- src/seat/helper.cpp | 2 +- src/session/session.cpp | 9 +++++---- src/session/session.h | 10 +++++----- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/greeter/usermodel.h b/src/greeter/usermodel.h index 3ab250bed..ec682f329 100644 --- a/src/greeter/usermodel.h +++ b/src/greeter/usermodel.h @@ -85,7 +85,7 @@ class UserModel : public QAbstractListModel void currentUserNameChanged(); void updateTranslations(const QLocale &locale); void countChanged(); - void userLoggedIn(const QString &username, int sessionId); + void userLoggedIn(const QString &username, const QString &session); private Q_SLOTS: void onUserAdded(quint64 uid); diff --git a/src/seat/helper.cpp b/src/seat/helper.cpp index d0f3f2b43..ab1745eda 100644 --- a/src/seat/helper.cpp +++ b/src/seat/helper.cpp @@ -1411,7 +1411,7 @@ void Helper::init(Treeland::Treeland *treeland) xdgOutputManager->setFilter([](WClient *client) { return !isXWaylandClient(client); }); xwaylandOutputManager->setFilter([](WClient *client) { return isXWaylandClient(client); }); // User dde does not has a real Logind session, so just pass 0 as id - m_sessionManager->updateActiveUserSession(QStringLiteral("dde"), 0); + m_sessionManager->updateActiveUserSession(QStringLiteral("dde"), {}); connect(m_userModel, &UserModel::userLoggedIn, m_sessionManager, &SessionManager::updateActiveUserSession); m_xdgDecorationManager = m_server->attach(); connect(m_xdgDecorationManager, diff --git a/src/session/session.cpp b/src/session/session.cpp index 2553760c1..01142fbf4 100644 --- a/src/session/session.cpp +++ b/src/session/session.cpp @@ -62,7 +62,7 @@ Session::~Session() } } -int Session::id() const +QString Session::id() const { return m_id; } @@ -192,7 +192,7 @@ void SessionManager::removeSession(std::shared_ptr session) * @param username Username to ensure session for * @returns Session for the given username, or nullptr on failure */ -std::shared_ptr SessionManager::ensureSession(int id, QString username) +std::shared_ptr SessionManager::ensureSession(QString id, QString username) { // Helper lambda to create WSocket and WXWayland auto createWSocket = [this]() { @@ -324,7 +324,7 @@ std::shared_ptr SessionManager::ensureSession(int id, QString username) * @param id Session ID to find session for * @returns Session for the given id, or nullptr if not found */ -std::shared_ptr SessionManager::sessionForId(int id) const +std::shared_ptr SessionManager::sessionForId(const QString &id) const { for (auto session : m_sessions) { if (session && session->m_id == id) @@ -404,8 +404,9 @@ bool SessionManager::isDDEUserClient(WClient *client) * active session changed. * * @param username Username to set as active session + * @param session Logind session ID to set as active session */ -void SessionManager::updateActiveUserSession(const QString &username, int id) +void SessionManager::updateActiveUserSession(const QString &username, const QString &id) { // Get previous active session auto previous = m_activeSession.lock(); diff --git a/src/session/session.h b/src/session/session.h index 25331aae2..797bf86e9 100644 --- a/src/session/session.h +++ b/src/session/session.h @@ -22,7 +22,7 @@ class Session : public QObject { public: ~Session(); - int id() const; + QString id() const; uid_t uid() const; const QString &username() const; WSocket *socket() const; @@ -35,7 +35,7 @@ class Session : public QObject { private: friend class SessionManager; - int m_id = 0; + QString m_id = {}; uid_t m_uid = 0; QString m_username = {}; WSocket *m_socket = nullptr; @@ -62,9 +62,9 @@ class SessionManager : public QObject { bool activeSocketEnabled() const; void setActiveSocketEnabled(bool newEnabled); - void updateActiveUserSession(const QString &username, int id); + void updateActiveUserSession(const QString &username, const QString &id); void removeSession(std::shared_ptr session); - std::shared_ptr sessionForId(int id) const; + std::shared_ptr sessionForId(const QString &id) const; std::shared_ptr sessionForUid(uid_t uid) const; std::shared_ptr sessionForUser(const QString &username) const; std::shared_ptr sessionForXWayland(WXWayland *xwayland) const; @@ -76,7 +76,7 @@ class SessionManager : public QObject { void sessionChanged(); private: - std::shared_ptr ensureSession(int id, QString username); + std::shared_ptr ensureSession(QString id, QString username); std::weak_ptr m_activeSession; QList> m_sessions;