summaryrefslogtreecommitdiff
path: root/src/managers/SessionLockManager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/managers/SessionLockManager.cpp')
-rw-r--r--src/managers/SessionLockManager.cpp83
1 files changed, 55 insertions, 28 deletions
diff --git a/src/managers/SessionLockManager.cpp b/src/managers/SessionLockManager.cpp
index bfd819cf..9ef37806 100644
--- a/src/managers/SessionLockManager.cpp
+++ b/src/managers/SessionLockManager.cpp
@@ -3,9 +3,10 @@
#include "../config/ConfigValue.hpp"
#include "../protocols/FractionalScale.hpp"
#include "../protocols/SessionLock.hpp"
-#include "../managers/SeatManager.hpp"
#include "../render/Renderer.hpp"
-#include "../managers/input/InputManager.hpp"
+#include "./managers/SeatManager.hpp"
+#include "./managers/input/InputManager.hpp"
+#include "./managers/eventLoop/EventLoopManager.hpp"
#include <algorithm>
#include <ranges>
@@ -49,16 +50,19 @@ void CSessionLockManager::onNewSessionLock(SP<CSessionLock> pLock) {
static auto PALLOWRELOCK = CConfigValue<Hyprlang::INT>("misc:allow_session_lock_restore");
if (PROTO::sessionLock->isLocked() && !*PALLOWRELOCK) {
- Debug::log(LOG, "Cannot re-lock, misc:allow_session_lock_restore is disabled");
+ LOGM(LOG, "Cannot re-lock, misc:allow_session_lock_restore is disabled");
pLock->sendDenied();
return;
}
- Debug::log(LOG, "Session got locked by {:x}", (uintptr_t)pLock.get());
+ if (m_sessionLock && !clientDenied() && !clientLocked())
+ return; // Not allowing to relock in case the old lock is still in a limbo
+
+ LOGM(LOG, "Session got locked by {:x}", (uintptr_t)pLock.get());
m_sessionLock = makeUnique<SSessionLock>();
m_sessionLock->lock = pLock;
- m_sessionLock->mLockTimer.reset();
+ m_sessionLock->lockTimer.reset();
m_sessionLock->listeners.newSurface = pLock->m_events.newLockSurface.listen([this](const SP<CSessionLockSurface>& surface) {
const auto PMONITOR = surface->monitor();
@@ -87,14 +91,48 @@ void CSessionLockManager::onNewSessionLock(SP<CSessionLock> pLock) {
g_pCompositor->focusSurface(nullptr);
g_pSeatManager->setGrab(nullptr);
+ m_sessionLock->sendDeniedTimer = makeShared<CEventLoopTimer>(
+ // Within this arbitrary amount of time, a session-lock client is expected to create and commit a lock surface for each output. If the client fails to do that, it will be denied.
+ std::chrono::seconds(5),
+ [](auto, auto) {
+ if (!g_pSessionLockManager || g_pSessionLockManager->clientLocked() || g_pSessionLockManager->clientDenied())
+ return;
+
+ if (g_pCompositor->m_unsafeState || !g_pCompositor->m_aqBackend->hasSession() || !g_pCompositor->m_aqBackend->session->active) {
+ // Because the session is inactive, there is a good reason for why the client did't recieve locked or denied.
+ // We send locked, although this could lead to imperfect frames when we start to render again.
+ g_pSessionLockManager->m_sessionLock->lock->sendLocked();
+ g_pSessionLockManager->m_sessionLock->hasSentLocked = true;
+ return;
+ }
+
+ if (g_pSessionLockManager->m_sessionLock && g_pSessionLockManager->m_sessionLock->lock) {
+ g_pSessionLockManager->m_sessionLock->lock->sendDenied();
+ g_pSessionLockManager->m_sessionLock->hasSentDenied = true;
+ }
+ },
+ nullptr);
+
+ if (m_sessionLock->sendDeniedTimer)
+ g_pEventLoopManager->addTimer(m_sessionLock->sendDeniedTimer);
+
// Normally the locked event is sent after each output rendered a lock screen frame.
// When there are no outputs, send it right away.
if (g_pCompositor->m_unsafeState) {
+ removeSendDeniedTimer();
m_sessionLock->lock->sendLocked();
m_sessionLock->hasSentLocked = true;
}
}
+void CSessionLockManager::removeSendDeniedTimer() {
+ if (!m_sessionLock || !m_sessionLock->sendDeniedTimer)
+ return;
+
+ g_pEventLoopManager->removeTimer(m_sessionLock->sendDeniedTimer);
+ m_sessionLock->sendDeniedTimer.reset();
+}
+
bool CSessionLockManager::isSessionLocked() {
return PROTO::sessionLock->isLocked();
}
@@ -115,28 +153,13 @@ WP<SSessionLockSurface> CSessionLockManager::getSessionLockSurfaceForMonitor(uin
return {};
}
-// We don't want the red screen to flash.
-float CSessionLockManager::getRedScreenAlphaForMonitor(uint64_t id) {
- if (!m_sessionLock)
- return 1.F;
-
- const auto& NOMAPPEDSURFACETIMER = m_sessionLock->mMonitorsWithoutMappedSurfaceTimers.find(id);
-
- if (NOMAPPEDSURFACETIMER == m_sessionLock->mMonitorsWithoutMappedSurfaceTimers.end()) {
- m_sessionLock->mMonitorsWithoutMappedSurfaceTimers.emplace(id, CTimer());
- m_sessionLock->mMonitorsWithoutMappedSurfaceTimers[id].reset();
- return 0.f;
- }
-
- return std::clamp(NOMAPPEDSURFACETIMER->second.getSeconds() - /* delay for screencopy */ 0.5f, 0.f, 1.f);
-}
-
void CSessionLockManager::onLockscreenRenderedOnMonitor(uint64_t id) {
- if (!m_sessionLock || m_sessionLock->hasSentLocked)
+ if (!m_sessionLock || m_sessionLock->hasSentLocked || m_sessionLock->hasSentDenied)
return;
m_sessionLock->lockedMonitors.emplace(id);
const bool LOCKED = std::ranges::all_of(g_pCompositor->m_monitors, [this](auto m) { return m_sessionLock->lockedMonitors.contains(m->m_id); });
if (LOCKED && m_sessionLock->lock->good()) {
+ removeSendDeniedTimer();
m_sessionLock->lock->sendLocked();
m_sessionLock->hasSentLocked = true;
}
@@ -157,6 +180,10 @@ bool CSessionLockManager::isSurfaceSessionLock(SP<CWLSurfaceResource> pSurface)
return false;
}
+bool CSessionLockManager::anySessionLockSurfacesPresent() {
+ return m_sessionLock && std::ranges::any_of(m_sessionLock->vSessionLockSurfaces, [](const auto& surf) { return surf->mapped; });
+}
+
void CSessionLockManager::removeSessionLockSurface(SSessionLockSurface* pSLS) {
if (!m_sessionLock)
return;
@@ -175,19 +202,19 @@ void CSessionLockManager::removeSessionLockSurface(SSessionLockSurface* pSLS) {
}
}
-bool CSessionLockManager::isSessionLockPresent() {
- return m_sessionLock && !m_sessionLock->vSessionLockSurfaces.empty();
+bool CSessionLockManager::clientLocked() {
+ return m_sessionLock && m_sessionLock->hasSentLocked;
}
-bool CSessionLockManager::anySessionLockSurfacesPresent() {
- return m_sessionLock && std::ranges::any_of(m_sessionLock->vSessionLockSurfaces, [](const auto& surf) { return surf->mapped; });
+bool CSessionLockManager::clientDenied() {
+ return m_sessionLock && m_sessionLock->hasSentDenied;
}
bool CSessionLockManager::shallConsiderLockMissing() {
if (!m_sessionLock)
- return false;
+ return true;
static auto LOCKDEAD_SCREEN_DELAY = CConfigValue<Hyprlang::INT>("misc:lockdead_screen_delay");
- return m_sessionLock->mLockTimer.getMillis() > *LOCKDEAD_SCREEN_DELAY;
+ return m_sessionLock->lockTimer.getMillis() > *LOCKDEAD_SCREEN_DELAY;
}