Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions src/dbus/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ set_source_files_properties(org.freedesktop.DBus.ObjectManager.xml PROPERTIES
INCLUDE ${CMAKE_CURRENT_SOURCE_DIR}/dbus_objectmanager_types.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
Expand All @@ -17,20 +22,26 @@ qt_add_dbus_interface(DBUS_INTERFACES
dbus_objectmanager
)

qt_add_dbus_adaptor(DBUS_INTERFACES
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
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
DEPENDENCIES Qt::DBus
HEADERS
Expand Down
2 changes: 1 addition & 1 deletion src/dbus/objectmanager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,4 @@ class DBusObjectManager: public QObject {
DBusObjectManagerInterface* mInterface = nullptr;
};

} // namespace qs::dbus
} // namespace qs::dbus
23 changes: 23 additions & 0 deletions src/dbus/org.quickshell.SessionLock.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<node>
<interface name="org.quickshell.SessionLock">
<!-- Get the current lock state -->
<method name="GetLocked">
<arg name="locked" direction="out" type="b"/>
</method>

<!-- Signal emitted when lock state changes -->
<signal name="LockedChanged">
<arg name="locked" type="b"/>
</signal>

<!-- Get whether the compositor has confirmed the lock (secure state) -->
<method name="GetSecure">
<arg name="secure" direction="out" type="b"/>
</method>

<!-- Signal emitted when secure state changes -->
<signal name="SecureChanged">
<arg name="secure" type="b"/>
</signal>
</interface>
</node>
66 changes: 66 additions & 0 deletions src/dbus/session_lock_dbus.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#include "session_lock_dbus.hpp"

#include <qdbusabstractadaptor.h>
#include <qdbusconnection.h>
#include <qdbuserror.h>
#include <qlogging.h>
#include <qloggingcategory.h>
#include <qobject.h>
#include <qtmetamacros.h>

#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
33 changes: 33 additions & 0 deletions src/dbus/session_lock_dbus.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#pragma once
#include <qdbusabstractadaptor.h>
#include <qobject.h>
#include <qtmetamacros.h>

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
8 changes: 3 additions & 5 deletions src/wayland/session_lock/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,12 @@ 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_include_directories(quickshell-wayland-sessionlock PRIVATE ${CMAKE_SOURCE_DIR}/src)
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)
37 changes: 35 additions & 2 deletions src/wayland/session_lock/session_lock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@
#include <private/qwaylanddisplay_p.h>
#include <qlogging.h>
#include <qobject.h>
#include <qtmetamacros.h>
#include <qwindow.h>

#include "../../dbus/session_lock_dbus.hpp"
#include "lock.hpp"
#include "manager.hpp"
#include "shell_integration.hpp"
#include "surface.hpp"

namespace {

QSWaylandSessionLockManager* manager() {
static QSWaylandSessionLockManager* manager = nullptr; // NOLINT

Expand All @@ -20,33 +23,59 @@ QSWaylandSessionLockManager* manager() {

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() {
if (this->isLocked() || SessionLockManager::sessionLocked()) return false;

this->mLock = manager()->acquireLock();
this->mLock->setParent(this);

// Notify DBus that we're attempting to lock (not yet secure)
this->mDbusAdaptor->setLocked(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->setLocked(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() {
Expand Down Expand Up @@ -83,14 +112,17 @@ bool LockWindowExtension::attach(QWindow* window, SessionLockManager* manager) {
window->setScreen(screen);

waylandWindow = dynamic_cast<QtWaylandClient::QWaylandWindow*>(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;
Expand All @@ -103,6 +135,7 @@ bool LockWindowExtension::attach(QWindow* window, SessionLockManager* manager) {

this->setParent(window);
window->setProperty("sessionlock_ext", QVariant::fromValue(this));

this->lock = manager->mLock;

if (waylandWindow != nullptr) {
Expand Down
11 changes: 6 additions & 5 deletions src/wayland/session_lock/session_lock.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#pragma once

#include <qobject.h>
#include <qtclasshelpermacros.h>
#include <qtmetamacros.h>
Expand All @@ -9,11 +8,15 @@ class QSWaylandSessionLock;
class QSWaylandSessionLockSurface;
class QSWaylandSessionLockIntegration;

namespace qs::dbus {
class SessionLockAdaptor;
}

class SessionLockManager: public QObject {
Q_OBJECT;

public:
explicit SessionLockManager(QObject* parent = nullptr): QObject(parent) {}
explicit SessionLockManager(QObject* parent = nullptr); // Declare only, implement in .cpp

[[nodiscard]] static bool lockAvailable();

Expand Down Expand Up @@ -46,11 +49,9 @@ 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::SessionLockAdaptor* mDbusAdaptor = nullptr;

friend class LockWindowExtension;
};
Expand Down