summaryrefslogtreecommitdiff
path: root/src/managers/SessionLockManager.cpp
diff options
context:
space:
mode:
authorMaximilian Seidler <78690852+PaideiaDilemma@users.noreply.github.com>2025-07-30 20:36:02 +0000
committerGitHub <noreply@github.com>2025-07-30 22:36:02 +0200
commitf309d860035373e6d1473142865fb8a39923f01f (patch)
tree0de8e7ecd4bc5cc84f08c85aad70cb2dcf54b20f /src/managers/SessionLockManager.cpp
parent38e13282cd5521a27a6e6dfe27109e93c64d049e (diff)
session-lock: explicitly consider dpms states for sending locked or denied (#11278)
* session-lock: explicitly consider dpms states for sending locked or denied * session-lock: check for active monitors before locking
Diffstat (limited to 'src/managers/SessionLockManager.cpp')
-rw-r--r--src/managers/SessionLockManager.cpp62
1 files changed, 35 insertions, 27 deletions
diff --git a/src/managers/SessionLockManager.cpp b/src/managers/SessionLockManager.cpp
index 68eee562..391b6dbb 100644
--- a/src/managers/SessionLockManager.cpp
+++ b/src/managers/SessionLockManager.cpp
@@ -91,36 +91,41 @@ void CSessionLockManager::onNewSessionLock(SP<CSessionLock> pLock) {
g_pCompositor->focusSurface(nullptr);
g_pSeatManager->setGrab(nullptr);
- if (!g_pCompositor->m_unsafeState) {
- 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 receive 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);
-
- g_pEventLoopManager->addTimer(m_sessionLock->sendDeniedTimer);
- } else {
+ const bool NOACTIVEMONS = std::ranges::all_of(g_pCompositor->m_monitors, [](const auto& m) { return !m->m_enabled || !m->m_dpmsStatus; });
+
+ if (NOACTIVEMONS || g_pCompositor->m_unsafeState) {
// Normally the locked event is sent after each output rendered a lock screen frame.
- // When there are no outputs, send it right away.
+ // When there are no active outputs, send it right away.
m_sessionLock->lock->sendLocked();
m_sessionLock->hasSentLocked = true;
+ return;
}
+
+ 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_pSessionLockManager->m_sessionLock || !g_pSessionLockManager->m_sessionLock->lock)
+ 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 manage to render to all outputs.
+ // 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;
+ }
+
+ LOGM(WARN, "Kicking lockscreen client, because it failed to render to all outputs within 5 seconds");
+ g_pSessionLockManager->m_sessionLock->lock->sendDenied();
+ g_pSessionLockManager->m_sessionLock->hasSentDenied = true;
+ },
+ nullptr);
+
+ g_pEventLoopManager->addTimer(m_sessionLock->sendDeniedTimer);
}
void CSessionLockManager::removeSendDeniedTimer() {
@@ -154,8 +159,11 @@ WP<SSessionLockSurface> CSessionLockManager::getSessionLockSurfaceForMonitor(uin
void CSessionLockManager::onLockscreenRenderedOnMonitor(uint64_t id) {
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); });
+ const bool LOCKED =
+ std::ranges::all_of(g_pCompositor->m_monitors, [this](auto m) { return !m->m_enabled || !m->m_dpmsStatus || m_sessionLock->lockedMonitors.contains(m->m_id); });
+
if (LOCKED && m_sessionLock->lock->good()) {
removeSendDeniedTimer();
m_sessionLock->lock->sendLocked();