Hyprland/src/managers/SessionLockManager.cpp

156 lines
5.2 KiB
C++
Raw Normal View History

2023-02-03 12:58:55 +01:00
#include "SessionLockManager.hpp"
#include "../Compositor.hpp"
#include "../config/ConfigValue.hpp"
2024-04-20 15:14:54 +02:00
#include "../protocols/FractionalScale.hpp"
2024-04-30 17:32:05 +02:00
#include "../protocols/SessionLock.hpp"
2023-02-03 12:58:55 +01:00
2024-04-30 17:32:05 +02:00
SSessionLockSurface::SSessionLockSurface(SP<CSessionLockSurface> surface_) : surface(surface_) {
pWlrSurface = surface->surface();
2023-02-03 12:58:55 +01:00
2024-04-30 17:32:05 +02:00
listeners.map = surface_->events.map.registerListener([this](std::any data) {
mapped = true;
2023-02-03 12:58:55 +01:00
g_pCompositor->focusSurface(surface->surface());
2023-02-03 12:58:55 +01:00
2024-04-30 17:32:05 +02:00
const auto PMONITOR = g_pCompositor->getMonitorFromID(iMonitorID);
2023-02-03 12:58:55 +01:00
2024-04-30 17:32:05 +02:00
if (PMONITOR)
g_pHyprRenderer->damageMonitor(PMONITOR);
});
2023-02-03 12:58:55 +01:00
2024-04-30 17:32:05 +02:00
listeners.destroy = surface_->events.destroy.registerListener([this](std::any data) {
if (pWlrSurface == g_pCompositor->m_pLastFocus)
g_pCompositor->m_pLastFocus.reset();
2023-02-03 12:58:55 +01:00
2024-04-30 17:32:05 +02:00
g_pSessionLockManager->removeSessionLockSurface(this);
});
2023-02-03 12:58:55 +01:00
2024-04-30 17:32:05 +02:00
listeners.commit = surface_->events.commit.registerListener([this](std::any data) {
const auto PMONITOR = g_pCompositor->getMonitorFromID(iMonitorID);
2023-02-03 12:58:55 +01:00
2024-04-30 17:32:05 +02:00
if (PMONITOR)
g_pHyprRenderer->damageMonitor(PMONITOR);
});
2023-02-03 12:58:55 +01:00
}
2024-04-30 17:32:05 +02:00
CSessionLockManager::CSessionLockManager() {
listeners.newLock = PROTO::sessionLock->events.newLock.registerListener([this](std::any data) { this->onNewSessionLock(std::any_cast<SP<CSessionLock>>(data)); });
2023-02-03 12:58:55 +01:00
}
2024-04-30 17:32:05 +02:00
void CSessionLockManager::onNewSessionLock(SP<CSessionLock> pLock) {
2023-02-03 12:58:55 +01:00
static auto PALLOWRELOCK = CConfigValue<Hyprlang::INT>("misc:allow_session_lock_restore");
2023-05-13 13:36:36 +02:00
2024-04-30 17:32:05 +02:00
if (PROTO::sessionLock->isLocked() && !*PALLOWRELOCK) {
Debug::log(LOG, "Cannot re-lock, misc:allow_session_lock_restore is disabled");
pLock->sendDenied();
2023-02-03 12:58:55 +01:00
return;
}
2024-04-30 17:32:05 +02:00
Debug::log(LOG, "Session got locked by {:x}", (uintptr_t)pLock.get());
2023-02-03 12:58:55 +01:00
2024-04-30 17:32:05 +02:00
m_pSessionLock = std::make_unique<SSessionLock>();
m_pSessionLock->lock = pLock;
2023-02-03 12:58:55 +01:00
2024-04-30 17:32:05 +02:00
m_pSessionLock->listeners.newSurface = pLock->events.newLockSurface.registerListener([this](std::any data) {
auto SURFACE = std::any_cast<SP<CSessionLockSurface>>(data);
2023-02-03 12:58:55 +01:00
2024-04-30 17:32:05 +02:00
const auto PMONITOR = SURFACE->monitor();
2023-02-03 12:58:55 +01:00
2024-04-30 17:32:05 +02:00
const auto NEWSURFACE = m_pSessionLock->vSessionLockSurfaces.emplace_back(std::make_unique<SSessionLockSurface>(SURFACE)).get();
NEWSURFACE->iMonitorID = PMONITOR->ID;
PROTO::fractional->sendScale(SURFACE->surface(), PMONITOR->scale);
});
2023-02-03 12:58:55 +01:00
2024-04-30 17:32:05 +02:00
m_pSessionLock->listeners.unlock = pLock->events.unlockAndDestroy.registerListener([this](std::any data) {
m_pSessionLock.reset();
g_pInputManager->refocus();
2024-04-30 17:32:05 +02:00
for (auto& m : g_pCompositor->m_vMonitors)
g_pHyprRenderer->damageMonitor(m.get());
});
2023-02-03 12:58:55 +01:00
m_pSessionLock->listeners.destroy = pLock->events.destroyed.registerListener([](std::any data) {
2024-04-30 17:32:05 +02:00
g_pCompositor->focusSurface(nullptr);
2023-02-03 12:58:55 +01:00
2024-04-30 17:32:05 +02:00
for (auto& m : g_pCompositor->m_vMonitors)
g_pHyprRenderer->damageMonitor(m.get());
});
2023-02-03 12:58:55 +01:00
2024-04-30 17:32:05 +02:00
pLock->sendLocked();
2023-02-03 12:58:55 +01:00
}
bool CSessionLockManager::isSessionLocked() {
2024-04-30 17:32:05 +02:00
return PROTO::sessionLock->isLocked();
2023-02-03 12:58:55 +01:00
}
SSessionLockSurface* CSessionLockManager::getSessionLockSurfaceForMonitor(uint64_t id) {
2024-04-30 17:32:05 +02:00
if (!m_pSessionLock)
return nullptr;
for (auto& sls : m_pSessionLock->vSessionLockSurfaces) {
2023-02-03 12:58:55 +01:00
if (sls->iMonitorID == id) {
if (sls->mapped)
return sls.get();
else
return nullptr;
}
}
return nullptr;
}
// We don't want the red screen to flash.
// This violates the protocol a bit, but tries to handle the missing sync between a lock surface beeing created and the red screen beeing drawn.
float CSessionLockManager::getRedScreenAlphaForMonitor(uint64_t id) {
2024-04-30 17:32:05 +02:00
if (!m_pSessionLock)
return 0.F;
2024-04-30 17:32:05 +02:00
const auto& NOMAPPEDSURFACETIMER = m_pSessionLock->mMonitorsWithoutMappedSurfaceTimers.find(id);
if (NOMAPPEDSURFACETIMER == m_pSessionLock->mMonitorsWithoutMappedSurfaceTimers.end()) {
m_pSessionLock->mMonitorsWithoutMappedSurfaceTimers.emplace(id, CTimer());
m_pSessionLock->mMonitorsWithoutMappedSurfaceTimers[id].reset();
return 0.f;
}
return std::clamp(NOMAPPEDSURFACETIMER->second.getSeconds() - /* delay for screencopy */ 0.5f, 0.f, 1.f);
}
bool CSessionLockManager::isSurfaceSessionLock(SP<CWLSurfaceResource> pSurface) {
2024-04-30 17:32:05 +02:00
// TODO: this has some edge cases when it's wrong (e.g. destroyed lock but not yet surfaces)
// but can be easily fixed when I rewrite wlr_surface
if (!m_pSessionLock)
return false;
for (auto& sls : m_pSessionLock->vSessionLockSurfaces) {
if (sls->surface->surface() == pSurface)
2023-02-03 12:58:55 +01:00
return true;
}
return false;
}
void CSessionLockManager::removeSessionLockSurface(SSessionLockSurface* pSLS) {
2024-04-30 17:32:05 +02:00
if (!m_pSessionLock)
return;
std::erase_if(m_pSessionLock->vSessionLockSurfaces, [&](const auto& other) { return pSLS == other.get(); });
if (g_pCompositor->m_pLastFocus)
return;
2024-04-30 17:32:05 +02:00
for (auto& sls : m_pSessionLock->vSessionLockSurfaces) {
if (!sls->mapped)
continue;
g_pCompositor->focusSurface(sls->surface->surface());
break;
}
2023-02-03 12:58:55 +01:00
}
2024-04-30 17:32:05 +02:00
bool CSessionLockManager::isSessionLockPresent() {
return m_pSessionLock && !m_pSessionLock->vSessionLockSurfaces.empty();
}