From 83bf693a85ae7bfc45ce7c8132470f81c2f5343c Mon Sep 17 00:00:00 2001 From: Dustin Pilgrim Date: Fri, 12 Dec 2025 22:34:38 -0400 Subject: [PATCH 1/7] feat: add DBus ScreenSaver interface for lock screen state tracking --- src/dbus/CMakeLists.txt | 19 +++---- src/dbus/org.freedesktop.ScreenSaver.xml | 18 +++++++ src/dbus/screensaver_dbus.cpp | 63 +++++++++++++++++++++++ src/dbus/screensaver_dbus.hpp | 40 ++++++++++++++ src/wayland/session_lock/CMakeLists.txt | 7 +-- src/wayland/session_lock/session_lock.cpp | 46 +++++++---------- src/wayland/session_lock/session_lock.hpp | 10 ++-- 7 files changed, 158 insertions(+), 45 deletions(-) create mode 100644 src/dbus/org.freedesktop.ScreenSaver.xml create mode 100644 src/dbus/screensaver_dbus.cpp create mode 100644 src/dbus/screensaver_dbus.hpp diff --git a/src/dbus/CMakeLists.txt b/src/dbus/CMakeLists.txt index fc004f3d..43a3866c 100644 --- a/src/dbus/CMakeLists.txt +++ b/src/dbus/CMakeLists.txt @@ -1,36 +1,39 @@ set_source_files_properties(org.freedesktop.DBus.Properties.xml PROPERTIES CLASSNAME DBusPropertiesInterface ) - set_source_files_properties(org.freedesktop.DBus.ObjectManager.xml PROPERTIES CLASSNAME DBusObjectManagerInterface INCLUDE ${CMAKE_CURRENT_SOURCE_DIR}/dbus_objectmanager_types.hpp ) - +set_source_files_properties(org.freedesktop.ScreenSaver.xml PROPERTIES + CLASSNAME ScreenSaverAdaptor + INCLUDE screensaver_dbus.hpp +) qt_add_dbus_interface(DBUS_INTERFACES org.freedesktop.DBus.Properties.xml dbus_properties ) - qt_add_dbus_interface(DBUS_INTERFACES org.freedesktop.DBus.ObjectManager.xml dbus_objectmanager ) - +qt_add_dbus_adaptor(DBUS_INTERFACES + org.freedesktop.ScreenSaver.xml + ${CMAKE_CURRENT_SOURCE_DIR}/screensaver_dbus.hpp + qs::dbus::ScreenSaverAdaptor +) qt_add_library(quickshell-dbus STATIC properties.cpp objectmanager.cpp bus.cpp + screensaver_dbus.cpp ${DBUS_INTERFACES} ) - # dbus headers target_include_directories(quickshell-dbus PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) - target_link_libraries(quickshell-dbus PRIVATE Qt::Core Qt::DBus) # todo: link dbus to quickshell here instead of in modules that use it directly # linker does not like this as is - qs_add_pchset(dbus DEPENDENCIES Qt::DBus HEADERS @@ -38,7 +41,5 @@ qs_add_pchset(dbus ) - qs_pch(quickshell-dbus SET dbus) - add_subdirectory(dbusmenu) diff --git a/src/dbus/org.freedesktop.ScreenSaver.xml b/src/dbus/org.freedesktop.ScreenSaver.xml new file mode 100644 index 00000000..77b5850b --- /dev/null +++ b/src/dbus/org.freedesktop.ScreenSaver.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/src/dbus/screensaver_dbus.cpp b/src/dbus/screensaver_dbus.cpp new file mode 100644 index 00000000..140584b7 --- /dev/null +++ b/src/dbus/screensaver_dbus.cpp @@ -0,0 +1,63 @@ +#include "screensaver_dbus.hpp" +#include +#include +#include + +#include "../core/logcat.hpp" + +QS_LOGGING_CATEGORY(logDbusScreenSaver, "quickshell.dbus.screensaver", QtWarningMsg); + +namespace qs::dbus { + +ScreenSaverAdaptor::ScreenSaverAdaptor(QObject* parent) + : QDBusAbstractAdaptor(parent) { + // Register on session bus + auto connection = QDBusConnection::sessionBus(); + + if (!connection.registerService("org.freedesktop.ScreenSaver")) { + qCWarning(logDbusScreenSaver) + << "Failed to register DBus service org.freedesktop.ScreenSaver:" + << connection.lastError().message(); + } else { + qCInfo(logDbusScreenSaver) << "Registered DBus service org.freedesktop.ScreenSaver"; + } + + if (!connection.registerObject( + "/org/freedesktop/ScreenSaver", + parent, + QDBusConnection::ExportAdaptors + )) { + qCWarning(logDbusScreenSaver) + << "Failed to register DBus object /org/freedesktop/ScreenSaver:" + << connection.lastError().message(); + } else { + qCInfo(logDbusScreenSaver) << "Registered DBus object /org/freedesktop/ScreenSaver"; + } +} + +void ScreenSaverAdaptor::setActive(bool active) { + if (this->mActive != active) { + this->mActive = active; + qCDebug(logDbusScreenSaver) << "Lock state changed to:" << active; + emit this->ActiveChanged(active); + } +} + +void ScreenSaverAdaptor::setSecure(bool secure) { + if (this->mSecure != secure) { + this->mSecure = secure; + qCDebug(logDbusScreenSaver) << "Secure state changed to:" << secure; + } +} + +bool ScreenSaverAdaptor::GetActive() const { + qCDebug(logDbusScreenSaver) << "GetActive called, returning:" << this->mActive; + return this->mActive; +} + +bool ScreenSaverAdaptor::GetSecure() const { + qCDebug(logDbusScreenSaver) << "GetSecure called, returning:" << this->mSecure; + return this->mSecure; +} + +} // namespace qs::dbus diff --git a/src/dbus/screensaver_dbus.hpp b/src/dbus/screensaver_dbus.hpp new file mode 100644 index 00000000..c84d9f81 --- /dev/null +++ b/src/dbus/screensaver_dbus.hpp @@ -0,0 +1,40 @@ +#pragma once + +#include +#include +#include + +namespace qs::dbus { + +// DBus adaptor for exposing screen lock state to other applications +// Implements org.freedesktop.ScreenSaver interface +class ScreenSaverAdaptor: public QDBusAbstractAdaptor { + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "org.freedesktop.ScreenSaver") + +public: + explicit ScreenSaverAdaptor(QObject* parent); + ~ScreenSaverAdaptor() override = default; + Q_DISABLE_COPY_MOVE(ScreenSaverAdaptor); + + // Update the active state and emit signal if changed + void setActive(bool active); + // Update the secure state (compositor has confirmed lock) + void setSecure(bool secure); + +public slots: // NOLINT + // DBus method: Get current lock state + [[nodiscard]] bool GetActive() const; + // DBus method: Get whether lock is secure (compositor confirmed) + [[nodiscard]] bool GetSecure() const; + +signals: // NOLINT + // DBus signal: Emitted when lock state changes + void ActiveChanged(bool active); + +private: + bool mActive = false; + bool mSecure = false; +}; + +} // namespace qs::dbus diff --git a/src/wayland/session_lock/CMakeLists.txt b/src/wayland/session_lock/CMakeLists.txt index d157fc13..56f58a60 100644 --- a/src/wayland/session_lock/CMakeLists.txt +++ b/src/wayland/session_lock/CMakeLists.txt @@ -5,14 +5,11 @@ qt_add_library(quickshell-wayland-sessionlock STATIC shell_integration.cpp session_lock.cpp ) - wl_proto(wlp-session-lock ext-session-lock-v1 "${WAYLAND_PROTOCOLS}/staging/ext-session-lock") - target_link_libraries(quickshell-wayland-sessionlock PRIVATE - Qt::Quick Qt::WaylandClient Qt::WaylandClientPrivate wayland-client + Qt::Quick Qt::WaylandClient Qt::WaylandClientPrivate Qt::DBus wayland-client wlp-session-lock + quickshell-dbus ) - qs_pch(quickshell-wayland-sessionlock SET large) - target_link_libraries(quickshell-wayland PRIVATE quickshell-wayland-sessionlock) diff --git a/src/wayland/session_lock/session_lock.cpp b/src/wayland/session_lock/session_lock.cpp index c32dd90a..39580603 100644 --- a/src/wayland/session_lock/session_lock.cpp +++ b/src/wayland/session_lock/session_lock.cpp @@ -1,41 +1,50 @@ #include "session_lock.hpp" - #include #include #include #include - +#include "../../dbus/screensaver_dbus.hpp" #include "lock.hpp" #include "manager.hpp" #include "shell_integration.hpp" #include "surface.hpp" - namespace { QSWaylandSessionLockManager* manager() { static QSWaylandSessionLockManager* manager = nullptr; // NOLINT - if (manager == nullptr) { manager = new QSWaylandSessionLockManager(); } - return manager; } } // namespace - bool SessionLockManager::lockAvailable() { return manager()->isActive(); } - bool SessionLockManager::lock() { if (this->isLocked() || SessionLockManager::sessionLocked()) return false; this->mLock = manager()->acquireLock(); this->mLock->setParent(this); - + + // Initialize DBus adaptor if not already created + if (this->mDbusAdaptor == nullptr) { + this->mDbusAdaptor = new qs::dbus::ScreenSaverAdaptor(this); + } + + // Notify DBus that we're attempting to lock (not yet secure) + this->mDbusAdaptor->setActive(true); + this->mDbusAdaptor->setSecure(false); + // clang-format off - QObject::connect(this->mLock, &QSWaylandSessionLock::compositorLocked, this, &SessionLockManager::locked); - QObject::connect(this->mLock, &QSWaylandSessionLock::unlocked, this, &SessionLockManager::unlocked); + QObject::connect(this->mLock, &QSWaylandSessionLock::compositorLocked, this, [this]() { + this->mDbusAdaptor->setSecure(true); + emit this->locked(); + }); + QObject::connect(this->mLock, &QSWaylandSessionLock::unlocked, this, [this]() { + this->mDbusAdaptor->setActive(false); + this->mDbusAdaptor->setSecure(false); + emit this->unlocked(); + }); // clang-format on return true; } - bool SessionLockManager::unlock() { if (!this->isLocked()) return false; this->mLock->unlock(); @@ -44,36 +53,28 @@ bool SessionLockManager::unlock() { delete lock; return true; } - bool SessionLockManager::isLocked() const { return this->mLock != nullptr; } bool SessionLockManager::sessionLocked() { return manager()->isLocked(); } bool SessionLockManager::isSecure() { return manager()->isSecure(); } - LockWindowExtension::~LockWindowExtension() { if (this->surface != nullptr) { this->surface->setExtension(nullptr); } } - LockWindowExtension* LockWindowExtension::get(QWindow* window) { auto v = window->property("sessionlock_ext"); - if (v.canConvert()) { return v.value(); } else { return nullptr; } } - bool LockWindowExtension::isAttached() const { return this->surface != nullptr; } - bool LockWindowExtension::attach(QWindow* window, SessionLockManager* manager) { if (this->surface != nullptr) qFatal() << "Cannot change the attached window of a LockWindowExtension"; - auto* current = LockWindowExtension::get(window); QtWaylandClient::QWaylandWindow* waylandWindow = nullptr; - if (current != nullptr) { current->surface->setExtension(this); } else { @@ -81,13 +82,11 @@ bool LockWindowExtension::attach(QWindow* window, SessionLockManager* manager) { auto* screen = window->screen(); window->create(); window->setScreen(screen); - waylandWindow = dynamic_cast(window->handle()); if (waylandWindow == nullptr) { qWarning() << window << "is not a wayland window. Cannot create lock surface."; return false; } - static QSWaylandSessionLockIntegration* lockIntegration = nullptr; // NOLINT if (lockIntegration == nullptr) { lockIntegration = new QSWaylandSessionLockIntegration(); @@ -97,22 +96,17 @@ bool LockWindowExtension::attach(QWindow* window, SessionLockManager* manager) { qWarning() << "Failed to initialize lockscreen integration"; } } - waylandWindow->setShellIntegration(lockIntegration); } - this->setParent(window); window->setProperty("sessionlock_ext", QVariant::fromValue(this)); this->lock = manager->mLock; - if (waylandWindow != nullptr) { this->surface = new QSWaylandSessionLockSurface(waylandWindow); if (this->immediatelyVisible) this->surface->setVisible(); } - return true; } - void LockWindowExtension::setVisible() { if (this->surface == nullptr) this->immediatelyVisible = true; else this->surface->setVisible(); diff --git a/src/wayland/session_lock/session_lock.hpp b/src/wayland/session_lock/session_lock.hpp index 5a558966..6c2b8732 100644 --- a/src/wayland/session_lock/session_lock.hpp +++ b/src/wayland/session_lock/session_lock.hpp @@ -9,9 +9,12 @@ class QSWaylandSessionLock; class QSWaylandSessionLockSurface; class QSWaylandSessionLockIntegration; +namespace qs::dbus { +class ScreenSaverAdaptor; +} + class SessionLockManager: public QObject { Q_OBJECT; - public: explicit SessionLockManager(QObject* parent = nullptr): QObject(parent) {} @@ -46,18 +49,15 @@ class SessionLockManager: public QObject { // After receiving this event the caller should destroy all of its lock surfaces. void unlocked(); -private slots: - //void onUnlocked(); - private: QSWaylandSessionLock* mLock = nullptr; + qs::dbus::ScreenSaverAdaptor* mDbusAdaptor = nullptr; friend class LockWindowExtension; }; class LockWindowExtension: public QObject { Q_OBJECT; - public: explicit LockWindowExtension(QObject* parent = nullptr): QObject(parent) {} ~LockWindowExtension() override; From cffd4d6dd2b3fe6380e87a85868223cbe72b60f7 Mon Sep 17 00:00:00 2001 From: Dustin Pilgrim Date: Fri, 12 Dec 2025 22:55:22 -0400 Subject: [PATCH 2/7] fix: linter formatting issue --- src/dbus/screensaver_dbus.cpp | 24 ++++++++++------------- src/wayland/session_lock/session_lock.cpp | 8 +++++--- src/wayland/session_lock/session_lock.hpp | 2 ++ 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/dbus/screensaver_dbus.cpp b/src/dbus/screensaver_dbus.cpp index 140584b7..e80524c7 100644 --- a/src/dbus/screensaver_dbus.cpp +++ b/src/dbus/screensaver_dbus.cpp @@ -1,4 +1,5 @@ #include "screensaver_dbus.hpp" + #include #include #include @@ -9,27 +10,22 @@ QS_LOGGING_CATEGORY(logDbusScreenSaver, "quickshell.dbus.screensaver", QtWarning namespace qs::dbus { -ScreenSaverAdaptor::ScreenSaverAdaptor(QObject* parent) - : QDBusAbstractAdaptor(parent) { +ScreenSaverAdaptor::ScreenSaverAdaptor(QObject* parent): QDBusAbstractAdaptor(parent) { // Register on session bus auto connection = QDBusConnection::sessionBus(); - + if (!connection.registerService("org.freedesktop.ScreenSaver")) { - qCWarning(logDbusScreenSaver) - << "Failed to register DBus service org.freedesktop.ScreenSaver:" - << connection.lastError().message(); + qCWarning(logDbusScreenSaver) << "Failed to register DBus service org.freedesktop.ScreenSaver:" + << connection.lastError().message(); } else { qCInfo(logDbusScreenSaver) << "Registered DBus service org.freedesktop.ScreenSaver"; } - if (!connection.registerObject( - "/org/freedesktop/ScreenSaver", - parent, - QDBusConnection::ExportAdaptors - )) { - qCWarning(logDbusScreenSaver) - << "Failed to register DBus object /org/freedesktop/ScreenSaver:" - << connection.lastError().message(); + if (!connection + .registerObject("/org/freedesktop/ScreenSaver", parent, QDBusConnection::ExportAdaptors)) + { + qCWarning(logDbusScreenSaver) << "Failed to register DBus object /org/freedesktop/ScreenSaver:" + << connection.lastError().message(); } else { qCInfo(logDbusScreenSaver) << "Registered DBus object /org/freedesktop/ScreenSaver"; } diff --git a/src/wayland/session_lock/session_lock.cpp b/src/wayland/session_lock/session_lock.cpp index 39580603..d4a80dd1 100644 --- a/src/wayland/session_lock/session_lock.cpp +++ b/src/wayland/session_lock/session_lock.cpp @@ -1,8 +1,10 @@ #include "session_lock.hpp" + #include #include #include #include + #include "../../dbus/screensaver_dbus.hpp" #include "lock.hpp" #include "manager.hpp" @@ -22,16 +24,16 @@ bool SessionLockManager::lock() { if (this->isLocked() || SessionLockManager::sessionLocked()) return false; this->mLock = manager()->acquireLock(); this->mLock->setParent(this); - + // Initialize DBus adaptor if not already created if (this->mDbusAdaptor == nullptr) { this->mDbusAdaptor = new qs::dbus::ScreenSaverAdaptor(this); } - + // Notify DBus that we're attempting to lock (not yet secure) this->mDbusAdaptor->setActive(true); this->mDbusAdaptor->setSecure(false); - + // clang-format off QObject::connect(this->mLock, &QSWaylandSessionLock::compositorLocked, this, [this]() { this->mDbusAdaptor->setSecure(true); diff --git a/src/wayland/session_lock/session_lock.hpp b/src/wayland/session_lock/session_lock.hpp index 6c2b8732..b61473e0 100644 --- a/src/wayland/session_lock/session_lock.hpp +++ b/src/wayland/session_lock/session_lock.hpp @@ -15,6 +15,7 @@ class ScreenSaverAdaptor; class SessionLockManager: public QObject { Q_OBJECT; + public: explicit SessionLockManager(QObject* parent = nullptr): QObject(parent) {} @@ -58,6 +59,7 @@ class SessionLockManager: public QObject { class LockWindowExtension: public QObject { Q_OBJECT; + public: explicit LockWindowExtension(QObject* parent = nullptr): QObject(parent) {} ~LockWindowExtension() override; From f7dee7af5e1b1b0b905442708fee939658504e2f Mon Sep 17 00:00:00 2001 From: Dustin Pilgrim Date: Fri, 12 Dec 2025 23:18:05 -0400 Subject: [PATCH 3/7] fix: imports in screensaver_dbus.cpp --- src/dbus/screensaver_dbus.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/dbus/screensaver_dbus.cpp b/src/dbus/screensaver_dbus.cpp index e80524c7..9231df5b 100644 --- a/src/dbus/screensaver_dbus.cpp +++ b/src/dbus/screensaver_dbus.cpp @@ -1,8 +1,8 @@ #include "screensaver_dbus.hpp" -#include -#include -#include +#include +#include +#include #include "../core/logcat.hpp" From d25f9bb2bf0cb7f0c2110963e9462247a748a0d4 Mon Sep 17 00:00:00 2001 From: Dustin Pilgrim Date: Sat, 13 Dec 2025 00:40:58 -0400 Subject: [PATCH 4/7] fix: linting issues in src/dbus dir --- src/dbus/org.freedesktop.ScreenSaver.xml | 6 +- src/dbus/screensaver_dbus.cpp | 74 +++++++++++++----------- src/dbus/screensaver_dbus.hpp | 41 ++++++------- 3 files changed, 60 insertions(+), 61 deletions(-) diff --git a/src/dbus/org.freedesktop.ScreenSaver.xml b/src/dbus/org.freedesktop.ScreenSaver.xml index 77b5850b..8fa118b3 100644 --- a/src/dbus/org.freedesktop.ScreenSaver.xml +++ b/src/dbus/org.freedesktop.ScreenSaver.xml @@ -1,17 +1,17 @@ - + - + - + diff --git a/src/dbus/screensaver_dbus.cpp b/src/dbus/screensaver_dbus.cpp index 9231df5b..042ecd2d 100644 --- a/src/dbus/screensaver_dbus.cpp +++ b/src/dbus/screensaver_dbus.cpp @@ -3,57 +3,63 @@ #include #include #include +#include // QtWarningMsg +#include // emit #include "../core/logcat.hpp" +namespace { QS_LOGGING_CATEGORY(logDbusScreenSaver, "quickshell.dbus.screensaver", QtWarningMsg); +} namespace qs::dbus { -ScreenSaverAdaptor::ScreenSaverAdaptor(QObject* parent): QDBusAbstractAdaptor(parent) { - // Register on session bus - auto connection = QDBusConnection::sessionBus(); - - if (!connection.registerService("org.freedesktop.ScreenSaver")) { - qCWarning(logDbusScreenSaver) << "Failed to register DBus service org.freedesktop.ScreenSaver:" - << connection.lastError().message(); - } else { - qCInfo(logDbusScreenSaver) << "Registered DBus service org.freedesktop.ScreenSaver"; - } - - if (!connection - .registerObject("/org/freedesktop/ScreenSaver", parent, QDBusConnection::ExportAdaptors)) - { - qCWarning(logDbusScreenSaver) << "Failed to register DBus object /org/freedesktop/ScreenSaver:" - << connection.lastError().message(); - } else { - qCInfo(logDbusScreenSaver) << "Registered DBus object /org/freedesktop/ScreenSaver"; - } +ScreenSaverAdaptor::ScreenSaverAdaptor(QObject* parent) + : QDBusAbstractAdaptor(parent) +{ + // Register on session bus + auto connection = QDBusConnection::sessionBus(); + + if (!connection.registerService("org.freedesktop.ScreenSaver")) { + qCWarning(logDbusScreenSaver) << "Failed to register DBus service org.freedesktop.ScreenSaver:" + << connection.lastError().message(); + } else { + qCInfo(logDbusScreenSaver) << "Registered DBus service org.freedesktop.ScreenSaver"; + } + + if (!connection.registerObject("/org/freedesktop/ScreenSaver", parent, + QDBusConnection::ExportAdaptors)) + { + qCWarning(logDbusScreenSaver) << "Failed to register DBus object /org/freedesktop/ScreenSaver:" + << connection.lastError().message(); + } else { + qCInfo(logDbusScreenSaver) << "Registered DBus object /org/freedesktop/ScreenSaver"; + } } void ScreenSaverAdaptor::setActive(bool active) { - if (this->mActive != active) { - this->mActive = active; - qCDebug(logDbusScreenSaver) << "Lock state changed to:" << active; - emit this->ActiveChanged(active); - } + if (this->mActive != active) { + this->mActive = active; + qCDebug(logDbusScreenSaver) << "Lock state changed to:" << active; + emit activeChanged(active); // method name fixed + } } void ScreenSaverAdaptor::setSecure(bool secure) { - if (this->mSecure != secure) { - this->mSecure = secure; - qCDebug(logDbusScreenSaver) << "Secure state changed to:" << secure; - } + if (this->mSecure != secure) { + this->mSecure = secure; + qCDebug(logDbusScreenSaver) << "Secure state changed to:" << secure; + } } -bool ScreenSaverAdaptor::GetActive() const { - qCDebug(logDbusScreenSaver) << "GetActive called, returning:" << this->mActive; - return this->mActive; +bool ScreenSaverAdaptor::getActive() const { // method name fixed + qCDebug(logDbusScreenSaver) << "getActive called, returning:" << this->mActive; + return this->mActive; } -bool ScreenSaverAdaptor::GetSecure() const { - qCDebug(logDbusScreenSaver) << "GetSecure called, returning:" << this->mSecure; - return this->mSecure; +bool ScreenSaverAdaptor::getSecure() const { // method name fixed + qCDebug(logDbusScreenSaver) << "getSecure called, returning:" << this->mSecure; + return this->mSecure; } } // namespace qs::dbus diff --git a/src/dbus/screensaver_dbus.hpp b/src/dbus/screensaver_dbus.hpp index c84d9f81..930598c0 100644 --- a/src/dbus/screensaver_dbus.hpp +++ b/src/dbus/screensaver_dbus.hpp @@ -1,40 +1,33 @@ #pragma once -#include -#include -#include +#include +#include +#include // QtWarningMsg namespace qs::dbus { -// DBus adaptor for exposing screen lock state to other applications -// Implements org.freedesktop.ScreenSaver interface class ScreenSaverAdaptor: public QDBusAbstractAdaptor { - Q_OBJECT - Q_CLASSINFO("D-Bus Interface", "org.freedesktop.ScreenSaver") + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "org.freedesktop.ScreenSaver") public: - explicit ScreenSaverAdaptor(QObject* parent); - ~ScreenSaverAdaptor() override = default; - Q_DISABLE_COPY_MOVE(ScreenSaverAdaptor); + explicit ScreenSaverAdaptor(QObject* parent); + ~ScreenSaverAdaptor() override = default; + Q_DISABLE_COPY_MOVE(ScreenSaverAdaptor); - // Update the active state and emit signal if changed - void setActive(bool active); - // Update the secure state (compositor has confirmed lock) - void setSecure(bool secure); + void setActive(bool active); + void setSecure(bool secure); -public slots: // NOLINT - // DBus method: Get current lock state - [[nodiscard]] bool GetActive() const; - // DBus method: Get whether lock is secure (compositor confirmed) - [[nodiscard]] bool GetSecure() const; +public slots: + [[nodiscard]] bool getActive() const; + [[nodiscard]] bool getSecure() const; -signals: // NOLINT - // DBus signal: Emitted when lock state changes - void ActiveChanged(bool active); +signals: + void activeChanged(bool active); private: - bool mActive = false; - bool mSecure = false; + bool mActive = false; + bool mSecure = false; }; } // namespace qs::dbus From e6c64026901143465bd7f14014721b1311d8bb3c Mon Sep 17 00:00:00 2001 From: Dustin Pilgrim Date: Sat, 13 Dec 2025 00:53:05 -0400 Subject: [PATCH 5/7] fix: clang formatting --- src/dbus/screensaver_dbus.cpp | 74 +++++++++++++++++------------------ src/dbus/screensaver_dbus.hpp | 24 ++++++------ 2 files changed, 48 insertions(+), 50 deletions(-) diff --git a/src/dbus/screensaver_dbus.cpp b/src/dbus/screensaver_dbus.cpp index 042ecd2d..0154e85b 100644 --- a/src/dbus/screensaver_dbus.cpp +++ b/src/dbus/screensaver_dbus.cpp @@ -3,8 +3,8 @@ #include #include #include -#include // QtWarningMsg -#include // emit +#include // emit +#include // QtWarningMsg #include "../core/logcat.hpp" @@ -14,52 +14,50 @@ QS_LOGGING_CATEGORY(logDbusScreenSaver, "quickshell.dbus.screensaver", QtWarning namespace qs::dbus { -ScreenSaverAdaptor::ScreenSaverAdaptor(QObject* parent) - : QDBusAbstractAdaptor(parent) -{ - // Register on session bus - auto connection = QDBusConnection::sessionBus(); - - if (!connection.registerService("org.freedesktop.ScreenSaver")) { - qCWarning(logDbusScreenSaver) << "Failed to register DBus service org.freedesktop.ScreenSaver:" - << connection.lastError().message(); - } else { - qCInfo(logDbusScreenSaver) << "Registered DBus service org.freedesktop.ScreenSaver"; - } - - if (!connection.registerObject("/org/freedesktop/ScreenSaver", parent, - QDBusConnection::ExportAdaptors)) - { - qCWarning(logDbusScreenSaver) << "Failed to register DBus object /org/freedesktop/ScreenSaver:" - << connection.lastError().message(); - } else { - qCInfo(logDbusScreenSaver) << "Registered DBus object /org/freedesktop/ScreenSaver"; - } +ScreenSaverAdaptor::ScreenSaverAdaptor(QObject* parent): QDBusAbstractAdaptor(parent) { + // Register on session bus + auto connection = QDBusConnection::sessionBus(); + + if (!connection.registerService("org.freedesktop.ScreenSaver")) { + qCWarning(logDbusScreenSaver) << "Failed to register DBus service org.freedesktop.ScreenSaver:" + << connection.lastError().message(); + } else { + qCInfo(logDbusScreenSaver) << "Registered DBus service org.freedesktop.ScreenSaver"; + } + + if (!connection + .registerObject("/org/freedesktop/ScreenSaver", parent, QDBusConnection::ExportAdaptors)) + { + qCWarning(logDbusScreenSaver) << "Failed to register DBus object /org/freedesktop/ScreenSaver:" + << connection.lastError().message(); + } else { + qCInfo(logDbusScreenSaver) << "Registered DBus object /org/freedesktop/ScreenSaver"; + } } void ScreenSaverAdaptor::setActive(bool active) { - if (this->mActive != active) { - this->mActive = active; - qCDebug(logDbusScreenSaver) << "Lock state changed to:" << active; - emit activeChanged(active); // method name fixed - } + if (this->mActive != active) { + this->mActive = active; + qCDebug(logDbusScreenSaver) << "Lock state changed to:" << active; + emit activeChanged(active); // method name fixed + } } void ScreenSaverAdaptor::setSecure(bool secure) { - if (this->mSecure != secure) { - this->mSecure = secure; - qCDebug(logDbusScreenSaver) << "Secure state changed to:" << secure; - } + if (this->mSecure != secure) { + this->mSecure = secure; + qCDebug(logDbusScreenSaver) << "Secure state changed to:" << secure; + } } -bool ScreenSaverAdaptor::getActive() const { // method name fixed - qCDebug(logDbusScreenSaver) << "getActive called, returning:" << this->mActive; - return this->mActive; +bool ScreenSaverAdaptor::getActive() const { // method name fixed + qCDebug(logDbusScreenSaver) << "getActive called, returning:" << this->mActive; + return this->mActive; } -bool ScreenSaverAdaptor::getSecure() const { // method name fixed - qCDebug(logDbusScreenSaver) << "getSecure called, returning:" << this->mSecure; - return this->mSecure; +bool ScreenSaverAdaptor::getSecure() const { // method name fixed + qCDebug(logDbusScreenSaver) << "getSecure called, returning:" << this->mSecure; + return this->mSecure; } } // namespace qs::dbus diff --git a/src/dbus/screensaver_dbus.hpp b/src/dbus/screensaver_dbus.hpp index 930598c0..9e30f315 100644 --- a/src/dbus/screensaver_dbus.hpp +++ b/src/dbus/screensaver_dbus.hpp @@ -7,27 +7,27 @@ namespace qs::dbus { class ScreenSaverAdaptor: public QDBusAbstractAdaptor { - Q_OBJECT - Q_CLASSINFO("D-Bus Interface", "org.freedesktop.ScreenSaver") + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "org.freedesktop.ScreenSaver") public: - explicit ScreenSaverAdaptor(QObject* parent); - ~ScreenSaverAdaptor() override = default; - Q_DISABLE_COPY_MOVE(ScreenSaverAdaptor); + explicit ScreenSaverAdaptor(QObject* parent); + ~ScreenSaverAdaptor() override = default; + Q_DISABLE_COPY_MOVE(ScreenSaverAdaptor); - void setActive(bool active); - void setSecure(bool secure); + void setActive(bool active); + void setSecure(bool secure); public slots: - [[nodiscard]] bool getActive() const; - [[nodiscard]] bool getSecure() const; + [[nodiscard]] bool getActive() const; + [[nodiscard]] bool getSecure() const; signals: - void activeChanged(bool active); + void activeChanged(bool active); private: - bool mActive = false; - bool mSecure = false; + bool mActive = false; + bool mSecure = false; }; } // namespace qs::dbus From 72778463546df091ad3e0b92e26ccc794c9c2e22 Mon Sep 17 00:00:00 2001 From: Dustin Pilgrim Date: Sat, 13 Dec 2025 01:46:32 -0400 Subject: [PATCH 6/7] fix: screensaver_dbus.cpp and session_lock.cpp linting errors --- src/dbus/objectmanager.hpp | 2 +- src/dbus/org.freedesktop.ScreenSaver.xml | 6 ++--- src/dbus/screensaver_dbus.cpp | 24 +++++++++++-------- src/dbus/screensaver_dbus.hpp | 14 +++++------ src/wayland/session_lock/CMakeLists.txt | 1 + src/wayland/session_lock/session_lock.cpp | 29 +++++++++++++++++++++++ src/wayland/session_lock/session_lock.hpp | 9 ++++--- 7 files changed, 59 insertions(+), 26 deletions(-) diff --git a/src/dbus/objectmanager.hpp b/src/dbus/objectmanager.hpp index 4246ea28..ea88d499 100644 --- a/src/dbus/objectmanager.hpp +++ b/src/dbus/objectmanager.hpp @@ -34,4 +34,4 @@ class DBusObjectManager: public QObject { DBusObjectManagerInterface* mInterface = nullptr; }; -} // namespace qs::dbus \ No newline at end of file +} // namespace qs::dbus diff --git a/src/dbus/org.freedesktop.ScreenSaver.xml b/src/dbus/org.freedesktop.ScreenSaver.xml index 8fa118b3..77b5850b 100644 --- a/src/dbus/org.freedesktop.ScreenSaver.xml +++ b/src/dbus/org.freedesktop.ScreenSaver.xml @@ -1,17 +1,17 @@ - + - + - + diff --git a/src/dbus/screensaver_dbus.cpp b/src/dbus/screensaver_dbus.cpp index 0154e85b..b25e4b56 100644 --- a/src/dbus/screensaver_dbus.cpp +++ b/src/dbus/screensaver_dbus.cpp @@ -1,15 +1,19 @@ #include "screensaver_dbus.hpp" -#include -#include -#include -#include // emit -#include // QtWarningMsg +#include +#include +#include +#include +#include +#include +#include #include "../core/logcat.hpp" namespace { + QS_LOGGING_CATEGORY(logDbusScreenSaver, "quickshell.dbus.screensaver", QtWarningMsg); + } namespace qs::dbus { @@ -39,7 +43,7 @@ void ScreenSaverAdaptor::setActive(bool active) { if (this->mActive != active) { this->mActive = active; qCDebug(logDbusScreenSaver) << "Lock state changed to:" << active; - emit activeChanged(active); // method name fixed + emit this->ActiveChanged(active); } } @@ -50,13 +54,13 @@ void ScreenSaverAdaptor::setSecure(bool secure) { } } -bool ScreenSaverAdaptor::getActive() const { // method name fixed - qCDebug(logDbusScreenSaver) << "getActive called, returning:" << this->mActive; +bool ScreenSaverAdaptor::GetActive() const { + qCDebug(logDbusScreenSaver) << "GetActive called, returning:" << this->mActive; return this->mActive; } -bool ScreenSaverAdaptor::getSecure() const { // method name fixed - qCDebug(logDbusScreenSaver) << "getSecure called, returning:" << this->mSecure; +bool ScreenSaverAdaptor::GetSecure() const { + qCDebug(logDbusScreenSaver) << "GetSecure called, returning:" << this->mSecure; return this->mSecure; } diff --git a/src/dbus/screensaver_dbus.hpp b/src/dbus/screensaver_dbus.hpp index 9e30f315..bb8995b7 100644 --- a/src/dbus/screensaver_dbus.hpp +++ b/src/dbus/screensaver_dbus.hpp @@ -1,13 +1,13 @@ #pragma once -#include -#include -#include // QtWarningMsg +#include +#include +#include namespace qs::dbus { class ScreenSaverAdaptor: public QDBusAbstractAdaptor { - Q_OBJECT + Q_OBJECT; Q_CLASSINFO("D-Bus Interface", "org.freedesktop.ScreenSaver") public: @@ -19,11 +19,11 @@ class ScreenSaverAdaptor: public QDBusAbstractAdaptor { void setSecure(bool secure); public slots: - [[nodiscard]] bool getActive() const; - [[nodiscard]] bool getSecure() const; + [[nodiscard]] bool GetActive() const; // NOLINT(readability-identifier-naming) + [[nodiscard]] bool GetSecure() const; // NOLINT(readability-identifier-naming) signals: - void activeChanged(bool active); + void ActiveChanged(bool active); // NOLINT(readability-identifier-naming) private: bool mActive = false; diff --git a/src/wayland/session_lock/CMakeLists.txt b/src/wayland/session_lock/CMakeLists.txt index 56f58a60..a73dc8b0 100644 --- a/src/wayland/session_lock/CMakeLists.txt +++ b/src/wayland/session_lock/CMakeLists.txt @@ -6,6 +6,7 @@ qt_add_library(quickshell-wayland-sessionlock STATIC session_lock.cpp ) wl_proto(wlp-session-lock ext-session-lock-v1 "${WAYLAND_PROTOCOLS}/staging/ext-session-lock") +target_include_directories(quickshell-wayland-sessionlock PRIVATE ${CMAKE_SOURCE_DIR}/src) target_link_libraries(quickshell-wayland-sessionlock PRIVATE Qt::Quick Qt::WaylandClient Qt::WaylandClientPrivate Qt::DBus wayland-client wlp-session-lock diff --git a/src/wayland/session_lock/session_lock.cpp b/src/wayland/session_lock/session_lock.cpp index d4a80dd1..dc18fbe4 100644 --- a/src/wayland/session_lock/session_lock.cpp +++ b/src/wayland/session_lock/session_lock.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include "../../dbus/screensaver_dbus.hpp" @@ -10,7 +11,9 @@ #include "manager.hpp" #include "shell_integration.hpp" #include "surface.hpp" + namespace { + QSWaylandSessionLockManager* manager() { static QSWaylandSessionLockManager* manager = nullptr; // NOLINT if (manager == nullptr) { @@ -18,10 +21,14 @@ QSWaylandSessionLockManager* manager() { } return manager; } + } // namespace + bool SessionLockManager::lockAvailable() { return manager()->isActive(); } + bool SessionLockManager::lock() { if (this->isLocked() || SessionLockManager::sessionLocked()) return false; + this->mLock = manager()->acquireLock(); this->mLock->setParent(this); @@ -39,30 +46,40 @@ bool SessionLockManager::lock() { this->mDbusAdaptor->setSecure(true); emit this->locked(); }); + QObject::connect(this->mLock, &QSWaylandSessionLock::unlocked, this, [this]() { this->mDbusAdaptor->setActive(false); this->mDbusAdaptor->setSecure(false); emit this->unlocked(); }); // clang-format on + return true; } + bool SessionLockManager::unlock() { if (!this->isLocked()) return false; + this->mLock->unlock(); auto* lock = this->mLock; this->mLock = nullptr; delete lock; + return true; } + bool SessionLockManager::isLocked() const { return this->mLock != nullptr; } + bool SessionLockManager::sessionLocked() { return manager()->isLocked(); } + bool SessionLockManager::isSecure() { return manager()->isSecure(); } + LockWindowExtension::~LockWindowExtension() { if (this->surface != nullptr) { this->surface->setExtension(nullptr); } } + LockWindowExtension* LockWindowExtension::get(QWindow* window) { auto v = window->property("sessionlock_ext"); if (v.canConvert()) { @@ -71,12 +88,16 @@ LockWindowExtension* LockWindowExtension::get(QWindow* window) { return nullptr; } } + bool LockWindowExtension::isAttached() const { return this->surface != nullptr; } + bool LockWindowExtension::attach(QWindow* window, SessionLockManager* manager) { if (this->surface != nullptr) qFatal() << "Cannot change the attached window of a LockWindowExtension"; + auto* current = LockWindowExtension::get(window); QtWaylandClient::QWaylandWindow* waylandWindow = nullptr; + if (current != nullptr) { current->surface->setExtension(this); } else { @@ -84,11 +105,13 @@ bool LockWindowExtension::attach(QWindow* window, SessionLockManager* manager) { auto* screen = window->screen(); window->create(); window->setScreen(screen); + waylandWindow = dynamic_cast(window->handle()); if (waylandWindow == nullptr) { qWarning() << window << "is not a wayland window. Cannot create lock surface."; return false; } + static QSWaylandSessionLockIntegration* lockIntegration = nullptr; // NOLINT if (lockIntegration == nullptr) { lockIntegration = new QSWaylandSessionLockIntegration(); @@ -98,17 +121,23 @@ bool LockWindowExtension::attach(QWindow* window, SessionLockManager* manager) { qWarning() << "Failed to initialize lockscreen integration"; } } + waylandWindow->setShellIntegration(lockIntegration); } + this->setParent(window); window->setProperty("sessionlock_ext", QVariant::fromValue(this)); + this->lock = manager->mLock; + if (waylandWindow != nullptr) { this->surface = new QSWaylandSessionLockSurface(waylandWindow); if (this->immediatelyVisible) this->surface->setVisible(); } + return true; } + void LockWindowExtension::setVisible() { if (this->surface == nullptr) this->immediatelyVisible = true; else this->surface->setVisible(); diff --git a/src/wayland/session_lock/session_lock.hpp b/src/wayland/session_lock/session_lock.hpp index b61473e0..030dcccb 100644 --- a/src/wayland/session_lock/session_lock.hpp +++ b/src/wayland/session_lock/session_lock.hpp @@ -14,7 +14,7 @@ class ScreenSaverAdaptor; } class SessionLockManager: public QObject { - Q_OBJECT; + Q_OBJECT public: explicit SessionLockManager(QObject* parent = nullptr): QObject(parent) {} @@ -30,11 +30,10 @@ class SessionLockManager: public QObject { bool unlock(); [[nodiscard]] bool isLocked() const; - static bool sessionLocked(); static bool isSecure(); -signals: +Q_SIGNALS: // This signal is sent once the compositor considers the session to be fully locked. // This corrosponds to the ext_session_lock_v1::locked event. void locked(); @@ -58,7 +57,7 @@ class SessionLockManager: public QObject { }; class LockWindowExtension: public QObject { - Q_OBJECT; + Q_OBJECT public: explicit LockWindowExtension(QObject* parent = nullptr): QObject(parent) {} @@ -78,7 +77,7 @@ class LockWindowExtension: public QObject { static LockWindowExtension* get(QWindow* window); -signals: +Q_SIGNALS: // This signal is sent once the compositor considers the session to be fully locked. // See SessionLockManager::locked for details. void locked(); From c4efd5582a4ce7ec02a8ff813e1ea40bf5acd0b0 Mon Sep 17 00:00:00 2001 From: Dustin Pilgrim Date: Tue, 16 Dec 2025 03:15:38 -0400 Subject: [PATCH 7/7] refactor: moved from using ScreenSaver to using custom dbus channel org.quickshell.SessionLock --- src/dbus/CMakeLists.txt | 24 +++++--- src/dbus/org.freedesktop.ScreenSaver.xml | 18 ------ src/dbus/org.quickshell.SessionLock.xml | 23 ++++++++ src/dbus/screensaver_dbus.cpp | 67 ----------------------- src/dbus/screensaver_dbus.hpp | 33 ----------- src/dbus/session_lock_dbus.cpp | 66 ++++++++++++++++++++++ src/dbus/session_lock_dbus.hpp | 33 +++++++++++ src/wayland/session_lock/session_lock.cpp | 26 ++++++--- src/wayland/session_lock/session_lock.hpp | 16 +++--- 9 files changed, 164 insertions(+), 142 deletions(-) delete mode 100644 src/dbus/org.freedesktop.ScreenSaver.xml create mode 100644 src/dbus/org.quickshell.SessionLock.xml delete mode 100644 src/dbus/screensaver_dbus.cpp delete mode 100644 src/dbus/screensaver_dbus.hpp create mode 100644 src/dbus/session_lock_dbus.cpp create mode 100644 src/dbus/session_lock_dbus.hpp diff --git a/src/dbus/CMakeLists.txt b/src/dbus/CMakeLists.txt index 43a3866c..e5ca75e5 100644 --- a/src/dbus/CMakeLists.txt +++ b/src/dbus/CMakeLists.txt @@ -1,37 +1,45 @@ set_source_files_properties(org.freedesktop.DBus.Properties.xml PROPERTIES CLASSNAME DBusPropertiesInterface ) + set_source_files_properties(org.freedesktop.DBus.ObjectManager.xml PROPERTIES CLASSNAME DBusObjectManagerInterface INCLUDE ${CMAKE_CURRENT_SOURCE_DIR}/dbus_objectmanager_types.hpp ) -set_source_files_properties(org.freedesktop.ScreenSaver.xml PROPERTIES - CLASSNAME ScreenSaverAdaptor - INCLUDE screensaver_dbus.hpp + +set_source_files_properties(org.quickshell.SessionLock.xml PROPERTIES + CLASSNAME SessionLockAdaptor + INCLUDE session_lock_dbus.hpp ) + qt_add_dbus_interface(DBUS_INTERFACES org.freedesktop.DBus.Properties.xml dbus_properties ) + qt_add_dbus_interface(DBUS_INTERFACES org.freedesktop.DBus.ObjectManager.xml dbus_objectmanager ) + qt_add_dbus_adaptor(DBUS_INTERFACES - org.freedesktop.ScreenSaver.xml - ${CMAKE_CURRENT_SOURCE_DIR}/screensaver_dbus.hpp - qs::dbus::ScreenSaverAdaptor + org.quickshell.SessionLock.xml + ${CMAKE_CURRENT_SOURCE_DIR}/session_lock_dbus.hpp + qs::dbus::SessionLockAdaptor ) + qt_add_library(quickshell-dbus STATIC properties.cpp objectmanager.cpp bus.cpp - screensaver_dbus.cpp + session_lock_dbus.cpp ${DBUS_INTERFACES} ) + # dbus headers target_include_directories(quickshell-dbus PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) target_link_libraries(quickshell-dbus PRIVATE Qt::Core Qt::DBus) + # todo: link dbus to quickshell here instead of in modules that use it directly # linker does not like this as is qs_add_pchset(dbus @@ -41,5 +49,7 @@ qs_add_pchset(dbus ) + qs_pch(quickshell-dbus SET dbus) + add_subdirectory(dbusmenu) diff --git a/src/dbus/org.freedesktop.ScreenSaver.xml b/src/dbus/org.freedesktop.ScreenSaver.xml deleted file mode 100644 index 77b5850b..00000000 --- a/src/dbus/org.freedesktop.ScreenSaver.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/src/dbus/org.quickshell.SessionLock.xml b/src/dbus/org.quickshell.SessionLock.xml new file mode 100644 index 00000000..3b5c477c --- /dev/null +++ b/src/dbus/org.quickshell.SessionLock.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/dbus/screensaver_dbus.cpp b/src/dbus/screensaver_dbus.cpp deleted file mode 100644 index b25e4b56..00000000 --- a/src/dbus/screensaver_dbus.cpp +++ /dev/null @@ -1,67 +0,0 @@ -#include "screensaver_dbus.hpp" - -#include -#include -#include -#include -#include -#include -#include - -#include "../core/logcat.hpp" - -namespace { - -QS_LOGGING_CATEGORY(logDbusScreenSaver, "quickshell.dbus.screensaver", QtWarningMsg); - -} - -namespace qs::dbus { - -ScreenSaverAdaptor::ScreenSaverAdaptor(QObject* parent): QDBusAbstractAdaptor(parent) { - // Register on session bus - auto connection = QDBusConnection::sessionBus(); - - if (!connection.registerService("org.freedesktop.ScreenSaver")) { - qCWarning(logDbusScreenSaver) << "Failed to register DBus service org.freedesktop.ScreenSaver:" - << connection.lastError().message(); - } else { - qCInfo(logDbusScreenSaver) << "Registered DBus service org.freedesktop.ScreenSaver"; - } - - if (!connection - .registerObject("/org/freedesktop/ScreenSaver", parent, QDBusConnection::ExportAdaptors)) - { - qCWarning(logDbusScreenSaver) << "Failed to register DBus object /org/freedesktop/ScreenSaver:" - << connection.lastError().message(); - } else { - qCInfo(logDbusScreenSaver) << "Registered DBus object /org/freedesktop/ScreenSaver"; - } -} - -void ScreenSaverAdaptor::setActive(bool active) { - if (this->mActive != active) { - this->mActive = active; - qCDebug(logDbusScreenSaver) << "Lock state changed to:" << active; - emit this->ActiveChanged(active); - } -} - -void ScreenSaverAdaptor::setSecure(bool secure) { - if (this->mSecure != secure) { - this->mSecure = secure; - qCDebug(logDbusScreenSaver) << "Secure state changed to:" << secure; - } -} - -bool ScreenSaverAdaptor::GetActive() const { - qCDebug(logDbusScreenSaver) << "GetActive called, returning:" << this->mActive; - return this->mActive; -} - -bool ScreenSaverAdaptor::GetSecure() const { - qCDebug(logDbusScreenSaver) << "GetSecure called, returning:" << this->mSecure; - return this->mSecure; -} - -} // namespace qs::dbus diff --git a/src/dbus/screensaver_dbus.hpp b/src/dbus/screensaver_dbus.hpp deleted file mode 100644 index bb8995b7..00000000 --- a/src/dbus/screensaver_dbus.hpp +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once - -#include -#include -#include - -namespace qs::dbus { - -class ScreenSaverAdaptor: public QDBusAbstractAdaptor { - Q_OBJECT; - Q_CLASSINFO("D-Bus Interface", "org.freedesktop.ScreenSaver") - -public: - explicit ScreenSaverAdaptor(QObject* parent); - ~ScreenSaverAdaptor() override = default; - Q_DISABLE_COPY_MOVE(ScreenSaverAdaptor); - - void setActive(bool active); - void setSecure(bool secure); - -public slots: - [[nodiscard]] bool GetActive() const; // NOLINT(readability-identifier-naming) - [[nodiscard]] bool GetSecure() const; // NOLINT(readability-identifier-naming) - -signals: - void ActiveChanged(bool active); // NOLINT(readability-identifier-naming) - -private: - bool mActive = false; - bool mSecure = false; -}; - -} // namespace qs::dbus diff --git a/src/dbus/session_lock_dbus.cpp b/src/dbus/session_lock_dbus.cpp new file mode 100644 index 00000000..9bb57d37 --- /dev/null +++ b/src/dbus/session_lock_dbus.cpp @@ -0,0 +1,66 @@ +#include "session_lock_dbus.hpp" + +#include +#include +#include +#include +#include +#include +#include + +#include "../core/logcat.hpp" + +namespace { +QS_LOGGING_CATEGORY(logDbusSessionLock, "quickshell.dbus.sessionlock", QtWarningMsg); +} + +namespace qs::dbus { + +SessionLockAdaptor::SessionLockAdaptor(QObject* parent): QDBusAbstractAdaptor(parent) { + // Register on session bus + auto connection = QDBusConnection::sessionBus(); + + if (!connection.registerService("org.quickshell.SessionLock")) { + qCWarning(logDbusSessionLock) << "Failed to register DBus service org.quickshell.SessionLock:" + << connection.lastError().message(); + } else { + qCInfo(logDbusSessionLock) << "Registered DBus service org.quickshell.SessionLock"; + } + + if (!connection + .registerObject("/org/quickshell/SessionLock", parent, QDBusConnection::ExportAdaptors)) + { + qCWarning(logDbusSessionLock) << "Failed to register DBus object /org/quickshell/SessionLock:" + << connection.lastError().message(); + } else { + qCInfo(logDbusSessionLock) << "Registered DBus object /org/quickshell/SessionLock"; + } +} + +void SessionLockAdaptor::setLocked(bool locked) { + if (this->mLocked != locked) { + this->mLocked = locked; + qCDebug(logDbusSessionLock) << "Lock state changed to:" << locked; + emit this->LockedChanged(locked); + } +} + +void SessionLockAdaptor::setSecure(bool secure) { + if (this->mSecure != secure) { + this->mSecure = secure; + qCDebug(logDbusSessionLock) << "Secure state changed to:" << secure; + emit this->SecureChanged(secure); + } +} + +bool SessionLockAdaptor::GetLocked() const { + qCDebug(logDbusSessionLock) << "GetLocked called, returning:" << this->mLocked; + return this->mLocked; +} + +bool SessionLockAdaptor::GetSecure() const { + qCDebug(logDbusSessionLock) << "GetSecure called, returning:" << this->mSecure; + return this->mSecure; +} + +} // namespace qs::dbus diff --git a/src/dbus/session_lock_dbus.hpp b/src/dbus/session_lock_dbus.hpp new file mode 100644 index 00000000..46aca932 --- /dev/null +++ b/src/dbus/session_lock_dbus.hpp @@ -0,0 +1,33 @@ +#pragma once +#include +#include +#include + +namespace qs::dbus { + +class SessionLockAdaptor: public QDBusAbstractAdaptor { + Q_OBJECT; + Q_CLASSINFO("D-Bus Interface", "org.quickshell.SessionLock") + +public: + explicit SessionLockAdaptor(QObject* parent); + ~SessionLockAdaptor() override = default; + Q_DISABLE_COPY_MOVE(SessionLockAdaptor); + + void setLocked(bool locked); + void setSecure(bool secure); + +public slots: + [[nodiscard]] bool GetLocked() const; // NOLINT(readability-identifier-naming) + [[nodiscard]] bool GetSecure() const; // NOLINT(readability-identifier-naming) + +signals: + void LockedChanged(bool locked); // NOLINT(readability-identifier-naming) + void SecureChanged(bool secure); // NOLINT(readability-identifier-naming) + +private: + bool mLocked = false; + bool mSecure = false; +}; + +} // namespace qs::dbus diff --git a/src/wayland/session_lock/session_lock.cpp b/src/wayland/session_lock/session_lock.cpp index dc18fbe4..32bd287b 100644 --- a/src/wayland/session_lock/session_lock.cpp +++ b/src/wayland/session_lock/session_lock.cpp @@ -6,7 +6,7 @@ #include #include -#include "../../dbus/screensaver_dbus.hpp" +#include "../../dbus/session_lock_dbus.hpp" #include "lock.hpp" #include "manager.hpp" #include "shell_integration.hpp" @@ -16,14 +16,22 @@ namespace { QSWaylandSessionLockManager* manager() { static QSWaylandSessionLockManager* manager = nullptr; // NOLINT + if (manager == nullptr) { manager = new QSWaylandSessionLockManager(); } + return manager; } } // namespace +SessionLockManager::SessionLockManager(QObject* parent) + : QObject(parent) + , mDbusAdaptor(new qs::dbus::SessionLockAdaptor(this)) { + // DBus adaptor initialized in member initializer list so the service is always available +} + bool SessionLockManager::lockAvailable() { return manager()->isActive(); } bool SessionLockManager::lock() { @@ -32,13 +40,8 @@ bool SessionLockManager::lock() { this->mLock = manager()->acquireLock(); this->mLock->setParent(this); - // Initialize DBus adaptor if not already created - if (this->mDbusAdaptor == nullptr) { - this->mDbusAdaptor = new qs::dbus::ScreenSaverAdaptor(this); - } - // Notify DBus that we're attempting to lock (not yet secure) - this->mDbusAdaptor->setActive(true); + this->mDbusAdaptor->setLocked(true); this->mDbusAdaptor->setSecure(false); // clang-format off @@ -46,9 +49,9 @@ bool SessionLockManager::lock() { this->mDbusAdaptor->setSecure(true); emit this->locked(); }); - + QObject::connect(this->mLock, &QSWaylandSessionLock::unlocked, this, [this]() { - this->mDbusAdaptor->setActive(false); + this->mDbusAdaptor->setLocked(false); this->mDbusAdaptor->setSecure(false); emit this->unlocked(); }); @@ -61,6 +64,7 @@ bool SessionLockManager::unlock() { if (!this->isLocked()) return false; this->mLock->unlock(); + auto* lock = this->mLock; this->mLock = nullptr; delete lock; @@ -82,6 +86,7 @@ LockWindowExtension::~LockWindowExtension() { LockWindowExtension* LockWindowExtension::get(QWindow* window) { auto v = window->property("sessionlock_ext"); + if (v.canConvert()) { return v.value(); } else { @@ -107,14 +112,17 @@ bool LockWindowExtension::attach(QWindow* window, SessionLockManager* manager) { window->setScreen(screen); waylandWindow = dynamic_cast(window->handle()); + if (waylandWindow == nullptr) { qWarning() << window << "is not a wayland window. Cannot create lock surface."; return false; } static QSWaylandSessionLockIntegration* lockIntegration = nullptr; // NOLINT + if (lockIntegration == nullptr) { lockIntegration = new QSWaylandSessionLockIntegration(); + if (!lockIntegration->initialize(waylandWindow->display())) { delete lockIntegration; lockIntegration = nullptr; diff --git a/src/wayland/session_lock/session_lock.hpp b/src/wayland/session_lock/session_lock.hpp index 030dcccb..80002533 100644 --- a/src/wayland/session_lock/session_lock.hpp +++ b/src/wayland/session_lock/session_lock.hpp @@ -1,5 +1,4 @@ #pragma once - #include #include #include @@ -10,14 +9,14 @@ class QSWaylandSessionLockSurface; class QSWaylandSessionLockIntegration; namespace qs::dbus { -class ScreenSaverAdaptor; +class SessionLockAdaptor; } class SessionLockManager: public QObject { - Q_OBJECT + Q_OBJECT; public: - explicit SessionLockManager(QObject* parent = nullptr): QObject(parent) {} + explicit SessionLockManager(QObject* parent = nullptr); // Declare only, implement in .cpp [[nodiscard]] static bool lockAvailable(); @@ -30,10 +29,11 @@ class SessionLockManager: public QObject { bool unlock(); [[nodiscard]] bool isLocked() const; + static bool sessionLocked(); static bool isSecure(); -Q_SIGNALS: +signals: // This signal is sent once the compositor considers the session to be fully locked. // This corrosponds to the ext_session_lock_v1::locked event. void locked(); @@ -51,13 +51,13 @@ class SessionLockManager: public QObject { private: QSWaylandSessionLock* mLock = nullptr; - qs::dbus::ScreenSaverAdaptor* mDbusAdaptor = nullptr; + qs::dbus::SessionLockAdaptor* mDbusAdaptor = nullptr; friend class LockWindowExtension; }; class LockWindowExtension: public QObject { - Q_OBJECT + Q_OBJECT; public: explicit LockWindowExtension(QObject* parent = nullptr): QObject(parent) {} @@ -77,7 +77,7 @@ class LockWindowExtension: public QObject { static LockWindowExtension* get(QWindow* window); -Q_SIGNALS: +signals: // This signal is sent once the compositor considers the session to be fully locked. // See SessionLockManager::locked for details. void locked();