diff --git a/src/auth/Fingerprint.cpp b/src/auth/Fingerprint.cpp index 8a1528ca..1b59be11 100644 --- a/src/auth/Fingerprint.cpp +++ b/src/auth/Fingerprint.cpp @@ -1,5 +1,6 @@ #include "Fingerprint.hpp" #include "../core/hyprlock.hpp" +#include "../core/DBusManager.hpp" #include "../helpers/Log.hpp" #include "../config/ConfigManager.hpp" @@ -48,8 +49,10 @@ CFingerprint::~CFingerprint() { } void CFingerprint::init() { - m_sDBUSState.connection = sdbus::createSystemBusConnection(); - m_sDBUSState.login = sdbus::createProxy(*m_sDBUSState.connection, sdbus::ServiceName{"org.freedesktop.login1"}, sdbus::ObjectPath{"/org/freedesktop/login1"}); + auto& dbusManager = DBusManager::getInstance(); + m_sDBUSState.connection = dbusManager.getConnection(); + m_sDBUSState.login = dbusManager.getLoginProxy(); + m_sDBUSState.login->getPropertyAsync("PreparingForSleep").onInterface(LOGIN_MANAGER).uponReplyInvoke([this](std::optional e, sdbus::Variant preparingForSleep) { if (e) { Debug::log(WARN, "fprint: Failed getting value for PreparingForSleep: {}", e->what()); @@ -62,6 +65,7 @@ void CFingerprint::init() { inhibitSleep(); startVerify(); }); + m_sDBUSState.login->uponSignal("PrepareForSleep").onInterface(LOGIN_MANAGER).call([this](bool start) { Debug::log(LOG, "fprint: PrepareForSleep (start: {})", start); if (start) { @@ -97,10 +101,6 @@ void CFingerprint::terminate() { releaseDevice(); } -std::shared_ptr CFingerprint::getConnection() { - return m_sDBUSState.connection; -} - void CFingerprint::inhibitSleep() { m_sDBUSState.login->callMethodAsync("Inhibit") .onInterface(LOGIN_MANAGER) diff --git a/src/auth/Fingerprint.hpp b/src/auth/Fingerprint.hpp index f07e3532..e6a11aa9 100644 --- a/src/auth/Fingerprint.hpp +++ b/src/auth/Fingerprint.hpp @@ -22,14 +22,12 @@ class CFingerprint : public IAuthImplementation { virtual std::optional getLastPrompt(); virtual void terminate(); - std::shared_ptr getConnection(); - private: struct SDBUSState { std::string message = ""; std::shared_ptr connection; - std::unique_ptr login; + std::shared_ptr login; std::unique_ptr device; sdbus::UnixFd inhibitLock; diff --git a/src/core/DBusManager.cpp b/src/core/DBusManager.cpp new file mode 100644 index 00000000..34f573ff --- /dev/null +++ b/src/core/DBusManager.cpp @@ -0,0 +1,83 @@ +#include "DBusManager.hpp" +#include "../helpers/Log.hpp" + +DBusManager& DBusManager::getInstance() { + static DBusManager instance; + return instance; +} + +DBusManager::DBusManager() { + initializeConnection(); +} + +DBusManager::~DBusManager() { + // Resources are automatically cleaned up. +} + +void DBusManager::initializeConnection() { + try { + m_pConnection = sdbus::createSystemBusConnection(); + + const sdbus::ServiceName destination{"org.freedesktop.login1"}; + const sdbus::ObjectPath loginPath{"/org/freedesktop/login1"}; + const sdbus::ObjectPath sessionPath{"/org/freedesktop/login1/session/auto"}; + + m_pLoginProxy = sdbus::createProxy(*m_pConnection, destination, loginPath); + m_pSessionProxy = sdbus::createProxy(*m_pConnection, destination, sessionPath); + + Debug::log(LOG, "[DBusManager] Initialized D-Bus connection. Service: {}. Login path: {}, Session path: {}", + std::string(destination), std::string(loginPath), std::string(sessionPath)); + } catch (const sdbus::Error& e) { + Debug::log(ERR, "[DBusManager] D-Bus connection initialization failed: {}", e.what()); + } +} + +std::shared_ptr DBusManager::getConnection() { + return m_pConnection; +} + +std::shared_ptr DBusManager::getLoginProxy() { + if (!m_pLoginProxy) + initializeConnection(); + + return m_pLoginProxy; +} + +std::shared_ptr DBusManager::getSessionProxy() { + if (!m_pSessionProxy) + initializeConnection(); + + return m_pSessionProxy; +} + +void DBusManager::setLockedHint(bool locked) { + if (!m_pSessionProxy) { + Debug::log(WARN, "[DBusManager] Cannot set locked hint: Proxy is not initialized."); + return; + } + + try { + const sdbus::ServiceName interface{"org.freedesktop.login1.Session"}; + m_pSessionProxy->callMethod("SetLockedHint").onInterface(interface).withArguments(locked); + + Debug::log(LOG, "[DBusManager] Sent 'SetLockedHint({})' on {}", locked, std::string(interface)); + } catch (const sdbus::Error& e) { + Debug::log(WARN, "[DBusManager] Failed to send 'SetLockedHint({})': {}", locked, e.what()); + } +} + +void DBusManager::sendUnlockSignal() { + if (!m_pSessionProxy) { + Debug::log(WARN, "[DBusManager] Unlock signal skipped: Proxy is not initialized."); + return; + } + + try { + const sdbus::ServiceName interface{"org.freedesktop.login1.Session"}; + m_pSessionProxy->callMethod("Unlock").onInterface(interface); + + Debug::log(LOG, "[DBusManager] Sent 'Unlock' on {}", std::string(interface)); + } catch (const sdbus::Error& e) { + Debug::log(WARN, "[DBusManager] Unlock signal failed: {}", e.what()); + } +} \ No newline at end of file diff --git a/src/core/DBusManager.hpp b/src/core/DBusManager.hpp new file mode 100644 index 00000000..66415779 --- /dev/null +++ b/src/core/DBusManager.hpp @@ -0,0 +1,27 @@ +#pragma once + +#include +#include +#include + +class DBusManager { +public: + static DBusManager& getInstance(); + + std::shared_ptr getConnection(); + std::shared_ptr getLoginProxy(); + std::shared_ptr getSessionProxy(); + + void setLockedHint(bool locked); + void sendUnlockSignal(); + +private: + DBusManager(); + ~DBusManager(); + + void initializeConnection(); + + std::shared_ptr m_pConnection; + std::shared_ptr m_pLoginProxy; + std::shared_ptr m_pSessionProxy; +}; diff --git a/src/core/hyprlock.cpp b/src/core/hyprlock.cpp index a61886da..db25da14 100644 --- a/src/core/hyprlock.cpp +++ b/src/core/hyprlock.cpp @@ -1,4 +1,5 @@ #include "hyprlock.hpp" +#include "DBusManager.hpp" #include "../helpers/Log.hpp" #include "../config/ConfigManager.hpp" #include "../renderer/Renderer.hpp" @@ -18,7 +19,6 @@ #include #include #include -#include #include using namespace Hyprutils::OS; @@ -422,8 +422,14 @@ void CHyprlock::run() { exit(1); } + auto& dbusManager = DBusManager::getInstance(); + const auto dbusConn = dbusManager.getConnection(); + dbusManager.setLockedHint(true); + const auto fingerprintAuth = g_pAuth->getImpl(AUTH_IMPL_FINGERPRINT); - const auto dbusConn = (fingerprintAuth) ? ((CFingerprint*)fingerprintAuth.get())->getConnection() : nullptr; + if (fingerprintAuth){ + fingerprintAuth->init(); + } registerSignalAction(SIGUSR1, handleUnlockSignal, SA_RESTART); registerSignalAction(SIGUSR2, handleForceUpdateSignal); @@ -995,6 +1001,11 @@ void CHyprlock::releaseSessionLock() { ext_session_lock_v1_unlock_and_destroy(m_sLockState.lock); m_sLockState.lock = nullptr; + // Notify unlock via D-Bus. + auto& dbusManager = DBusManager::getInstance(); + dbusManager.sendUnlockSignal(); + dbusManager.setLockedHint(false); + Debug::log(LOG, "Unlocked, exiting!"); m_bTerminate = true; diff --git a/src/core/hyprlock.hpp b/src/core/hyprlock.hpp index 8b2cdf85..4b860ebd 100644 --- a/src/core/hyprlock.hpp +++ b/src/core/hyprlock.hpp @@ -164,7 +164,7 @@ class CHyprlock { std::mutex timerRequestMutex; bool timerEvent = false; } m_sLoopState; - + std::vector> m_vTimers; std::vector m_vPressedKeys;