session-lock: don't render workspaces when locked (#10865)
Avoid rendering the workspace behind if we are locked
This commit is contained in:
parent
d0f58baf29
commit
01971cb6c7
7 changed files with 129 additions and 81 deletions
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue